Files
barker/barker/gunicorn.conf.py
2026-02-22 04:23:14 +00:00

115 lines
3.7 KiB
Python

import json
import multiprocessing
import os
# --- Worker sizing -----------------------------------------------------------
# Prefer explicit WEB_CONCURRENCY in containers. Otherwise fall back to
# WORKERS_PER_CORE * cpu_count(), with a minimum of 2 and optional MAX_WORKERS.
workers_per_core_str = os.getenv("WORKERS_PER_CORE", "1")
max_workers_str = os.getenv("MAX_WORKERS")
use_max_workers = None
if max_workers_str:
use_max_workers = int(max_workers_str)
web_concurrency_str = os.getenv("WEB_CONCURRENCY", None)
cores = multiprocessing.cpu_count()
workers_per_core = float(workers_per_core_str)
default_web_concurrency = workers_per_core * cores
if web_concurrency_str:
web_concurrency = int(web_concurrency_str)
assert web_concurrency > 0
else:
web_concurrency = max(int(default_web_concurrency), 2)
if use_max_workers:
web_concurrency = min(web_concurrency, use_max_workers)
# --- Bind / logging ----------------------------------------------------------
host = os.getenv("HOST", "0.0.0.0")
port = os.getenv("PORT", "9995")
bind_env = os.getenv("BIND", None)
use_bind = bind_env if bind_env else f"{host}:{port}"
loglevel = os.getenv("LOG_LEVEL", "info")
accesslog_var = os.getenv("ACCESS_LOG", "-")
accesslog = accesslog_var or None
errorlog_var = os.getenv("ERROR_LOG", "-")
errorlog = errorlog_var or None
worker_tmp_dir = "/dev/shm"
# --- Timeouts / keepalive ----------------------------------------------------
graceful_timeout = int(os.getenv("GRACEFUL_TIMEOUT", "120"))
timeout = int(os.getenv("TIMEOUT", "120"))
keepalive = int(os.getenv("KEEP_ALIVE", "5"))
# --- Robustness knobs (recommended) -----------------------------------------
# Recycle workers gradually to mitigate memory leaks / fragmentation without
# full container restarts. Tune via env if needed.
max_requests = int(os.getenv("MAX_REQUESTS", "10000"))
max_requests_jitter = int(os.getenv("MAX_REQUESTS_JITTER", "1000"))
# Prevent slow clients from holding connections forever (defaults are fine).
# You can tune these via env if you ever need to.
# worker_connections matters only for async worker types; kept here for clarity.
worker_connections = int(os.getenv("WORKER_CONNECTIONS", "1000"))
# Helpful in containerized environments: ensure workers are responsive.
# (Defaults are okay; leaving commented unless you want strict behavior.)
# heartbeat_interval = int(os.getenv("HEARTBEAT_INTERVAL", "30"))
# --- Gunicorn config vars ----------------------------------------------------
workers = web_concurrency
bind = use_bind
# --- Debug print (keep if you like) ------------------------------------------
log_data = {
"loglevel": loglevel,
"workers": workers,
"bind": bind,
"graceful_timeout": graceful_timeout,
"timeout": timeout,
"keepalive": keepalive,
"errorlog": errorlog,
"accesslog": accesslog,
"worker_tmp_dir": worker_tmp_dir,
"max_requests": max_requests,
"max_requests_jitter": max_requests_jitter,
"worker_connections": worker_connections,
# Additional, non-gunicorn variables
"workers_per_core": workers_per_core,
"use_max_workers": use_max_workers,
"host": host,
"port": port,
"cores": cores,
}
print(json.dumps(log_data)) # noqa: T201
# Variables Gunicorn reads
# (these must be module-level names)
# fmt: off
# Core
loglevel = loglevel
workers = workers
bind = bind
# Logging
accesslog = accesslog
errorlog = errorlog
# Runtime
worker_tmp_dir = worker_tmp_dir
graceful_timeout = graceful_timeout
timeout = timeout
keepalive = keepalive
# Recycling
max_requests = max_requests
max_requests_jitter = max_requests_jitter
# Concurrency (relevant for some worker types; harmless otherwise)
worker_connections = worker_connections
# fmt: on