py_context_router (erlang_python v2.3.1)
View SourceScheduler-affinity router for Python contexts.
This module provides automatic routing of Python calls to contexts based on the calling process's scheduler ID. This ensures that processes on the same scheduler reuse the same context, providing good cache locality while still enabling N-way parallelism.
Architecture
Scheduler 1 ---+
+---> Context 1 (Subinterp/Worker)
Scheduler 2 ---+
+---> Context 2 (Subinterp/Worker)
Scheduler 3 ---+
+---> Context 3 (Subinterp/Worker)
... |
Scheduler N ---+---> Context N (Subinterp/Worker)
Usage
%% Start the router with default settings
{ok, Contexts} = py_context_router:start(),
%% Get context for current scheduler (automatic routing)
Ctx = py_context_router:get_context(),
{ok, Result} = py_context:call(Ctx, math, sqrt, [16], #{}),
%% Or get a specific context by index
Ctx2 = py_context_router:get_context(2),
%% Bind a specific context to this process
ok = py_context_router:bind_context(Ctx2),
Ctx2 = py_context_router:get_context(), %% Returns bound context
%% Unbind to return to scheduler-based routing
ok = py_context_router:unbind_context().
Summary
Functions
Bind a context to the current process for the default pool.
Bind a context to the current process for a specific pool.
Get all context pids from the default pool.
Get all context pids from a pool.
Get the context for the current process from the default pool.
Get a context by index or from a named pool.
Initialize the pool registry.
Check if contexts have been started and are still alive.
List all pool registrations.
Look up which pool a module/function is registered to.
Get the number of contexts in the default pool.
Get the number of contexts in a pool.
Check if a pool has been started and is still alive.
Register a module to use a specific pool for all functions.
Register a specific module/function to use a specific pool.
Start the context router with default settings.
Start the context router with options.
Start a named pool with given size.
Start a named pool with given size and mode.
Stop the context router.
Stop a named pool.
Unbind the current process's context from the default pool.
Unbind the current process's context from a specific pool.
Unregister a module from pool routing.
Unregister a specific module/function from pool routing.
Types
-type pool_name() :: default | io | atom().
-type start_opts() :: #{contexts => pos_integer(), mode => py_context:context_mode()}.
Functions
-spec bind_context(pid()) -> ok.
Bind a context to the current process for the default pool.
After binding, get_context/0 will always return this context instead of selecting by scheduler.
Bind a context to the current process for a specific pool.
-spec contexts() -> [pid()].
Get all context pids from the default pool.
Get all context pids from a pool.
-spec get_context() -> pid().
Get the context for the current process from the default pool.
If the process has a bound context, returns that context. Otherwise, selects a context based on the current scheduler ID.
-spec get_context(pos_integer() | pool_name()) -> pid().
Get a context by index or from a named pool.
When called with an integer, gets the Nth context from the default pool. When called with an atom, gets a scheduler-affinity context from that pool.
-spec init_pool_registry() -> ok.
Initialize the pool registry.
This is called automatically on first registration. Safe to call multiple times - does nothing if already initialized.
-spec is_started() -> boolean().
Check if contexts have been started and are still alive.
List all pool registrations.
Returns a list of {{Module, Func}, Pool} tuples.
Look up which pool a module/function is registered to.
First checks for a specific module+func registration. If not found, checks for a module-only registration. Returns default if no registration found.
-spec num_contexts() -> non_neg_integer().
Get the number of contexts in the default pool.
-spec num_contexts(pool_name()) -> non_neg_integer().
Get the number of contexts in a pool.
Check if a pool has been started and is still alive.
Register a module to use a specific pool for all functions.
All calls to Module:* will be routed to the specified pool.
Example:
%% Route all 'requests' module calls to io pool
py_context_router:register_pool(io, requests).
Register a specific module/function to use a specific pool.
Calls to Module:Func will be routed to the specified pool. More specific registrations (module+func) take precedence over module-only registrations.
Example:
%% Route requests.get to io pool
py_context_router:register_pool(io, requests, get).
Start the context router with default settings.
Creates one context per scheduler using worker mode.
-spec start(start_opts()) -> {ok, [pid()]} | {error, term()}.
Start the context router with options.
Options: - contexts - Number of contexts to create (default: number of schedulers) - mode - Context mode: worker, subinterp, or owngil (default: worker)
-spec start_pool(pool_name(), pos_integer()) -> {ok, [pid()]} | {error, term()}.
Start a named pool with given size.
-spec start_pool(pool_name(), pos_integer(), py_context:context_mode()) -> {ok, [pid()]} | {error, term()}.
Start a named pool with given size and mode.
-spec stop() -> ok.
Stop the context router.
Stops the default pool and removes persistent_term entries.
-spec stop_pool(pool_name()) -> ok.
Stop a named pool.
-spec unbind_context() -> ok.
Unbind the current process's context from the default pool.
After unbinding, get_context/0 will return to scheduler-based selection.
-spec unbind_context(pool_name()) -> ok.
Unbind the current process's context from a specific pool.
-spec unregister_pool(atom()) -> ok.
Unregister a module from pool routing.
Calls will return to using the default pool.
Unregister a specific module/function from pool routing.