Skip to main content

Machine

Trait Machine 

Source
pub trait Machine<M>
where M: Fsm, Effects<M>: Drain,
{ // Required methods fn input(&self) -> Sender<In<M>>; fn with_output( self, output: impl Adapter<Item = Out<M>> + 'static, ) -> impl Machine<M>; fn merge_output( self, output: impl Adapter<Item = Out<M>> + 'static, ) -> impl Machine<M> where Out<M>: Clone + Send; fn with_event_log( self, log: impl Adapter<Item = Event<M>> + Feed<Item = Event<M>> + 'static, ) -> impl Machine<M>; fn merge_event_log( self, output: impl Adapter<Item = Event<M>> + 'static, ) -> impl Machine<M>; fn task(self) -> impl Future<Output = Result<()>> + Send + 'static where Self: Sized, Out<M>: Send, Event<M>: Send + Terminating, Effects<M>: Init<State<M>> + Send, Command<M>: Send, State<M>: Default + Send; }
Expand description

A Machine is a state machine (implementing Fsm) that will run in a rust task.

Each Machine has an input channel, and adapters for output and event log. The type of the input messages, events and output messages are part of the state machine specification, ie the Fsm implementation. Conversely, the wiring or inputs and outputs is independent of the underlying state machine and involves channels and adapters.

A Machine also has a data structure used to perform side effects, including generating output messages. The type of this is also part of the state machine specification (the SE associated type).
Note: side effects must be synchronous. If they may block they should be bracketed with tokio’s block_in_place or equivalent.

A machine is created by functions machine or machine_with_effects. It is wired to other machines or channels by functions input, with_output, merge_output and with_event_log.

The machine is made runnable by function task. This is a future intended to be spawned onto the tokio (or other) runtime.

Once running, a Machine

  • initialises state, which may involve replaying messages from the event log
  • performs initial effects
  • enters the main loop, which is dirven by messages received on the input channel
  • each message may cause the state to evolve and/or generate side effects
  • an event is logged if the state changed
  • any output messages are dispatched

Required Methods§

Source

fn input(&self) -> Sender<In<M>>

Return a new Sender for the input channel. Any number can be created , enabling fan-in of messages.

The sender accepts the Fsm Input values, representing either a command or an event. It implements Adapter so the type can be adjusted. For example, to accept events only use:

machine.input().adapt_map(Input::Event)

Source

fn with_output( self, output: impl Adapter<Item = Out<M>> + 'static, ) -> impl Machine<M>

Connect a channel Sender or an adapter for output messages.

This method replaces any existing adapter for output messages. Note that if the channel or adapter stalls this will stall the state machine.

Source

fn merge_output( self, output: impl Adapter<Item = Out<M>> + 'static, ) -> impl Machine<M>
where Out<M>: Clone + Send,

Connect an additional channel or adapter for output messages.

Any number of channels or adapters can be connected, enabling fan-out of messages. Each will receive all output messages, however if an adapter stalls this will stall the state machine.

Source

fn with_event_log( self, log: impl Adapter<Item = Event<M>> + Feed<Item = Event<M>> + 'static, ) -> impl Machine<M>

Connect an event log that provides intialisation from historical events and records live events.

Each event received by the machine and each event produced by a command will be notified. This method replaces any existing event log.

Source

fn merge_event_log( self, output: impl Adapter<Item = Event<M>> + 'static, ) -> impl Machine<M>

Connect an additional channel or adapter for events.

Each event received by the machine and each event produced by a command will be notified. Any number of channels or adapters can be connected, enabling fan-out of events. Each will receive all output messages, however if an adapter stalls this will stall the state machine.

Source

fn task(self) -> impl Future<Output = Result<()>> + Send + 'static
where Self: Sized, Out<M>: Send, Event<M>: Send + Terminating, Effects<M>: Init<State<M>> + Send, Command<M>: Send, State<M>: Default + Send,

Convert this machine into a future that will run as a task

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§