def test(self): # pylint:disable=too-many-locals # If this test is broken, there are a few failure modes. # - In the original examples, the parent process just hangs, because the # child has raced ahead, spawned the greenlet and read the data. When the # greenlet goes to read in the parent, it blocks, and the hub and loop # wait for it. # - Here, our child detects the greenlet ran when it shouldn't and # raises an error, which translates to a non-zero exit status, # which the parent checks for and fails by raising an exception before # returning control to the hub. We can replicate the hang by removing the # assertion in the child. from time import sleep as hang from gevent import get_hub from gevent import spawn from gevent.socket import wait_read from gevent.os import nb_read from gevent.os import nb_write from gevent.os import make_nonblocking from gevent.os import fork from gevent.os import waitpid pipe_read_fd, pipe_write_fd = os.pipe() make_nonblocking(pipe_read_fd) make_nonblocking(pipe_write_fd) run = [] def reader(): run.append(1) return nb_read(pipe_read_fd, 4096) # Put data in the pipe DATA = b'test' nb_write(pipe_write_fd, DATA) # Make sure we're ready to read it wait_read(pipe_read_fd) # Schedule a greenlet to start reader = spawn(reader) hub = get_hub() pid = fork() if pid == 0: # Child destroys the hub. The reader should not have run. hub.destroy(destroy_loop=True) self.assertFalse(run) os._exit(0) return # The parent. # Briefly prevent us from spinning our event loop. hang(0.5) wait_child_result = waitpid(pid, 0) self.assertEqual(wait_child_result, (pid, 0)) # We should get the data; the greenlet only runs in the parent. data = reader.get() self.assertEqual(run, [1]) self.assertEqual(data, DATA)
def daemonize(close=False): """\ Standard daemonization of a process. http://www.svbug.com/documentation/comp.unix.programmer-FAQ/faq_2.html#SEC16 """ if not 'TPROXY_FD' in os.environ: try: if fork(): os._exit(0) except OSError, e: sys.stderr.write("fork #1 failed: %s\n" % str(e)) sys.exit(1) os.setsid() try: if fork(): os._exit(0) except OSError, e: sys.stderr.write("fork #2 failed: %s\n" % str(e)) sys.exit(1)
def handle(self, *args, **options): try: host = port = None if len(args) > 0: host = args[0] if ':' in host: host, port = host.rsplit(':') if host is None: host = '0.0.0.0' if port is None: port = 80 # Monkey Patch for Gevent monkey.patch_all() if not options['disable_psycogreen']: # Monkey Patch for Psycopg2 using psycogreen import psycogreen.gevent psycogreen.gevent.patch_psycopg() application = bootstrap.get_wsgi_application() if options['disable_socketio']: from gevent.pywsgi import WSGIServer server = WSGIServer((host, int(port)), application) else: from socketio.server import SocketIOServer server = SocketIOServer((host, int(port)), application, resource="socket.io") print 'Starting server on {host}:{port} with {workers} workers.'.format( host=host, port=port, workers=options['child_workers'] ) server.start() print 'Listening on http://{host}:{port}'.format(host=host, port=port) for i in range(options['child_workers']): pid = fork() if pid == 0: break server.serve_forever() except Exception, ex: raise CommandError("Exception occurred during gevent wsgi process startup.", ex)
def fork_workers(self, num): for i in range(num): if fork() == 0: self.worker_execute() exit(0)