简体   繁体   中英

Issues with python-gevent and python-daemon

So I've been trying to make a process that runs a server in the background, and start it with a daemon process. So my code is:

class App():
  def __init__(self):
    self.stdin_path = '/dev/null'
    self.stdout_path = '/dev/tty'
    self.stderr_path = '/dev/tty'
    self.pidfile_path = '/tmp/foo.pid'
    self.pidfile_timeout = 5
  def run(self):
    server = WSGIServer(('localhost',28080),handle_request)
    server.serve_forever()

if __name__ == '__main__':
  app = App()
  daemon_runner = runner.DaemonRunner(app)
  daemon_runner.do_action()

However, this gives me the error:

[warn] Epoll ADD(1) on fd 5 failed.  Old events were 0; read change was 1 (add); write change was 0 (none): Invalid argument
Traceback (most recent call last):
  File "enrollmentrunner2.py", line 110, in <module>
    daemon_runner.do_action()
  File "/usr/lib/python2.7/dist-packages/daemon/runner.py", line 186, in do_action
    func(self)
  File "/usr/lib/python2.7/dist-packages/daemon/runner.py", line 131, in _start
    self.app.run()
  File "enrollmentrunner2.py", line 105, in run
    server.serve_forever()
  File "/usr/lib/python2.7/dist-packages/gevent/baseserver.py", line 188, in serve_forever
    self.start()
  File "/usr/lib/python2.7/dist-packages/gevent/baseserver.py", line 149, in start
    self.start_accepting()
  File "/usr/lib/python2.7/dist-packages/gevent/server.py", line 99, in start_accepting
    self._accept_event = core.read_event(self.socket.fileno(), self._do_accept, persist=True)
  File "core.pyx", line 308, in gevent.core.read_event.__init__ (gevent/core.c:3960)
  File "core.pyx", line 252, in gevent.core.event.add (gevent/core.c:2952)
IOError: [Errno 22] Invalid argument

I looked online for the warning, and I couldn't find it anywhere, and the error didn't really give me too much useful information. I've run the program described here https://stackoverflow.com/a/9047339 , and I've run the program alone, just by putting it in main, etc.. However, when I combine them it seems to mess things up. Does anybody know why this might be?

You hitting the problem of bad interaction between fork and epoll (or kqueue). Generally, it's hard to make epoll-based event loop to work reliably after fork and it's best to re-create a new event loop.

There a few ways to fix your problem:

  • Upgrade to gevent 1.0. Unlike gevent 0.x it creates the event loop when first used, not when first imported, and thus avoids the problem. It also uses libev, which handles fork slightly better than libevent, although not 100% reliable though. There's a good chance your problem goes away simply after you've upgraded gevent.

  • Delay import of gevent package until after fork.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM