What's Changed
New features
* Experimental support for *free-threaded* Python
* `runtime-blocking-threads` option
* `blocking-threads-idle-timeout` option
* `http1-header-read-timeout` option
* PyPy 3.11 support
* Embeddable server variant in `granian.server.embed` module
Changes
* `uvloop` dependency is now optional and gated behind the relevant dependency extra
* **BREAKING** renamed `threads` option to `runtime-threads`
* **BREAKING** `blocking-threads` option now affects Python interop threads only
* **BREAKING** removed `threading-mode` in favor of `runtime-mode`
* previous `workers` option is now `st`
* previous `runtime` option is now `mt`
* **BREAKING** `blocking-threads` is now limited to 1 on ASGI and RSGI protocols
* `rust` task implementation is now available on Python < 3.12 only
* Removed PGO builds
* Bump dependencies
Enhancements
* Refactor the Rust task implementation
* Refactor the Python blocking threadpool
* Refactor application protocols failure handling
* Re-export `loops` registry to facilitate customisations
* Added warn messages for most common workers/threads misconfigurations
* Review README's workers, threads and backpressure sections
* Added range validations on all the relevant HTTP/2 options
* Added back custom allocators, with `jemalloc` as default option and `mimalloc` as gated feature, used by default in the following cases:
* MUSL builds
* Windows builds
* Python 3.13t
* Avoid to strip symbols from release builds