Files
IT_Ticket_System/gunicorn.conf.py
T
2026-03-26 13:18:09 -04:00

66 lines
2.4 KiB
Python

# 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