Skip to content

Add OWN_GIL subinterpreter execution to event loop pool#44

Merged
benoitc merged 4 commits intomainfrom
feature/owngil-event-loop-pool
Mar 20, 2026
Merged

Add OWN_GIL subinterpreter execution to event loop pool#44
benoitc merged 4 commits intomainfrom
feature/owngil-event-loop-pool

Conversation

@benoitc
Copy link
Owner

@benoitc benoitc commented Mar 20, 2026

Summary

  • Add true parallel Python execution with OWN_GIL subinterpreters
  • Session management with process affinity (same PID -> same worker)
  • Asyncio event loop per worker for coroutine support
  • Automatic session cleanup via process monitoring

Changes

Erlang:

  • py_event_loop_pool.erl: Session registry, task routing, process monitoring
  • py_nif.erl: New NIF exports for session management

C:

  • py_nif.c: NIFs for create/submit/destroy session
  • py_subinterp_thread.c/h: Asyncio initialization, async task handling

Tests:

  • py_event_loop_pool_owngil_SUITE.erl: 9 tests for OWN_GIL mode

Configuration

{erlang_python, [
    {event_loop_pool_size, 4},
    {event_loop_pool_owngil, true}
]}

When enabled, py_event_loop_pool:create_task/3,4 and spawn_task/3,4 automatically route through OWN_GIL workers.

benoitc added 4 commits March 20, 2026 13:15
This adds true parallel Python execution with OWN_GIL subinterpreters
while keeping event loop coordination in the main interpreter.

Key features:
- Session management with process affinity (same PID -> same worker)
- Sessions created automatically on first task from a process
- Sessions cleaned up via process monitoring on process exit
- Asyncio event loop per worker for coroutine support
- Tasks run via run_until_complete() in worker's event loop
- Results sent back via enif_send() to calling process

New functions:
- py_nif:owngil_create_session/1 - Create session in worker
- py_nif:owngil_submit_task/7 - Submit async task to worker
- py_nif:owngil_destroy_session/2 - Destroy session

Configuration:
  {erlang_python, [{event_loop_pool_owngil, true}]}

When enabled, py_event_loop_pool:create_task/3,4 and spawn_task/3,4
automatically route through OWN_GIL workers instead of the shared
event loop.
Compares regular event loop pool vs OWN_GIL mode:
- Sequential calls (single caller)
- Concurrent calls (multiple processes)
- CPU-bound parallel tasks (time.sleep)

Run with: escript examples/bench_owngil_pool.erl
- Use ets:foldl instead of match spec in handle_info DOWN to avoid
  dialyzer type violations with '_' atoms in record construction
- Remove unused destroy_session/2 function
- Fix test_async_coroutine_call to use asyncio.sleep instead of
  custom function (OWN_GIL subinterpreters have separate namespaces)
- Fix test_same_process_same_worker to test process affinity
  without relying on shared namespace state
- Simplify test_async_coroutine_call to use math.sqrt instead of
  asyncio.sleep (more reliable on CI)
- Add OWN_GIL event loop pool documentation to event_loop_architecture.md
  covering architecture, configuration, usage, and performance
@benoitc benoitc merged commit 3816b80 into main Mar 20, 2026
11 checks passed
@benoitc benoitc deleted the feature/owngil-event-loop-pool branch March 20, 2026 13:07
benoitc added a commit that referenced this pull request Mar 20, 2026
Enable true parallel Python execution with per-worker GILs.
Sessions map PIDs to workers with automatic cleanup on process exit.

Config: {event_loop_pool_owngil, true}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant