- SIGINT/SIGQUIT triggers immediate shutdown, skipping connection waits
- SIGTERM triggers graceful shutdown, waiting for connections
- Arbiter forwards SIGQUIT to workers if received during graceful shutdown
- Workers have 2s to exit cleanly after quick shutdown before SIGKILL
- Add get_app_workers_attribute() to read workers class attribute
- Update _parse_app_specs() to check class attribute when no config override
- Add Docker-based e2e tests for per-app worker allocation
- Add test apps: HeavyModelApp (workers=2), LightweightApp
- Add unit tests for get_app_workers_attribute function
- Add integration tests for class attribute detection
Allow dirty apps to specify how many workers should load them, enabling
significant memory savings for heavy applications like ML models.
- Add `workers` class attribute to DirtyApp (None = all workers)
- Add `parse_dirty_app_spec()` to parse "module:Class:N" format
- Add `DirtyNoWorkersAvailableError` for app-specific error handling
- Update DirtyArbiter with per-app worker tracking and routing
- Maintain backward compatibility when no dirty_apps configured
Example: 8 workers x 10GB model = 80GB RAM needed
With workers=2: 2 x 10GB = 20GB RAM (75% savings)
Configuration formats:
- Class attribute: `workers = 2` on DirtyApp subclass
- Config format: `module:class:N` (e.g., `myapp.ml:HugeModel:2`)
- Fix mobile side menu not displaying on iPad by keeping site_nav
content but hiding sidebar on desktop via CSS
- Fix broken links in asgi.md and guides/http2.md
- Add HTTP/2 guide to navigation
- Add explicit do_handshake() in base_async.py before ALPN check
when do_handshake_on_connect is False
- Mark eventlet worker as deprecated (removal in 26.0)
- Add HTTP/2 gevent example with Docker and tests
- Update documentation to reflect eventlet deprecation
- Remove eventlet websocket example (gevent version exists)
The ALPN fix ensures HTTP/2 works correctly with gevent and eventlet
workers when do_handshake_on_connect config is False (the default).
Without explicit handshake, selected_alpn_protocol() returns None.
- Reorder exception handlers: specific exceptions before ProtocolError
- Extract _wait_for_flow_control_window() to reduce return statements
- Refactor flow control waiting to avoid too-many-return-statements
- Add three tuning profiles: Conservative, Balanced, High Concurrency
- Document pros/cons and trade-offs for each HTTP/2 setting
- Add Linux kernel tuning parameters for high concurrency
- Add Docker-specific tuning recommendations
- Include benchmark results from h2load testing
- Send GOAWAY with correct error codes for protocol violations
- Handle StreamClosedError and FlowControlError gracefully
- Return False instead of raising for missing/closed streams
- Handle flow control window overflow per RFC 7540
- Fix reader race condition and add h2 exception handling
- Wait for WINDOW_UPDATE when flow control window is zero/negative
- Use h2 exception's error_code for INITIAL_WINDOW_SIZE violations
Add complete HTTP/2 example in examples/http2_features/:
- ASGI app showing priority access and trailer sending
- Test script using raw h2 library for HTTP/2 testing
- Docker setup for easy testing
- Documentation update referencing the example
The example demonstrates:
- Reading http.response.priority extension in ASGI scope
- Sending http.response.trailers messages
- Multiple streams on the same connection
- Guard early_hints callback against calls after response started
- Fix :authority precedence over Host header per RFC 9113 section 8.3.1
- Add nginx early_hints documentation link
- Use standard port 443 in curl examples
- Add pylint disable comments for global-statement in lazy import pattern
- Remove unnecessary pass statements in error subclasses
- Remove useless return None at end of _handle_request_received methods
- Add docs/content/guides/http2.md with comprehensive HTTP/2 guide
- Quick start and requirements
- Configuration options and settings
- Worker compatibility matrix
- HTTP 103 Early Hints usage for WSGI and ASGI
- Production deployment with nginx
- Troubleshooting guide
- Update docs/content/asgi.md to reflect HTTP/2 support
- Update docs/content/2026-news.md with 25.0.0 release featuring
HTTP/2 and Early Hints
- Regenerate docs/content/reference/settings.md with HTTP/2 settings
Implement HTTP 103 Early Hints as modern replacement for HTTP/2 Server Push.
This allows servers to send resource hints before the final response,
enabling browsers to preload assets in parallel.
WSGI support:
- Add wsgi.early_hints callback to environ dict
- Apps can call environ['wsgi.early_hints'](headers) to send 103 responses
- Silently ignored for HTTP/1.0 clients (don't support 1xx responses)
ASGI support:
- Handle http.response.informational message type
- Apps can await send({"type": "http.response.informational", "status": 103, ...})
HTTP/2 support:
- Add send_informational() method to HTTP2ServerConnection
- Add async send_informational() method to AsyncHTTP2Connection
- Wire up early hints in gthread worker for HTTP/2 requests
Includes unit tests and Docker integration tests for all protocols.
Integrate HTTP/2 support with gunicorn workers:
- sync worker: Add warning that HTTP/2 is not supported
- gthread worker: Full HTTP/2 support
- ALPN negotiation with explicit handshake for deferred SSL
- HTTP/2 connection lifecycle management
- Per-stream request handling with WSGI
- AsyncHTTP2Connection: Async version for ASGI workers
- Same features as sync version with async/await
- Proper flow control with chunked data sending
- ASGI worker: HTTP/2 support via AsyncHTTP2Connection
- AsyncWorker base: HTTP/2 connection handling
- tornado worker: Add warning that HTTP/2 is not supported
Also exports helper functions from http2 module.
The `test` and `coverage` targets rely on `setup.py` which was removed "about
10 years ago". There is apparently no interest in fixing them. This change
removes them to avoid confusion.
As per https://github.com/benoitc/gunicorn/issues/3386
Force early setproctitle initialization by calling getproctitle()
immediately after import. This ensures setproctitle captures the
argv/environ memory layout before systemd.listen_fds() modifies
the environment by removing LISTEN_FDS and LISTEN_PID.
Without this fix, if LISTEN_FDS is the first environment variable,
setproctitle fails to detect argv correctly and silently fails.
Fixes#3430
Tests the ASGI worker with direct HTTP requests without uWSGI protocol.
Includes tests for GET, POST, query strings, path handling, keepalive,
large bodies, and custom headers.