pub trait Algorithm {
type Event;
type Action;
type Context;
// Required method
fn event(
&self,
event: Self::Event,
context: Self::Context
) -> Result<Vec<Self::Action>, AlgorithmError>;
// Provided method
fn into_algorithm<E, A, C>(self) -> IntoAlgorithm<Self, E, A, C>
where Self: Sized,
Self::Event: TryFrom<E, Error = InternalError>,
A: TryFrom<Self::Action, Error = InternalError>,
Self::Context: TryFrom<C, Error = InternalError> { ... }
}
Expand description
A consensus algorithm.
An algorithm processes events with a given context, producing a set of actions.
Events are inputs into the algorithm. For example, if a message is received from another process, it is input into the algorithm as an event (likely a message delivery event).
Actions are the outputs of the algorithm. For example, the algorithm may output an action to update the context and another action to send a message to another process.
The context of the algorithm contains the state of the algorithm which must be remembered between events. For example, if an algorithm must keep track of how other processes have voted, it will be stored in the context. A context is passed in with an event and updated using an action.
Required Associated Types§
Required Methods§
Provided Methods§
sourcefn into_algorithm<E, A, C>(self) -> IntoAlgorithm<Self, E, A, C>where
Self: Sized,
Self::Event: TryFrom<E, Error = InternalError>,
A: TryFrom<Self::Action, Error = InternalError>,
Self::Context: TryFrom<C, Error = InternalError>,
fn into_algorithm<E, A, C>(self) -> IntoAlgorithm<Self, E, A, C>where
Self: Sized,
Self::Event: TryFrom<E, Error = InternalError>,
A: TryFrom<Self::Action, Error = InternalError>,
Self::Context: TryFrom<C, Error = InternalError>,
Maps the inputs and output of algorithm into alternate types.
In order to easily facilitate the run-time selection of Algorithm
this function provides
a way to transform an algorithm such that it may accept inputs and produce outputs for the
general system. This could be used to handle things like run-time switching,
serialization, or the like.
Example
Suppose we have a very simple counting algorithm:
use augrim::Algorithm;
struct ExampleEvent(Option<u32>);
struct ExampleAction(Option<u32>);
struct ExampleContext(u32);
struct ExampleAlgorithm;
impl Algorithm for ExampleAlgorithm {
type Event = ExampleEvent;
type Action = ExampleAction;
type Context = ExampleContext;
fn event(
&self,
event: Self::Event,
context: Self::Context,
) -> Result<Vec<Self::Action>, augrim::error::AlgorithmError> {
if let ExampleEvent(Some(i)) = event {
Ok(vec![ExampleAction(Some(i + context.0))])
} else {
Ok(vec![ExampleAction(None)])
}
}
}
We can imagine a scenario where another component operates on the values in their
serialized string formats. Adding the appropriate TryFrom
implementations for the
event, context, and action types allows the use of into_algorithm
. The results of which
would be an algorithm with the following types:
impl Algorithm<Event=Option<&'_ str>, Context=&'_ str, Action=Option<String>>
We can see it used as follows:
use augrim::Algorithm;
let algorithm = ExampleAlgorithm.into_algorithm();
let actions: Vec<Option<String>> = algorithm.event(Some("1"), "1")?;
assert_eq!(actions, vec![Some("2".to_string())]);
let actions = algorithm.event(None, "2")?;
assert_eq!(actions, vec![None]);