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}