mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-01 10:11:30 +08:00
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>
107 lines
4.5 KiB
Markdown
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>
|
|
|
|
[](https://pypi.python.org/pypi/gunicorn)
|
|
[](https://pypi.python.org/pypi/gunicorn)
|
|
[](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.
|
|
|
|
[](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.
|