ruva_core/
unit_of_work.rs

1//! ### TUnitOfWork
2//! [TUnitOfWork] is a trait to manage atomic transaction.
3//!
4//! `commit`, and `rollback`, is governed by this implementation.
5//!
6//!
7//! To make sure that events raised in `Aggregate` object is properly collected, you want to implement
8//!
9//! [TCommitHook] as well.
10//!
11//!
12//! [UOW]: crate::unit_of_work::TUnitOfWork
13//! [TCommitHook]: crate::unit_of_work::TCommitHook
14
15//! [Handler]: crate::unit_of_work::Handler
16//!
17//! #### Usage Pattern
18//!
19//! ```rust,no_run
20//! // Service Handler
21//! pub struct CustomHandler<R> {
22//!     _r: PhantomData<R>,
23//! }
24//! impl<R> CustomHandler<R>
25//! where
26//!     R: TCustomRepository + TUnitOfWork,
27//! {
28//!     pub async fn create_aggregate(
29//!         cmd: CreateCommand,
30//!         mut uow: R,
31//!     ) -> Result<CustomResponse, CustomError> {
32//!         // Transation begin
33//!         uow.begin().await?;
34//!         let mut aggregate: CustomAggregate = CustomAggregate::new(cmd);
35//!         uow.add(&mut aggregate).await?;
36//!
37//!         // Transation commit
38//!         uow.commit().await?;
39//!         Ok(aggregate.id.into())
40//!     }
41//! }
42//!
43//! ```
44//!
45
46use crate::prelude::BaseError;
47
48/// Template for Unit of Work
49/// Concrete implementation must implement `_commit` method
50/// If you want to add hooks on events, you can implement `process_internal_events` and `process_external_events`
51
52pub trait TUnitOfWork: Send + Sync {
53	fn begin(&mut self) -> impl std::future::Future<Output = Result<(), BaseError>> + Send;
54
55	// Template method
56	fn commit(&mut self) -> impl std::future::Future<Output = Result<(), BaseError>> + Send {
57		async {
58			self.process_internal_events().await?;
59			self.process_external_events().await?;
60			self._commit().await?;
61			Ok(())
62		}
63	}
64	// Actual commit which concrete implementation must implement
65	fn _commit(&mut self) -> impl std::future::Future<Output = Result<(), BaseError>> + Send;
66
67	fn rollback(&mut self) -> impl std::future::Future<Output = Result<(), BaseError>> + Send;
68
69	fn close(&mut self) -> impl std::future::Future<Output = ()> + Send;
70
71	// Hook
72	fn process_internal_events(&mut self) -> impl std::future::Future<Output = Result<(), BaseError>> + Send {
73		async { Ok(()) }
74	}
75	// Hook
76	fn process_external_events(&mut self) -> impl std::future::Future<Output = Result<(), BaseError>> + Send {
77		async { Ok(()) }
78	}
79}