Skip to content

Commit 4cd37f3

Browse files
committed
Bump version to 2.0.0 and update documentation
- Update version from 1.8.1 to 2.0.0 in app.src and docs - Add changelog entries for ensure_venv/2,3 and dup_fd/1 - Rewrite context-affinity.md for new py_context_router API - Fix asyncio.md to remove erlang_asyncio references - Update migration.md with correct function mappings - Add Virtual Environments section to getting-started.md - Fix web-frameworks.md to use asyncio.sleep()
1 parent 3483f41 commit 4cd37f3

File tree

7 files changed

+228
-173
lines changed

7 files changed

+228
-173
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
# Changelog
22

3-
## Unreleased
3+
## 2.0.0 (2026-03-09)
44

55
### Added
66

7+
- **Virtual Environment Management** - Automatic venv creation and activation
8+
- `py:ensure_venv/2,3` - Create venv if missing, then activate
9+
- Automatically detects Python executable
10+
- Supports pip install of dependencies
11+
12+
- **File Descriptor Duplication** - Safe socket handoff from Erlang to Python
13+
- `py:dup_fd/1` - Duplicate fd for independent ownership
14+
- Prevents double-close issues when passing sockets to Python reactor
15+
716
- **Dual Pool Support** - Separate pools for CPU-bound and I/O-bound operations
817
- `default` pool - For quick CPU-bound operations, sized to number of schedulers
918
- `io` pool - For I/O-bound operations, larger pool (default: 10) for concurrency

docs/asyncio.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ erlang.run(main())
5252
│ └──────────────────┘ │ Routes events to correct loop │ │
5353
│ │ based on resource backref │ │
5454
│ ┌──────────────────┐ └────────────────────────────────────┘ │
55-
│ │ erlang_asyncio │ │
56-
│ │ │ ┌────────────────────────────────────┐ │
55+
│ │ asyncio (via │ │
56+
│ │ erlang.run()) │ ┌────────────────────────────────────┐ │
5757
│ │ sleep() ──┼─{sleep_wait}──▶│ erlang:send_after() + cond_wait │ │
5858
│ │ gather() │ │ │ │
5959
│ │ wait_for() │◀──{complete}───│ pthread_cond_broadcast() │ │
@@ -70,7 +70,7 @@ erlang.run(main())
7070
| `ErlangEventLoop` | Python asyncio event loop using Erlang for I/O and timers |
7171
| `py_event_worker` | Erlang gen_server managing FDs and timers for a Python context |
7272
| `py_event_router` | Routes timer/FD events to the correct event loop instance |
73-
| `erlang_asyncio` | High-level asyncio-compatible API with direct Erlang integration |
73+
| `erlang.run()` | Entry point to run asyncio code with the Erlang event loop |
7474

7575
## Usage Patterns
7676

@@ -620,34 +620,32 @@ A shared router process handles timer and FD events for all loops:
620620

621621
Each loop has its own pending queue, ensuring callbacks are processed only by the loop that scheduled them. The shared router dispatches timer and FD events to the correct loop based on the capsule backref.
622622

623-
## Erlang Asyncio Primitives
623+
## Erlang Timer Integration
624624

625-
> **Note:** The `erlang_asyncio` module has been unified into the main `erlang` module. Use `import erlang` and `erlang.run()` instead.
626-
627-
The `erlang` module provides asyncio-compatible primitives that use Erlang's native scheduler for maximum performance. This is the recommended way to use async/await patterns when you need explicit Erlang timer integration.
625+
When using `erlang.run()` to execute asyncio code, standard asyncio functions like `asyncio.sleep()` are automatically backed by Erlang's native timer system for maximum performance.
628626

629627
### Overview
630628

631-
Unlike the standard `asyncio` module which uses Python's polling-based event loop, the `erlang` module uses Erlang's `erlang:send_after/3` for timers and integrates directly with the BEAM scheduler. This eliminates Python event loop overhead (~0.5-1ms per operation) and provides more precise timing.
629+
Unlike Python's standard polling-based event loop, the Erlang event loop uses `erlang:send_after/3` for timers and integrates directly with the BEAM scheduler. This eliminates Python event loop overhead (~0.5-1ms per operation) and provides more precise timing.
632630

633631
### Architecture
634632

635633
```
636634
┌─────────────────────────────────────────────────────────────────────────┐
637-
erlang_asyncio.sleep()
635+
asyncio.sleep() via ErlangEventLoop
638636
│ │
639637
│ Python Erlang │
640638
│ ────── ────── │
641639
│ │
642640
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
643-
│ │ erlang_asyncio │ │ py_event_worker │ │
644-
│ │ .sleep(0.1) │ │ │ │
641+
│ │ asyncio.sleep │ │ py_event_worker │ │
642+
│ │ (0.1) │ │ │ │
645643
│ └────────┬────────┘ │ handle_info({sleep_wait,...}) │ │
646644
│ │ │ │ │ │
647645
│ ▼ │ ▼ │ │
648646
│ ┌─────────────────┐ │ erlang:send_after(100ms) │ │
649-
│ │ py_event_loop. │──{sleep_wait,│ │ │ │
650-
│ │ _erlang_sleep() │ 100, Id}──▶│ ▼ │ │
647+
│ │ ErlangEventLoop │──{sleep_wait,│ │ │ │
648+
│ │ call_later() │ 100, Id}──▶│ ▼ │ │
651649
│ └────────┬────────┘ │ handle_info({sleep_complete}) │ │
652650
│ │ │ │ │ │
653651
│ ┌────────▼────────┐ │ ▼ │ │

0 commit comments

Comments
 (0)