Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consistency level in projector and store #122

Merged
merged 5 commits into from
Oct 10, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
in the `AggregateManager` the `EventStore` associated type as `Box<dyn EventStore<Manager = >>` (with `Send` + `Sync`
bounds).
- [[#115]]: Added `apply_events` to `Aggregate` with default implementation.
- [[#122]]:
- `Consistency` level enum.
- `consistency` function to `Projector` to instruct the `EventStore` on the persistence guarantees with default
implementation returning `Consistency::Strong`.
- [[#123]]: Added `postgres` documentation in docs.rs with `package.metadata.docs.rs` in `Cargo.toml`. Improved
modules documentation.

@@ -136,6 +140,7 @@ Refer to: [#107], [#108] and [#109]
[0.6.2]: https://github.com/primait/event_sourcing.rs/compare/0.6.1...0.6.2

[#123]: https://github.com/primait/event_sourcing.rs/pull/123
[#122]: https://github.com/primait/event_sourcing.rs/pull/122
[#117]: https://github.com/primait/event_sourcing.rs/pull/117
[#115]: https://github.com/primait/event_sourcing.rs/pull/115
[#114]: https://github.com/primait/event_sourcing.rs/pull/114
23 changes: 23 additions & 0 deletions src/esrs/postgres/projector.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,21 @@ use uuid::Uuid;

use crate::{AggregateManager, StoreEvent};

/// This enum is used to instruct via [`Projector::consistency`] function which guarantees to have
/// while projecting an event in the read side.
/// - [`Consistency::Strong`] means that the projected data will be always available in the read
/// side. In the actual default store implementation it implies that if a strong consistent
/// projector fails the event will not be stored in the event store and the transaction rollbacks.
/// - [`Consistency::Eventual`] means that there are no guarantees for the projected data to be
/// persisted in the read side. In the actual default store implementation it implies that if an
/// eventual consistent projector fails that event is stored anyway but nothing will be persisted
/// in the read side. If no other projector fails the event will be stored in the event store with
/// all the other projections and the transaction will be committed.
pub enum Consistency {
Strong,
Eventual,
}

/// This trait is used to implement a `Projector`. A projector is intended to be an entity where to
/// create, update and delete a read side. Every projector should be responsible to update a single
/// read model.
@@ -12,6 +27,14 @@ pub trait Projector<Manager>: Sync
where
Manager: AggregateManager,
{
/// This function could be used to instruct the [`Projector`] about its the [`Consistency`] level.
///
/// It has a default implementation that returns [`Consistency::Strong`]. Override this function
/// to change its [`Consistency`] level.
fn consistency(&self) -> Consistency {
Consistency::Strong
}

/// This function projects one event in each read model that implements this trait.
/// The result is meant to catch generic errors.
///
8 changes: 7 additions & 1 deletion src/esrs/postgres/store.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ use sqlx::{Executor, Pool, Postgres, Transaction};
use uuid::Uuid;

use crate::esrs::policy;
use crate::esrs::postgres::projector::Consistency;
use crate::types::SequenceNumber;
use crate::{Aggregate, AggregateManager, EventStore, StoreEvent};

@@ -238,7 +239,12 @@ where

for store_event in &store_events {
for projector in self.projectors().iter() {
projector.project(store_event, &mut transaction).await?;
match projector.consistency() {
Consistency::Strong => projector.project(store_event, &mut transaction).await?,
Consistency::Eventual => {
let _ = projector.project(store_event, &mut transaction).await;
}
}
}
}

2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ mod esrs;
#[cfg(feature = "postgres")]
pub mod postgres {
//! Provides implementation of the [`EventStore`] for Postgres.
pub use crate::esrs::postgres::projector::Projector;
pub use crate::esrs::postgres::projector::{Consistency, Projector};
pub use crate::esrs::postgres::store::PgStore;
}