def run(self): self.log.info('(%s) *** Controller starting at %s' % (self.controller_pid, time.asctime())) if self.config.get('pidfile'): with open(self.config.get('pidfile'), 'w') as fd: fd.write('%s\n' % self.controller_pid) spawning.setproctitle("spawn: controller " + self.args.get('argv_str', '')) if self.sock is None: self.sock = bind_socket(self.config) install_reload_handler(self) #signal.signal(signal.SIGUSR1, self.handle_deadlychild) if self.config.get('status_port'): self.log.debug('start_status_port') from spawning.util import status eventlet.spawn(status.Server, self, self.config['status_host'], self.config['status_port']) try: self.runloop() except KeyboardInterrupt: self.keep_going = False self.kill_children() self.log.info('(%s) *** Controller exiting' % (self.controller_pid))
def run(self): self.log.info('(%s) *** Controller starting at %s' % (self.controller_pid, time.asctime())) if self.config.get('pidfile'): with open(self.config.get('pidfile'), 'w') as fd: fd.write('%s\n' % self.controller_pid) spawning.setproctitle("spawn: controller " + self.args.get('argv_str', '')) if self.sock is None: self.sock = bind_socket(self.config) signal.signal(signal.SIGHUP, self.handle_sighup) signal.signal(signal.SIGUSR1, self.handle_deadlychild) if self.config.get('status_port'): from spawning.util import status eventlet.spawn(status.Server, self, self.config['status_host'], self.config['status_port']) try: self.runloop() except KeyboardInterrupt: self.keep_going = False self.kill_children() self.log.info('(%s) *** Controller exiting' % (self.controller_pid))
def main(): log.debug('here') parser = optparse.OptionParser() parser.add_option("-r", "--reload", action='store_true', dest='reload', help='If --reload is passed, reload the server any time ' 'a loaded module changes.') options, args = parser.parse_args() if len(args) != 6: print "Usage: %s controller_pid httpd_fd death_fd warn_fd factory_qual factory_args" % ( sys.argv[0], ) sys.exit(1) controller_pid, httpd_fd, death_fd, warn_fd, factory_qual, factory_args = args controller_pid = int(controller_pid) config = spawning.util.named(factory_qual)(json.loads(factory_args)) setproctitle("spawn: child (%s)" % ", ".join(config.get("args"))) log.debug('httpd_fd (%s), death_fd (%s), warn_fd(%s)', httpd_fd, death_fd, warn_fd) ## Set up status reporter, if requested init_statusobj(config.get('status_port')) ## Set up the reloader if config.get('reload'): watch = config.get('watch', None) if watch: watching = ' and %s' % watch else: watching = '' print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching) eventlet.spawn( reloader_dev.watch_forever, controller_pid, 1, watch) ## The parent will catch sigint and tell us to shut down #signal.signal(signal.SIGINT, signal.SIG_IGN) ## Expect a SIGHUP when we want the child to die #signal.signal(signal.SIGHUP, child_sighup) eventlet.spawn(read_pipe_and_die, get_fd(death_fd, os.O_RDONLY), eventlet.getcurrent()) ## Make the socket object from the fd given to us by the controller sock = eventlet.greenio.GreenSocket( socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM)) serve_from_child( sock, config, controller_pid, get_fd(warn_fd, os.O_WRONLY))
def main(): parser = optparse.OptionParser() parser.add_option("-r", "--reload", action='store_true', dest='reload', help='If --reload is passed, reload the server any time ' 'a loaded module changes.') options, args = parser.parse_args() if len(args) != 5: print "Usage: %s controller_pid httpd_fd death_fd factory_qual factory_args" % ( sys.argv[0], ) sys.exit(1) controller_pid, httpd_fd, death_fd, factory_qual, factory_args = args controller_pid = int(controller_pid) config = spawning.util.named(factory_qual)(json.loads(factory_args)) setproctitle("spawn: child (%s)" % ", ".join(config.get("args"))) ## Set up status reporter, if requested init_statusobj(config.get('status_port')) ## Set up the reloader if config.get('reload'): watch = config.get('watch', None) if watch: watching = ' and %s' % watch else: watching = '' print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching) eventlet.spawn(reloader_dev.watch_forever, controller_pid, 1, watch) ## The parent will catch sigint and tell us to shut down signal.signal(signal.SIGINT, signal.SIG_IGN) ## Expect a SIGHUP when we want the child to die signal.signal(signal.SIGHUP, child_sighup) eventlet.spawn(read_pipe_and_die, int(death_fd), eventlet.getcurrent()) ## Make the socket object from the fd given to us by the controller sock = eventlet.greenio.GreenSocket( socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM)) serve_from_child(sock, config, controller_pid)
def main(): parser = optparse.OptionParser() parser.add_option( "-r", "--reload", action="store_true", dest="reload", help="If --reload is passed, reload the server any time " "a loaded module changes.", ) options, args = parser.parse_args() if len(args) != 5: print "Usage: %s controller_pid httpd_fd death_fd factory_qual factory_args" % (sys.argv[0],) sys.exit(1) controller_pid, httpd_fd, death_fd, factory_qual, factory_args = args controller_pid = int(controller_pid) config = spawning.util.named(factory_qual)(json.loads(factory_args)) setproctitle("spawn: child (%s)" % ", ".join(config.get("args"))) ## Set up the reloader if config.get("reload"): watch = config.get("watch", None) if watch: watching = " and %s" % watch else: watching = "" print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching) eventlet.spawn(reloader_dev.watch_forever, controller_pid, 1, watch) ## The parent will catch sigint and tell us to shut down signal.signal(signal.SIGINT, signal.SIG_IGN) ## Expect a SIGHUP when we want the child to die signal.signal(signal.SIGHUP, lambda *a, **kw: exit(0)) eventlet.spawn(read_pipe_and_die, int(death_fd), eventlet.getcurrent()) ## Make the socket object from the fd given to us by the controller sock = eventlet.greenio.GreenSocket(socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM)) serve_from_child(sock, config, controller_pid)
def run(self): self.log.info('(%s) *** Controller starting at %s' % (self.controller_pid, time.asctime())) if self.config.get('pidfile'): with open(self.config.get('pidfile'), 'w') as fd: fd.write('%s\n' % self.controller_pid) spawning.setproctitle("spawn: controller " + self.args.get('argv_str', '')) if self.sock is None: self.sock = bind_socket(self.config) signal.signal(signal.SIGHUP, self.handle_sighup) signal.signal(signal.SIGUSR1, self.handle_deadlychild) try: self.runloop() except KeyboardInterrupt: self.kill_children() self.log.info('(%s) *** Controller exiting' % (self.controller_pid))
def main(): parser = optparse.OptionParser() parser.add_option("-r", "--reload", action='store_true', dest='reload', help='If --reload is passed, reload the server any time ' 'a loaded module changes.') options, args = parser.parse_args() if len(args) != 5: print "Usage: %s controller_pid httpd_fd death_fd factory_qual factory_args" % ( sys.argv[0], ) sys.exit(1) controller_pid, httpd_fd, death_fd, factory_qual, factory_args = args controller_pid = int(controller_pid) config = api.named(factory_qual)(json.loads(factory_args)) setproctitle("spawn: child (%s)" % ", ".join(config.get("args"))) ## Set up the reloader if options.reload: watch = config.get('watch', None) if watch: watching = ' and %s' % watch else: watching = '' print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching) api.spawn( reloader_dev.watch_forever, controller_pid, 1, watch) ## The parent will catch sigint and tell us to shut down signal.signal(signal.SIGINT, signal.SIG_IGN) api.spawn(read_pipe_and_die, int(death_fd), api.getcurrent()) ## Make the socket object from the fd given to us by the controller sock = greenio.GreenSocket( socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM)) serve_from_child( sock, config, controller_pid)
def main(): parser = optparse.OptionParser() parser.add_option("-r", "--reload", action='store_true', dest='reload', help='If --reload is passed, reload the server any time ' 'a loaded module changes.') parser.add_option('--ssl-certificate', dest='ssl_certificate', type='string', default='', help='Absolute path to SSL certificate file.') parser.add_option('--ssl-private-key', dest='ssl_private_key', type='string', default='', help='Absolute path to SSL private key.') options, args = parser.parse_args() if len(args) != 5: print "Usage: %s controller_pid httpd_fd death_fd factory_qual factory_args" % ( sys.argv[0], ) sys.exit(1) controller_pid, httpd_fd, death_fd, factory_qual, factory_args = args controller_pid = int(controller_pid) config = spawning.util.named(factory_qual)(json.loads(factory_args)) setproctitle("spawn: child (%s)" % ", ".join(config.get("args"))) ## Set up status reporter, if requested init_statusobj(config.get('status_port')) ## Set up the reloader if config.get('reload'): watch = config.get('watch', None) if watch: watching = ' and %s' % watch else: watching = '' print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching) eventlet.spawn(reloader_dev.watch_forever, controller_pid, 1, watch) ## The parent will catch sigint and tell us to shut down signal.signal(signal.SIGINT, signal.SIG_IGN) ## Expect a SIGHUP when we want the child to die signal.signal(signal.SIGHUP, child_sighup) eventlet.spawn(read_pipe_and_die, int(death_fd), eventlet.getcurrent()) ## Make the socket object from the fd given to us by the controller sock = eventlet.greenio.GreenSocket( socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM)) if options.ssl_certificate and options.ssl_private_key: # The way spawning works is that there's a parent process which forks off long-lived # children, each of which can be multithreaded. What we're using is a single-threaded, # single-process server that does things asynchronously (using coroutines). Spawning creates # a socket and then calls fork() at least once. In the child process, it exec()'s something # else, so as a result the child loses all context. It puts the file descriptor for the # socket as a command-line argument to the child, which then uses the fromfd function of the # socket module to create a socket object. Unfortunately, the resulting object isn't quite # the same as the socket created by the parent. In particular, when we go to upgrade this # socket to ssl using eventlet's wrap_with_ssl(), it fails because it expects sock.fd to be # of type "socket._socketobject", but it's actually of type "_socket.socket". Patching # up the object in this way solves this problem. sock.fd = socket._socketobject(_sock=sock.fd) sock = eventlet.wrap_ssl(sock, certfile=options.ssl_certificate, keyfile=options.ssl_private_key, server_side=True) serve_from_child(sock, config, controller_pid)
def main(): parser = optparse.OptionParser() parser.add_option("-r", "--reload", action='store_true', dest='reload', help='If --reload is passed, reload the server any time ' 'a loaded module changes.') parser.add_option('--ssl-certificate', dest='ssl_certificate', type='string', default='', help='Absolute path to SSL certificate file.') parser.add_option('--ssl-private-key', dest='ssl_private_key', type='string', default='', help='Absolute path to SSL private key.') options, args = parser.parse_args() if len(args) != 5: print "Usage: %s controller_pid httpd_fd death_fd factory_qual factory_args" % ( sys.argv[0], ) sys.exit(1) controller_pid, httpd_fd, death_fd, factory_qual, factory_args = args controller_pid = int(controller_pid) config = spawning.util.named(factory_qual)(json.loads(factory_args)) setproctitle("spawn: child (%s)" % ", ".join(config.get("args"))) ## Set up status reporter, if requested init_statusobj(config.get('status_port')) ## Set up the reloader if config.get('reload'): watch = config.get('watch', None) if watch: watching = ' and %s' % watch else: watching = '' print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching) eventlet.spawn( reloader_dev.watch_forever, controller_pid, 1, watch) ## The parent will catch sigint and tell us to shut down signal.signal(signal.SIGINT, signal.SIG_IGN) ## Expect a SIGHUP when we want the child to die signal.signal(signal.SIGHUP, child_sighup) eventlet.spawn(read_pipe_and_die, int(death_fd), eventlet.getcurrent()) ## Make the socket object from the fd given to us by the controller sock = eventlet.greenio.GreenSocket( socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM)) if options.ssl_certificate and options.ssl_private_key: # The way spawning works is that there's a parent process which forks off long-lived # children, each of which can be multithreaded. What we're using is a single-threaded, # single-process server that does things asynchronously (using coroutines). Spawning creates # a socket and then calls fork() at least once. In the child process, it exec()'s something # else, so as a result the child loses all context. It puts the file descriptor for the # socket as a command-line argument to the child, which then uses the fromfd function of the # socket module to create a socket object. Unfortunately, the resulting object isn't quite # the same as the socket created by the parent. In particular, when we go to upgrade this # socket to ssl using eventlet's wrap_with_ssl(), it fails because it expects sock.fd to be # of type "socket._socketobject", but it's actually of type "_socket.socket". Patching # up the object in this way solves this problem. sock.fd = socket._socketobject(_sock=sock.fd) sock = eventlet.wrap_ssl(sock, certfile=options.ssl_certificate, keyfile=options.ssl_private_key, server_side=True) serve_from_child(sock, config, controller_pid)
def run_controller(factory_qual, args, sock=None): controller_pid = os.getpid() print "(%s) **** Controller starting up at %s" % ( controller_pid, time.asctime()) try: config = api.named(factory_qual)(args) except: print_exc("Couldn't import the WSGI factory! Panic!") restart_controller(factory_qual, args, sock, panic=True) ## Never gets here! pidfile = config.get("pidfile") if pidfile: f = open(pidfile, "w") try: f.write("%s\n" % (controller_pid,)) finally: f.close() setproctitle("spawn: controller " + args["argv_str"]) dev = config.get('dev', False) if not dev: ## Set up the production reloader that watches the svn revision number. if not os.fork(): if sock is not None: sock.close() base = os.path.dirname(__file__) os.chdir(base) args = [ sys.executable, 'reloader_svn.py', '--pid=' + str(controller_pid), '--dir=' + base, ] for dirname in config.get('source_directories', []): args.append('--dir=' + dirname) os.execve(sys.executable, args, environ()) ## Never gets here! if sock is None: sock = bind_socket(config) spawn_new_children(sock, factory_qual, args, config) start_time = time.time() start_delay = args.get('start_delay') while True: reap_children() ## Random heuristic: If we've been running for 64x longer than the start_delay ## or 5 minutes, whatever is shorter, we can clear the start_delay if start_delay is not None: if time.time() - start_time > min(start_delay * 64, 60 * 5): print "(%s) We've been running OK for a while, clear the exponential backoff" % ( os.getpid(), ) del args['start_delay'] if RESTART_CONTROLLER: break if KEEP_GOING: restart_controller(factory_qual, args, sock, panic=PANIC)