(<State>, <Event>)
formatStateMachine
s are first registered with the StateMachineManager
, which I will refer
to as simply the Manager
. Every call to Manager::cycle()
processes a single event.
A single event corresponds to running on a single state machine. The Manager
accesses
the contents of the Controller
and manipulates it. A single Controller
is shared
amongst all state machines registered with the Manager
.
There are two types of events UserEvent
s and SystemEvent
s. UserEvent
s are passed to
StateMachine::cycle()
while SystemEvent
s are not. StateMachine::cycle()
accepts a
&mut Controller
and a UserEvent
. The StateMachine
uses the functions in the Controller
to add/remove events from the event queue; all functions do this except for timer related functions.
SystemEvent
s are consumed by the manager and used to modify the Controller
internals or send
data or notifications to outside the state machine group.
signal_queue
) ; this allows lifts and transits to be processed homogeneously thus avoiding type opacity through Box<dyn Signal>
I/O
Input
(handles both external and internal events)
rust
Signal {
id: StateId<K>,
input: I,
}
Two outputs:Signal
output (events meant to be processed as inputs for other state machines)Notification
output (events meant to be processed by anything that is not a state machine fed by a given signal_queue
)StateMachineManager
owns:NodeStorage
)StateMachineManager
is responsible for:Signal
s to the appropriate state machinesProcessorContext
s into the state machines: this action is what allows state machines to cycle concurrentlyhttps://github.com/knox-networks/core/blob/67f7dc6ac57f5c6650d82ce0019e65a31278ae93/common/src/statemachine/nodestate_machine.rs#L65-L74
NodeStore
is responsible for:Arc<Mutex<_>>
containers.NodeStore
storage to:DashMap
key insertions) pointing to the same tree by incrementing the Arc
count and inserting a new entry per child nodehttps://github.com/knox-networks/core/blob/67f7dc6ac57f5c6650d82ce0019e65a31278ae93/common/src/state_machine/storage.rs#L10-L16
TimeoutManager
(in development)Considerations:
- only one timer is active per StateId<K>
, State machines should not have
to keep track of Operation::Set(Instant::now())
emitted to notifications.
Thus, all timers should be indexable by StateId<K>
.
- A newer Operation::Set
for the same StateId<K>
should override an old timer.
- A timeout should emit a Signal
that is pertinent to the related state machine.
Approach:
* TimeoutManager
implements a per tick polling approach to resolving
timeouts:
https://github.com/knox-networks/core/blob/83d57647e38a55c5cfecacca8c89ebe98d45ab68/common/src/statemachine/timeout.rs#L170-L193
* TimeoutManager accepts two types of inputs, set and cancel (timeout):
https://github.com/knox-networks/core/blob/83d57647e38a55c5cfecacca8c89ebe98d45ab68/common/src/statemachine/timeout.rs#L85-L89
* Timeouts are stored within the TimeoutLedger
:
https://github.com/knox-networks/core/blob/83d57647e38a55c5cfecacca8c89ebe98d45ab68/common/src/state_machine/timeout.rs#L25-L32
* TimeoutLedger
contains a BTreeMap
that indexes IDs by Instant
and a
HashMap
that indexes Instant
s by ID This double indexing allows timeout
cancellations to go through without providing the Instant
that they were
meant to remove