pub trait WalSupport: Storable {
    type Command: WalCommand;
    type Change: WalChange;
    type Error: Error + From<WalStoreError>;

    // Required methods
    fn revision(&self) -> u64;
    fn apply(&mut self, set: WalSet<Self>);
    fn process_command(
        &self,
        command: Self::Command
    ) -> Result<Vec<Self::Change>, Self::Error>;
}
Expand description

Implement this trait to get write-ahead logging support for a type.

We achieve write-ahead logging support by insisting that implementing types define the following:

  • commands

Commands are used to send an intent to change the state. However, rather than changing the state, they return a result which can either be an error or a list of ‘events’.

  • events

Events contain the data that can be applied to a type to change its state. We do this as a separate step, because this will allow us to replay events - from write-ahead logs - to get a stored snapshot to a current state.

The following caveats apply to this: – Events MUST NOT cause side-effects – Events MUST NOT return errors when applied – All state changes MUST use events

  • errors

So that we can have type specific errors.

This is similar to how the [Aggregate] trait works, and in fact we re-use some its definitions here - such as [Event] and [Command].

But, there is a key difference which is that in this case there are no guarantees that all past events are kept - or rather they are very likely NOT kept. And we have no “init” event.

While there are similar concepts being used, the concerns here are somewhat different.. we use this type to achieve atomicity and durability by way of the WalStore defined below, but we can keep things a bit simpler here compared to the fully event-sourced [Aggregate] types.

Required Associated Types§

Required Methods§

source

fn revision(&self) -> u64

Returns the current version.

source

fn apply(&mut self, set: WalSet<Self>)

Applies the event to this. This MUST not result in any errors, and this MUST be side-effect free. Applying the event just updates the internal data of the aggregate.

Note the event is moved. This is done because we want to avoid doing additional allocations where we can.

source

fn process_command( &self, command: Self::Command ) -> Result<Vec<Self::Change>, Self::Error>

Processes a command. I.e. validate the command, and return a list of events that will result in the desired new state, but do not apply these events here.

The command is moved, because we want to enable moving its data without reallocating.

Object Safety§

This trait is not object safe.

Implementors§