Skip to content

Commit b916d61

Browse files
authored
Merge pull request #7 from benoitc/feature/scalable-io-model
Implement scalable I/O model with worker-per-context
2 parents e5ce2b4 + 5b4a728 commit b916d61

24 files changed

+4622
-145
lines changed

ASGI_NIF_OPTIMIZATIONS.md

Lines changed: 461 additions & 0 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,64 @@
11
# Changelog
22

3+
## 1.8.0 (Unreleased)
4+
5+
### Added
6+
7+
- **ASGI NIF Optimizations** - Six optimizations for high-performance ASGI request handling
8+
- **Direct Response Tuple Extraction** - Extract `(status, headers, body)` directly without generic conversion
9+
- **Pre-Interned Header Names** - 16 common HTTP headers cached as PyBytes objects
10+
- **Cached Status Code Integers** - 14 common HTTP status codes cached as PyLong objects
11+
- **Zero-Copy Request Body** - Large bodies (≥1KB) use buffer protocol for zero-copy access
12+
- **Scope Template Caching** - Thread-local cache of 64 scope templates keyed by path hash
13+
- **Lazy Header Conversion** - Headers converted on-demand for requests with ≥4 headers
14+
15+
- **erlang_asyncio Module** - Asyncio-compatible primitives using Erlang's native scheduler
16+
- `erlang_asyncio.sleep(delay, result=None)` - Sleep using Erlang's `erlang:send_after/3`
17+
- `erlang_asyncio.run(coro)` - Run coroutine with ErlangEventLoop
18+
- `erlang_asyncio.gather(*coros)` - Run coroutines concurrently
19+
- `erlang_asyncio.wait_for(coro, timeout)` - Wait with timeout
20+
- `erlang_asyncio.wait(fs, timeout, return_when)` - Wait for multiple futures
21+
- `erlang_asyncio.create_task(coro)` - Create background task
22+
- `erlang_asyncio.ensure_future(coro)` - Wrap coroutine in Future
23+
- `erlang_asyncio.shield(arg)` - Protect from cancellation
24+
- `erlang_asyncio.timeout` - Context manager for timeouts
25+
- Event loop functions: `get_event_loop()`, `new_event_loop()`, `set_event_loop()`, `get_running_loop()`
26+
- Re-exports: `TimeoutError`, `CancelledError`, `ALL_COMPLETED`, `FIRST_COMPLETED`, `FIRST_EXCEPTION`
27+
28+
- **Erlang Sleep NIF** - Synchronous sleep primitive for Python
29+
- `py_event_loop._erlang_sleep(delay_ms)` - Sleep using Erlang timer
30+
- Releases GIL during sleep, no Python event loop overhead
31+
- Uses pthread condition variables for efficient blocking
32+
- `py_nif:dispatch_sleep_complete/2` - NIF to signal sleep completion
33+
34+
- **Scalable I/O Model** - Worker-per-context architecture
35+
- `py_event_worker` - Dedicated worker process per Python context
36+
- Combined FD event dispatch and reselect via `handle_fd_event_and_reselect` NIF
37+
- Sleep tracking with `sleeps` map in worker state
38+
39+
- **New Test Suite** - `test/py_erlang_sleep_SUITE.erl` with 8 tests
40+
- `test_erlang_sleep_available` - Verify NIF is exposed
41+
- `test_erlang_sleep_basic` - Basic functionality
42+
- `test_erlang_sleep_zero` - Zero delay returns immediately
43+
- `test_erlang_sleep_accuracy` - Timing accuracy
44+
- `test_erlang_asyncio_module` - Module functions present
45+
- `test_erlang_asyncio_gather` - Concurrent execution
46+
- `test_erlang_asyncio_wait_for` - Timeout support
47+
- `test_erlang_asyncio_create_task` - Background tasks
48+
49+
### Performance
50+
51+
- **ASGI marshalling optimizations** - 40-60% improvement for typical ASGI workloads
52+
- Direct response extraction: 5-10% improvement
53+
- Pre-interned headers: 3-5% improvement
54+
- Cached status codes: 1-2% improvement
55+
- Zero-copy body buffers: 10-15% for large bodies (≥1KB)
56+
- Scope template caching: 15-20% for repeated paths
57+
- Lazy header conversion: 5-10% for apps accessing few headers
58+
- **Eliminates event loop overhead** for sleep operations (~0.5-1ms saved per call)
59+
- **Sub-millisecond timer precision** via BEAM scheduler (vs 10ms asyncio polling)
60+
- **Zero CPU when idle** - event-driven, no polling
61+
362
## 1.7.1 (2026-02-23)
463

564
### Fixed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,8 @@ py:execution_mode(). %% => free_threaded | subinterp | multi_executor
571571
- [Streaming](docs/streaming.md)
572572
- [Threading](docs/threading.md)
573573
- [Logging and Tracing](docs/logging.md)
574+
- [Asyncio Event Loop](docs/asyncio.md) - Erlang-native asyncio with TCP/UDP support
575+
- [Web Frameworks](docs/web-frameworks.md) - ASGI/WSGI integration
574576
- [Changelog](https://github.com/benoitc/erlang-python/releases)
575577

576578
## License

0 commit comments

Comments
 (0)