示例#1
0
def main():
    import optparse
    parser = optparse.OptionParser(
        usage="usage: %prog [options]",
        description="Simple saranwrap.Server wrapper")
    parser.add_option(
        '-c', '--child', default=False, action='store_true',
        help='Wrap an object serialed via setattr.')
    parser.add_option(
        '-m', '--module', type='string', dest='module', default=None,
        help='a module to load and export.')
    parser.add_option(
        '-l', '--logfile', type='string', dest='logfile', default=None,
        help='file to log to.')
    options, args = parser.parse_args()
    global _g_logfile
    if options.logfile:
        _g_logfile = open(options.logfile, 'a')
    if options.module:
        export = api.named(options.module)
        server = Server(sys.stdin, sys.stdout, export)
    elif options.child:
        server = Server(sys.stdin, sys.stdout, {})

    # *HACK: some modules may emit on stderr, which breaks everything.
    class NullSTDOut(object):
        def write(a, b):
            pass
    sys.stderr = NullSTDOut()
    sys.stdout = NullSTDOut()

    # Loop until EOF
    server.loop()
    if _g_logfile:
        _g_logfile.close()
示例#2
0
def main():
    import optparse
    parser = optparse.OptionParser(
        usage="usage: %prog [options]",
        description="Simple saranwrap.Server wrapper")
    parser.add_option(
        '-c', '--child', default=False, action='store_true',
        help='Wrap an object serialed via setattr.')
    parser.add_option(
        '-m', '--module', type='string', dest='module', default=None,
        help='a module to load and export.')
    parser.add_option(
        '-l', '--logfile', type='string', dest='logfile', default=None,
        help='file to log to.')
    options, args = parser.parse_args()
    global _g_logfile
    if options.logfile:
        _g_logfile = open(options.logfile, 'a')
    if options.module:
        export = api.named(options.module)
        server = Server(sys.stdin, sys.stdout, export)
    elif options.child:
        server = Server(sys.stdin, sys.stdout, {})

    # *HACK: some modules may emit on stderr, which breaks everything.
    class NullSTDOut(object):
        def write(a, b):
            pass
    sys.stderr = NullSTDOut()
    sys.stdout = NullSTDOut()

    # Loop until EOF
    server.loop()
    if _g_logfile:
        _g_logfile.close()
示例#3
0
def config_factory(args):
    args["app_factory"] = "spawning.wsgi_factory.app_factory"
    args["app"] = args["args"][0]
    args["middleware"] = args["args"][1:]

    args["source_directories"] = [os.path.split(inspect.getfile(inspect.getmodule(api.named(args["app"]))))[0]]

    return args
 def __init__(self, sock, factory, args, **kwargs):
     self.sock = sock
     self.factory = factory
     self.config = api.named(factory)(args)
     self.args = args
     self.child_pipes = {}
     self.log = logging.getLogger('Spawning')
     if not kwargs.get('log_handler'):
         self.log.addHandler(logging.StreamHandler())
     self.log.setLevel(logging.DEBUG)
     self.controller_pid = os.getpid()
     self.num_processes = int(self.config.get('num_processes', 0))
示例#5
0
def config_factory(args):
    args['django_settings_module'] = args.get('args', [None])[0]
    args['app_factory'] = 'spawning.django_factory.app_factory'

    ## TODO More directories
    ## INSTALLED_APPS (list of quals)
    ## ROOT_URL_CONF (qual)
    ## MIDDLEWARE_CLASSES (list of quals)
    ## TEMPLATE_CONTEXT_PROCESSORS (list of quals)
    settings_module = api.named(args['django_settings_module'])

    dirs = [os.path.split(
        inspect.getfile(
            inspect.getmodule(
                settings_module)))[0]]
    args['source_directories'] = dirs

    return args
示例#6
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)
示例#7
0
 def test_named(self):
     named_foo = api.named('tests.api_test.Foo')
     self.assertEqual(named_foo.__name__, "Foo")
示例#8
0
 def test_named(self):
     named_foo = api.named('tests.api_test.Foo')
     self.assertEqual(named_foo.__name__, "Foo")
示例#9
0
def serve_from_child(sock, config, controller_pid):
    threads = config.get('threadpool_workers', 0)
    wsgi_application = api.named(config['app_factory'])(config)

    if config.get('coverage'):
        wsgi_application = FigleafCoverage(wsgi_application)

    if threads > 1:
        wsgi_application = ExecuteInThreadpool(wsgi_application)
    elif threads != 1:
        print "(%s) not using threads, installing eventlet cooperation monkeypatching" % (
            os.getpid(), )
        from eventlet import util
        util.wrap_socket_with_coroutine_socket()
        #util.wrap_pipes_with_coroutine_pipes()
        #util.wrap_threading_local_with_coro_local()

    host, port = sock.getsockname()

    access_log_file = config.get('access_log_file')
    if access_log_file is not None:
        access_log_file = open(access_log_file, 'a')

    max_age = 0
    if config.get('max_age'):
        max_age = int(config.get('max_age'))

    server_event = coros.event()
    http_version = config.get('no_keepalive') and 'HTTP/1.0' or 'HTTP/1.1'
    try:
        wsgi_args = (sock, wsgi_application)
        wsgi_kwargs = {'log' : access_log_file, 'server_event' : server_event, 'max_http_version' : http_version}
        if config.get('no_keepalive'):
            wsgi_kwargs.update({'keepalive' : False})
        if max_age:
            wsgi_kwargs.update({'timeout_value' : True})
            api.with_timeout(max_age, wsgi.server, *wsgi_args, **wsgi_kwargs)
        else:
            wsgi.server(*wsgi_args, **wsgi_kwargs)
    except KeyboardInterrupt:
        pass
    except ExitChild:
        pass

    ## Set a deadman timer to violently kill the process if it doesn't die after
    ## some long timeout.
    signal.signal(signal.SIGALRM, deadman_timeout)
    signal.alarm(config['deadman_timeout'])

    ## Once we get here, we just need to handle outstanding sockets, not
    ## accept any new sockets, so we should close the server socket.
    sock.close()

    server = server_event.wait()

    last_outstanding = None
    if server.outstanding_requests:
        ## Let's tell our parent that we're dying
        try:
            os.kill(controller_pid, signal.SIGUSR1)
        except OSError, e:
            if not e.errno == errno.ESRCH:
                raise
示例#10
0
def app_factory(config):
    app = api.named(config["app"])
    for mid in config["middleware"]:
        app = api.named(mid)(app)
    return app
示例#11
0
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)