83 Commits

Author SHA1 Message Date
Benoit Chesneau
2d4310116d docs: merge gunicornc into 25.1.0 release 2026-02-13 12:03:48 +01:00
Benoit Chesneau
bf4ad8d610 docs: update 25.1.0 release date to 2026-02-13 2026-02-13 11:59:42 +01:00
Benoit Chesneau
3e60d2942d docs: add gunicornc control interface guide
- Add guides/gunicornc.md with usage examples and command reference
- Update mkdocs.yml navigation to include Control Interface guide
- Update 2026-news.md and news.md changelog with 25.2.0 release
- Regenerate reference/settings.md with control socket settings
2026-02-13 02:29:44 +01:00
Benoit Chesneau
0077b05916 docs: add TTIN/TTOU to changelog 2026-02-12 23:59:20 +01:00
Benoit Chesneau
2639215aa3 feat(dirty): add TTIN/TTOU signal support for dynamic worker scaling
Add support for SIGTTIN and SIGTTOU signals to the dirty arbiter,
allowing dynamic scaling of dirty workers at runtime without restarting
gunicorn.

Changes:
- Add TTIN/TTOU to DirtyArbiter.SIGNALS
- Add num_workers instance variable for dynamic count
- Add _get_minimum_workers() to enforce app worker constraints
- Add signal handlers for TTIN (increase) and TTOU (decrease)
- Update manage_workers() to use dynamic count
- Add documentation for dynamic scaling
- Add unit tests for signal handling
- Add Docker integration tests

The minimum worker constraint ensures TTOU cannot reduce workers below
what apps require (e.g., if an app has workers=3, minimum is 3).

