|
17 | 17 | - Works in sync code called by Erlang (where `asyncio.get_running_loop()` fails) |
18 | 18 | - Returns `asyncio.Task` for optional await/cancel (fire-and-forget pattern) |
19 | 19 | - Automatically wakes up the event loop in sync context |
20 | | - - Works with both ErlangEventLoop and standard asyncio loops |
| 20 | + |
| 21 | +- **Explicit Scheduling API** - Control dirty scheduler release from Python |
| 22 | + - `erlang.schedule(callback, *args)` - Release scheduler, continue via Erlang callback |
| 23 | + - `erlang.schedule_py(module, func, args, kwargs)` - Release scheduler, continue in Python |
| 24 | + - `erlang.consume_time_slice(percent)` - Check if NIF time slice exhausted |
| 25 | + - `ScheduleMarker` type for cooperative long-running tasks |
| 26 | + - See [Scheduling API docs](docs/asyncio.md#explicit-scheduling-api) |
| 27 | + |
| 28 | +- **Distributed Python Execution** - Documentation and Docker demo |
| 29 | + - Run Python across Erlang nodes using `rpc:call` |
| 30 | + - Docker Compose setup for testing distributed patterns |
| 31 | + - See [Distributed Execution docs](docs/distributed.md) |
| 32 | + |
| 33 | +### Changed |
| 34 | + |
| 35 | +- **Event Loop Performance Optimizations** |
| 36 | + - Growable pending queue with capacity doubling (256 to 16384) |
| 37 | + - Snapshot-detach pattern to reduce mutex contention |
| 38 | + - Callable cache (64 slots) avoids PyImport/GetAttr per task |
| 39 | + - Task wakeup coalescing with atomic flag |
| 40 | + - Drain-until-empty loop for faster task processing |
| 41 | + |
| 42 | +### Fixed |
| 43 | + |
| 44 | +- `ensure_venv` now always installs dependencies, even if venv exists |
| 45 | +- `erlang.sleep()` timing in sync context |
| 46 | +- `time()` returns fresh value when loop not running |
| 47 | +- Handle pooling bugs in ErlangEventLoop |
| 48 | +- Task wakeup race causing batch task stalls |
21 | 49 |
|
22 | 50 | ## 2.0.0 (2026-03-09) |
23 | 51 |
|
|
0 commit comments