Skip to content

Subsystem Lifecycle

Librux treats a subsystem as the smallest runtime unit managed by the runtime kernel. It is similar to an operating system process in that it has identity, session state, resource ownership, and lifecycle transitions. It is different from a generic process because lifecycle states carry robotics meaning.

The runtime owns the lifecycle state. User code does not set the state directly. Operators and developers request transitions through the runtime, the runtime validates the request, and the SDK calls the corresponding subsystem hook.

operator or deployment request
  -> runtime transition validation
  -> subsystem lifecycle notification
  -> SDK hook
  -> heartbeat/status update
  -> Runtime Graph update

The main lifecycle shape is a finite-state machine.

stateDiagram-v2 [*] --> Created Created --> Booting Booting --> Registering Registering --> WaitingBinding Registering --> Ready: no required bindings WaitingBinding --> WaitingTarget: binding selected WaitingTarget --> Ready: provider route available Ready --> Operating: start Operating --> Pausing: pause Pausing --> Paused Paused --> Resuming: resume Resuming --> Operating Operating --> Stopping: stop Stopping --> Stopped Stopped --> Operating: start Operating --> Degraded: dependency or timing impaired Degraded --> Operating: recovered Operating --> Faulted: fault Degraded --> Faulted: fault Faulted --> Resetting: reset Resetting --> Ready Created --> Disconnected Booting --> Disconnected Registering --> Disconnected WaitingBinding --> Disconnected WaitingTarget --> Disconnected Ready --> Disconnected Operating --> Disconnected Paused --> Disconnected Stopped --> Disconnected Faulted --> Disconnected

The graph shows the normal control path. Runtime availability states such as WaitingBinding and WaitingTarget can also return to Ready when deployment wiring or provider routes become valid.

Canonical States

State Meaning
Created The subsystem object exists but has not registered.
Booting The process is starting and constructing runtime state.
Registering The SDK is registering identity, session, and notify channels.
WaitingBinding Required binding information is absent or structurally invalid.
WaitingTarget Binding exists, but the selected provider route is unavailable.
Ready The subsystem is initialized and safe to start.
Operating The subsystem is actively executing its runtime role.
Pausing A pause request is being applied.
Paused The process is alive, heartbeat continues, and outputs are held safe.
Resuming A resume request is being applied.
Stopping A runtime stop request is being applied.
Stopped The subsystem is alive but no longer operating.
Resetting A reset request is clearing fault/degraded state.
Degraded The subsystem can still run, but a dependency, timing, or health condition is impaired.
Faulted The subsystem must not continue normal operation until reset.
Disconnected The runtime no longer has an active session for the subsystem.

Transition Requests

Lifecycle commands are requests, not state assignments.

lbx subsystem pause component.arm
lbx subsystem resume component.arm
lbx subsystem reset component.arm
lbx subsystem fault component.arm --reason "encoder timeout"

The runtime rejects invalid transitions. For example, Faulted -> Operating must go through reset -> Ready -> start. WaitingTarget -> resume is not a valid transition.

reset recovers a subsystem to Ready. It does not automatically restart operation. Use start after reset when the subsystem should return to Operating.

SDK Hooks

Every subsystem still implements the required startup hooks.

  • on_initialize
  • on_start
  • on_terminate
  • on_reset

Runtime lifecycle requests use optional hooks.

  • on_pause
  • on_resume
  • on_stop
  • on_fault
  • on_degraded
  • on_state_changed

pause is a robotics-safe state. It does not suspend the operating-system process. A mobile subsystem should command zero velocity or hold mode. A manipulator subsystem should hold or safe-stop. An app subsystem should stop issuing new decisions while keeping its session observable.

stop is also a cooperative lifecycle request. It asks the subsystem to enter a safe stopped state while the process can remain alive and observable. A subsystem must implement on_pause, on_resume, and on_stop to accept those requests. The SDK default is conservative and rejects them rather than pretending an unsafe pause or stop succeeded.

Managed Process Actions

Runtime lifecycle and OS process control are separate.

Action Effect
Lifecycle stop Calls the subsystem hook and keeps the process under runtime observation.
Process terminate Stops the managed resource lease, sends SIGTERM, then escalates to SIGKILL if the process scope does not exit in the grace window.
Process kill Immediately sends SIGKILL to the managed process scope.

Process actions only work for managed subsystem packages that have a resource lease. Direct-run subsystem processes can still receive lifecycle requests, but the runtime does not arbitrarily kill unmanaged shell, IDE, or debugger processes.

Session State Is Separate

Lifecycle state is not the same as session liveness.

Dimension Examples
Session active, stale, dead
Lifecycle Ready, Operating, Paused, Faulted
Binding bound, waiting binding, waiting target
Ownership managed, unmanaged

This separation matters during development. A direct-run subsystem can be Operating while unmanaged by the launcher. A managed subsystem can be Paused while its resource lease remains active. A stale session can be replaced without silently stealing the identity of a live subsystem.