diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index e23f1bde..19f9fa74 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -32,13 +32,14 @@ class Arbiter(object): if name[:3] == "SIG" and name[3] != "_" ) - def __init__(self, address, num_workers, modname): + def __init__(self, address, num_workers, modname, debug=False): self.address = address self.num_workers = num_workers self.modname = modname self.timeout = 30 self.reexec_pid = 0 self.pid = os.getpid() + self.debug = debug self.log = logging.getLogger(__name__) self.init_signals() self.listen(self.address) @@ -270,7 +271,7 @@ class Arbiter(object): continue worker = Worker(i, self.pid, self.LISTENER, self.modname, - self.timeout) + self.timeout, self.debug) pid = os.fork() if pid != 0: self.WORKERS[pid] = worker diff --git a/gunicorn/http/request.py b/gunicorn/http/request.py index d6ff7b84..9721a5b1 100644 --- a/gunicorn/http/request.py +++ b/gunicorn/http/request.py @@ -43,7 +43,9 @@ class HttpRequest(object): } - def __init__(self, socket, client_address, server_address): + def __init__(self, socket, client_address, server_address, + debug=False): + self.debug = debug self.socket = socket self.client_address = client_address self.server_address = server_address @@ -82,13 +84,24 @@ class HttpRequest(object): else: wsgi_input = TeeInput(self.socket, self.parser, buf[i:]) + + if self.debug: + # according to the doc + # This value should evaluate true if an equivalent application object + # may be simultaneously invoked by another process, and should evaluate + # false otherwise. In debug mode we fall to one worker + # so we comply to pylons and other paster app. + wsgi_multiprocess = False + else: + wsgi_multiprocess = True + environ = { "wsgi.url_scheme": 'http', "wsgi.input": wsgi_input, "wsgi.errors": sys.stderr, "wsgi.version": (1, 0), "wsgi.multithread": False, - "wsgi.multiprocess": True, + "wsgi.multiprocess": wsgi_multiprocess, "wsgi.run_once": False, "SCRIPT_NAME": "", "SERVER_SOFTWARE": self.SERVER_VERSION, diff --git a/gunicorn/main.py b/gunicorn/main.py index 919bb177..5e89147d 100644 --- a/gunicorn/main.py +++ b/gunicorn/main.py @@ -28,7 +28,9 @@ def options(): op.make_option('--log-level', dest='loglevel', default='info', help='Log level below which to silence messages. [%default]'), op.make_option('--log-file', dest='logfile', default='-', - help='Log to a file. - is stdout. [%default]') + help='Log to a file. - is stdout. [%default]'), + op.make_option('-d', '--debug', dest='debug', action="store_true", + default=False, help='Debug mode. only 1 worker.') ] def configure_logging(opts): @@ -52,7 +54,12 @@ def main(usage, get_app): configure_logging(opts) app = get_app(parser, opts, args) - arbiter = Arbiter((opts.host, opts.port), opts.workers, app) + workers = opts.workers + if opts.debug: + workers = 1 + + arbiter = Arbiter((opts.host, opts.port), workers, app, + opts.debug) arbiter.run() def paste_server(app, global_conf=None, host="127.0.0.1", port=None, @@ -69,5 +76,11 @@ def paste_server(app, global_conf=None, host="127.0.0.1", port=None, else: workers = int(global_conf.get('workers', 1)) - arbiter = Arbiter(bind_addr, workers, app) + debug = global_conf.get('debug') == "true" + if debug: + # we force to one worker in debug mode. + workers = 1 + + arbiter = Arbiter(bind_addr, workers, app, + debug) arbiter.run() \ No newline at end of file diff --git a/gunicorn/worker.py b/gunicorn/worker.py index e6d9874a..9ac365aa 100644 --- a/gunicorn/worker.py +++ b/gunicorn/worker.py @@ -25,9 +25,11 @@ class Worker(object): "HUP QUIT INT TERM TTIN TTOU USR1".split() ) - def __init__(self, workerid, ppid, socket, app, timeout): + def __init__(self, workerid, ppid, socket, app, timeout, + debug=False): self.id = workerid self.ppid = ppid + self.debug = debug self.timeout = timeout / 2.0 fd, tmpname = tempfile.mkstemp() self.tmp = os.fdopen(fd, "r+b") @@ -115,7 +117,7 @@ class Worker(object): def handle(self, client, addr): util.close_on_exec(client) try: - req = http.HttpRequest(client, addr, self.address) + req = http.HttpRequest(client, addr, self.address, self.debug) try: response = self.app(req.read(), req.start_response) except Exception, e: diff --git a/setup.py b/setup.py index abd42136..695a8120 100644 --- a/setup.py +++ b/setup.py @@ -45,5 +45,4 @@ setup( main=gunicorn.main:paste_server """, test_suite = 'nose.collector', -) - +) \ No newline at end of file