Closes #3489
2026-02-12 23:52:12 +01:00
Benoit Chesneau
ac00c862d7 docs: mark ASGI as stable, Dirty Arbiters as beta
- Remove beta warning from ASGI worker documentation
- Add beta warning to Dirty Arbiters documentation
- Update README feature list accordingly
- Update changelog to reflect stability changes
2026-02-12 22:09:14 +01:00
Benoit Chesneau
7f6cf908e5 release: 25.1.0
New Features:
- Dirty Stash: global shared state between workers (#3503)
- Dirty Binary Protocol: TLV encoding for efficient IPC (#3500)

Documentation:
- Fix Markdown formatting in /configure
2026-02-12 22:06:44 +01:00
Benoit Chesneau
709a6ad159
feat(dirty): add stash - global shared state between workers (#3503)
* feat(dirty): add stash - global shared state between workers

Add a simple key-value store (stash) that allows dirty workers to share
state through the arbiter. Tables are stored directly in arbiter memory
for fast access and simplicity.

Features:
- Auto-create tables on first access
- Dict-like interface via stash.table()
- Pattern matching for keys (glob patterns)
- Module-level API: stash.put(), stash.get(), stash.delete(), etc.

Usage:
    from gunicorn.dirty import stash

    stash.put("sessions", "user:1", {"name": "Alice"})
    user = stash.get("sessions", "user:1")

    # Or dict-like
    sessions = stash.table("sessions")
    sessions["user:1"] = {"name": "Alice"}

New files:
- gunicorn/dirty/stash.py - Client API and StashTable class
- Protocol additions for MSG_TYPE_STASH and STASH_OP_* codes

Note: Tables are ephemeral - lost if arbiter restarts.

* test(dirty): add tests for stash protocol and encoding

Test coverage for:
- Stash message creation and encoding
- Protocol constants (MSG_TYPE_STASH, STASH_OP_*)
- Error classes (StashError, StashTableNotFoundError, StashKeyNotFoundError)
- StashTable dict-like interface
- Edge cases: unicode, complex values, special patterns

* example(dirty): add stash usage example and integration tests

- Add SessionApp to dirty_app.py demonstrating stash usage
- Add /session/* endpoints to wsgi_app.py
- Add test_stash_integration.py with Docker tests
- Update docker-compose.yml with stash-test service
- Fix: Set GUNICORN_DIRTY_SOCKET in dirty arbiter for worker access

* docs(dirty): add stash documentation
2026-02-12 21:45:49 +01:00
Benoit Chesneau
236c9371d0
Merge pull request #3502 from Juneezee/docs/issues-3498
docs: fix Markdown formatting in /configure
2026-02-12 17:52:07 +01:00
Eng Zer Jun
1cd4db8ddf
docs: fix Markdown formatting in /configure
Fixes https://github.com/benoitc/gunicorn/issues/3498.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2026-02-12 21:12:24 +08:00
Benoit Chesneau
00da70292f docs(dirty): update examples and docs for binary protocol
- Update test_protocol.py example to use binary protocol
- Add test_binary_data_handling example showing raw bytes transfer
- Update dirty.md to document binary TLV protocol format
- Replace JSON references with binary protocol
- Add Binary Protocol section with header and TLV encoding details
2026-02-11 23:15:14 +01:00
Benoit Chesneau
fc850687df chore: prepare release 25.0.3 2026-02-07 15:36:43 +01:00
Benoit Chesneau
874e8be0a1 docs: shorten sponsor section on homepage
Simplify the sponsor section to a single concise line and link to
the dedicated sponsor page instead of GitHub sponsors directly.
2026-02-07 11:31:40 +01:00
Benoit Chesneau
7293b216f4 docs: add prominent sponsorship options
- Add sponsor banner at top of README
- Add Revolut and Open Collective to FUNDING.yml
- Add dedicated sponsor page in docs
- Add sponsor heart link in footer
2026-02-07 11:29:15 +01:00
Benoit Chesneau
70d571bd7c docs: update homepage title and remove version display
- Change title from "The Python WSGI Server" to "Serve Python Apps on the Web"
- Remove "Version {{ version }}" text from hero section
- Remove unused .hero__version CSS
2026-02-07 11:08:04 +01:00
Benoit Chesneau
95b7ffeeaa chore: prepare release 25.0.2
- Bump version to 25.0.2
- Update copyright year to 2026 in LICENSE and NOTICE
- Add license headers to all Python source files
- Add changelog entry for 25.0.2
2026-02-06 08:21:18 +01:00
Benoit Chesneau
3bf718ea52 fix: graceful disconnect handling for ASGI worker
Closes #3484

When a client disconnects during an ASGI request, the worker now:
1. Sends http.disconnect message to the app's receive queue
2. Allows a configurable grace period for cleanup (default: 3 seconds)
3. Only cancels the task after the grace period expires

This follows the ASGI HTTP Connection Scope spec which defines
http.disconnect as the message apps should receive when clients
disconnect: https://asgi.readthedocs.io/en/latest/specs/www.html#disconnect-receive-event

The grace period prevents CancelledError from propagating to async
database operations, allowing SQLAlchemy and other async DB libraries
to properly reset their connection pools.

New config option: --asgi-disconnect-grace-period (default: 3 seconds)
2026-02-03 02:46:07 +01:00
Benoit Chesneau
3373e4b987 docs: add CNAME file for custom domain 2026-02-02 23:36:30 +01:00
Benoit Chesneau
a7e14e16fd docs: replace sponsors section with expanded support section
Update README.md and docs homepage with detailed support messaging
including sponsorship benefits and corporate contact information.
2026-02-02 21:49:15 +01:00
Benoit Chesneau
3bf529f6c2 docs: sync news.md with 2026-news.md 2026-02-02 14:28:37 +01:00
Benoit Chesneau
e1519c0569 docs: add ASGI compliance test suite to changelog 2026-02-02 14:11:22 +01:00
Benoit Chesneau
658924c436 docs: update changelog for 25.0.1 2026-02-02 10:17:50 +01:00
Benoit Chesneau
9ece4a6873 docs: add GitHub icon to header, remove header.autohide 2026-02-01 15:04:41 +01:00
Benoit Chesneau
8652aec783 docs: update news.md with complete 25.0.0 changelog 2026-02-01 14:50:02 +01:00
Benoit Chesneau
d621aa81f9 fix: add version number to homepage hero section 2026-02-01 14:47:48 +01:00
Benoit Chesneau
617a85ea91 docs: update 25.0.0 release date to 2026-02-01 2026-02-01 14:30:56 +01:00
Benoit Chesneau
86264ef900 docs: add per-app worker allocation to 25.0.0 changelog 2026-02-01 08:32:46 +01:00
Benoit Chesneau
c4fe116d71 docs: add per-app worker allocation documentation 2026-02-01 03:15:22 +01:00
Benoit Chesneau
1af599769f docs: regenerate settings.md 2026-02-01 03:11:42 +01:00
Benoit Chesneau
1591a6c773 fix: iPad mobile menu and documentation link warnings
- 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
2026-01-30 01:29:45 +01:00
Benoit Chesneau
490817d149 docs: update changelog for 25.0.0
- Add ALPN fix for gevent/eventlet workers
- Add eventlet worker deprecation notice
- Update HTTP/2 feature to mention gevent example
- Remove eventlet from HTTP/2 supported workers list
2026-01-28 13:43:54 +01:00
Benoit Chesneau
315e7bde80 fix(http2): ALPN negotiation for gevent/eventlet workers
- 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.
2026-01-28 13:42:48 +01:00
Benoit Chesneau
200977bc0b docs: update 25.0.0 changelog with all changes since 24.0
- Fix PR references for HTTP/2 and Early Hints (#3468)
- Add uWSGI protocol support for ASGI worker (#3467)
- Add bug fixes: setproctitle, 100-continue, macOS segfault
- Add changes: remove obsolete Makefile targets (#3471)
2026-01-28 11:45:36 +01:00
Benoit Chesneau
49193223d5 docs(http2): add performance tuning section
- 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
2026-01-27 16:11:05 +01:00
Benoit Chesneau
34dc8b8fad docs(http2): add RFC compliance, security, and testing sections
- Add RFC compliance table covering RFC 7540, 9113, 7541, 8297
- Document security considerations and built-in protections
- Add recommended security-hardened configuration example
- Document compliance testing with h2spec and nghttp2 tools
- Note that Server Push is intentionally not implemented
2026-01-27 15:42:53 +01:00
Benoit Chesneau
fa5e319f15 docs(http2): add ASGI example demonstrating priority and trailers
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
2026-01-27 13:15:36 +01:00
Benoit Chesneau
0f298e4838 feat(http2): add response trailer support 2026-01-27 12:33:12 +01:00
Benoit Chesneau
655716a181 feat(http2): add stream priority support (RFC 7540 Section 5.3) 2026-01-27 11:44:33 +01:00
Benoit Chesneau
66d0880c74 Address PR #3468 review feedback
- 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
2026-01-27 09:59:35 +01:00
Benoit Chesneau
955893b6ab Add HTTP/2 documentation
- 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
2026-01-27 09:59:35 +01:00
Benoit Chesneau
1fe9e5816e
Merge pull request #3460 from benoitc/feature/dirty-arbiters
feat: add dirty arbiters for long-running blocking operations
2026-01-27 09:45:05 +01:00
Benoit Chesneau
891990befa docs(dirty): update streaming from future to current feature 2026-01-26 09:39:46 +01:00
Benoit Chesneau
8663740907
Add uWSGI protocol support to ASGI worker (#3467)
Add uWSGI protocol support to ASGI worker

- Implements AsyncUWSGIRequest class extending sync UWSGIRequest to reuse parsing logic with async I/O
- ASGI protocol handler selects between HTTP and uWSGI based on --protocol config option
- Allows gunicorn's ASGI worker to receive requests from nginx using uwsgi_pass directive
- Includes unit tests and Docker integration tests
2026-01-25 14:45:07 +01:00
Benoit Chesneau
d85be79102 docs: regenerate settings.md with dirty arbiter options 2026-01-25 10:33:38 +01:00
Benoit Chesneau
cc39ed922e examples(dirty): add streaming chat demo with SSE
Add a lightweight chat simulator demonstrating dirty worker streaming:
- Token-by-token SSE streaming via async generators
- FastAPI endpoint with browser UI
- Multiple canned responses based on keywords
- Docker deployment with docker-compose
- Integration tests for SSE protocol

Update docs/content/dirty.md to link to both examples.
2026-01-25 10:26:12 +01:00
Benoit Chesneau
ae8665c4d5 docs(dirty): expand architecture, signal handling, and health monitoring
- Enhance architecture diagram with Unix socket paths, signal flow, and
  heartbeat indicators
- Add process relationships table
- Expand signal handling section with flow diagram, comprehensive signal
  reference table, and async handling explanation
- Add new "Liveness and Health Monitoring" section covering heartbeat
  mechanism, timeout detection, parent death detection, orphan cleanup,
  and respawn behavior
- Add link to embedding service example
2026-01-25 10:23:25 +01:00
Benoit Chesneau
f6418d4eb0 feat(dirty): add streaming support and async client benchmarks
Add support for streaming responses when dirty app actions return
generators (sync or async). This enables real-time delivery of
incremental results for use cases like LLM token generation.

Features:
- Streaming protocol with chunk/end/error message types
- Worker support for sync and async generators
- Arbiter forwarding of streaming messages
- Deadline-based timeout handling
- Async client streaming API

Protocol:
- Chunk messages (type: "chunk") contain partial data
- End messages (type: "end") signal stream completion
- Error messages can occur mid-stream

New files:
- benchmarks/dirty_streaming.py: Streaming benchmark suite
- tests/dirty/test_*_streaming*.py: Streaming test coverage
- docs/content/dirty.md: Streaming documentation with examples
2026-01-25 10:23:25 +01:00
Benoit Chesneau
9b0e87deb8 docs(dirty): clarify application initialization sequence 2026-01-25 10:23:25 +01:00
Benoit Chesneau
c914f336b8 docs: add dirty arbiters to navigation and changelog 2026-01-25 10:23:25 +01:00
Benoit Chesneau
77222b8017 feat: add dirty arbiters for long-running blocking operations
Introduce Dirty Arbiters - a separate process pool for executing
long-running, blocking operations (AI model loading, heavy computation)
without blocking HTTP workers. Inspired by Erlang's dirty schedulers.

Key features:
- Completely separate from HTTP workers - can be killed/restarted independently
- Stateful - loaded resources persist in dirty worker memory
- Message-passing IPC via Unix sockets with JSON serialization
- Explicit execute() API from HTTP workers
- Asyncio-based for clean concurrent handling

Architecture:
- DirtyArbiter: manages the dirty worker pool, routes requests
- DirtyWorker: executes functions, maintains state, handles requests
- DirtyClient: sync/async API for HTTP workers to call dirty apps
- DirtyProtocol: length-prefixed JSON messages over Unix sockets
- DirtyApp: base class for dirty applications

Configuration options:
- dirty_apps: list of import paths for dirty applications
- dirty_workers: number of dirty workers (default: 0)
- dirty_timeout: task timeout in seconds (default: 300)
- dirty_graceful_timeout: shutdown timeout (default: 30)

Lifecycle hooks:
- on_dirty_starting(arbiter)
- dirty_post_fork(arbiter, worker)
- dirty_worker_init(worker)
- dirty_worker_exit(arbiter, worker)

Includes comprehensive test suite with 164 tests covering:
- Protocol encoding/decoding
- Worker and arbiter lifecycle
- Client sync/async APIs
- Signal handling
- Error handling and timeouts
- Integration tests
2026-01-25 10:21:18 +01:00