Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: benoitc/gunicorn
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 25.0.1
Choose a base ref
...
head repository: benoitc/gunicorn
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 25.0.2
Choose a head ref
  • 11 commits
  • 210 files changed
  • 1 contributor

Commits on Feb 2, 2026

  1. 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.
    benoitc committed Feb 2, 2026
    Configuration menu
    Copy the full SHA
    a7e14e1 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    3373e4b View commit details
    Browse the repository at this point in the history

Commits on Feb 3, 2026

  1. fix: lazy import dirty module for gevent compatibility

    Closes #3482
    
    The dirty module (which uses asyncio and concurrent.futures) was being
    imported at gunicorn startup via gunicorn.arbiter. This caused
    concurrent.futures to be imported before user code could call
    gevent.monkey.patch_all(), breaking gevent's monkey-patching.
    
    Changes:
    - gunicorn/arbiter.py: Import DirtyArbiter and set_dirty_socket_path
      lazily inside spawn_dirty_arbiter() instead of at module level
    - gunicorn/dirty/worker.py: Import ThreadPoolExecutor lazily inside
      run() method instead of at module level
    - Add tests/workers/test_gevent_import_order.py with 5 tests verifying:
      - concurrent.futures is NOT imported when gunicorn.arbiter loads
      - gevent patching works correctly with gunicorn
      - Reproduces the exact scenario from the bug report gist
    
    This ensures gevent's monkey.patch_all() can run before concurrent.futures
    is imported, allowing proper patching of threading primitives.
    benoitc committed Feb 3, 2026
    Configuration menu
    Copy the full SHA
    b19c648 View commit details
    Browse the repository at this point in the history
  2. Merge pull request #3483 from benoitc/fix/gevent-concurrent-futures-i…

    …mport
    
    fix: lazy import dirty module for gevent compatibility
    benoitc authored Feb 3, 2026
    Configuration menu
    Copy the full SHA
    15cadf8 View commit details
    Browse the repository at this point in the history
  3. 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)
    benoitc committed Feb 3, 2026
    Configuration menu
    Copy the full SHA
    3bf718e View commit details
    Browse the repository at this point in the history
  4. Merge pull request #3485 from benoitc/fix/asgi-graceful-disconnect

    fix: graceful disconnect handling for ASGI worker
    benoitc authored Feb 3, 2026
    Configuration menu
    Copy the full SHA
    866e88c View commit details
    Browse the repository at this point in the history

Commits on Feb 6, 2026

  1. fix: resolve ASGI concurrent request failures through nginx proxy

    - Fix nginx config to use keepalive with upstream (was sending
      Connection: close which caused premature connection closure)
    - Add _safe_write() to handle socket errors (EPIPE, ECONNRESET,
      ENOTCONN) gracefully when client disconnects
    - Fix ASGI scope server/client to always be 2-tuples for IPv6
      compatibility (IPv6 sockets return 4-tuples)
    - Add write_eof() before close() to ensure buffered data is flushed
    - Bind to [::] for dual-stack IPv4/IPv6 support in test containers
    benoitc committed Feb 6, 2026
    Configuration menu
    Copy the full SHA
    e780508 View commit details
    Browse the repository at this point in the history
  2. refactor: extract _normalize_sockaddr utility function

    Consolidate the repeated pattern for normalizing socket addresses
    to ASGI-compatible (host, port) tuples into a single utility function.
    benoitc committed Feb 6, 2026
    Configuration menu
    Copy the full SHA
    026167a View commit details
    Browse the repository at this point in the history
  3. 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
    benoitc committed Feb 6, 2026
    Configuration menu
    Copy the full SHA
    95b7ffe View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    2c0f959 View commit details
    Browse the repository at this point in the history
  5. 1 Configuration menu
    Copy the full SHA
    9508df6 View commit details
    Browse the repository at this point in the history
Loading