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))
Beispiel #2
0
    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))
Beispiel #3
0
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))
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
    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))
Beispiel #7
0
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)
Beispiel #8
0
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)