You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/scalability.md
+234-3Lines changed: 234 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,14 +30,174 @@ When running on a free-threaded Python build (compiled with `--disable-gil`), er
30
30
31
31
### Sub-interpreter Mode (Python 3.12+)
32
32
33
-
Uses Python's sub-interpreter feature with per-interpreter GIL. Each sub-interpreter has its own GIL, allowing true parallel execution across interpreters.
33
+
Uses Python's sub-interpreter feature with per-interpreter GIL (`Py_GIL_OWN`). Each sub-interpreter runs in its own dedicated thread with its own GIL, enabling true parallel execution across interpreters.
34
+
35
+
**Architecture:**
36
+
- Thread pool manages N subinterpreters (default: number of schedulers)
37
+
- Each subinterpreter has its own thread, GIL, and Python state
38
+
- Requests are routed to subinterpreters via `py_context_router`
39
+
- 25-30% faster cast operations compared to worker mode
34
40
35
41
**Note:** Each sub-interpreter has isolated state. Use the [Shared State](#shared-state) API to share data between workers.
36
42
43
+
**Explicit Context Selection:**
44
+
```erlang
45
+
%% Get a specific context by index (1-based)
46
+
Ctx=py:context(1),
47
+
{ok, Result} =py:call(Ctx, math, sqrt, [16]).
48
+
49
+
%% Or use automatic scheduler-affinity routing
50
+
{ok, Result} =py:call(math, sqrt, [16]).
51
+
```
52
+
37
53
### Multi-Executor Mode (Python < 3.12)
38
54
39
55
Runs N executor threads that share the GIL. Requests are distributed round-robin across executors. Good for I/O-bound workloads where Python releases the GIL during I/O operations.
**py_context_router**: Routes requests to context processes based on scheduler affinity or explicit binding.
157
+
158
+
**py_context_process**: Gen_server that owns a Python context reference and handles call/eval/exec operations.
159
+
160
+
**Subinterpreter Thread Pool (C)**: Manages N threads, each with its own Python subinterpreter created with `Py_NewInterpreterFromConfig()` and `Py_GIL_OWN`.
161
+
162
+
### Request Flow
163
+
164
+
1. Erlang process calls `py:call(Module, Func, Args)`
165
+
2.`py_context_router` selects context based on scheduler ID
166
+
3. Request sent to `py_context_process` gen_server
167
+
4. Gen_server calls NIF which executes on subinterpreter's thread
168
+
5. Result returned through gen_server to caller
169
+
170
+
### Pool Size
171
+
172
+
The subinterpreter pool size is configured at two levels:
0 commit comments