Dispatcharr/docker/uwsgi.modular.ini
SergeantPanda c33d456743 Enable gevent in uWSGI workers; fix WS delivery and DB exhaustion
- Enable gevent cooperative multitasking in all uWSGI worker configs
  (gevent-early-monkey-patch + import dispatcharr.gevent_patch)
- Rewrite WebSocket group sends to bypass asyncio in gevent workers:
  _gevent_ws_send() replicates the channels_redis 4.x wire format
  directly via synchronous Redis so send_websocket_update() and
  _send_async() no longer fail silently after epoll is patched out
- Fix PostgreSQL connection exhaustion: CONN_MAX_AGE=0 + explicit
  close_old_connections() in stream manager and cleanup watchdog loops
- Fix stream proxy race: register client before the connect-wait loop
  so the cleanup watchdog never sees zero clients on a live channel
- Channel list/logo/profile queryset optimisations: conditional DISTINCT,
  EXISTS semi-joins for filter-options, channel_count annotation to
  eliminate N+1 in LogoSerializer, prefetched memberships in
  ChannelProfileSerializer
- JsonResponse for channel ID list and summary endpoints
2026-05-14 18:55:09 -05:00

66 lines
2.4 KiB
INI

[uwsgi]
; Modular deployment mode - external PostgreSQL, Redis, and Celery
; Remove file creation commands since we're not logging to files anymore
; exec-pre = mkdir -p /data/logs
; exec-pre = touch /data/logs/uwsgi.log
; exec-pre = chmod 666 /data/logs/uwsgi.log
; Redis wait + flush is handled by the entrypoint in modular mode
; (uWSGI exec-pre runs under 'su -' which strips Docker env vars)
; Start Daphne for WebSocket support (required for real-time features)
; Redis and Celery run in separate containers in modular mode
attach-daemon = daphne -b 0.0.0.0 -p 8001 dispatcharr.asgi:application
# Core settings
chdir = /app
module = dispatcharr.wsgi:application
virtualenv = /dispatcharrpy
master = true
env = DJANGO_SETTINGS_MODULE=dispatcharr.settings
env = USE_NGINX_ACCEL=true
socket = /app/uwsgi.sock
chmod-socket = 777
vacuum = true
die-on-term = true
static-map = /static=/app/static
# Worker management
workers = 4
# Optimize for streaming
http = 0.0.0.0:5656
http-keepalive = 1
buffer-size = 65536 # Increase buffer for large payloads
post-buffering = 4096 # Reduce buffering for real-time streaming
http-timeout = 600 # Prevent disconnects from long streams
socket-timeout = 600 # Prevent write timeouts when client buffers
lazy-apps = true # Improve memory efficiency
# Async mode (use gevent for high concurrency)
gevent = 400 # Each unused greenlet costs ~2-4KB of memory
# Higher values have minimal performance impact when idle, but provide capacity for traffic spikes
# If memory usage becomes an issue, reduce this value
# Patch the stdlib (socket, threading, time, ...) before any app code
# loads so blocking calls yield to the gevent hub. Without this, a single
# blocking psycopg2 / requests / DNS call freezes every greenlet on the
# worker. The companion module greens psycopg2 specifically.
gevent-early-monkey-patch = true
import = dispatcharr.gevent_patch
# Performance tuning
thunder-lock = true
log-4xx = true
log-5xx = true
disable-logging = false
# Logging configuration
# Enable console logging (stdout)
log-master = true
# Enable strftime formatting for timestamps
logformat-strftime = true
log-date = %%Y-%%m-%%d %%H:%%M:%%S,000
# Use formatted time with environment variable for log level
log-format = %(ftime) $(DISPATCHARR_LOG_LEVEL) uwsgi.requests Worker ID: %(wid) %(method) %(status) %(uri) %(msecs)ms
log-buffering = 1024 # Add buffer size limit for logging