gunicorn/README.md
Ankush Menat 6d09a2e912 Merge upstream gunicorn 26.0.0 into Frappe fork
Reconcile the Frappe-specific gthread changes with upstream's major
26.0.0 release (HTTP/2, ASGI, lock-free main-thread event loop).

Conflict resolution:
- gunicorn/workers/gthread.py: reimplemented our features on top of
  upstream's rewritten event loop instead of merging line-by-line:
  - Per-request timeout + faulthandler traceback dump, tracked via an
    in-flight future set and keyed on exec_start_time so client-wait
    time (upstream's _DEFER path) is excluded and long-lived HTTP/2
    connections are exempt.
  - Adaptive slow/fast-lane queueing: the request-line peek/classify
    now reuses upstream's pending_conns poller-park mechanism, then
    dispatches to a fast or slow ThreadPoolExecutor.
  - Dropped our eventfd-based shutdown wakeup in favour of upstream's
    PollableMethodQueue.defer(), which already wakes the poller on
    SIGTERM.
- gunicorn/config.py: kept both new validators; our EnableAdaptiveQueueing
  and SlowRequestThreshold settings merged cleanly.
- README.rst was removed upstream (converted to README.md); ported an
  updated Fork Information section into README.md.
- tox.ini / .github/workflows/tox.yml: took upstream's Python matrix
  (it already drops the EoL versions our fork had pruned).

All gthread + routing tests pass (91), full suite 1976 passed / 263
skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:28:45 +05:30

107 lines
4.5 KiB
Markdown

<!-- FRAPPE FORK NOTE -->
## Fork Information
This is a fork of gunicorn with the following Frappe-specific changes to the
`gthread` worker:
1. **Request timeout for `gthread`** — upstream has no per-request timeout; a
slow request can otherwise tie up a thread indefinitely. See
https://github.com/frappe/gunicorn/pull/1
2. **Traceback dump on timeout** — when a request times out we
`faulthandler.dump_traceback()` before exiting, to aid debugging.
See https://github.com/frappe/gunicorn/pull/6
3. **Adaptive slow/fast-lane queueing** — when `enable_adaptive_queueing` is
set, the configured threads are split into a fast lane and a slow lane so
slow requests cannot starve fast ones. Controlled by
`--enable-adaptive-queueing` / `GUNICORN_ENABLE_ADAPTIVE_QUEUEING` and
`--slow-request-threshold`. See `gunicorn/workers/gthread_routing.py`.
4. **Higher selector timeout** — small optional throughput improvement.
See https://github.com/frappe/gunicorn/pull/2
Note to anyone upgrading / adding changes:
- Pull upstream changes.
- Reapply or reconcile our changes (the work lives in
`gunicorn/workers/gthread.py`, `gunicorn/workers/gthread_routing.py` and
`gunicorn/config.py`).
- Update the commit/ref in frappe/frappe `pyproject.toml`.
- Keep this section up to date. Keep changes small and to the point.
TODO:
- [ ] Plan a cleaner solution using custom workers. All current changes could
live in a custom worker, but that carries the same awkwardness of
maintaining a fork since we want to "override" rather than "extend" core
behaviour.
<!-- END FRAPPE FORK NOTE -->
# Gunicorn
<p align="center">
<strong>Gunicorn is maintained by volunteers. If it powers your production, please consider supporting us:</strong><br>
<a href="https://github.com/sponsors/benoitc"><img src="https://img.shields.io/badge/GitHub_Sponsors-❤-ea4aaa?style=for-the-badge&logo=github" alt="GitHub Sponsors"></a>
<a href="https://checkout.revolut.com/pay/ac271e5e-172a-408b-947b-2f9f79d3a88a"><img src="https://img.shields.io/badge/Revolut-Donate-191c20?style=for-the-badge" alt="Revolut"></a>
</p>
[![PyPI version](https://img.shields.io/pypi/v/gunicorn.svg?style=flat)](https://pypi.python.org/pypi/gunicorn)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/gunicorn.svg)](https://pypi.python.org/pypi/gunicorn)
[![Build Status](https://github.com/benoitc/gunicorn/actions/workflows/tox.yml/badge.svg)](https://github.com/benoitc/gunicorn/actions/workflows/tox.yml)
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's [Unicorn](https://bogomips.org/unicorn/) project. The Gunicorn server is broadly
compatible with various web frameworks, simply implemented, light on server
resource usage, and fairly speedy.
**New in v25**: Per-app worker allocation for dirty arbiters, HTTP/2 support (beta)!
## Quick Start
```bash
pip install gunicorn
gunicorn myapp:app --workers 4
```
For ASGI applications (FastAPI, Starlette):
```bash
gunicorn myapp:app --worker-class asgi
```
## Features
- WSGI support for Django, Flask, Pyramid, and any WSGI framework
- **ASGI support** for FastAPI, Starlette, Quart
- **HTTP/2 support** (beta) with multiplexed streams
- **Dirty Arbiters** (beta) for heavy workloads (ML models, long-running tasks)
- uWSGI binary protocol for nginx integration
- Multiple worker types: sync, gthread, gevent, asgi
- Graceful worker process management
- Compatible with Python 3.9+
## Documentation
Full documentation at https://gunicorn.org
- [Quickstart](https://gunicorn.org/quickstart/)
- [Configuration](https://gunicorn.org/configure/)
- [Deployment](https://gunicorn.org/deploy/)
- [Settings Reference](https://gunicorn.org/reference/settings/)
## Community
- Report bugs on [GitHub Issues](https://github.com/benoitc/gunicorn/issues)
- Chat in [#gunicorn](https://web.libera.chat/?channels=#gunicorn) on [Libera.chat](https://libera.chat/)
- See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines
## Support
Powering Python apps since 2010. Support continued development.
[![Become a Sponsor](https://img.shields.io/badge/Become_a_Sponsor-❤-ff69b4)](https://gunicorn.org/sponsor/)
### Sponsors
<a href="https://enki-multimedia.eu"><img src="docs/content/assets/enki-multimedia.svg" alt="Enki Multimedia" height="50" /></a>
## License
Gunicorn is released under the MIT License. See the [LICENSE](https://github.com/benoitc/gunicorn/blob/master/LICENSE) file for details.