if kwargs: raise TypeError('Unexpected arguments: %r' % kwargs.keys()) if isinstance(fobj, integer_types): if not self._close: # we cannot do this, since fdopen object will close the descriptor raise TypeError('FileObjectBlock does not support close=False') fobj = os.fdopen(fobj, *args) self.io = fobj def __repr__(self): return '<%s %r>' % (self.io, ) def __getattr__(self, item): assert item != '_fobj' if self.io is None: raise FileObjectClosed return getattr(self.io, item) config = os.environ.get('GEVENT_FILE') if config: klass = {'thread': 'gevent.fileobject.FileObjectThread', 'posix': 'gevent.fileobject.FileObjectPosix', 'block': 'gevent.fileobject.FileObjectBlock'}.get(config, config) if klass.startswith('gevent.fileobject.'): FileObject = globals()[klass.split('.', 2)[-1]] else: from gevent.hub import _import FileObject = _import(klass) del klass
if isinstance(fobj, integer_types): if not self._close: # we cannot do this, since fdopen object will close the descriptor raise TypeError('FileObjectBlock does not support close=False') fobj = os.fdopen(fobj, *args) self._fobj = fobj def __repr__(self): return '<%s %r>' % (self._fobj, ) def __getattr__(self, item): assert item != '_fobj' if self._fobj is None: raise FileObjectClosed return getattr(self._fobj, item) config = os.environ.get('GEVENT_FILE') if config: klass = { 'thread': 'gevent.fileobject.FileObjectThread', 'posix': 'gevent.fileobject.FileObjectPosix', 'block': 'gevent.fileobject.FileObjectBlock' }.get(config, config) if klass.startswith('gevent.fileobject.'): FileObject = globals()[klass.split('.', 2)[-1]] else: from gevent.hub import _import FileObject = _import(klass) del klass
def worker_main(): global PREFIX PREFIX = '[W%05d] ' % os.getpid() import optparse parser = optparse.OptionParser() parser.add_option('--fileno', type=int) parser.add_option('--pipe', type=int) parser.add_option('-u', '--user') parser.add_option('-s', '--server-class', default='wsgi') parser.add_option('--preexec') parser.add_option('--pythonpath', help='Colon-separated entries to prepend to sys.path') parser.add_option('--setuid', type=int) parser.add_option('--setgid', type=int) parser.add_option('--maxaccept', type=int) parser.add_option('--notify-period', type=float) options, args = parser.parse_args() if args: if len(args) > 1: sys.exit('Too many arguments. Expected at most one: application') application_name = args[0] else: application_name = None server_class = server_classes.get(options.server_class, options.server_class) if server_class in server_classes.values(): if application_name is None: sys.exit('Expected argument: application or handler') if options.pipe: fcntl.fcntl(options.pipe, fcntl.F_SETFL, os.O_NONBLOCK) if options.pythonpath: sys.path = options.pythonpath.split(':') + sys.path import _socket socket = _socket.fromfd(options.fileno, _socket.AF_INET, _socket.SOCK_STREAM) # _socket.fromfd dups the file descriptor; it does not seem possible to avoid it # therefore close the old filenot that we no longer need os.close(options.fileno) del options.fileno import geventserver geventserver.socket = socket from gevent.hub import _import if options.preexec: preexec = _import(options.preexec) preexec() socket_txt = ':'.join(str(x) for x in socket.getsockname()) setproctitle('geventserver worker', options.server_class, socket_txt, application_name) drop_privileges(options.setuid, options.setgid) # master must always outlive its workers; if the master died, something # awful happened and SIGKILL for worker is warranted # Note, that die_if_parent_dies must be called after dropping privileges, # otherwise it does not work die_if_parent_dies(signal.SIGKILL) ppid = os.getppid() if ppid == 1: sys.exit(PREFIX + 'ppid cannot be 1') _reseed_random() from gevent import monkey monkey.patch_all() geventserver.quit_handler = gevent.signal(signal.SIGQUIT, worker_handle_quit, None) signal.signal(signal.SIGTERM, worker_handle_term) signal.signal(signal.SIGINT, worker_handle_int) # signal handlers are installed before importing user code so that imported modules could override signals geventserver.looptimer = LoopTimer() server_class = _import(options.server_class) if application_name: application = _import(application_name) args = (socket, application) else: application = None args = (socket, ) server = server_class(*args) if options.maxaccept: # XXX unused currently? server.max_accept = options.max_accept geventserver.server = server server.start() geventserver.quit_handler.args = (server, ) log('Serving %s', application_name or options.server_class) if callable(getattr(application, 'on_start', None)): application.on_start() if options.pipe is not None: gevent.get_hub().loop.timer(0, options.notify_period, ref=False).start(write_pipe, options.pipe) try: gevent.wait() except Interrupt: sys.exit(102) # 100 + SIGINT else: log('Exiting cleanly.')
def worker_main(): global PREFIX PREFIX = "[W%05d] " % os.getpid() import optparse parser = optparse.OptionParser() parser.add_option("--fileno", type=int) parser.add_option("--pipe", type=int) parser.add_option("-u", "--user") parser.add_option("-s", "--server-class", default="wsgi") parser.add_option("--preexec") parser.add_option("--pythonpath", help="Colon-separated entries to prepend to sys.path") parser.add_option("--setuid", type=int) parser.add_option("--setgid", type=int) parser.add_option("--maxaccept", type=int) parser.add_option("--notify-period", type=float) options, args = parser.parse_args() if args: if len(args) > 1: sys.exit("Too many arguments. Expected at most one: application") application_name = args[0] else: application_name = None server_class = server_classes.get(options.server_class, options.server_class) if server_class in server_classes.values(): if application_name is None: sys.exit("Expected argument: application or handler") if options.pipe: fcntl.fcntl(options.pipe, fcntl.F_SETFL, os.O_NONBLOCK) if options.pythonpath: sys.path = options.pythonpath.split(":") + sys.path import _socket socket = _socket.fromfd(options.fileno, _socket.AF_INET, _socket.SOCK_STREAM) # _socket.fromfd dups the file descriptor; it does not seem possible to avoid it # therefore close the old filenot that we no longer need os.close(options.fileno) del options.fileno import geventserver geventserver.socket = socket from gevent.hub import _import if options.preexec: preexec = _import(options.preexec) preexec() socket_txt = ":".join(str(x) for x in socket.getsockname()) setproctitle("geventserver worker", options.server_class, socket_txt, application_name) drop_privileges(options.setuid, options.setgid) # master must always outlive its workers; if the master died, something # awful happened and SIGKILL for worker is warranted # Note, that die_if_parent_dies must be called after dropping privileges, # otherwise it does not work die_if_parent_dies(signal.SIGKILL) ppid = os.getppid() if ppid == 1: sys.exit(PREFIX + "ppid cannot be 1") _reseed_random() from gevent import monkey monkey.patch_all() geventserver.quit_handler = gevent.signal(signal.SIGQUIT, worker_handle_quit, None) signal.signal(signal.SIGTERM, worker_handle_term) signal.signal(signal.SIGINT, worker_handle_int) # signal handlers are installed before importing user code so that imported modules could override signals geventserver.looptimer = LoopTimer() server_class = _import(options.server_class) if application_name: application = _import(application_name) args = (socket, application) else: application = None args = (socket,) server = server_class(*args) if options.maxaccept: # XXX unused currently? server.max_accept = options.max_accept geventserver.server = server server.start() geventserver.quit_handler.args = (server,) log("Serving %s", application_name or options.server_class) if callable(getattr(application, "on_start", None)): application.on_start() if options.pipe is not None: gevent.get_hub().loop.timer(0, options.notify_period, ref=False).start(write_pipe, options.pipe) try: gevent.wait() except Interrupt: sys.exit(102) # 100 + SIGINT else: log("Exiting cleanly.")