pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/www/py-gunicorn



Module Name:    pkgsrc
Committed By:   adam
Date:           Tue Feb  3 09:17:23 UTC 2026

Modified Files:
        pkgsrc/www/py-gunicorn: Makefile PLIST distinfo

Log Message:
py-gunicorn: updated to 25.0.1

25.0.1 - 2026-02-02

Bug Fixes

- Fix ASGI streaming responses (SSE) hanging: add chunked transfer encoding for
  HTTP/1.1 responses without Content-Length header. Without chunked encoding,
  clients wait for connection close to determine end-of-response.

Changes

- Update celery_alternative example to use FastAPI with native ASGI worker and
  uvloop for async task execution

Testing

- Add ASGI compliance test suite with Docker-based integration tests covering HTTP,
  WebSocket, streaming, lifespan, framework integration (Starlette, FastAPI),
  HTTP/2, and concurrency scenarios

25.0.0 - 2026-02-01

New Features

- **Dirty Arbiters**: Separate process pool for executing long-running, blocking
  operations (AI model loading, heavy computation) without blocking HTTP workers
  - Inspired by Erlang's dirty schedulers
  - Asyncio-based with Unix socket IPC
  - Stateful workers that persist loaded resources
  - New settings: `--dirty-app`, `--dirty-workers`, `--dirty-timeout`,
    `--dirty-threads`, `--dirty-graceful-timeout`
  - Lifecycle hooks: `on_dirty_starting`, `dirty_post_fork`,
    `dirty_worker_init`, `dirty_worker_exit`

- **Per-App Worker Allocation for Dirty Arbiters**: Control how many dirty workers
  load each app for memory optimization with heavy models
  - Set `workers` class attribute on DirtyApp (e.g., `workers = 2`)
  - Or use config format `module:class:N` (e.g., `myapp:HeavyModel:2`)
  - Requests automatically routed to workers with the target app
  - New exception `DirtyNoWorkersAvailableError` for graceful error handling
  - Example: 8 workers × 10GB model = 80GB → with `workers=2`: 20GB (75% savings)

- **HTTP/2 Support (Beta)**: Native HTTP/2 (RFC 7540) support for improved performance
  with modern clients
  - Multiplexed streams over a single connection
  - Header compression (HPACK)
  - Flow control and stream prioritization
  - Works with gthread, gevent, and ASGI workers
  - New settings: `--http-protocols`, `--http2-max-concurrent-streams`,
    `--http2-initial-window-size`, `--http2-max-frame-size`, `--http2-max-header-list-size`
  - Requires SSL/TLS and h2 library: `pip install gunicorn[http2]`
  - See [HTTP/2 Guide](guides/http2.md) for details
  - New example: `examples/http2_gevent/` with Docker and tests

- **HTTP 103 Early Hints**: Support for RFC 8297 Early Hints to enable browsers to
  preload resources before the final response
  - WSGI: `environ['wsgi.early_hints'](headers)` callback
  - ASGI: `http.response.informational` message type
  - Works with both HTTP/1.1 and HTTP/2

- **uWSGI Protocol for ASGI Worker**: The ASGI worker now supports receiving requests
  via the uWSGI binary protocol from nginx

Bug Fixes

- Fix HTTP/2 ALPN negotiation for gevent and eventlet workers when
  `do_handshake_on_connect` is False (the default). The TLS handshake is now
  explicitly performed before checking `selected_alpn_protocol()`.

- Fix setproctitle initialization with systemd socket activation

- Fix `Expect: 100-continue` handling: ignore the header for HTTP/1.0 requests
  since 100-continue is only valid for HTTP/1.1+

- Fix missing `_expected_100_continue` attribute in UWSGIRequest

- Disable setproctitle on macOS to prevent segfaults during process title updates

- Publish full exception traceback when the application fails to load

Deprecations

