Skip to content

Commit 424e80d

Browse files
committed
Handle subinterpreters not supported gracefully
The subinterp pool now starts successfully even when Python doesn't support sub-interpreters. All requests will return an error instead of crashing the supervisor.
1 parent 16171ed commit 424e80d

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

src/py_subinterp_pool.erl

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@
3737
]).
3838

3939
-record(state, {
40-
workers :: queue:queue(pid()),
40+
workers :: queue:queue(pid()) | undefined,
4141
worker_refs :: [reference()], %% NIF refs for parallel_execute
4242
num_workers :: pos_integer(),
4343
pending :: non_neg_integer(),
44-
worker_sup :: pid()
44+
worker_sup :: pid() | undefined,
45+
supported :: boolean() %% whether subinterpreters are supported
4546
}).
4647

4748
%%% ============================================================================
@@ -90,20 +91,38 @@ init([NumWorkers]) ->
9091
worker_refs = WorkerRefs,
9192
num_workers = NumWorkers,
9293
pending = 0,
93-
worker_sup = WorkerSup
94+
worker_sup = WorkerSup,
95+
supported = true
9496
}};
9597
false ->
96-
{stop, {error, subinterpreters_not_supported}}
98+
%% Sub-interpreters not supported, but pool still starts
99+
%% All requests will return an error
100+
{ok, #state{
101+
workers = undefined,
102+
worker_refs = [],
103+
num_workers = 0,
104+
pending = 0,
105+
worker_sup = undefined,
106+
supported = false
107+
}}
97108
end.
98109

99110
handle_call(get_stats, _From, State) ->
111+
AvailWorkers = case State#state.workers of
112+
undefined -> 0;
113+
Q -> queue:len(Q)
114+
end,
100115
Stats = #{
101116
num_workers => State#state.num_workers,
102117
pending_requests => State#state.pending,
103-
available_workers => queue:len(State#state.workers)
118+
available_workers => AvailWorkers,
119+
supported => State#state.supported
104120
},
105121
{reply, Stats, State};
106122

123+
handle_call({parallel, _Calls}, _From, #state{supported = false} = State) ->
124+
{reply, {error, subinterpreters_not_supported}, State};
125+
107126
handle_call({parallel, Calls}, From, State) ->
108127
%% For parallel execution, we use the NIF refs directly
109128
BinCalls = [{to_binary(M), to_binary(F), A} || {M, F, A} <- Calls],
@@ -120,6 +139,11 @@ handle_call({parallel, Calls}, From, State) ->
120139
handle_call(_Request, _From, State) ->
121140
{reply, {error, unknown_request}, State}.
122141

142+
handle_cast({request, Request}, #state{supported = false} = State) ->
143+
{Ref, Caller, _} = extract_ref_caller(Request),
144+
Caller ! {py_error, Ref, subinterpreters_not_supported},
145+
{noreply, State};
146+
123147
handle_cast({request, Request}, State) ->
124148
case queue:out(State#state.workers) of
125149
{{value, Worker}, Rest} ->

0 commit comments

Comments
 (0)