From f168a21dae77cad37254c4ecd46d0c562f37eb6a Mon Sep 17 00:00:00 2001 From: benoitc Date: Sun, 19 Feb 2012 11:27:46 +0100 Subject: [PATCH] fix whitespaces --- gunicorn/app/base.py | 30 ++-- gunicorn/app/djangoapp.py | 40 +++--- gunicorn/app/pasterapp.py | 24 ++-- gunicorn/app/wsgiapp.py | 6 +- gunicorn/arbiter.py | 92 ++++++------- gunicorn/config.py | 138 +++++++++---------- gunicorn/debug.py | 6 +- gunicorn/errors.py | 4 +- gunicorn/glogging.py | 12 +- gunicorn/http/_sendfile.py | 6 +- gunicorn/http/body.py | 40 +++--- gunicorn/http/errors.py | 12 +- gunicorn/http/message.py | 22 +-- gunicorn/http/parser.py | 8 +- gunicorn/http/unreader.py | 10 +- gunicorn/http/wsgi.py | 8 +- gunicorn/logging_config.py | 2 +- gunicorn/management/commands/run_gunicorn.py | 16 +-- gunicorn/pidfile.py | 14 +- gunicorn/sock.py | 36 ++--- gunicorn/util.py | 36 ++--- gunicorn/workers/async.py | 4 +- gunicorn/workers/base.py | 26 ++-- gunicorn/workers/geventlet.py | 6 +- gunicorn/workers/ggevent_wsgi.py | 8 +- gunicorn/workers/gtornado.py | 10 +- gunicorn/workers/sync.py | 14 +- gunicorn/workers/workertmp.py | 8 +- 28 files changed, 319 insertions(+), 319 deletions(-) diff --git a/gunicorn/app/base.py b/gunicorn/app/base.py index e8128dfe..4d6175d4 100644 --- a/gunicorn/app/base.py +++ b/gunicorn/app/base.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import errno @@ -20,7 +20,7 @@ class Application(object): An application interface for configuring and loading the various necessities for any given web framework. """ - + def __init__(self, usage=None): self.usage = usage self.cfg = None @@ -35,23 +35,23 @@ class Application(object): sys.stderr.write("\nError: %s\n" % str(e)) sys.stderr.flush() sys.exit(1) - + def load_config(self): # init configuration self.cfg = Config(self.usage) - + # parse console args parser = self.cfg.parser() opts, args = parser.parse_args() - + # optional settings from apps cfg = self.init(parser, opts, args) - + # Load up the any app specific configuration if cfg and cfg is not None: for k, v in cfg.items(): self.cfg.set(k.lower(), v) - + # Load up the config file if its found. if opts.config and os.path.exists(opts.config): cfg = { @@ -67,7 +67,7 @@ class Application(object): print "Failed to read config file: %s" % opts.config traceback.print_exc() sys.exit(1) - + for k, v in cfg.items(): # Ignore unknown names if k not in self.cfg.settings: @@ -77,17 +77,17 @@ class Application(object): except: sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) raise - + # Lastly, update the configuration with any command line # settings. for k, v in opts.__dict__.items(): if v is None: continue self.cfg.set(k.lower(), v) - + def init(self, parser, opts, args): raise NotImplementedError - + def load(self): raise NotImplementedError @@ -95,12 +95,12 @@ class Application(object): self.do_load_config() if self.cfg.spew: debug.spew() - + def wsgi(self): if self.callable is None: self.callable = self.load() return self.callable - + def run(self): if self.cfg.spew: debug.spew() @@ -111,11 +111,11 @@ class Application(object): os.setpgrp() except OSError, e: if e[0] != errno.EPERM: - raise + raise try: Arbiter(self).run() except RuntimeError, e: sys.stderr.write("\nError: %s\n\n" % e) sys.stderr.flush() sys.exit(1) - + diff --git a/gunicorn/app/djangoapp.py b/gunicorn/app/djangoapp.py index 56885ae9..09b60fb1 100644 --- a/gunicorn/app/djangoapp.py +++ b/gunicorn/app/djangoapp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import imp @@ -17,7 +17,7 @@ from gunicorn.app.base import Application ENVIRONMENT_VARIABLE = 'DJANGO_SETTINGS_MODULE' class DjangoApplication(Application): - + def init(self, parser, opts, args): self.global_settings_path = None self.project_path = None @@ -25,7 +25,7 @@ class DjangoApplication(Application): self.global_settings_path = args[0] if not os.path.exists(os.path.abspath(args[0])): self.no_settings(args[0]) - + def get_settings_modname(self): from django.conf import ENVIRONMENT_VARIABLE @@ -69,7 +69,7 @@ class DjangoApplication(Application): os.pardir))) return settings_modname - + def setup_environ(self, settings_modname): from django.core.management import setup_environ @@ -82,7 +82,7 @@ class DjangoApplication(Application): path = os.path.dirname(os.path.abspath( os.path.normpath(settings_mod.__file__))) sys.path.append(path) - for part in parts[1:]: + for part in parts[1:]: settings_mod = getattr(settings_mod, part) setup_environ(settings_mod) except ImportError: @@ -101,9 +101,9 @@ class DjangoApplication(Application): from django.conf import settings from django.utils import translation translation.activate(settings.LANGUAGE_CODE) - + def validate(self): - """ Validate models. This also ensures that all models are + """ Validate models. This also ensures that all models are imported in case of import-time side effects.""" from django.core.management.base import CommandError from django.core.management.validation import get_validation_errors @@ -123,14 +123,14 @@ class DjangoApplication(Application): def load(self): from django.core.handlers.wsgi import WSGIHandler - + self.setup_environ(self.get_settings_modname()) self.validate() self.activate_translation() return WSGIHandler() class DjangoApplicationCommand(DjangoApplication): - + def __init__(self, options, admin_media_path): self.usage = None self.cfg = None @@ -139,16 +139,16 @@ class DjangoApplicationCommand(DjangoApplication): self.admin_media_path = admin_media_path self.callable = None self.project_path = None - + self.do_load_config() for k, v in self.options.items(): if k.lower() in self.cfg.settings and v is not None: self.cfg.set(k.lower(), v) - + def load_config(self): self.cfg = Config() - + if self.config_file and os.path.exists(self.config_file): cfg = { "__builtins__": __builtins__, @@ -164,7 +164,7 @@ class DjangoApplicationCommand(DjangoApplication): print "Failed to read config file: %s" % self.config_file traceback.print_exc() sys.exit(1) - + for k, v in cfg.items(): # Ignore unknown names if k not in self.cfg.settings: @@ -174,7 +174,7 @@ class DjangoApplicationCommand(DjangoApplication): except: sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) raise - + for k, v in self.options.items(): if k.lower() in self.cfg.settings and v is not None: self.cfg.set(k.lower(), v) @@ -191,7 +191,7 @@ class DjangoApplicationCommand(DjangoApplication): settings_path = os.path.join(project_path, "settings.py") if not os.path.exists(settings_path): return self.no_settings(settings_path) - + if not settings_modname: project_name = os.path.split(project_path)[-1] settings_name, ext = os.path.splitext( @@ -220,7 +220,7 @@ class DjangoApplicationCommand(DjangoApplication): def reload_django_settings(self, settings_modname): from django.conf import settings from django.utils import importlib - + mod = importlib.import_module(settings_modname) # reload module @@ -283,14 +283,14 @@ class DjangoApplicationCommand(DjangoApplication): def load(self): from django.core.handlers.wsgi import WSGIHandler - + # reload django settings and setup environ self.setup_environ(self.get_settings_modname()) # validate models and activate translation - self.validate() + self.validate() self.activate_translation() - + from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException try: @@ -308,7 +308,7 @@ class DjangoApplicationCommand(DjangoApplication): error_text = str(e) sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') sys.exit(1) - + def run(): """\ The ``gunicorn_django`` command line runner for launching Django diff --git a/gunicorn/app/pasterapp.py b/gunicorn/app/pasterapp.py index 477e9958..ddeed199 100644 --- a/gunicorn/app/pasterapp.py +++ b/gunicorn/app/pasterapp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import os @@ -20,7 +20,7 @@ class PasterBaseApplication(Application): cx = loadwsgi.loadcontext(SERVER, self.cfgurl, relative_to=self.relpath) gc, lc = cx.global_conf.copy(), cx.local_conf.copy() cfg = {} - + host, port = lc.pop('host', ''), lc.pop('port', '') if host and port: cfg['bind'] = '%s:%s' % (host, port) @@ -61,11 +61,11 @@ class PasterBaseApplication(Application): config_file = os.path.abspath(self.cfgfname) fileConfig(config_file, dict(__file__=config_file, here=os.path.dirname(config_file))) - + class PasterApplication(PasterBaseApplication): - + def init(self, parser, opts, args): if len(args) != 1: parser.error("No application name specified.") @@ -81,14 +81,14 @@ class PasterApplication(PasterBaseApplication): sys.path.insert(0, self.relpath) pkg_resources.working_set.add_entry(self.relpath) - + return self.app_config() - + def load(self): return loadapp(self.cfgurl, relative_to=self.relpath) - + class PasterServerApplication(PasterBaseApplication): - + def __init__(self, app, gcfg=None, host="127.0.0.1", port=None, *args, **kwargs): self.cfg = Config() self.app = app @@ -127,7 +127,7 @@ class PasterServerApplication(PasterBaseApplication): def load_config(self): if not hasattr(self, "cfgfname"): return - + cfg = self.app_config() for k,v in cfg.items(): try: @@ -153,14 +153,14 @@ def run(): def paste_server(app, gcfg=None, host="127.0.0.1", port=None, *args, **kwargs): """\ A paster server. - + Then entry point in your paster ini file should looks like this: - + [server:main] use = egg:gunicorn#main host = 127.0.0.1 port = 5000 - + """ from gunicorn.app.pasterapp import PasterServerApplication PasterServerApplication(app, gcfg=gcfg, host=host, port=port, *args, **kwargs).run() diff --git a/gunicorn/app/wsgiapp.py b/gunicorn/app/wsgiapp.py index 001f4db5..5e80647d 100644 --- a/gunicorn/app/wsgiapp.py +++ b/gunicorn/app/wsgiapp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import os @@ -10,7 +10,7 @@ from gunicorn import util from gunicorn.app.base import Application class WSGIApplication(Application): - + def init(self, parser, opts, args): if len(args) != 1: parser.error("No application module specified.") @@ -29,4 +29,4 @@ def run(): generic WSGI applications. """ from gunicorn.app.wsgiapp import WSGIApplication - WSGIApplication("%prog [OPTIONS] APP_MODULE").run() \ No newline at end of file + WSGIApplication("%prog [OPTIONS] APP_MODULE").run() diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index 5c0f80db..83626923 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from __future__ import with_statement @@ -34,9 +34,9 @@ class Arbiter(object): WORKER_BOOT_ERROR = 3 START_CTX = {} - + LISTENER = None - WORKERS = {} + WORKERS = {} PIPE = [] # I love dynamic languages @@ -49,17 +49,17 @@ class Arbiter(object): (getattr(signal, name), name[3:].lower()) for name in dir(signal) if name[:3] == "SIG" and name[3] != "_" ) - + def __init__(self, app): os.environ["SERVER_SOFTWARE"] = SERVER_SOFTWARE self.setup(app) - + self.pidfile = None self.worker_age = 0 self.reexec_pid = 0 self.master_name = "Master" - + # get current path, try to use PWD env first try: a = os.stat(os.environ['PWD']) @@ -70,7 +70,7 @@ class Arbiter(object): cwd = os.getcwd() except: cwd = os.getcwd() - + args = sys.argv[:] args.insert(0, sys.executable) @@ -80,27 +80,27 @@ class Arbiter(object): "cwd": cwd, 0: sys.executable } - + def setup(self, app): self.app = app self.cfg = app.cfg self.log = self.cfg.logger_class(app.cfg) - + if 'GUNICORN_FD' in os.environ: self.log.reopen_files() - + self.address = self.cfg.address self.num_workers = self.cfg.workers self.debug = self.cfg.debug self.timeout = self.cfg.timeout self.proc_name = self.cfg.proc_name self.worker_class = self.cfg.worker_class - + if self.cfg.debug: self.log.debug("Current configuration:") for config, value in sorted(self.cfg.settings.iteritems()): self.log.debug(" %s: %s", config, value.value) - + if self.cfg.preload_app: if not self.cfg.debug: self.app.wsgi() @@ -117,7 +117,7 @@ class Arbiter(object): self.init_signals() if not self.LISTENER: self.LISTENER = create_socket(self.cfg, self.log) - + if self.cfg.pidfile is not None: self.pidfile = Pidfile(self.cfg.pidfile) self.pidfile.create(self.pid) @@ -128,7 +128,7 @@ class Arbiter(object): self.cfg.settings['worker_class'].get()) self.cfg.when_ready(self) - + def init_signals(self): """\ Initialize master signal handling. Most of the signals @@ -152,7 +152,7 @@ class Arbiter(object): "Main master loop." self.start() util._setproctitle("master [%s]" % self.proc_name) - + self.manage_workers() while True: try: @@ -163,18 +163,18 @@ class Arbiter(object): self.murder_workers() self.manage_workers() continue - + if sig not in self.SIG_NAMES: self.log.info("Ignoring unknown signal: %s", sig) continue - + signame = self.SIG_NAMES.get(sig) handler = getattr(self, "handle_%s" % signame, None) if not handler: self.log.error("Unhandled signal: %s", signame) continue self.log.info("Handling signal: %s", signame) - handler() + handler() self.wakeup() except StopIteration: self.halt() @@ -185,7 +185,7 @@ class Arbiter(object): except SystemExit: raise except Exception: - self.log.info("Unhandled exception in main loop:\n%s", + self.log.info("Unhandled exception in main loop:\n%s", traceback.format_exc()) self.stop(False) if self.pidfile is not None: @@ -195,7 +195,7 @@ class Arbiter(object): def handle_chld(self, sig, frame): "SIGCHLD handling" self.wakeup() - + def handle_hup(self): """\ HUP handling. @@ -205,16 +205,16 @@ class Arbiter(object): """ self.log.info("Hang up: %s", self.master_name) self.reload() - + def handle_quit(self): "SIGQUIT handling" raise StopIteration - + def handle_int(self): "SIGINT handling" self.stop(False) raise StopIteration - + def handle_term(self): "SIGTERM handling" self.stop(False) @@ -227,7 +227,7 @@ class Arbiter(object): """ self.num_workers += 1 self.manage_workers() - + def handle_ttou(self): """\ SIGTTOU handling. @@ -245,7 +245,7 @@ class Arbiter(object): """ self.kill_workers(signal.SIGUSR1) self.log.reopen_files() - + def handle_usr2(self): """\ SIGUSR2 handling. @@ -254,7 +254,7 @@ class Arbiter(object): deployment with the ability to backout a change. """ self.reexec() - + def handle_winch(self): "SIGWINCH handling" if os.getppid() == 1 or os.getpgrp() != os.getpid(): @@ -263,7 +263,7 @@ class Arbiter(object): self.kill_workers(signal.SIGQUIT) else: self.log.info("SIGWINCH ignored. Not daemonized") - + def wakeup(self): """\ Wake up the arbiter by writing to the PIPE @@ -273,7 +273,7 @@ class Arbiter(object): except IOError, e: if e.errno not in [errno.EAGAIN, errno.EINTR]: raise - + def halt(self, reason=None, exit_status=0): """ halt arbiter """ self.stop() @@ -283,7 +283,7 @@ class Arbiter(object): if self.pidfile is not None: self.pidfile.unlink() sys.exit(exit_status) - + def sleep(self): """\ Sleep until PIPE is readable or we timeout. @@ -303,12 +303,12 @@ class Arbiter(object): raise except KeyboardInterrupt: sys.exit() - - + + def stop(self, graceful=True): """\ Stop workers - + :attr graceful: boolean, If True (the default) workers will be killed gracefully (ie. trying to wait for the current connection) """ @@ -357,11 +357,11 @@ class Arbiter(object): if old_address != self.cfg.address: self.LISTENER.close() self.LISTENER = create_socket(self.cfg, self.log) - self.log.info("Listening at: %s", self.LISTENER) + self.log.info("Listening at: %s", self.LISTENER) # spawn new workers with new app & conf self.cfg.on_reload(self) - + # unlink pidfile if self.pidfile is not None: self.pidfile.unlink() @@ -370,15 +370,15 @@ class Arbiter(object): if self.cfg.pidfile is not None: self.pidfile = Pidfile(self.cfg.pidfile) self.pidfile.create(self.pid) - + # set new proc_name util._setproctitle("master [%s]" % self.proc_name) - + # manage workers self.log.reopen_files() - self.manage_workers() - + self.manage_workers() + def murder_workers(self): """\ Kill unused/idle workers @@ -392,7 +392,7 @@ class Arbiter(object): self.log.critical("WORKER TIMEOUT (pid:%s)", pid) self.kill_worker(pid, signal.SIGKILL) - + def reap_workers(self): """\ Reap workers to avoid zombie processes @@ -418,7 +418,7 @@ class Arbiter(object): except OSError, e: if e.errno == errno.ECHILD: pass - + def manage_workers(self): """\ Maintain the number of workers by spawning or killing @@ -432,7 +432,7 @@ class Arbiter(object): while len(workers) > self.num_workers: (pid, _) = workers.pop(0) self.kill_worker(pid, signal.SIGQUIT) - + def spawn_worker(self): self.worker_age += 1 worker = self.worker_class(self.worker_age, self.pid, self.LISTENER, @@ -470,11 +470,11 @@ class Arbiter(object): def spawn_workers(self): """\ Spawn new workers as needed. - + This is where a worker process leaves the main loop of the master process. """ - + for i in range(self.num_workers - len(self.WORKERS.keys())): self.spawn_worker() @@ -485,11 +485,11 @@ class Arbiter(object): """ for pid in self.WORKERS.keys(): self.kill_worker(pid, sig) - + def kill_worker(self, pid, sig): """\ Kill a worker - + :attr pid: int, worker pid :attr sig: `signal.SIG*` value """ @@ -504,4 +504,4 @@ class Arbiter(object): return except (KeyError, OSError): return - raise + raise diff --git a/gunicorn/config.py b/gunicorn/config.py index f23df2b2..cef15f35 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import copy @@ -34,21 +34,21 @@ def make_settings(ignore=None): return settings class Config(object): - + def __init__(self, usage=None): self.settings = make_settings() self.usage = usage - + def __getattr__(self, name): if name not in self.settings: raise AttributeError("No configuration setting for: %s" % name) return self.settings[name].get() - + def __setattr__(self, name, value): if name != "settings" and name in self.settings: raise AttributeError("Invalid access!") super(Config, self).__setattr__(name, value) - + def set(self, name, value): if name not in self.settings: raise AttributeError("No configuration setting for: %s" % name) @@ -77,7 +77,7 @@ class Config(object): worker_class.setup() return worker_class - @property + @property def workers(self): return self.settings['workers'].get() @@ -85,15 +85,15 @@ class Config(object): def address(self): bind = self.settings['bind'].get() return util.parse_address(util.to_bytestring(bind)) - + @property def uid(self): return self.settings['user'].get() - + @property def gid(self): return self.settings['group'].get() - + @property def proc_name(self): pn = self.settings['proc_name'].get() @@ -112,17 +112,17 @@ class Config(object): logger_class.install() return logger_class - + class SettingMeta(type): def __new__(cls, name, bases, attrs): super_new = super(SettingMeta, cls).__new__ parents = [b for b in bases if isinstance(b, SettingMeta)] if not parents: return super_new(cls, name, bases, attrs) - + attrs["order"] = len(KNOWN_SETTINGS) attrs["validator"] = wrap_method(attrs["validator"]) - + new_class = super_new(cls, name, bases, attrs) new_class.fmt_desc(attrs.get("desc", "")) KNOWN_SETTINGS.append(new_class) @@ -135,7 +135,7 @@ class SettingMeta(type): class Setting(object): __metaclass__ = SettingMeta - + name = None value = None section = None @@ -147,11 +147,11 @@ class Setting(object): default = None short = None desc = None - + def __init__(self): if self.default is not None: - self.set(self.default) - + self.set(self.default) + def add_option(self, parser): if not self.cli: return @@ -167,13 +167,13 @@ class Setting(object): if kwargs["action"] != "store": kwargs.pop("type") parser.add_option(*args, **kwargs) - + def copy(self): return copy.copy(self) - + def get(self): return self.value - + def set(self, val): assert callable(self.validator), "Invalid validator: %s" % self.name self.value = self.validator(val) @@ -256,7 +256,7 @@ def validate_post_request(val): def _wrapped(instance, req, environ): return fun(instance, req) return _wrapped - + if not callable(val): raise TypeError("Value isn't a callable: %s" % val) @@ -279,9 +279,9 @@ class ConfigFile(Setting): default = None desc = """\ The path to a Gunicorn config file. - + Only has an effect when specified on the command line or as part of an - application specific configuration. + application specific configuration. """ class Bind(Setting): @@ -293,11 +293,11 @@ class Bind(Setting): default = "127.0.0.1:8000" desc = """\ The socket to bind. - + A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. An IP is a valid HOST. """ - + class Backlog(Setting): name = "backlog" section = "Server Socket" @@ -307,14 +307,14 @@ class Backlog(Setting): type = "int" default = 2048 desc = """\ - The maximum number of pending connections. - + The maximum number of pending connections. + This refers to the number of clients that can be waiting to be served. Exceeding this number results in the client getting an error when attempting to connect. It should only affect servers under significant load. - - Must be a positive integer. Generally set in the 64-2048 range. + + Must be a positive integer. Generally set in the 64-2048 range. """ class Workers(Setting): @@ -327,7 +327,7 @@ class Workers(Setting): default = 1 desc = """\ The number of worker process for handling requests. - + A positive integer generally in the 2-4 x $(NUM_CORES) range. You'll want to vary this a bit to find the best for your particular application's work load. @@ -342,18 +342,18 @@ class WorkerClass(Setting): default = "sync" desc = """\ The type of workers to use. - + The default class (sync) should handle most 'normal' types of workloads. You'll want to read http://gunicorn.org/design.html for information on when you might want to choose one of the other worker classes. - + A string referring to one of the following bundled classes: - + * ``sync`` * ``eventlet`` - Requires eventlet >= 0.9.7 * ``gevent`` - Requires gevent >= 0.12.2 (?) * ``tornado`` - Requires tornado >= 0.2 - + Optionally, you can provide your own worker by giving gunicorn a python path to a subclass of gunicorn.workers.base.Worker. This alternative syntax will load the gevent class: @@ -371,7 +371,7 @@ class WorkerConnections(Setting): default = 1000 desc = """\ The maximum number of simultaneous clients. - + This setting only affects the Eventlet and Gevent worker types. """ @@ -385,11 +385,11 @@ class MaxRequests(Setting): default = 0 desc = """\ The maximum number of requests a worker will process before restarting. - + Any value greater than zero will limit the number of requests a work will process before automatically restarting. This is a simple method to help limit the damage of memory leaks. - + If this is set to zero (the default) then the automatic worker restarts are disabled. """ @@ -404,7 +404,7 @@ class Timeout(Setting): default = 30 desc = """\ Workers silent for more than this many seconds are killed and restarted. - + Generally set to thirty seconds. Only set this noticeably higher if you're sure of the repercussions for sync workers. For the non sync workers it just means that the worker process is still communicating and @@ -421,8 +421,8 @@ class Keepalive(Setting): default = 2 desc = """\ The number of seconds to wait for requests on a Keep-Alive connection. - - Generally set in the 1-5 seconds range. + + Generally set in the 1-5 seconds range. """ class Debug(Setting): @@ -434,7 +434,7 @@ class Debug(Setting): default = False desc = """\ Turn on debugging in the server. - + This limits the number of worker processes to 1 and changes some error handling that's sent to clients. """ @@ -448,8 +448,8 @@ class Spew(Setting): default = False desc = """\ Install a trace function that spews every line executed by the server. - - This is the nuclear option. + + This is the nuclear option. """ class PreloadApp(Setting): @@ -461,7 +461,7 @@ class PreloadApp(Setting): default = False desc = """\ Load application code before the worker processes are forked. - + By preloading an application you can save some RAM resources as well as speed up server boot times. Although, if you defer application loading to each worker process, you can reload your application code easily by @@ -477,7 +477,7 @@ class Daemon(Setting): default = False desc = """\ Daemonize the Gunicorn process. - + Detaches the server from the controlling terminal and enters the background. """ @@ -491,7 +491,7 @@ class Pidfile(Setting): default = None desc = """\ A filename to use for the PID file. - + If not set, no PID file will be written. """ @@ -504,7 +504,7 @@ class User(Setting): default = os.geteuid() desc = """\ Switch worker processes to run as this user. - + A valid user id (as an integer) or the name of a user that can be retrieved with a call to pwd.getpwnam(value) or None to not change the worker process user. @@ -519,7 +519,7 @@ class Group(Setting): default = os.getegid() desc = """\ Switch worker process to run as this group. - + A valid group id (as an integer) or the name of a user that can be retrieved with a call to pwd.getgrnam(value) or None to not change the worker processes group. @@ -535,9 +535,9 @@ class Umask(Setting): default = 0 desc = """\ A bit mask for the file mode on files written by Gunicorn. - + Note that this affects unix socket permissions. - + A valid value for the os.umask(mode) call or a string compatible with int(value, 0) (0 means Python guesses the base, so values like "0", "0xFF", "0022" are valid for decimal, hex, and octal representations) @@ -551,9 +551,9 @@ class TmpUploadDir(Setting): default = None desc = """\ Directory to store temporary request data as they are read. - + This may disappear in the near future. - + This path should be writable by the process permissions set for Gunicorn workers. If not specified, Gunicorn will choose a system generated temporary directory. @@ -599,10 +599,10 @@ class AccessLog(Setting): cli = ["--access-logfile"] meta = "FILE" validator = validate_string - default = None + default = None desc = """\ The Access log file to write to. - + "-" means log to stdout. """ @@ -612,7 +612,7 @@ class AccessLogFormat(Setting): cli = ["--access-logformat"] meta = "STRING" validator = validate_string - default = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' + default = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' desc = """\ The Access log format . @@ -631,7 +631,7 @@ class AccessLogFormat(Setting): T: request time in seconds D: request time in microseconds - You can also pass any WSGI request header as a parameter. + You can also pass any WSGI request header as a parameter. (ex '%(HTTP_HOST)s'). """ @@ -644,7 +644,7 @@ class ErrorLog(Setting): default = "-" desc = """\ The Error log file to write to. - + "-" means log to stdout. """ @@ -657,9 +657,9 @@ class Loglevel(Setting): default = "info" desc = """\ The granularity of Error log outputs. - + Valid level names are: - + * debug * info * warning @@ -681,8 +681,8 @@ class LoggerClass(Setting): normal usages in logging. It provides error and access logging. You can provide your own worker by giving gunicorn a - python path to a subclass like gunicorn.glogging.Logger. - Alternatively the syntax can also load the Logger class + python path to a subclass like gunicorn.glogging.Logger. + Alternatively the syntax can also load the Logger class with `egg:gunicorn#simple` """ @@ -695,12 +695,12 @@ class Procname(Setting): default = None desc = """\ A base to use with setproctitle for process naming. - + This affects things like ``ps`` and ``top``. If you're going to be running more than one instance of Gunicorn you'll probably want to set a name to tell them apart. This requires that you install the setproctitle module. - + It defaults to 'gunicorn'. """ @@ -723,7 +723,7 @@ class OnStarting(Setting): default = staticmethod(on_starting) desc = """\ Called just before the master process is initialized. - + The callable needs to accept a single instance variable for the Arbiter. """ @@ -752,7 +752,7 @@ class WhenReady(Setting): default = staticmethod(start_server) desc = """\ Called just after the server is started. - + The callable needs to accept a single instance variable for the Arbiter. """ @@ -766,11 +766,11 @@ class Prefork(Setting): default = staticmethod(pre_fork) desc = """\ Called just before a worker is forked. - + The callable needs to accept two instance variables for the Arbiter and new Worker. """ - + class Postfork(Setting): name = "post_fork" section = "Server Hooks" @@ -781,7 +781,7 @@ class Postfork(Setting): default = staticmethod(post_fork) desc = """\ Called just after a worker has been forked. - + The callable needs to accept two instance variables for the Arbiter and new Worker. """ @@ -796,7 +796,7 @@ class PreExec(Setting): default = staticmethod(pre_exec) desc = """\ Called just before a new master process is forked. - + The callable needs to accept a single instance variable for the Arbiter. """ @@ -810,7 +810,7 @@ class PreRequest(Setting): default = staticmethod(pre_request) desc = """\ Called just before a worker processes the request. - + The callable needs to accept two instance variables for the Worker and the Request. """ diff --git a/gunicorn/debug.py b/gunicorn/debug.py index ebd9aaec..3f342448 100644 --- a/gunicorn/debug.py +++ b/gunicorn/debug.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. -"""The debug module contains utilities and functions for better +"""The debug module contains utilities and functions for better debugging Gunicorn.""" import sys @@ -69,5 +69,5 @@ def unspew(): """Remove the trace hook installed by spew. """ sys.settrace(None) - + diff --git a/gunicorn/errors.py b/gunicorn/errors.py index 5270393c..e4fbcdd3 100644 --- a/gunicorn/errors.py +++ b/gunicorn/errors.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. @@ -8,7 +8,7 @@ class HaltServer(Exception): def __init__(self, reason, exit_status=1): self.reason = reason self.exit_status = exit_status - + def __str__(self): return "" % (self.reason, self.exit_status) diff --git a/gunicorn/glogging.py b/gunicorn/glogging.py index eb8c0ebe..2193ede8 100644 --- a/gunicorn/glogging.py +++ b/gunicorn/glogging.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import datetime @@ -39,7 +39,7 @@ class Logger(object): loglevel = self.LOG_LEVELS.get(cfg.loglevel.lower(), logging.INFO) self.error_log.setLevel(loglevel) - + # always info in access log self.access_log.setLevel(logging.INFO) @@ -100,13 +100,13 @@ class Logger(object): 'D': str(request_time.microseconds) } - # add WSGI request headers + # add WSGI request headers atoms.update(dict([(k,v) for k, v in environ.items() \ if k.startswith('HTTP_')])) for k, v in atoms.items(): atoms[k] = v.replace('"', '\\"') - + try: self.access_log.info(self.cfg.access_log_format % atoms) except: @@ -138,12 +138,12 @@ class Logger(object): util.close_on_exec(handler.stream.fileno()) handler.release() - + def _get_gunicorn_handler(self, log): for h in log.handlers: if getattr(h, "_gunicorn", False) == True: return h - + def _set_handler(self, log, output, fmt): # remove previous gunicorn log handler h = self._get_gunicorn_handler(log) diff --git a/gunicorn/http/_sendfile.py b/gunicorn/http/_sendfile.py index a822a851..82dcbafe 100644 --- a/gunicorn/http/_sendfile.py +++ b/gunicorn/http/_sendfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import errno @@ -35,7 +35,7 @@ def sendfile(fdout, fdin, offset, nbytes): ctypes.c_int] _nbytes = ctypes.c_uint64(nbytes) result = _sendfile(fdin, fdout, offset, _nbytes, None, 0) - + if result == -1: e = ctypes.get_errno() if e == errno.EAGAIN and _nbytes.value is not None: @@ -60,7 +60,7 @@ def sendfile(fdout, fdin, offset, nbytes): ctypes.POINTER(ctypes.c_uint64), ctypes.c_size_t] _offset = ctypes.c_uint64(offset) - sent = _sendfile(fdout, fdin, _offset, nbytes) + sent = _sendfile(fdout, fdin, _offset, nbytes) if sent == -1: e = ctypes.get_errno() raise OSError(e, os.strerror(e)) diff --git a/gunicorn/http/body.py b/gunicorn/http/body.py index a8ba8721..feb77c36 100644 --- a/gunicorn/http/body.py +++ b/gunicorn/http/body.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import sys @@ -18,7 +18,7 @@ class ChunkedReader(object): self.req = req self.parser = self.parse_chunked(unreader) self.buf = StringIO() - + def read(self, size): if not isinstance(size, (int, long)): raise TypeError("size must be an integral type") @@ -40,11 +40,11 @@ class ChunkedReader(object): self.buf.truncate(0) self.buf.write(rest) return ret - + def parse_trailers(self, unreader, data): buf = StringIO() buf.write(data) - + idx = buf.getvalue().find("\r\n\r\n") done = buf.getvalue()[:2] == "\r\n" while idx < 0 and not done: @@ -73,7 +73,7 @@ class ChunkedReader(object): rest += unreader.read() if rest[:2] != '\r\n': raise ChunkMissingTerminator(rest[:2]) - (size, rest) = self.parse_chunk_size(unreader, data=rest[2:]) + (size, rest) = self.parse_chunk_size(unreader, data=rest[2:]) def parse_chunk_size(self, unreader, data=None): buf = StringIO() @@ -87,7 +87,7 @@ class ChunkedReader(object): data = buf.getvalue() line, rest_chunk = data[:idx], data[idx+2:] - + chunk_size = line.split(";", 1)[0].strip() try: chunk_size = int(chunk_size, 16) @@ -112,18 +112,18 @@ class LengthReader(object): def __init__(self, unreader, length): self.unreader = unreader self.length = length - + def read(self, size): if not isinstance(size, (int, long)): raise TypeError("size must be an integral type") - + size = min(self.length, size) if size < 0: raise ValueError("Size must be positive.") if size == 0: return "" - - + + buf = StringIO() data = self.unreader.read() while data: @@ -131,7 +131,7 @@ class LengthReader(object): if buf.tell() >= size: break data = self.unreader.read() - + buf = buf.getvalue() ret, rest = buf[:size], buf[size:] self.unreader.unread(rest) @@ -143,7 +143,7 @@ class EOFReader(object): self.unreader = unreader self.buf = StringIO() self.finished = False - + def read(self, size): if not isinstance(size, (int, long)): raise TypeError("size must be an integral type") @@ -151,7 +151,7 @@ class EOFReader(object): raise ValueError("Size must be positive.") if size == 0: return "" - + if self.finished: data = self.buf.getvalue() ret, rest = data[:size], data[size:] @@ -179,10 +179,10 @@ class Body(object): def __init__(self, reader): self.reader = reader self.buf = StringIO() - + def __iter__(self): return self - + def next(self): ret = self.readline() if not ret: @@ -197,7 +197,7 @@ class Body(object): elif size < 0: return sys.maxint return size - + def read(self, size=None): size = self.getsize(size) if size == 0: @@ -221,12 +221,12 @@ class Body(object): self.buf.truncate(0) self.buf.write(rest) return ret - + def readline(self, size=None): size = self.getsize(size) if size == 0: return "" - + line = self.buf.getvalue() idx = line.find("\n") if idx >= 0: @@ -234,7 +234,7 @@ class Body(object): self.buf.truncate(0) self.buf.write(line[idx+1:]) return ret - + self.buf.truncate(0) ch = "" buf = [line] @@ -246,7 +246,7 @@ class Body(object): lsize += 1 buf.append(ch) return "".join(buf) - + def readlines(self, size=None): ret = [] data = self.read() diff --git a/gunicorn/http/errors.py b/gunicorn/http/errors.py index beafa05c..dc428420 100644 --- a/gunicorn/http/errors.py +++ b/gunicorn/http/errors.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. class ParseException(Exception): @@ -26,18 +26,18 @@ class InvalidRequestMethod(ParseException): def __str__(self): return "Invalid HTTP method: %r" % self.method - + class InvalidHTTPVersion(ParseException): def __init__(self, version): self.version = version - + def __str__(self): return "Invalid HTTP Version: %s" % self.version class InvalidHeader(ParseException): def __init__(self, hdr): self.hdr = hdr - + def __str__(self): return "Invalid HTTP Header: %r" % self.hdr @@ -51,13 +51,13 @@ class InvalidHeaderName(ParseException): class InvalidChunkSize(ParseException): def __init__(self, data): self.data = data - + def __str__(self): return "Invalid chunk size: %r" % self.data class ChunkMissingTerminator(ParseException): def __init__(self, term): self.term = term - + def __str__(self): return "Invalid chunk terminator is not '\\r\\n': %r" % self.term diff --git a/gunicorn/http/message.py b/gunicorn/http/message.py index d2b97bf9..565e71bd 100644 --- a/gunicorn/http/message.py +++ b/gunicorn/http/message.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import re @@ -28,7 +28,7 @@ class Message(object): unused = self.parse(self.unreader) self.unreader.unread(unused) self.set_body_reader() - + def parse(self): raise NotImplementedError() @@ -50,12 +50,12 @@ class Message(object): if self.hdrre.search(name): raise InvalidHeaderName(name) name, value = name.strip(), [value.lstrip()] - + # Consume value continuation lines while len(lines) and lines[0].startswith((" ", "\t")): value.append(lines.pop(0)) value = ''.join(value).rstrip() - + headers.append((name, value)) return headers @@ -99,7 +99,7 @@ class Request(Message): def __init__(self, unreader): self.methre = re.compile("[A-Z0-9$-_.]{3,20}") self.versre = re.compile("HTTP/(\d+).(\d+)") - + self.method = None self.uri = None self.scheme = None @@ -119,12 +119,12 @@ class Request(Message): raise StopIteration() raise NoMoreData(buf.getvalue()) buf.write(data) - + def parse(self, unreader): buf = StringIO() self.get_data(unreader, buf, stop=True) - + # Request line idx = buf.getvalue().find("\r\n") while idx < 0: @@ -134,8 +134,8 @@ class Request(Message): rest = buf.getvalue()[idx+2:] # Skip \r\n buf = StringIO() buf.write(rest) - - + + # Headers idx = buf.getvalue().find("\r\n\r\n") @@ -144,7 +144,7 @@ class Request(Message): self.get_data(unreader, buf) idx = buf.getvalue().find("\r\n\r\n") done = buf.getvalue()[:2] == "\r\n" - + if done: self.unreader.unread(buf.getvalue()[2:]) return "" @@ -154,7 +154,7 @@ class Request(Message): ret = buf.getvalue()[idx+4:] buf = StringIO() return ret - + def parse_request_line(self, line): bits = line.split(None, 2) if len(bits) != 3: diff --git a/gunicorn/http/parser.py b/gunicorn/http/parser.py index 1ee29448..92d33842 100644 --- a/gunicorn/http/parser.py +++ b/gunicorn/http/parser.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from gunicorn.http.message import Request @@ -17,18 +17,18 @@ class Parser(object): def __iter__(self): return self - + def next(self): # Stop if HTTP dictates a stop. if self.mesg and self.mesg.should_close(): raise StopIteration() - + # Discard any unread body of the previous message if self.mesg: data = self.mesg.body.read(8192) while data: data = self.mesg.body.read(8192) - + # Parse the next request self.mesg = self.mesg_class(self.unreader) if not self.mesg: diff --git a/gunicorn/http/unreader.py b/gunicorn/http/unreader.py index 4dcee55a..be1ca3dc 100644 --- a/gunicorn/http/unreader.py +++ b/gunicorn/http/unreader.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import os @@ -16,10 +16,10 @@ except ImportError: class Unreader(object): def __init__(self): self.buf = StringIO() - + def chunk(self): raise NotImplementedError() - + def read(self, size=None): if size is not None and not isinstance(size, (int, long)): raise TypeError("size parameter must be an int or long.") @@ -48,7 +48,7 @@ class Unreader(object): self.buf.truncate(0) self.buf.write(data[size:]) return data[:size] - + def unread(self, data): self.buf.seek(0, os.SEEK_END) self.buf.write(data) @@ -58,7 +58,7 @@ class SocketUnreader(Unreader): super(SocketUnreader, self).__init__() self.sock = sock self.mxchunk = max_chunk - + def chunk(self): return self.sock.recv(self.mxchunk) diff --git a/gunicorn/http/wsgi.py b/gunicorn/http/wsgi.py index 03f7b4ba..41d20db2 100644 --- a/gunicorn/http/wsgi.py +++ b/gunicorn/http/wsgi.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import logging @@ -59,7 +59,7 @@ def create(req, sock, client, server, cfg): "CONTENT_TYPE": "", "CONTENT_LENGTH": "" } - + # authors should be aware that REMOTE_HOST and REMOTE_ADDR # may not qualify the remote addr: # http://www.ietf.org/rfc/rfc3875 @@ -98,7 +98,7 @@ def create(req, sock, client, server, cfg): environ[key] = hdr_value environ['wsgi.url_scheme'] = url_scheme - + if isinstance(forward, basestring): # we only took the last one # http://en.wikipedia.org/wiki/X-Forwarded-For @@ -121,7 +121,7 @@ def create(req, sock, client, server, cfg): remote = (host, port) else: - remote = forward + remote = forward environ['REMOTE_ADDR'] = remote[0] environ['REMOTE_PORT'] = str(remote[1]) diff --git a/gunicorn/logging_config.py b/gunicorn/logging_config.py index e092785a..f1dd6dd8 100644 --- a/gunicorn/logging_config.py +++ b/gunicorn/logging_config.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. # # Copyright 2001-2005 by Vinay Sajip. All Rights Reserved. diff --git a/gunicorn/management/commands/run_gunicorn.py b/gunicorn/management/commands/run_gunicorn.py index 7fa1c42c..b57ef317 100644 --- a/gunicorn/management/commands/run_gunicorn.py +++ b/gunicorn/management/commands/run_gunicorn.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from optparse import make_option import sys - + import django from django.core.management.base import BaseCommand, CommandError from django.conf import settings @@ -56,17 +56,17 @@ class Command(BaseCommand): option_list = BaseCommand.option_list + GUNICORN_OPTIONS help = "Starts a fully-functional Web server using gunicorn." args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]' - + # Validation is called explicitly each time the server is reloaded. requires_model_validation = False - + def handle(self, addrport=None, *args, **options): if args: raise CommandError('Usage is run_gunicorn %s' % self.args) - + if addrport: options['bind'] = addrport - + options['default_proc_name'] = settings.SETTINGS_MODULE admin_media_path = options.pop('admin_media_path', '') @@ -74,11 +74,11 @@ class Command(BaseCommand): print "Validating models..." self.validate(display_num_errors=True) - print "\nDjango version %s, using settings %r" % (django.get_version(), + print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE) print "Server is running" print "Quit the server with %s." % quit_command - + # django.core.management.base forces the locale to en-us. translation.activate(settings.LANGUAGE_CODE) DjangoApplicationCommand(options, admin_media_path).run() diff --git a/gunicorn/pidfile.py b/gunicorn/pidfile.py index 7e303af7..d04f941e 100644 --- a/gunicorn/pidfile.py +++ b/gunicorn/pidfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from __future__ import with_statement @@ -20,7 +20,7 @@ class Pidfile(object): def __init__(self, fname): self.fname = fname self.pid = None - + def create(self, pid): oldpid = self.validate() if oldpid: @@ -30,7 +30,7 @@ class Pidfile(object): "(or pid file '%s' is stale)" % (os.getpid(), self.fname)) self.pid = pid - + # Write pidfile fdir = os.path.dirname(self.fname) if fdir and not os.path.isdir(fdir): @@ -43,14 +43,14 @@ class Pidfile(object): self.fname = fname os.close(fd) - # set permissions to -rw-r--r-- + # set permissions to -rw-r--r-- os.chmod(self.fname, 420) - + def rename(self, path): self.unlink() self.fname = path self.create(self.pid) - + def unlink(self): """ delete pidfile""" try: @@ -61,7 +61,7 @@ class Pidfile(object): os.unlink(self.fname) except: pass - + def validate(self): """ Validate pidfile and make it stale if needed""" if not self.fname: diff --git a/gunicorn/sock.py b/gunicorn/sock.py index 16a6092f..a31e574a 100644 --- a/gunicorn/sock.py +++ b/gunicorn/sock.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import errno @@ -14,7 +14,7 @@ from gunicorn import util class BaseSocket(object): - + def __init__(self, conf, log, fd=None): self.log = log self.conf = conf @@ -24,13 +24,13 @@ class BaseSocket(object): else: sock = socket.fromfd(fd, self.FAMILY, socket.SOCK_STREAM) self.sock = self.set_options(sock, bound=(fd is not None)) - + def __str__(self, name): return "" % self.sock.fileno() - + def __getattr__(self, name): return getattr(self.sock, name) - + def set_options(self, sock, bound=False): sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if not bound: @@ -38,10 +38,10 @@ class BaseSocket(object): sock.setblocking(0) sock.listen(self.conf.backlog) return sock - + def bind(self, sock): sock.bind(self.address) - + def close(self): try: self.sock.close() @@ -51,12 +51,12 @@ class BaseSocket(object): del self.sock class TCPSocket(BaseSocket): - + FAMILY = socket.AF_INET - + def __str__(self): return "http://%s:%d" % self.sock.getsockname() - + def set_options(self, sock, bound=False): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) return super(TCPSocket, self).set_options(sock, bound=bound) @@ -70,9 +70,9 @@ class TCP6Socket(TCPSocket): return "http://[%s]:%d" % (host, port) class UnixSocket(BaseSocket): - + FAMILY = socket.AF_UNIX - + def __init__(self, conf, log, fd=None): if fd is None: try: @@ -80,16 +80,16 @@ class UnixSocket(BaseSocket): except OSError: pass super(UnixSocket, self).__init__(conf, log, fd=fd) - + def __str__(self): return "unix:%s" % self.address - + def bind(self, sock): old_umask = os.umask(self.conf.umask) sock.bind(self.address) util.chown(self.address, self.conf.uid, self.conf.gid) os.umask(old_umask) - + def close(self): super(UnixSocket, self).close() os.unlink(self.address) @@ -103,7 +103,7 @@ def create_socket(conf, log): """ # get it only once addr = conf.address - + if isinstance(addr, tuple): if util.is_ipv6(addr[0]): sock_type = TCP6Socket @@ -127,7 +127,7 @@ def create_socket(conf, log): # If we fail to create a socket from GUNICORN_FD # we fall through and try and open the socket # normally. - + for i in range(5): try: return sock_type(conf, log) @@ -140,6 +140,6 @@ def create_socket(conf, log): if i < 5: log.error("Retrying in 1 second.") time.sleep(1) - + log.error("Can't connect to %s", str(addr)) sys.exit(1) diff --git a/gunicorn/util.py b/gunicorn/util.py index 62bec73d..054d76ac 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. @@ -55,11 +55,11 @@ hop_headers = set(""" te trailers transfer-encoding upgrade server date """.split()) - + try: from setproctitle import setproctitle def _setproctitle(title): - setproctitle("gunicorn: %s" % title) + setproctitle("gunicorn: %s" % title) except ImportError: def _setproctitle(title): return @@ -82,9 +82,9 @@ def load_class(uri, default="sync", section="gunicorn.workers"): if uri.startswith("#"): uri = uri[1:] - return pkg_resources.load_entry_point("gunicorn", + return pkg_resources.load_entry_point("gunicorn", section, uri) - except ImportError: + except ImportError: raise RuntimeError("class uri invalid or not found") klass = components.pop(-1) mod = __import__('.'.join(components)) @@ -103,10 +103,10 @@ def set_owner_process(uid,gid): # versions of python < 2.6.2 don't manage unsigned int for # groups like on osx or fedora os.setgid(-ctypes.c_int(-gid).value) - + if uid: os.setuid(uid) - + def chown(path, uid, gid): try: os.chown(path, uid, gid) @@ -122,7 +122,7 @@ def is_ipv6(addr): except socket.error: # not a valid address return False return True - + def parse_address(netloc, default_port=8000): if netloc.startswith("unix:"): return netloc.split("unix:")[1] @@ -136,7 +136,7 @@ def parse_address(netloc, default_port=8000): host = "0.0.0.0" else: host = netloc.lower() - + #get port netloc = netloc.split(']')[-1] if ":" in netloc: @@ -145,9 +145,9 @@ def parse_address(netloc, default_port=8000): raise RuntimeError("%r is not a valid port number." % port) port = int(port) else: - port = default_port + port = default_port return (host, port) - + def get_maxfd(): maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if (maxfd == resource.RLIM_INFINITY): @@ -158,7 +158,7 @@ def close_on_exec(fd): flags = fcntl.fcntl(fd, fcntl.F_GETFD) flags |= fcntl.FD_CLOEXEC fcntl.fcntl(fd, fcntl.F_SETFD, flags) - + def set_non_blocking(fd): flags = fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK fcntl.fcntl(fd, fcntl.F_SETFL, flags) @@ -183,7 +183,7 @@ except ImportError: def write_chunk(sock, data): chunk = "".join(("%X\r\n" % len(data), data, "\r\n")) sock.sendall(chunk) - + def write(sock, data, chunked=False): if chunked: return write_chunk(sock, data) @@ -199,7 +199,7 @@ def write_nonblock(sock, data, chunked=False): sock.setblocking(1) else: return write(sock, data, chunked) - + def writelines(sock, lines, chunked=False): for line in list(lines): write(sock, line, chunked) @@ -229,7 +229,7 @@ def write_error(sock, status_int, reason, mesg): def normalize_name(name): return "-".join([w.lower().capitalize() for w in name.split("-")]) - + def import_app(module): parts = module.split(":", 1) if len(parts) == 1: @@ -264,7 +264,7 @@ def http_date(timestamp=None): day, monthname[month], year, hh, mm, ss) return s - + def to_bytestring(s): """ convert to bytestring an unicode """ if not isinstance(s, basestring): @@ -289,11 +289,11 @@ def daemonize(): if os.fork(): os._exit(0) - + os.umask(0) maxfd = get_maxfd() closerange(0, maxfd) - + os.open(REDIRECT_TO, os.O_RDWR) os.dup2(0, 1) os.dup2(0, 2) diff --git a/gunicorn/workers/async.py b/gunicorn/workers/async.py index 6f31e314..635ed831 100644 --- a/gunicorn/workers/async.py +++ b/gunicorn/workers/async.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from __future__ import with_statement @@ -21,7 +21,7 @@ class AsyncWorker(base.Worker): def __init__(self, *args, **kwargs): super(AsyncWorker, self).__init__(*args, **kwargs) self.worker_connections = self.cfg.worker_connections - + def timeout_ctx(self): raise NotImplementedError() diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py index 5616c837..893f4248 100644 --- a/gunicorn/workers/base.py +++ b/gunicorn/workers/base.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. @@ -24,7 +24,7 @@ class Worker(object): lambda x: getattr(signal, "SIG%s" % x), "HUP QUIT INT TERM USR1 USR2 WINCH CHLD".split() ) - + PIPE = [] def __init__(self, age, ppid, socket, app, timeout, cfg, log): @@ -47,11 +47,11 @@ class Worker(object): self.log = log self.debug = cfg.debug self.address = self.socket.getsockname() - self.tmp = WorkerTmp(cfg) - + self.tmp = WorkerTmp(cfg) + def __str__(self): return "" % self.pid - + @property def pid(self): return os.getpid() @@ -88,7 +88,7 @@ class Worker(object): self.PIPE = os.pipe() map(util.set_non_blocking, self.PIPE) map(util.close_on_exec, self.PIPE) - + # Prevent fd inherientence util.close_on_exec(self.socket) util.close_on_exec(self.tmp.fileno()) @@ -96,9 +96,9 @@ class Worker(object): self.log.close_on_exec() self.init_signals() - + self.wsgi = self.app.wsgi() - + # Enter main run loop self.booted = True self.run() @@ -118,7 +118,7 @@ class Worker(object): def handle_usr1(self, sig, frame): self.log.reopen_files() - + def handle_quit(self, sig, frame): self.alive = False @@ -135,10 +135,10 @@ class Worker(object): if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,)): - + status_int = 400 reason = "Bad Request" - + if isinstance(exc, InvalidRequestLine): mesg = "

Invalid Request Line '%s'

" % str(exc) elif isinstance(exc, InvalidRequestMethod): @@ -147,7 +147,7 @@ class Worker(object): mesg = "

Invalid HTTP Version '%s'

" % str(exc) elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)): mesg = "

Invalid Header '%s'

" % str(exc) - + if self.debug: tb = traceback.format_exc() mesg += "

Traceback:

\n
%s
" % tb @@ -156,7 +156,7 @@ class Worker(object): util.write_error(client, status_int, reason, mesg) except: self.log.warning("Failed to send error message.") - + def handle_winch(self, sig, fname): # Ignore SIGWINCH in worker. Fixes a crash on OpenBSD. return diff --git a/gunicorn/workers/geventlet.py b/gunicorn/workers/geventlet.py index f01880b4..e020ca4b 100644 --- a/gunicorn/workers/geventlet.py +++ b/gunicorn/workers/geventlet.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from __future__ import with_statement @@ -28,9 +28,9 @@ class EventletWorker(AsyncWorker): def init_process(self): hubs.use_hub() super(EventletWorker, self).init_process() - + def timeout_ctx(self): - return eventlet.Timeout(self.cfg.keepalive, False) + return eventlet.Timeout(self.cfg.keepalive, False) def run(self): self.socket = GreenSocket(family_or_realsock=self.socket.sock) diff --git a/gunicorn/workers/ggevent_wsgi.py b/gunicorn/workers/ggevent_wsgi.py index bab05a02..cb5985b3 100644 --- a/gunicorn/workers/ggevent_wsgi.py +++ b/gunicorn/workers/ggevent_wsgi.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from datetime import datetime -from gunicorn.workers.ggevent import BASE_WSGI_ENV, GeventWorker +from gunicorn.workers.ggevent import BASE_WSGI_ENV, GeventWorker from gevent import wsgi @@ -30,9 +30,9 @@ class WSGIHandler(wsgi.WSGIHandler): self.time_start = datetime.now() super(WSGIHandler, self).handle() - + class WSGIServer(wsgi.WSGIServer): - base_env = BASE_WSGI_ENV + base_env = BASE_WSGI_ENV class GeventWSGIWorker(GeventWorker): "The Gevent StreamServer based workers." diff --git a/gunicorn/workers/gtornado.py b/gunicorn/workers/gtornado.py index d1f2630a..5c81e68c 100644 --- a/gunicorn/workers/gtornado.py +++ b/gunicorn/workers/gtornado.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import os @@ -19,7 +19,7 @@ from gunicorn.workers.base import Worker from gunicorn import __version__ as gversion class TornadoWorker(Worker): - + @classmethod def setup(cls): web = sys.modules.pop("tornado.web") @@ -29,18 +29,18 @@ class TornadoWorker(Worker): self._headers["Server"] += " (Gunicorn/%s)" % gversion web.RequestHandler.clear = clear sys.modules["tornado.web"] = web - + def handle_quit(self, sig, frame): super(TornadoWorker, self).handle_quit(sig, frame) self.ioloop.stop() def watchdog(self): self.notify() - + if self.ppid != os.getppid(): self.log.info("Parent changed, shutting down: %s", self) self.ioloop.stop() - + def run(self): self.socket.setblocking(0) self.ioloop = IOLoop.instance() diff --git a/gunicorn/workers/sync.py b/gunicorn/workers/sync.py index d619c365..4726201a 100644 --- a/gunicorn/workers/sync.py +++ b/gunicorn/workers/sync.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. # @@ -16,7 +16,7 @@ import gunicorn.util as util import gunicorn.workers.base as base class SyncWorker(base.Worker): - + def run(self): # self.socket appears to lose its blocking status after # we fork in the arbiter. Reset it here. @@ -24,7 +24,7 @@ class SyncWorker(base.Worker): while self.alive: self.notify() - + # Accept a connection. If we get an error telling us # that no connection is waiting we fall down to the # select which is where we'll wait for a bit for new @@ -48,7 +48,7 @@ class SyncWorker(base.Worker): if self.ppid != os.getppid(): self.log.info("Parent changed, shutting down: %s", self) return - + try: self.notify() ret = select.select([self.socket], [], self.PIPE, self.timeout) @@ -63,7 +63,7 @@ class SyncWorker(base.Worker): else: return raise - + def handle(self, client, addr): try: parser = http.RequestParser(client) @@ -78,7 +78,7 @@ class SyncWorker(base.Worker): self.log.debug("Ignoring EPIPE") except Exception, e: self.handle_error(client, e) - finally: + finally: util.close(client) def handle_request(self, req, client, addr): @@ -113,7 +113,7 @@ class SyncWorker(base.Worker): raise except Exception, e: # Only send back traceback in HTTP in debug mode. - self.handle_error(client, e) + self.handle_error(client, e) return finally: try: diff --git a/gunicorn/workers/workertmp.py b/gunicorn/workers/workertmp.py index 02456049..37e75393 100644 --- a/gunicorn/workers/workertmp.py +++ b/gunicorn/workers/workertmp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 - # -# This file is part of gunicorn released under the MIT license. +# This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. import os @@ -13,7 +13,7 @@ class WorkerTmp(object): def __init__(self, cfg): old_umask = os.umask(cfg.umask) fd, name = tempfile.mkstemp(prefix="wgunicorn-") - + # allows the process to write to the file util.chown(name, cfg.uid, cfg.gid) os.umask(old_umask) @@ -28,7 +28,7 @@ class WorkerTmp(object): self.spinner = 0 - def notify(self): + def notify(self): try: self.spinner = (self.spinner+1) % 2 os.fchmod(self._tmp.fileno(), self.spinner) @@ -42,6 +42,6 @@ class WorkerTmp(object): def fileno(self): return self._tmp.fileno() - + def close(self): return self._tmp.close()