The state machine in Rind is the runtime store for active state instances. Persistence serializes that store to disk and restores it on boot.
Runtime Store
The state machine is implemented in crates/base/src/flow.rs.
StateMachine.states:HashMap<String, Vec<FlowInstance>>- key: state full name (for example
unit@state) - value: branches/instances for that state name
StateMachine::KEY:runtime@state_machine
FlowInstance stores:
namepayload(json,string,bytes,none)type(stateorsignal)
Load/Save Boundary
StateMachine wraps a StatePersistence handle and exposes:
load_from_persistence(): decode snapshot and rebuildstatessnapshot_for_persistence(): build snapshot for persistence
Persistence filtering rule:
- states whose name contains
@_are skipped during snapshot save (impermanent state names).
Persistence Format
StateSnapshot:HashMap<String, Vec<StateEntry>>StateEntry:{ data: Vec<u8> }(bincode-encodedFlowInstance)- file header:
- magic:
RIND - version:
u16(current1) - checksum:
u32CRC32 of payload - payload: bincode bytes for snapshot map
Writes are atomic-style:
- encode snapshot
- write to
path.tmp sync_alltemp file- rename temp to target
- sync parent directory
Async vs Sync Save
StatePersistence supports both:
save(snapshot): async via internal channel + writer threadsave_sync(&snapshot): direct blocking write
Flow runtime currently calls save via save_state_machine, so normal state updates are async persisted.
Boot Integration
Units orchestrator initializes state machine in preload.
- creates
StateMachinesingleton if missing - creates
StatePersistenceusingstate_path() - calls
load_from_persistence()best-effort
Default state file path:
- env override:
RIND_STATE_PATH - fallback:
/var/lib/system-state
Runtime Actions That Mutate State
Flow runtime actions touching state/persistence:
set_stateremove_statebootstrap(reconcile existing states)
After mutation/reconcile, flow runtime saves snapshot.