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 #523

Closed
jeffforbes opened this issue Aug 24, 2015 · 1 comment
Closed

multiprocessing exception: No Child processes #523

jeffforbes opened this issue Aug 24, 2015 · 1 comment
Labels

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. 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.

Please advise on any possible solutions.

Below in the diff between my modified version and the most recent version from the GitHub site:

# 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()
[root@rndgw tmp]# diff /opt/websockify/websocket.py websocket.py  | less
[root@rndgw tmp]# less  websocket.py                                   
[root@rndgw tmp]# diff /opt/websockify/websocket.py websocket.py  | less
[root@rndgw tmp]# 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()
@DirectXMan12
Copy link
Member

This actually looks like a websockify issue. Also, you shouldn't need to make many changes to log to a file -- websockify now uses the python logging module from the standard library, so it should be a pretty simple change to log to a file (replace the StreamHandler with a FileHandler in websocketproxy.py if you're running websocketproxy.py directly, or use logging.basicConfig at the top of your application if you're using websockify as a library)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants