Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiprocessing exception: No Child processes #193

Open
jeffforbes opened this issue Aug 25, 2015 · 10 comments
Open

multiprocessing exception: No Child processes #193

jeffforbes opened this issue Aug 25, 2015 · 10 comments
Labels
bug Something isn't working

Comments

@jeffforbes
Copy link

I recently modified the logging in a recent version of websocket.py so that the all of the loggeded information would go to a log file. I am not sure if my changes have caused a recurrence of the multiprocessing exception that was fixed in 2013. This error occurs on a RHEL-5 system with python2.4

Below in the error trace :

2015-08-20 03:00:58,182 exception
Traceback (most recent call last):
File "/opt/websockify/websocket.py", line 977, in start_server
child_count = len(multiprocessing.active_children())
File "/usr/lib64/python2.4/site-packages/multiprocessing/process.py", line 48, in active_children
_cleanup()
File "/usr/lib64/python2.4/site-packages/multiprocessing/process.py", line 58, in _cleanup
if p._popen.poll() is not None:
File "/usr/lib64/python2.4/site-packages/multiprocessing/forking.py", line 106, in poll
pid, sts = os.waitpid(self.pid, flag)
OSError: [Errno 10] No child processes
2015-08-20 03:00:58,182 handler exception: [Errno 10] No child processes

The error only shows up on a busy site which is spawning many child processes.
When this error occurs, the parent process CPU eventually goes to 100% and the log file get filled with these messages. if verbose is off, then only the "OSError: [Errno 10] No child processes" is recorded.

Any ideas what may be causing this exception?

I have modified the code for logging to go to a file.
I changed the reference to self.log_message to self.msg so that the location of the logged messages
would be consistent. I then set up a file handler to replace the streamhandler with a filehandler. I then added a new command line argument to turn on/off the logging to a file. I don't think that these logging changes would affect the multiprocessing module. I can put up a diff if it would be helpful.

@DirectXMan12
Copy link
Member

X-Post from novnc/noVNC#523. Can you post a diff of the new code please?

@DirectXMan12 DirectXMan12 added bug Something isn't working python labels Aug 25, 2015
@jeffforbes
Copy link
Author

The first file is the one that I am testing and the second is current one off of the github source

