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

combine depricated on saga and view, in faviour of merge #56

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions src/saga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ impl<'a, AR, A> Saga<'a, AR, A> {

/// Combines two sagas into one.
/// Creates a new instance of a Saga by combining two sagas of type `AR`, `A` and `AR2`, `A2` into a new saga of type `Sum<AR, AR2>`, `Sum<A2, A>`
#[deprecated(
since = "0.8.0",
note = "Use the `merge` function instead. This ensures all your sagas can subscribe to all `Event`/`E` in the system."
)]
pub fn combine<AR2, A2>(self, saga2: Saga<'a, AR2, A2>) -> Saga<'a, Sum<AR, AR2>, Sum<A2, A>> {
let new_react = Box::new(move |ar: &Sum<AR, AR2>| match ar {
Sum::First(ar) => {
Expand All @@ -134,6 +138,8 @@ impl<'a, AR, A> Saga<'a, AR, A> {

/// Merges two sagas into one.
/// Creates a new instance of a Saga by merging two sagas of type `AR`, `A` and `AR`, `A2` into a new saga of type `AR`, `Sum<A, A2>`
/// Similar to `combine`, but the event type is the same for both sagas.
/// This ensures all your sagas can subscribe to all `Event`/`E` in the system.
pub fn merge<A2>(self, saga2: Saga<'a, AR, A2>) -> Saga<'a, AR, Sum<A2, A>> {
let new_react = Box::new(move |ar: &AR| {
let a: Vec<Sum<A2, A>> = (self.react)(ar)
Expand Down
6 changes: 5 additions & 1 deletion src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ impl<'a, S, E> View<'a, S, E> {
/// Combines two views into one.
/// Creates a new instance of a View by combining two views of type `S`, `E` and `S2`, `E2` into a new view of type `(S, S2)`, `Sum<E, E2>`
/// Combines two views that operate on different event types (`E`` and `E2``) into a new view operating on `Sum<E, E2>`
#[deprecated(
since = "0.8.0",
note = "Use the `merge` function instead. This ensures all your views can subscribe to all `Event`/`E` in the system."
)]
pub fn combine<S2, E2>(self, view2: View<'a, S2, E2>) -> View<'a, (S, S2), Sum<E, E2>>
where
S: Clone,
Expand Down Expand Up @@ -161,7 +165,7 @@ impl<'a, S, E> View<'a, S, E> {
/// Merges two views into one.
/// Creates a new instance of a View by merging two views of type `S`, `E` and `S2`, `E` into a new view of type `(S, S2)`, `E`
/// Similar to `combine`, but the event type is the same for both views.
/// Composes two views that operate on the same/shared event type (`E`) into a new view operating on `E`
/// This ensures all your views can subscribe to all `Event`/`E` in the system.
pub fn merge<S2>(self, view2: View<'a, S2, E>) -> View<'a, (S, S2), E>
where
S: Clone,
Expand Down
37 changes: 24 additions & 13 deletions tests/aggregate_combined_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,36 +211,49 @@ fn shipment_decider<'a>() -> Decider<'a, ShipmentCommand, ShipmentState, Shipmen
}
}

fn order_saga<'a>() -> Saga<'a, OrderEvent, ShipmentCommand> {
fn order_saga<'a>() -> Saga<'a, Event, ShipmentCommand> {
Saga {
react: Box::new(|event| match event {
OrderEvent::Created(evt) => {
Event::OrderCreated(evt) => {
vec![ShipmentCommand::Create(CreateShipmentCommand {
shipment_id: evt.order_id,
order_id: evt.order_id,
customer_name: evt.customer_name.to_owned(),
items: evt.items.to_owned(),
})]
}
OrderEvent::Updated(_) => {
Event::OrderUpdated(_) => {
vec![]
}
OrderEvent::Cancelled(_) => {
Event::OrderCancelled(_) => {
vec![]
}
Event::ShipmentCreated(_) => {
vec![]
}
}),
}
}

fn shipment_saga<'a>() -> Saga<'a, ShipmentEvent, OrderCommand> {
fn shipment_saga<'a>() -> Saga<'a, Event, OrderCommand> {
Saga {
react: Box::new(|event| match event {
ShipmentEvent::Created(evt) => {
vec![OrderCommand::Update(api::UpdateOrderCommand {
Event::ShipmentCreated(evt) => {
vec![OrderCommand::Update(UpdateOrderCommand {
order_id: evt.order_id,
new_items: evt.items.to_owned(),
})]
}

Event::OrderCreated(_) => {
vec![]
}
Event::OrderUpdated(_) => {
vec![]
}
Event::OrderCancelled(_) => {
vec![]
}
}),
}
}
Expand Down Expand Up @@ -367,9 +380,8 @@ async fn orchestrated_event_sourced_aggregate_test() {
.map_command(&command_from_sum) // Decider<Command, (OrderState, ShipmentState), Sum<OrderEvent, ShipmentEvent>>
.map_event(&event_from_sum, &sum_to_event); // Decider<Command, (OrderState, ShipmentState), Event>
let combined_saga = order_saga()
.combine(shipment_saga())
.map_action(&sum_to_command)
.map_action_result(&event_from_sum);
.merge(shipment_saga())
.map_action(&sum_to_command);
let repository = InMemoryEventRepository::new();
let aggregate = Arc::new(EventSourcedOrchestratingAggregate::new(
repository,
Expand Down Expand Up @@ -700,9 +712,8 @@ async fn state_stored_combined_test() {
.map_event(&event_from_sum, &sum_to_event); // Decider<Command, (OrderState, ShipmentState), Event>

let combined_saga = order_saga()
.combine(shipment_saga())
.map_action(&sum_to_command)
.map_action_result(&event_from_sum);
.merge(shipment_saga())
.map_action(&sum_to_command);

let repository = InMemoryStateRepository::new();
let aggregate = Arc::new(StateStoredOrchestratingAggregate::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ use fmodel_rust::view::View;
use fmodel_rust::Identifier;

use crate::api::{
OrderCancelledEvent, OrderCreatedEvent, OrderEvent, OrderUpdatedEvent, OrderViewState,
ShipmentEvent, ShipmentViewState,
OrderCancelledEvent, OrderCreatedEvent, OrderUpdatedEvent, OrderViewState, ShipmentViewState,
};
use crate::application::{event_from_sum, Event, MaterializedViewError};
use crate::application::{Event, MaterializedViewError};

mod api;
mod application;

fn order_view<'a>() -> View<'a, OrderViewState, OrderEvent> {
fn order_view<'a>() -> View<'a, OrderViewState, Event> {
View {
evolve: Box::new(|state, event| {
let mut new_state = state.clone();
match event {
OrderEvent::Created(evt) => {
Event::OrderCreated(evt) => {
new_state.order_id = evt.order_id;
new_state.customer_name = evt.customer_name.to_owned();
new_state.items = evt.items.to_owned();
}
OrderEvent::Updated(evt) => {
Event::OrderUpdated(evt) => {
new_state.items = evt.updated_items.to_owned();
}
OrderEvent::Cancelled(_) => {
Event::OrderCancelled(_) => {
new_state.is_cancelled = true;
}
Event::ShipmentCreated(_) => {}
}
new_state
}),
Expand All @@ -43,17 +43,20 @@ fn order_view<'a>() -> View<'a, OrderViewState, OrderEvent> {
}
}

fn shipment_view<'a>() -> View<'a, ShipmentViewState, ShipmentEvent> {
fn shipment_view<'a>() -> View<'a, ShipmentViewState, Event> {
View {
evolve: Box::new(|state, event| {
let mut new_state = state.clone();
match event {
ShipmentEvent::Created(evt) => {
Event::ShipmentCreated(evt) => {
new_state.shipment_id = evt.shipment_id;
new_state.order_id = evt.order_id;
new_state.customer_name = evt.customer_name.to_owned();
new_state.items = evt.items.to_owned();
}
Event::OrderCreated(_) => {}
Event::OrderUpdated(_) => {}
Event::OrderCancelled(_) => {}
}
new_state
}),
Expand Down Expand Up @@ -108,9 +111,7 @@ impl ViewStateRepository<Event, (OrderViewState, ShipmentViewState), Materialize

#[tokio::test]
async fn test() {
let combined_view = order_view()
.combine(shipment_view())
.map_event(&event_from_sum);
let combined_view = order_view().merge(shipment_view());
let repository = InMemoryViewStateRepository::new();
let materialized_view = Arc::new(MaterializedView::new(repository, combined_view));
let materialized_view1 = Arc::clone(&materialized_view);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,59 @@ use fmodel_rust::saga::Saga;
use fmodel_rust::saga_manager::{ActionPublisher, SagaManager};

use crate::api::{
CreateShipmentCommand, OrderCommand, OrderCreatedEvent, OrderEvent, ShipmentCommand,
ShipmentEvent, UpdateOrderCommand,
CreateShipmentCommand, OrderCommand, OrderCreatedEvent, ShipmentCommand, UpdateOrderCommand,
};
use crate::application::{event_from_sum2, sum_to_command2, Command, Event, SagaManagerError};
use crate::application::{sum_to_command2, Command, Event, SagaManagerError};

mod api;
mod application;

fn order_saga<'a>() -> Saga<'a, OrderEvent, ShipmentCommand> {
fn order_saga<'a>() -> Saga<'a, Event, ShipmentCommand> {
Saga {
react: Box::new(|event| match event {
OrderEvent::Created(evt) => {
Event::OrderCreated(evt) => {
vec![ShipmentCommand::Create(CreateShipmentCommand {
shipment_id: evt.order_id,
order_id: evt.order_id,
customer_name: evt.customer_name.to_owned(),
items: evt.items.to_owned(),
})]
}
OrderEvent::Updated(_) => {
Event::OrderUpdated(_) => {
vec![]
}
OrderEvent::Cancelled(_) => {
Event::OrderCancelled(_) => {
vec![]
}
Event::ShipmentCreated(_) => {
vec![]
}
}),
}
}

fn shipment_saga<'a>() -> Saga<'a, ShipmentEvent, OrderCommand> {
fn shipment_saga<'a>() -> Saga<'a, Event, OrderCommand> {
Saga {
react: Box::new(|event| match event {
ShipmentEvent::Created(evt) => {
Event::ShipmentCreated(evt) => {
vec![OrderCommand::Update(UpdateOrderCommand {
order_id: evt.order_id,
new_items: evt.items.to_owned(),
})]
}

Event::OrderCreated(_) => {
vec![]
}
Event::OrderUpdated(_) => {
vec![]
}
Event::OrderCancelled(_) => {
vec![]
}
}),
}
}

/// Simple action publisher that just returns the action/command.
/// It is used for testing. In real life, it would publish the action/command to some external system. or to an aggregate that is able to handel the action/command.
struct SimpleActionPublisher;
Expand Down Expand Up @@ -71,9 +82,8 @@ async fn test() {
let saga_manager = SagaManager::new(
SimpleActionPublisher::new(),
shipment_saga()
.combine(order_saga())
.map_action(&sum_to_command2)
.map_action_result(&event_from_sum2),
.merge(order_saga())
.map_action(&sum_to_command2),
);
let result = saga_manager.handle(&order_created_event).await;
assert!(result.is_ok());
Expand Down
34 changes: 2 additions & 32 deletions tests/saga_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use fmodel_rust::saga::{ActionComputation, Saga};

use crate::api::{
CreateShipmentCommand, OrderCommand, OrderCreatedEvent, OrderEvent, ShipmentCommand,
ShipmentEvent, UpdateOrderCommand,
UpdateOrderCommand,
};
use crate::application::{event_from_sum, sum_to_command, Command, Event};
use crate::application::{sum_to_command, Command, Event};

mod api;
mod application;
Expand Down Expand Up @@ -54,19 +54,6 @@ fn order_saga_2<'a>() -> Saga<'a, Event, ShipmentCommand> {
}
}

fn shipment_saga<'a>() -> Saga<'a, ShipmentEvent, OrderCommand> {
Saga {
react: Box::new(|event| match event {
ShipmentEvent::Created(evt) => {
vec![OrderCommand::Update(UpdateOrderCommand {
order_id: evt.order_id,
new_items: evt.items.to_owned(),
})]
}
}),
}
}

fn shipment_saga_2<'a>() -> Saga<'a, Event, OrderCommand> {
Saga {
react: Box::new(|event| match event {
Expand All @@ -93,14 +80,8 @@ fn shipment_saga_2<'a>() -> Saga<'a, Event, OrderCommand> {
#[test]
fn test() {
let order_saga: Saga<OrderEvent, ShipmentCommand> = order_saga();
let order_saga2: Saga<OrderEvent, ShipmentCommand> = crate::order_saga();
let order_saga_2: Saga<Event, ShipmentCommand> = crate::order_saga_2();
let shipment_saga: Saga<ShipmentEvent, OrderCommand> = shipment_saga();
let shipment_saga_2: Saga<Event, OrderCommand> = crate::shipment_saga_2();
let combined_saga = order_saga2
.combine(shipment_saga)
.map_action(&sum_to_command)
.map_action_result(&event_from_sum);
let merged_saga = order_saga_2
.merge(shipment_saga_2)
.map_action(&sum_to_command);
Expand All @@ -126,17 +107,6 @@ fn test() {
items: vec!["Item 1".to_string(), "Item 2".to_string()],
});

let combined_commands = combined_saga.compute_new_actions(&order_created_event2);
assert_eq!(
combined_commands,
[Command::ShipmentCreate(CreateShipmentCommand {
shipment_id: 1,
order_id: 1,
customer_name: "John Doe".to_string(),
items: vec!["Item 1".to_string(), "Item 2".to_string()],
})]
);

let merged_commands = merged_saga.compute_new_actions(&order_created_event2);
assert_eq!(
merged_commands,
Expand Down
Loading