Raxol. Core. Runtime. ProcessComponent
(Raxol v2.8.0)
View Source
A GenServer wrapping a single component module for crash isolation.
Each ProcessComponent runs in its own process under Raxol.DynamicSupervisor,
so a crash in one component does not bring down the rest of the application.
The rendering engine that draws a process_component/2 node owns its
process: it starts it on the first frame the node is in the view, keeps it
(and the component's state) across frames, and stops it when the node
leaves the view or the engine stops. A process also stops when its owner
(:parent_pid, required) exits. The supervisor does not restart a crashed
component; the frame draws a placeholder in its place and a later frame
starts it again with fresh state from init/1.
Start-up
start_link/1 only checks that the module is loaded (an unloadable module
is {:error, {:module_not_available, module, reason}} and no process is
started) and returns as soon as the process exists. init/1 and mount/1
run afterwards inside the new process, so a slow init/1 holds up neither
the caller nor the supervisor that starts every component in the VM. Once
both have run, the owner receives {:process_component_ready, pid}, once;
until then the engine draws a "starting" placeholder for the node. A call
such as get_render_tree/2 made before that simply waits.
init/1 must return {:ok, state} or a bare map. {:error, reason} stops
the process with reason; anything else stops it with
{:bad_init_return, value}. Nothing is silently turned into empty state.
Usage
Components used with ProcessComponent must implement:
init/1- receives props, returns{:ok, state}, a state map, or{:error, reason}render/2- receives state and context, returns element treeupdate/2(optional) - receives message and state, returns new stateupdate_props/2(optional) - receives the node's changed props and the state, returns new state. A component that exports it keeps its state across props changes; one that doesn't is re-initialised from the new props throughinit/1(andmount/1) in the same process, afterunmount/1has seen the old state.mount/1(optional) - receives the initial state afterinit/1, returns the state to continue withunmount/1(optional) - the mirror ofmount/1: receives the live state when the component stops for any reason (its node left the view, the engine or owner stopped, the supervisor shut it down, a crash) or just before a re-init. Its return value is ignored, and an exception raised in it is logged and does not change why or whether the component stops. It does not run for a component whoseinit/1failed.
Crash reports and :sys.get_status/1 show the component module and id
only; its state and props are redacted, since props routinely carry
credentials.
Use the process_component/2 View DSL helper to embed process components:
process_component(MyHeavyWidget, %{path: "/tmp"})
Summary
Functions
Returns a specification to start this module under a supervisor.
Replaces the component's props in its running process. A component that
exports update_props/2 gets update_props(props, state) and keeps the
state it returns; any other has unmount/1 called on its current state
and is re-initialised from props through init/1 (and mount/1, if
exported). A re-init whose init/1 fails stops the process with that
reason, and this call exits.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Replaces the component's props in its running process. A component that
exports update_props/2 gets update_props(props, state) and keeps the
state it returns; any other has unmount/1 called on its current state
and is re-initialised from props through init/1 (and mount/1, if
exported). A re-init whose init/1 fails stops the process with that
reason, and this call exits.