#diff /opt/websockify/websocketproxy.py ./websocketproxy.py
14c14
< import signal, socket, optparse, time, os, sys, subprocess, logging
---
> import signal, socket, optparse, time, os, sys, subprocess, logging, errno
19c19
< from select import select
---
> import select
49a50,54
>         if self.server.auth_plugin:
>             self.server.auth_plugin.authenticate(
>                 headers=self.headers, target_host=self.server.target_host,
>                 target_port=self.server.target_port)
> 
61c66
<         self.msg(msg)
---
>         self.log_message(msg)
77c82
<                     self.msg("%s:%s: Closed target",
---
>                     self.log_message("%s:%s: Closed target",
131c136,149
<             ins, outs, excepts = select(rlist, wlist, [], 1)
---
>             try:
>                 ins, outs, excepts = select.select(rlist, wlist, [], 1)
>             except (select.error, OSError):
>                 exc = sys.exc_info()[1]
>                 if hasattr(exc, 'errno'):
>                     err = exc.errno
>                 else:
>                     err = exc[0]
> 
>                 if err != errno.EINTR:
>                     raise
>                 else:
>                     continue
> 
148c166
<                         self.msg("%s:%s: Client closed connection",
---
>                         self.log_message("%s:%s: Client closed connection",
170c188
<                         self.msg("%s:%s: Target closed connection",
---
>                         self.log_message("%s:%s: Target closed connection",
197,211c215,216
<         token_plugin = kwargs.pop('token_plugin', None)
<         token_source = kwargs.pop('token_source', None)
< 
<         if token_plugin is not None:
<             if '.' not in token_plugin:
<                 token_plugin = 'websockify.token_plugins.%s' % token_plugin
< 
<             token_plugin_module, token_plugin_cls = token_plugin.rsplit('.', 1)
< 
<             __import__(token_plugin_module)
<             token_plugin_cls = getattr(sys.modules[token_plugin_module], token_plugin_cls)
< 
<             self.token_plugin = token_plugin_cls(token_source)
<         else:
<             self.token_plugin = None
---
>         self.token_plugin = kwargs.pop('token_plugin', None)
>         self.auth_plugin = kwargs.pop('auth_plugin', None)
308a314
> 
314c320,321
< def logger_init(logFile, logFileName):
---
> 
> def logger_init():
318,324c325
<     if not logFile:
<         h = logging.StreamHandler()
<     else:
<         h = logging.FileHandler(logFileName)
< # Redirect stdout and stderr to the logging facility
<         sys.stderr = h.stream
<         sys.stdout = h.stream
---
>     h = logging.StreamHandler()
326c327
<     h.setFormatter(logging.Formatter("%(asctime)-15s %(message)s"))
---
>     h.setFormatter(logging.Formatter("%(message)s"))
328a330
> 
329a332
>     logger_init()
385a389,394
>     parser.add_option("--auth-plugin", default=None, metavar="PLUGIN",
>                       help="use the given Python class to determine if "
>                            "a connection is allowed")
>     parser.add_option("--auth-source", default=None, metavar="ARG",
>                       help="an argument to be passed to the auth plugin"
>                            "on instantiation")
390,393d398
<     parser.add_option("--log-file", dest="log_file", action="store_true",
<                       help="Store logging to a log file", default=False)
<     parser.add_option("--log-file-name", dest="log_file_name", default="/var/log/websockify",
<             help="Absolute path to log file")
396d400
<     logger_init(opts.log_file, opts.log_file_name)
403a408,411
>     if opts.auth_source and not opts.auth_plugin:
>         parser.error("You must use --auth-plugin to use --auth-source")
> 
> 
451a460,486
>     if opts.token_plugin is not None:
>         if '.' not in opts.token_plugin:
>             opts.token_plugin = (
>                 'websockify.token_plugins.%s' % opts.token_plugin)
> 
>         token_plugin_module, token_plugin_cls = opts.token_plugin.rsplit('.', 1)
> 
>         __import__(token_plugin_module)
>         token_plugin_cls = getattr(sys.modules[token_plugin_module], token_plugin_cls)
>
>         opts.token_plugin = token_plugin_cls(opts.token_source)
>
>     del opts.token_source
>
>     if opts.auth_plugin is not None:
>         if '.' not in opts.auth_plugin:
>             opts.auth_plugin = 'websockify.auth_plugins.%s' % opts.auth_plugin
>
>         auth_plugin_module, auth_plugin_cls = opts.auth_plugin.rsplit('.', 1)
>
>         __import__(auth_plugin_module)
>         auth_plugin_cls = getattr(sys.modules[auth_plugin_module], auth_plugin_cls)
>
>         opts.auth_plugin = auth_plugin_cls(opts.auth_source)
>
>     del opts.auth_source
>
480c515
<         self.token_source   = kwargs.pop('token_source', None)
---
>         self.auth_plugin    = kwargs.pop('auth_plugin', None)
483a519
>         self.auth_plugin = None
517a554
>

The first file is the one that I am testing and the second is the current version on github:

# diff /opt/websockify/websocket.py ./websocket.py     
107a108
>         self.strict_mode = getattr(server, "strict_mode", True)
112d112
<         self.log_file = getattr(server, "log_file", False)
181c181
<     def decode_hybi(buf, base64=False, logger=None):
---
>     def decode_hybi(buf, base64=False, logger=None, strict=True):
246a247,250
> 
>             if strict:
>                 raise WebSocketRequestHandler.CClose(1002, "The client sent an unmasked frame.")
> 
355c359,360
<                                      logger=self.logger)
---
>                                      logger=self.logger,
>                                      strict=self.strict_mode)
499c504
<             self.msg("%s: %s WebSocket connection", client_addr,
---
>             self.log_message("%s: %s WebSocket connection", client_addr,
501c506
<             self.msg("%s: Version %s, base64: '%s'", client_addr,
---
>             self.log_message("%s: Version %s, base64: '%s'", client_addr,
504c509
<                 self.msg("%s: Path: '%s'", client_addr, self.path)
---
>                 self.log_message("%s: Path: '%s'", client_addr, self.path)
510c515
<                 self.msg("opening record file: %s", fname)
---
>                 self.log_message("opening record file: %s", fname)
592c597
<             file_only=False, log_file=False, log_file_name='',
---
>             file_only=False,
595c600
<             tcp_keepintvl=None, auto_pong=False):
---
>             tcp_keepintvl=None, auto_pong=False, strict_mode=True):
608a614,615
>         self.file_only      = file_only
>         self.strict_mode    = strict_mode
615d621
<         self.log_file       = log_file
648c654,657
<             self.msg("  - Web server. Web root: %s", self.web)
---
>             if self.file_only:
>                 self.msg("  - Web server (no directory listings). Web root: %s", self.web)
>             else:
>                 self.msg("  - Web server. Web root: %s", self.web)
730c739
<     def daemonize(keepfd=[], chdir='/', stdStream=None):
---
>     def daemonize(keepfd=None, chdir='/'):
753c762
<                 if (fd not in keepfd ):
---
>                 if fd != keepfd:
761,766c770,771
<         if stdStream :
<             sys.stdout = stdStream
<             sys.stderr = stdStream
<         else:
<             os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdout.fileno())
<             os.dup2(os.open(os.devnull, os.O_RDWR), sys.stderr.fileno())
---
>         os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdout.fileno())
>         os.dup2(os.open(os.devnull, os.O_RDWR), sys.stderr.fileno())
795c800
<         if handshake == "":
---
>         if not handshake:
939,946c944
<             if self.log_file:
< # Get the stream for the log file so that it can be used for logging in the daemon mode
<                 logStream = self.logger.parent.handlers[0].stream
<                 files_preserve = [lsock.fileno(), logStream.fileno()]
<                 self.daemonize(files_preserve, self.web, logStream)
<             else:
<                 files_preserve =  [lsock.fileno()]
<                 self.daemonize(files_preserve, self.web)
---
>             self.daemonize(keepfd=lsock.fileno(), chdir=self.web)
1052d1049
<                         _, exc, _ = sys.exc_info()

@kanaka
Copy link
Member

kanaka commented Aug 25, 2015

@jeffforbes I quoted your diff so that it's a least formatted correctly. However, please provide a unified diff (diff -up). The default format of diff (which really shouldn't be default any more) is neither particularly readable nor as reliable for patching.

@DirectXMan12
Copy link
Member

@jeffforbes Can you clarify which version of Python 2.4 you're using? It's possible that you've run into something like this: http://bugs.python.org/issue1731717#msg122556

Also, this may be a bit of a stretch for you, but are you able to reproduce on Python 2.7?

@jeffforbes
Copy link
Author

Python 2.4.3 (#1, Oct 23 2012, 22:02:41)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2

We have not determined what causes the error to arise on the system running Python 2.4.3, so it would be difficult to test on python 2.7 or higher. When the error does occur, the process produces a deluge of the errors (which can quickly fill the logging partition) and the CPU usage for the parent websockify process goes up to 100%.

@jeffforbes
Copy link
Author

./websocket.py is the current github version
/opt/websockify/websocket.py is my version based on a May 2015 github version

# diff -up ./websocket.py /opt/websockify/websocket.py           
--- ./websocket.py      2015-08-24 12:14:43.000000000 -0400
+++ /opt/websockify/websocket.py        2015-05-07 17:28:12.000000000 -0400
@@ -105,11 +105,11 @@ class WebSocketRequestHandler(SimpleHTTP
         self.file_only = getattr(server, "file_only", False)
         self.traffic = getattr(server, "traffic", False)
         self.auto_pong = getattr(server, "auto_pong", False)
-        self.strict_mode = getattr(server, "strict_mode", True)

         self.logger = getattr(server, "logger", None)
         if self.logger is None:
             self.logger = WebSocketServer.get_logger()
+        self.log_file = getattr(server, "log_file", False)

         SimpleHTTPRequestHandler.__init__(self, req, addr, server)

@@ -178,7 +178,7 @@ class WebSocketRequestHandler(SimpleHTTP
         return header + buf, len(header), 0

     @staticmethod
-    def decode_hybi(buf, base64=False, logger=None, strict=True):
+    def decode_hybi(buf, base64=False, logger=None):
         """ Decode HyBi style WebSocket packets.
         Returns:
             {'fin'          : 0_or_1,
@@ -244,10 +244,6 @@ class WebSocketRequestHandler(SimpleHTTP
                                                   f['length'])
         else:
             logger.debug("Unmasked frame: %s" % repr(buf))
-
-            if strict:
-                raise WebSocketRequestHandler.CClose(1002, "The client sent an unmasked frame.")
-
             f['payload'] = buf[(f['hlen'] + f['masked'] * 4):full_len]

         if base64 and f['opcode'] in [1, 2]:
@@ -356,8 +352,7 @@ class WebSocketRequestHandler(SimpleHTTP

         while buf:
             frame = self.decode_hybi(buf, base64=self.base64,
-                                     logger=self.logger,
-                                     strict=self.strict_mode)
+                                     logger=self.logger)
             #self.msg("Received buf: %s, frame: %s", repr(buf), frame)

             if frame['payload'] == None:
@@ -501,18 +496,18 @@ class WebSocketRequestHandler(SimpleHTTP
             else:
                 self.stype = "Plain non-SSL (ws://)"

-            self.log_message("%s: %s WebSocket connection", client_addr,
+            self.msg("%s: %s WebSocket connection", client_addr,
                              self.stype)
-            self.log_message("%s: Version %s, base64: '%s'", client_addr,
+            self.msg("%s: Version %s, base64: '%s'", client_addr,
                              self.version, self.base64)
             if self.path != '/':
-                self.log_message("%s: Path: '%s'", client_addr, self.path)
+                self.msg("%s: Path: '%s'", client_addr, self.path)

             if self.record:
                 # Record raw frame data as JavaScript array
                 fname = "%s.%s" % (self.record,
                                    self.handler_id)
-                self.log_message("opening record file: %s", fname)
+                self.msg("opening record file: %s", fname)
                 self.rec = open(fname, 'w+')
                 encoding = "binary"
                 if self.base64: encoding = "base64"
@@ -594,10 +589,10 @@ class WebSocketServer(object):
                  listen_port=None, source_is_ipv6=False,
             verbose=False, cert='', key='', ssl_only=None,
             daemon=False, record='', web='',
-            file_only=False,
+            file_only=False, log_file=False, log_file_name='',
             run_once=False, timeout=0, idle_timeout=0, traffic=False,
             tcp_keepalive=True, tcp_keepcnt=None, tcp_keepidle=None,
-            tcp_keepintvl=None, auto_pong=False, strict_mode=True):
+            tcp_keepintvl=None, auto_pong=False):

         # settings
         self.RequestHandlerClass = RequestHandlerClass
@@ -611,14 +606,13 @@ class WebSocketServer(object):
         self.timeout        = timeout
         self.idle_timeout   = idle_timeout
         self.traffic        = traffic
-        self.file_only      = file_only
-        self.strict_mode    = strict_mode

         self.launch_time    = time.time()
         self.ws_connection  = False
         self.handler_id     = 1

         self.logger         = self.get_logger()
+        self.log_file       = log_file
         self.tcp_keepalive  = tcp_keepalive
         self.tcp_keepcnt    = tcp_keepcnt
         self.tcp_keepidle   = tcp_keepidle
@@ -651,10 +645,7 @@ class WebSocketServer(object):
                 self.listen_host, self.listen_port)
         self.msg("  - Flash security policy server")
         if self.web:
-            if self.file_only:
-                self.msg("  - Web server (no directory listings). Web root: %s", self.web)
-            else:
-                self.msg("  - Web server. Web root: %s", self.web)
+            self.msg("  - Web server. Web root: %s", self.web)
         if ssl:
             if os.path.exists(self.cert):
                 self.msg("  - SSL/TLS support")
@@ -736,7 +727,7 @@ class WebSocketServer(object):
         return sock

     @staticmethod
-    def daemonize(keepfd=None, chdir='/'):
+    def daemonize(keepfd=[], chdir='/', stdStream=None):
         os.umask(0)
         if chdir:
             os.chdir(chdir)
@@ -759,7 +750,7 @@ class WebSocketServer(object):
         if maxfd == resource.RLIM_INFINITY: maxfd = 256
         for fd in reversed(range(maxfd)):
             try:
-                if fd != keepfd:
+                if (fd not in keepfd ):
                     os.close(fd)
             except OSError:
                 _, exc, _ = sys.exc_info()
@@ -767,8 +758,12 @@ class WebSocketServer(object):

         # Redirect I/O to /dev/null
         os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdin.fileno())
-        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdout.fileno())
-        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stderr.fileno())
+        if stdStream :
+            sys.stdout = stdStream
+            sys.stderr = stdStream
+        else:
+            os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdout.fileno())
+            os.dup2(os.open(os.devnull, os.O_RDWR), sys.stderr.fileno())

     def do_handshake(self, sock, address):
         """
@@ -797,7 +792,7 @@ class WebSocketServer(object):
         handshake = sock.recv(1024, socket.MSG_PEEK)
         #self.msg("Handshake [%s]" % handshake)

-        if not handshake:
+        if handshake == "":
             raise self.EClose("ignoring empty handshake")

         elif handshake.startswith(s2b("<policy-file-request/>")):
@@ -941,7 +936,14 @@ class WebSocketServer(object):
                             tcp_keepintvl=self.tcp_keepintvl)

         if self.daemon:
-            self.daemonize(keepfd=lsock.fileno(), chdir=self.web)
+            if self.log_file:
+# Get the stream for the log file so that it can be used for logging in the daemon mode
+                logStream = self.logger.parent.handlers[0].stream
+                files_preserve = [lsock.fileno(), logStream.fileno()]
+                self.daemonize(files_preserve, self.web, logStream)
+            else:
+                files_preserve =  [lsock.fileno()]
+                self.daemonize(files_preserve, self.web)

         self.started()  # Some things need to happen after daemonizing

@@ -1047,6 +1049,7 @@ class WebSocketServer(object):
                         self.msg("In exit")
                         break
                     except Exception:
+                        _, exc, _ = sys.exc_info()
                         self.msg("handler exception: %s", str(exc))
                         self.vmsg("exception", exc_info=True)

@jeffforbes
Copy link
Author

./websocketproxy.py is the current version for github
/opt/websockify/websocketproxy.py is my modified version base on a May 2015 github version

# diff -up ./websocketproxy.py /opt/websockify/websocketproxy.py 
--- ./websocketproxy.py 2015-08-25 09:09:00.000000000 -0400
+++ /opt/websockify/websocketproxy.py   2015-05-07 17:28:12.000000000 -0400
@@ -11,12 +11,12 @@ as taken from http://docs.python.org/dev

 '''

-import signal, socket, optparse, time, os, sys, subprocess, logging, errno
+import signal, socket, optparse, time, os, sys, subprocess, logging
 try:    from socketserver import ForkingMixIn
 except: from SocketServer import ForkingMixIn
 try:    from http.server import HTTPServer
 except: from BaseHTTPServer import HTTPServer
-import select
+from select import select
 from websockify import websocket
 try:
     from urllib.parse import parse_qs, urlparse
@@ -47,11 +47,6 @@ Traffic Legend:
         if self.server.token_plugin:
             (self.server.target_host, self.server.target_port) = self.get_target(self.server.token_plugin, self.path)

-        if self.server.auth_plugin:
-            self.server.auth_plugin.authenticate(
-                headers=self.headers, target_host=self.server.target_host,
-                target_port=self.server.target_port)
-
         # Connect to the target
         if self.server.wrap_cmd:
             msg = "connecting to command: '%s' (port %s)" % (" ".join(self.server.wrap_cmd), self.server.target_port)
@@ -63,7 +58,7 @@ Traffic Legend:

         if self.server.ssl_target:
             msg += " (using SSL)"
-        self.log_message(msg)
+        self.msg(msg)

         tsock = websocket.WebSocketServer.socket(self.server.target_host,
                                                  self.server.target_port,
@@ -79,7 +74,7 @@ Traffic Legend:
                 tsock.shutdown(socket.SHUT_RDWR)
                 tsock.close()
                 if self.verbose:
-                    self.log_message("%s:%s: Closed target",
+                    self.msg("%s:%s: Closed target",
                             self.server.target_host, self.server.target_port)
             raise

@@ -133,20 +128,7 @@ Traffic Legend:

             if tqueue: wlist.append(target)
             if cqueue or c_pend: wlist.append(self.request)
-            try:
-                ins, outs, excepts = select.select(rlist, wlist, [], 1)
-            except (select.error, OSError):
-                exc = sys.exc_info()[1]
-                if hasattr(exc, 'errno'):
-                    err = exc.errno
-                else:
-                    err = exc[0]
-
-                if err != errno.EINTR:
-                    raise
-                else:
-                    continue
-
+            ins, outs, excepts = select(rlist, wlist, [], 1)
             if excepts: raise Exception("Socket exception")

             if self.request in outs:
@@ -163,7 +145,7 @@ Traffic Legend:
                 if closed:
                     # TODO: What about blocking on client socket?
                     if self.verbose:
-                        self.log_message("%s:%s: Client closed connection",
+                        self.msg("%s:%s: Client closed connection",
                                 self.server.target_host, self.server.target_port)
                     raise self.CClose(closed['code'], closed['reason'])

@@ -185,7 +167,7 @@ Traffic Legend:
                 buf = target.recv(self.buffer_size)
                 if len(buf) == 0:
                     if self.verbose:
-                        self.log_message("%s:%s: Target closed connection",
+                        self.msg("%s:%s: Target closed connection",
                                 self.server.target_host, self.server.target_port)
                     raise self.CClose(1000, "Target closed")

@@ -212,8 +194,21 @@ class WebSocketProxy(websocket.WebSocket
         self.ssl_target     = kwargs.pop('ssl_target', None)
         self.heartbeat      = kwargs.pop('heartbeat', None)

-        self.token_plugin = kwargs.pop('token_plugin', None)
-        self.auth_plugin = kwargs.pop('auth_plugin', None)
+        token_plugin = kwargs.pop('token_plugin', None)
+        token_source = kwargs.pop('token_source', None)
+
+        if token_plugin is not None:
+            if '.' not in token_plugin:
+                token_plugin = 'websockify.token_plugins.%s' % token_plugin
+
+            token_plugin_module, token_plugin_cls = token_plugin.rsplit('.', 1)
+
+            __import__(token_plugin_module)
+            token_plugin_cls = getattr(sys.modules[token_plugin_module], token_plugin_cls)
+
+            self.token_plugin = token_plugin_cls(token_source)
+        else:
+            self.token_plugin = None

         # Last 3 timestamps command was run
         self.wrap_times    = [0, 0, 0]
@@ -311,25 +306,27 @@ class WebSocketProxy(websocket.WebSocket
                 else:
                     self.run_wrap_cmd()

-
 def _subprocess_setup():
     # Python installs a SIGPIPE handler by default. This is usually not what
     # non-Python successfulbprocesses expect.
     signal.signal(signal.SIGPIPE, signal.SIG_DFL)

-
-def logger_init():
+def logger_init(logFile, logFileName):
     logger = logging.getLogger(WebSocketProxy.log_prefix)
     logger.propagate = False
     logger.setLevel(logging.INFO)
-    h = logging.StreamHandler()
+    if not logFile:
+        h = logging.StreamHandler()
+    else:
+        h = logging.FileHandler(logFileName)
+# Redirect stdout and stderr to the logging facility
+        sys.stderr = h.stream
+        sys.stdout = h.stream
     h.setLevel(logging.DEBUG)
-    h.setFormatter(logging.Formatter("%(message)s"))
+    h.setFormatter(logging.Formatter("%(asctime)-15s %(message)s"))
     logger.addHandler(h)

-
 def websockify_init():
-    logger_init()

     usage = "\n    %prog [options]"
     usage += " [source_addr:]source_port [target_addr:target_port]"
@@ -386,18 +383,17 @@ def websockify_init():
     parser.add_option("--token-source", default=None, metavar="ARG",
                       help="an argument to be passed to the token plugin"
                            "on instantiation")
-    parser.add_option("--auth-plugin", default=None, metavar="PLUGIN",
-                      help="use the given Python class to determine if "
-                           "a connection is allowed")
-    parser.add_option("--auth-source", default=None, metavar="ARG",
-                      help="an argument to be passed to the auth plugin"
-                           "on instantiation")
     parser.add_option("--auto-pong", action="store_true",
             help="Automatically respond to ping frames with a pong")
     parser.add_option("--heartbeat", type=int, default=0,
             help="send a ping to the client every HEARTBEAT seconds")
+    parser.add_option("--log-file", dest="log_file", action="store_true",
+                      help="Store logging to a log file", default=False)
+    parser.add_option("--log-file-name", dest="log_file_name", default="/var/log/websockify",
+            help="Absolute path to log file")

     (opts, args) = parser.parse_args()
+    logger_init(opts.log_file, opts.log_file_name)

     if opts.verbose:
         logging.getLogger(WebSocketProxy.log_prefix).setLevel(logging.DEBUG)
@@ -405,10 +401,6 @@ def websockify_init():
     if opts.token_source and not opts.token_plugin:
         parser.error("You must use --token-plugin to use --token-source")

-    if opts.auth_source and not opts.auth_plugin:
-        parser.error("You must use --auth-plugin to use --auth-source")
-
-
     # Transform to absolute path as daemon may chdir
     if opts.target_cfg:
         opts.target_cfg = os.path.abspath(opts.target_cfg)
@@ -457,33 +449,6 @@ def websockify_init():
         try:    opts.target_port = int(opts.target_port)
         except: parser.error("Error parsing target port")

-    if opts.token_plugin is not None:
-        if '.' not in opts.token_plugin:
-            opts.token_plugin = (
-                'websockify.token_plugins.%s' % opts.token_plugin)
-
-        token_plugin_module, token_plugin_cls = opts.token_plugin.rsplit('.', 1)
-
-        __import__(token_plugin_module)
-        token_plugin_cls = getattr(sys.modules[token_plugin_module], token_plugin_cls)
-
-        opts.token_plugin = token_plugin_cls(opts.token_source)
-
-    del opts.token_source
-
-    if opts.auth_plugin is not None:
-        if '.' not in opts.auth_plugin:
-            opts.auth_plugin = 'websockify.auth_plugins.%s' % opts.auth_plugin
-
-        auth_plugin_module, auth_plugin_cls = opts.auth_plugin.rsplit('.', 1)
-
-        __import__(auth_plugin_module)
-        auth_plugin_cls = getattr(sys.modules[auth_plugin_module], auth_plugin_cls)
-
-        opts.auth_plugin = auth_plugin_cls(opts.auth_source)
-
-    del opts.auth_source
-
     # Create and start the WebSockets proxy
     libserver = opts.libserver
     del opts.libserver
@@ -512,11 +477,10 @@ class LibProxyServer(ForkingMixIn, HTTPS
         self.unix_target    = kwargs.pop('unix_target', None)
         self.ssl_target     = kwargs.pop('ssl_target', None)
         self.token_plugin   = kwargs.pop('token_plugin', None)
-        self.auth_plugin    = kwargs.pop('auth_plugin', None)
+        self.token_source   = kwargs.pop('token_source', None)
         self.heartbeat      = kwargs.pop('heartbeat', None)

         self.token_plugin = None
-        self.auth_plugin = None
         self.daemon = False

         # Server configuration
@@ -551,4 +515,3 @@ class LibProxyServer(ForkingMixIn, HTTPS

 if __name__ == '__main__':
     websockify_init()
-

@DirectXMan12
Copy link
Member

Python 2.4.3 (#1, Oct 23 2012, 22:02:41) [GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2

It could be the issue I linked above then, although it's strange that it only occurs with your modifications. @astrand have you guys seen anything think this? You have some Python 2.4 systems, correct?

@astrand
Copy link

astrand commented Aug 27, 2015

We have not seen this, but we are not using websocketproxy but only websocket.py.

@jeffforbes
Copy link
Author

The error we are getting:
handler exception: [Errno 10] No child processes

can come from one of these lines in websockify.py
915 self.msg("handler exception: %s" % str(exc))
1053 self.msg("handler exception: %s", str(exc))

Will there be different behavior between using a "," or a "%" between the arguments causing a different output? I am not a python expert, so please forgive me if this is not really relevant.

When this error is thrown, it comes many times per second.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants