0005: The isolated context process is a gen_statem
View SourceSince 5.0.0. Code: src/py_isolated.erl, entered from init/4 in py_context
with gen_statem:enter_loop/5.
Situation
The embedded context process is a hand-written receive loop in
py_context. The isolated process has more to track: a request in
flight, requests to hold while the child restarts, a running loop with a
grace period, an interrupt with a kill backstop bound to one request id,
and callback processes whose nested requests must pass while others
wait. A first version as a receive loop mirrored py_context but every
wait needed its own selective receive and its own timer bookkeeping.
Decision
py_isolated is a gen_statem (handle_event_function, state enter
calls) with states idle, {busy, Id}, looping, stopping_loop and
{restarting, Reason}. Requests that must wait are postponed and
replayed by the behaviour in arrival order; timers are state_timeout
and named generic timeouts ({timeout, kill}) cancelled by the state
change that makes them moot. It is spawned with proc_lib so it keeps
the process identity and message protocol of py_context.
Not chosen: sharing the receive loop with py_context (the two have
different failure models: a child can die and restart, a thread cannot),
or a gen_server with a state field (postpone and state timeouts would
have to be reimplemented).
Consequences
sys:get_state/1shows what a context is doing andsys:trace/2prints every event; the state machines page is a transcription of the callback module.- Callers do not see the behaviour: messages and replies are those of
py_context. - The two context processes are different code. A change to the message protocol touches both.