# gunicorn.conf.py # Server socket bind = "127.0.0.1:7000" # match your nginx proxy_pass port backlog = 2048 # Worker — eventlet requires exactly 1 worker process. # Concurrency is handled by eventlet's cooperative green-thread pool. worker_class = "eventlet" workers = 1 worker_connections= 2000 timeout = 300 keepalive = 75 # preload_app must be False with the eventlet worker. # # With preload_app = True, gunicorn loads the WSGI app in the master process # before forking workers. At that point gunicorn's own internals have already # imported `logging` and other stdlib modules, creating real OS RLocks. # The eventlet worker calls eventlet.monkey_patch() at its own import time — # but that import happens *after* the master has already loaded the app, so # the patch arrives too late and eventlet emits: # "1 RLock(s) were not greened" # # With preload_app = False, workers are forked first. The eventlet worker # module is imported inside each worker process, its module-level # monkey_patch() fires before the app is loaded, and all subsequent imports # (including logging) get the green versions from the start. preload_app = False # Application wsgi_app = "run:app" # Logging accesslog = "logs/gunicorn_access.log" errorlog = "logs/gunicorn_error.log" loglevel = "warning" # suppress routine socket close noise capture_output = False # don't capture eventlet's stderr Errno 9 messages access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(a)s" %(D)sµs' # Process naming proc_name = "it_ticket_system" daemon = False pidfile = "/tmp/it_tickets.pid" def post_fork(server, worker): """Called after a worker is forked. Patch eventlet per-worker.""" import eventlet eventlet.monkey_patch() def worker_exit(server, worker): """ Called when a worker exits. Cleanly close any remaining eventlet sockets to prevent [Errno 9] Bad file descriptor errors in the logs. These errors are benign (connections recover automatically) but noisy. """ try: import eventlet.greenio # Hub cleanup — tells eventlet to stop watching all open file descriptors hub = eventlet.hubs.get_hub() if hasattr(hub, 'abort'): hub.abort(wait=False) except Exception: pass