Docs / ArchitectureKit / Rust / Guides / Reading Long Streams

Reading Long Streams

By default, execute reads all events of a subject every time it runs a command. For a subject that collects many events over time, this gets slower with every event. If an event of one type carries everything the state needs from the events before it, the state can start from the latest event of that type instead.

Suppose every book is audited regularly, and every audit records the complete status of the book:

use architecturekit::Event;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Event)]
#[event(type = "io.eventsourcingdb.library.book-audited")]
#[serde(rename_all = "camelCase")]
struct BookAudited {
  is_acquired: bool,
  is_borrowed: bool,
}

Add a variant for it to the enum of the state, as in Audited(BookAudited), with an arm in evolve that sets the state from the event alone, without looking at the state before it. Then return its event type from the from_latest function of the state:

impl State for Book {
  type Event = BookEvent;

  fn evolve(self, event: &BookEvent) -> Self {
    match event {
      // ...
      BookEvent::Audited(audited) => {
        Book { is_acquired: audited.is_acquired, is_borrowed: audited.is_borrowed }
      }
    }
  }

  fn from_latest() -> Option<&'static str> {
    Some(BookAudited::EVENT_TYPE)
  }
}

execute then reads the events of a subject from its latest BookAudited event onwards. If the subject has no such event yet, it reads all events, as before. replay and replay_stored start from the same event, so tests of a decider see exactly what execute sees (see Testing Deciders).

Note that the state is only correct if the arm of evolve for that event type does not depend on the state before it. Events before the latest one of that type are never read.

Note that the database looks for the type under which an event is stored. If the event type is the result of an upcaster, events stored under the older type are not found, and all events are read.

Note that returning an event type from from_latest that is none of the variants of the enum of the state makes reading the state panic.