- **Eventlet Worker**: The `eventlet` worker is deprecated and will be removed in
  Gunicorn 26.0. Eventlet itself is [no longer actively maintained](https://eventlet.readthedocs.io/en/latest/asyncio/migration.html).
  Please migrate to `gevent`, `gthread`, or another supported worker type.

Changes

- Remove obsolete Makefile targets


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 pkgsrc/www/py-gunicorn/Makefile
cvs rdiff -u -r1.15 -r1.16 pkgsrc/www/py-gunicorn/PLIST
cvs rdiff -u -r1.19 -r1.20 pkgsrc/www/py-gunicorn/distinfo

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/www/py-gunicorn/Makefile
diff -u pkgsrc/www/py-gunicorn/Makefile:1.27 pkgsrc/www/py-gunicorn/Makefile:1.28
--- pkgsrc/www/py-gunicorn/Makefile:1.27        Mon Apr 14 19:12:54 2025
+++ pkgsrc/www/py-gunicorn/Makefile     Tue Feb  3 09:17:23 2026
@@ -1,8 +1,7 @@
-# $NetBSD: Makefile,v 1.27 2025/04/14 19:12:54 adam Exp $
+# $NetBSD: Makefile,v 1.28 2026/02/03 09:17:23 adam Exp $
 
-DISTNAME=      gunicorn-23.0.0
+DISTNAME=      gunicorn-25.0.1
 PKGNAME=       ${PYPKGPREFIX}-${DISTNAME}
-PKGREVISION=   1
 CATEGORIES=    www python
 MASTER_SITES=  ${MASTER_SITE_PYPI:=g/gunicorn/}
 
@@ -14,7 +13,8 @@ LICENSE=      mit
 TOOL_DEPENDS+= ${PYPKGPREFIX}-setuptools>=78:../../devel/py-setuptools
 DEPENDS+=      ${PYPKGPREFIX}-packaging-[0-9]*:../../devel/py-packaging
 TEST_DEPENDS+= ${PYPKGPREFIX}-cryptography-[0-9]*:../../security/py-cryptography
-TEST_DEPENDS+= ${PYPKGPREFIX}-gevent-[0-9]*:../../net/py-gevent
+TEST_DEPENDS+= ${PYPKGPREFIX}-gevent>=24.10.1:../../net/py-gevent
+TEST_DEPENDS+= ${PYPKGPREFIX}-test-asyncio-[0-9]*:../../devel/py-test-asyncio
 TEST_DEPENDS+= ${PYPKGPREFIX}-test-cov-[0-9]*:../../devel/py-test-cov
 
 USE_LANGUAGES= # none

Index: pkgsrc/www/py-gunicorn/PLIST
diff -u pkgsrc/www/py-gunicorn/PLIST:1.15 pkgsrc/www/py-gunicorn/PLIST:1.16
--- pkgsrc/www/py-gunicorn/PLIST:1.15   Mon Apr 14 19:12:54 2025
+++ pkgsrc/www/py-gunicorn/PLIST        Tue Feb  3 09:17:23 2026
@@ -1,4 +1,4 @@
-@comment $NetBSD: PLIST,v 1.15 2025/04/14 19:12:54 adam Exp $
+@comment $NetBSD: PLIST,v 1.16 2026/02/03 09:17:23 adam Exp $
 bin/gunicorn-${PYVERSSUFFIX}
 ${PYSITELIB}/${WHEEL_INFODIR}/METADATA
 ${PYSITELIB}/${WHEEL_INFODIR}/RECORD
@@ -27,12 +27,54 @@ ${PYSITELIB}/gunicorn/app/wsgiapp.pyo
 ${PYSITELIB}/gunicorn/arbiter.py
 ${PYSITELIB}/gunicorn/arbiter.pyc
 ${PYSITELIB}/gunicorn/arbiter.pyo
+${PYSITELIB}/gunicorn/asgi/__init__.py
+${PYSITELIB}/gunicorn/asgi/__init__.pyc
+${PYSITELIB}/gunicorn/asgi/__init__.pyo
+${PYSITELIB}/gunicorn/asgi/lifespan.py
+${PYSITELIB}/gunicorn/asgi/lifespan.pyc
+${PYSITELIB}/gunicorn/asgi/lifespan.pyo
+${PYSITELIB}/gunicorn/asgi/message.py
+${PYSITELIB}/gunicorn/asgi/message.pyc
+${PYSITELIB}/gunicorn/asgi/message.pyo
+${PYSITELIB}/gunicorn/asgi/protocol.py
+${PYSITELIB}/gunicorn/asgi/protocol.pyc
+${PYSITELIB}/gunicorn/asgi/protocol.pyo
+${PYSITELIB}/gunicorn/asgi/unreader.py
+${PYSITELIB}/gunicorn/asgi/unreader.pyc
+${PYSITELIB}/gunicorn/asgi/unreader.pyo
+${PYSITELIB}/gunicorn/asgi/uwsgi.py
+${PYSITELIB}/gunicorn/asgi/uwsgi.pyc
+${PYSITELIB}/gunicorn/asgi/uwsgi.pyo
+${PYSITELIB}/gunicorn/asgi/websocket.py
+${PYSITELIB}/gunicorn/asgi/websocket.pyc
+${PYSITELIB}/gunicorn/asgi/websocket.pyo
 ${PYSITELIB}/gunicorn/config.py
 ${PYSITELIB}/gunicorn/config.pyc
 ${PYSITELIB}/gunicorn/config.pyo
 ${PYSITELIB}/gunicorn/debug.py
 ${PYSITELIB}/gunicorn/debug.pyc
 ${PYSITELIB}/gunicorn/debug.pyo
+${PYSITELIB}/gunicorn/dirty/__init__.py
+${PYSITELIB}/gunicorn/dirty/__init__.pyc
+${PYSITELIB}/gunicorn/dirty/__init__.pyo
+${PYSITELIB}/gunicorn/dirty/app.py
+${PYSITELIB}/gunicorn/dirty/app.pyc
+${PYSITELIB}/gunicorn/dirty/app.pyo
+${PYSITELIB}/gunicorn/dirty/arbiter.py
+${PYSITELIB}/gunicorn/dirty/arbiter.pyc
+${PYSITELIB}/gunicorn/dirty/arbiter.pyo
+${PYSITELIB}/gunicorn/dirty/client.py
+${PYSITELIB}/gunicorn/dirty/client.pyc
+${PYSITELIB}/gunicorn/dirty/client.pyo
+${PYSITELIB}/gunicorn/dirty/errors.py
+${PYSITELIB}/gunicorn/dirty/errors.pyc
+${PYSITELIB}/gunicorn/dirty/errors.pyo
+${PYSITELIB}/gunicorn/dirty/protocol.py
+${PYSITELIB}/gunicorn/dirty/protocol.pyc
+${PYSITELIB}/gunicorn/dirty/protocol.pyo
+${PYSITELIB}/gunicorn/dirty/worker.py
+${PYSITELIB}/gunicorn/dirty/worker.pyc
+${PYSITELIB}/gunicorn/dirty/worker.pyo
 ${PYSITELIB}/gunicorn/errors.py
 ${PYSITELIB}/gunicorn/errors.pyc
 ${PYSITELIB}/gunicorn/errors.pyo
@@ -60,6 +102,24 @@ ${PYSITELIB}/gunicorn/http/unreader.pyo
 ${PYSITELIB}/gunicorn/http/wsgi.py
 ${PYSITELIB}/gunicorn/http/wsgi.pyc
 ${PYSITELIB}/gunicorn/http/wsgi.pyo
+${PYSITELIB}/gunicorn/http2/__init__.py
+${PYSITELIB}/gunicorn/http2/__init__.pyc
+${PYSITELIB}/gunicorn/http2/__init__.pyo
+${PYSITELIB}/gunicorn/http2/async_connection.py
+${PYSITELIB}/gunicorn/http2/async_connection.pyc
+${PYSITELIB}/gunicorn/http2/async_connection.pyo
+${PYSITELIB}/gunicorn/http2/connection.py
+${PYSITELIB}/gunicorn/http2/connection.pyc
+${PYSITELIB}/gunicorn/http2/connection.pyo
+${PYSITELIB}/gunicorn/http2/errors.py
+${PYSITELIB}/gunicorn/http2/errors.pyc
+${PYSITELIB}/gunicorn/http2/errors.pyo
+${PYSITELIB}/gunicorn/http2/request.py
+${PYSITELIB}/gunicorn/http2/request.pyc
+${PYSITELIB}/gunicorn/http2/request.pyo
+${PYSITELIB}/gunicorn/http2/stream.py
+${PYSITELIB}/gunicorn/http2/stream.pyc
+${PYSITELIB}/gunicorn/http2/stream.pyo
 ${PYSITELIB}/gunicorn/instrument/__init__.py
 ${PYSITELIB}/gunicorn/instrument/__init__.pyc
 ${PYSITELIB}/gunicorn/instrument/__init__.pyo
@@ -81,6 +141,18 @@ ${PYSITELIB}/gunicorn/systemd.pyo
 ${PYSITELIB}/gunicorn/util.py
 ${PYSITELIB}/gunicorn/util.pyc
 ${PYSITELIB}/gunicorn/util.pyo
+${PYSITELIB}/gunicorn/uwsgi/__init__.py
+${PYSITELIB}/gunicorn/uwsgi/__init__.pyc
+${PYSITELIB}/gunicorn/uwsgi/__init__.pyo
+${PYSITELIB}/gunicorn/uwsgi/errors.py
+${PYSITELIB}/gunicorn/uwsgi/errors.pyc
+${PYSITELIB}/gunicorn/uwsgi/errors.pyo
+${PYSITELIB}/gunicorn/uwsgi/message.py
+${PYSITELIB}/gunicorn/uwsgi/message.pyc
+${PYSITELIB}/gunicorn/uwsgi/message.pyo
+${PYSITELIB}/gunicorn/uwsgi/parser.py
+${PYSITELIB}/gunicorn/uwsgi/parser.pyc
+${PYSITELIB}/gunicorn/uwsgi/parser.pyo
 ${PYSITELIB}/gunicorn/workers/__init__.py
 ${PYSITELIB}/gunicorn/workers/__init__.pyc
 ${PYSITELIB}/gunicorn/workers/__init__.pyo
@@ -90,6 +162,9 @@ ${PYSITELIB}/gunicorn/workers/base.pyo
 ${PYSITELIB}/gunicorn/workers/base_async.py
 ${PYSITELIB}/gunicorn/workers/base_async.pyc
 ${PYSITELIB}/gunicorn/workers/base_async.pyo
+${PYSITELIB}/gunicorn/workers/gasgi.py
+${PYSITELIB}/gunicorn/workers/gasgi.pyc
+${PYSITELIB}/gunicorn/workers/gasgi.pyo
 ${PYSITELIB}/gunicorn/workers/geventlet.py
 ${PYSITELIB}/gunicorn/workers/geventlet.pyc
 ${PYSITELIB}/gunicorn/workers/geventlet.pyo

Index: pkgsrc/www/py-gunicorn/distinfo
diff -u pkgsrc/www/py-gunicorn/distinfo:1.19 pkgsrc/www/py-gunicorn/distinfo:1.20
--- pkgsrc/www/py-gunicorn/distinfo:1.19        Mon Sep 16 11:41:12 2024
+++ pkgsrc/www/py-gunicorn/distinfo     Tue Feb  3 09:17:23 2026
@@ -1,5 +1,5 @@
-$NetBSD: distinfo,v 1.19 2024/09/16 11:41:12 adam Exp $
+$NetBSD: distinfo,v 1.20 2026/02/03 09:17:23 adam Exp $
 
-BLAKE2s (gunicorn-23.0.0.tar.gz) = 462731b1ecc7a5ed6b1115fbc7d67fa60fe25206cd4b9059978a96dd58e3f110
-SHA512 (gunicorn-23.0.0.tar.gz) = a623cdf943658a8275d007be62f6b22e4da0d9074ff6fef73a1f9839eeace44284b42f09e07896770b036e01db4ae45dc59fda675bdddad1bcc456ba4d1b93ba
-Size (gunicorn-23.0.0.tar.gz) = 375031 bytes
+BLAKE2s (gunicorn-25.0.1.tar.gz) = ef0e29ac8bedbed4790af597c3fbb5c62e79c3ea0813035c2c8ed93c4030f1f7
+SHA512 (gunicorn-25.0.1.tar.gz) = 7947d2bb63c50a9d8aaf1233ad1423ea4d18cbce79983a0279027cf0da64fa1c8f54ed7210f3d18e6bdd5d2bdd581a76e350c0b80d88de9f18604e0b245c38cb
+Size (gunicorn-25.0.1.tar.gz) = 9693127 bytes



Home | Main Index | Thread Index | Old Index