1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
//! A library providing components to build event-sourced applications.
//!
//! The `eventually` crate provides base abstractions to design your application
//! domain using [Domain-driven Design], using the [`Aggregate`] trait,
//! and provides a set of nice utilities around those core abstractions:
//! [`EventStore`], [`Repository`], [`Subscription`] and [`Projection`].
//!
//! ## Event Sourcing Primer
//!
//! Event Sourcing is an architectural pattern which requires domain entities'
//! (in ES lingo, **_Aggregates_**) internal state to be mutated and persisted
//! as a list of **_Domain Events_**, rather than serializing the whole state
//! to the database (as you would do with a typical CRUD architecture).
//!
//! Events are persisted in an **_Event Store_**: an ordered, append-only log of all
//! the events produced in your domain.
//!
//! Events can be retrieved from an Event Store through **_Event Streams_**,
//! stream of chronologically-ordered events.
//!
//! The state of your Aggregates can thus be rebuilt by **streaming all the Events**
//! back in the application, as they happened in time, to build the latest version
//! of the state.
//!
//! This architectural pattern brings in a lot of interesting goodies:
//! * **Auditing**: never need to guess what happened in your system,
//! thanks to the Event Store, you have a list of all the Events that have been committed
//! during time.
//! * **Time-machine**: _travel back in time_, by setting the state of your service
//! to a specific point in time, thanks to the Event Store; useful for debugging purposes.
//! * **Projections**: create read-optimized models of your Aggregates as needed
//! for you business operations, continuously, every time new Events are committed
//! to the Event Store.
//! * **Concurrency Handling**: Event-sourced application make extensive use
//! of Optimistic Concurrency to handle concurrent-writes scenarios -- concurrency
//! conflicts and state reconciliation can become part of your Domain!
//! * **High Performance, High Availability**: thanks to the append-only Event Store
//! and the use of Projections, you can write highly performant and highly available
//! services that handle an intense amount of traffic.
//!
//! [More information about this pattern can be found here.](https://eventstore.com/blog/what-is-event-sourcing/)
//!
//! [Domain-driven Design]: https://en.wikipedia.org/wiki/Domain-driven_design
//! [`Aggregate`]: trait.Aggregate.html
//! [`EventStore`]: trait.EventStore.html
//! [`Repository`]: struct.Repository.html
//! [`Subscription`]: trait.Subscription.html
//! [`Projection`]: trait.Projection.html

pub use eventually_core::aggregate::{
    Aggregate, AggregateExt, AggregateId, AggregateRoot, AggregateRootBuilder,
};
pub use eventually_core::projection::Projection;
pub use eventually_core::repository::Repository;
pub use eventually_core::store::EventStore;
pub use eventually_core::subscription::{EventSubscriber, Subscription};
pub use eventually_core::versioning::Versioned;
pub use eventually_util::inmemory::Projector;
pub use eventually_util::spawn;

pub mod aggregate {
    //! Module containing support for the Aggergate pattern.
    //!
    //! ## What is an Aggregate?
    //!
    //! An [Aggregate] is the most important concept in your domain.
    //!
    //! It represents the entities your business domain is composed of,
    //! and the business logic your domain is exposing.
    //!
    //! For example: in an Order Management bounded-context (e.g. a microservice),
    //! the concepts of Order or Customer are two potential [Aggregate]s.
    //!
    //! Aggregates expose mutations with the concept of **commands**:
    //! from the previous example, an Order might expose some commands such as
    //! _"Add Order Item"_, or _"Remove Order Item"_, or _"Place Order"_
    //! to close the transaction.
    //!
    //! In Event Sourcing, the Aggregate state is modified by the usage of
    //! **Domain Events**, which carry some or all the fields in the state
    //! in a certain logical meaning.
    //!
    //! As such, commands in Event Sourcing will **produce** Domain Events.
    //!
    //! Aggregates should provide a way to **fold** Domain Events on the
    //! current value of the state, to produce the next state.
    //!
    //! ## Aggregate in `eventually`
    //!
    //! `eventually` supports the Aggregates through the [`Aggregate`] trait.
    //!
    //! An [`Aggregate`] allows to:
    //! * specify the available commands through the [`Command`] associated type,
    //! usually an `enum`,
    //! * define how to handle commands through the [`handle`] method,
    //! * specify the Aggregate's Domain Events through the [`Event`]
    //! associated type, usually an `enum`,
    //! * define the transition logic from one state to another by an [`Event`],
    //! through the [`apply`] method.
    //!
    //! An [`Aggregate`] is essentialy an _actor_, which means it should contain
    //! all the dependencies it needs to execute commands (e.g. repositories,
    //! external clients, validators, etc...)
    //!
    //! Let's take the Orders Management example:
    //!
    //! ```rust
    //! use eventually::Aggregate;
    //! use futures::future::BoxFuture;
    //!
    //! // This is the state of our Order, which contains one or more items,
    //! // and whether it has been placed or not.
    //! #[derive(Default)]
    //! struct OrderState {
    //!     items: Vec<OrderItem>,
    //!     placed: bool,
    //! }
    //!
    //! // This is a single order item, which contains the order SKU, the number
    //! // of quantities of the same item and the price.
    //! struct OrderItem {
    //!     sku: String,
    //!     quantity: u32,
    //!     price: f32,
    //! }
    //!
    //! // Let's say we have a catalog of available items in our system.
    //! //
    //! // We want to make sure that each item that has been added to the Order
    //! // is available in the catalog.
    //! //
    //! // We're going to use this trait in the Aggregate implementation,
    //! // when handling events to add OrderItems.
    //! trait OrderItemsCatalog {
    //!     fn get_item(&self, sku: String) -> BoxFuture<OrderItem>;
    //! }
    //!
    //! // This is the list of all the commands that are available on our Aggregate.
    //! enum OrderCommand {
    //!     // Make the order final and place it to the production line.
    //!     PlaceOrder,
    //!     // Add an OrderItem to the Order, specifying a quantity.
    //!     AddOrderItem {
    //!         sku: String,
    //!         quantity: u32,
    //!     },
    //!     // Remove an OrderItem from the Order: the item is removed
    //!     // when the quantity in the Order is less or equal than
    //!     // the quantity asked to be removed by the command.
    //!     RemoveOrderItem {
    //!         sku: String,
    //!         quantity: u32,
    //!     },
    //! }
    //!
    //! // This is the list of all the domain events defined on the Order aggregate.
    //! enum OrderEvent {
    //!     // The list of OrderItems is updated with the specified value.
    //!     OrderItemsUpdated {
    //!         items: Vec<OrderItem>,
    //!     },
    //!     // Marks the order as placed.
    //!     OrderPlaced,
    //! }
    //!
    //! // This is our Aggregate actor, which will contain all the necessary
    //! // dependencies for handling commands.
    //! //
    //! // In this case, it will only contain the OrderItemCatalog.
    //! struct OrderAggregate {
    //!     catalog: std::sync::Arc<dyn OrderItemsCatalog>,
    //! }
    //!
    //! // Implementation for the Aggregate trait.
    //! impl Aggregate for OrderAggregate {
    //!     type Id = u64;
    //!     type State = OrderState;
    //!     type Event = OrderEvent;
    //!     type Command = OrderCommand;
    //!     type Error = std::convert::Infallible; // This should be a meaningful error.
    //!
    //!     fn apply(state: Self::State, event: Self::Event) -> Result<Self::State, Self::Error> {
    //!         unimplemented!()
    //!     }
    //!
    //!     fn handle<'a, 's: 'a>(
    //!         &'a self,
    //!         id: &'s Self::Id,
    //!         state: &'s Self::State,
    //!         command: Self::Command,
    //!     ) -> BoxFuture<'a, Result<Option<Vec<Self::Event>>, Self::Error>>
    //!     where
    //!         Self: Sized
    //!     {
    //!         unimplemented!()
    //!     }
    //! }
    //! ```
    //!
    //! ### Note on [`State`]
    //!
    //! An [`Aggregate`]'s [`State`] type needs to implement the `Default` trait,
    //! to always have an initial state representation.
    //!
    //! This is very important for functional _folding_ of [`Event`]s
    //! done by [`apply`].
    //!
    //! A common type used in [`State`] is `Option<StateType>`, where
    //! `StateType` doesn't usually implement `Default`. This is to represent
    //! a nullable state before the first command is received.
    //!
    //! Given the common use-case, `eventually` has included support for
    //! the [`Optional`] aggregate trait, where you can use `StateType`
    //! directly in the `State` associated type.
    //!
    //! [`Optional`] is compatible with the [`Aggregate`] trait through
    //! the [`as_aggregate`] method, or the [`optional::AsAggregate`]
    //! newtype adapter.
    //!
    //! ### Interacting with Aggregates using `AggregateRoot`
    //!
    //! Interaction with Aggregates is doable through an [`AggregateRoot`].
    //!
    //! An [`AggregateRoot`] represents a specific Aggregate instance,
    //! by managing its [`State`] and the access to submit commands.
    //!
    //! Access to an [`AggregateRoot`] is obtainable in two ways:
    //! 1. Through the [`AggregateRootBuilder`], useful for testing
    //! 2. Through a [`Repository`] instance
    //!
    //! More on the [`Repository`] in the [module-level documentation](../repository/index.html).
    //!
    //! [Aggregate]: https://martinfowler.com/bliki/DDD_Aggregate.html
    //! [`Aggregate`]: trait.Aggregate.html
    //! [`Command`]: trait.Aggregate.html#associatedType.Command
    //! [`Event`]: trait.Aggregate.html#associatedType.Event
    //! [`State`]: trait.Aggregate.html#associatedType.State
    //! [`handle`]: trait.Aggregate.html#tymethod.handle
    //! [`apply`]: trait.Aggregate.html#tymethod.apply
    //! [`Optional`]: trait.Optional.html
    //! [`as_aggregate`]: trait.Optional.html#method.as_aggregate
    //! [`optional::AsAggregate`]: ../optional/struct.AsAggregate.html
    //! [`AggregateRoot`]: struct.AggregateRoot.html
    //! [`AggregateRootBuilder`]: struct.AggregateRootBuilder.html
    //! [`Repository`]: struct.Repository.html

    pub use eventually_core::aggregate::*;

    pub use eventually_core::repository::Repository;
    pub use eventually_util::optional::Aggregate as Optional;
}

pub mod versioning {
    //! Module containing support for Optimistic Concurrency using
    //! Versioning.
    //!
    //! In the future, it will contain support for conflict resolution
    //! caused by concurrent writes scenarios.

    pub use eventually_core::versioning::*;
}

pub mod repository {
    //! Module containing Repository implementation to retrieve,
    //! save and delete Aggregates.
    //!
    //! ## Repository and Aggregates
    //!
    //! As described in the [Interacting with Aggregates using `AggregateRoot`]
    //! section in the `aggregate` module-level documentation, in order to
    //! interact with an Aggregate instance you need to use an [`AggregateRoot`].
    //!
    //! To get an [`AggregateRoot`], you can use a [`Repository`] instance.
    //!
    //! The [`Repository`] allows to **retrieve**, **save** and **remove**
    //! specific Aggregate instances, by using an underlying [`EventStore`]
    //! implementation that handles the Aggregate's events.
    //!
    //! A [`Repository`] will **always** return an [`AggregateRoot`] instance
    //! on read, whether or not events are present in the [`EventStore`].
    //!
    //! Use the [`Repository`] to implement your bounded-context application logic,
    //! for example in HTTP or RPC handlers.
    //!
    //! [Interacting with Aggregates using `AggregateRoot`]: ../aggregate/index.html#interacting-with-aggregates-using-aggregateroot
    //! [`AggregateRoot`]: ../aggregate/struct.AggregateRoot.html
    //! [`Repository`]: struct.Repository.html
    //! [`EventStore`]: ../store/trait.EventStore.html

    pub use eventually_core::repository::*;
}

pub mod store {
    //! Module containing support for the Event Store.
    //!
    //! ## Event Store and `eventually`
    //!
    //! An Event Store is an ordered, append-only log of many Domain Events
    //! related to one or more Aggregate instances.
    //!
    //! The Domain Events committed to the Event Store can be streamed back into
    //! the application to load the latest value of an Aggregate state,
    //! by using the concept of Event Streams.
    //!
    //! Since Domain Events in the Store are ordered both globally and
    //! on an Aggregate-instance basis, the Event Stream can either be global
    //! or related to a single Aggregate.
    //!
    //! `eventually` adds support for the Event Store through the [`EventStore`]
    //! trait.
    //!
    //! You rarely need to use the [`EventStore`] directly when writing your
    //! application, since `eventually` exposes multiple utilities that
    //! instrument the usage of the store for you. For example:
    //! * [`Repository`] for retrieving, saving and deleting Aggregates
    //! * [`Projector`] to run [`Projection`]s (check out the [`projection` module documentation])
    //!
    //! [`EventStore`]: trait.EventStore.html
    //! [`Repository`]: ../repository/struct.Repository.html
    //! [`Projector`]: ../struct.Projector.html
    //! [`Projection`]: ../trait.Projection.html
    //! [`projection` module documentation]: ../projection/index.html

    pub use eventually_core::store::*;
}

pub mod subscription {
    //! Module containing support for Subscriptions to Events coming
    //! from the Event Store.
    //!
    //! ## What are Subscriptions?
    //!
    //! Subscriptions, as the name suggest, allows to subscribe to changes
    //! in the Event Store. Essentialy, Subscriptions receive Events
    //! when they get committed to the Store.
    //!
    //! This allows for near real-time processing of multiple things, such as
    //! publishing committed events on a message broker, or running **projections**
    //! (more on that on [`Projection` documentation]).
    //!
    //! ## Subscriptions in `eventually`
    //!
    //! ### `EventSubscriber` trait
    //!
    //! In order to subscribe to Events, `eventually` exposes the [`EventSubscriber`]
    //! trait, usually implemented by [`EventStore`] implementations.
    //!
    //! An [`EventSubscriber`] opens an _endless_ [`EventStream`], that gets
    //! closed only at application shutdown, or if the stream gets explicitly dropped.
    //!
    //! The [`EventStream`] receives all the **new Events** committed
    //! to the [`EventStore`].
    //!
    //! ### `Subscription` trait
    //!
    //! The [`Subscription`] trait represent an ongoing subscription
    //! to Events coming from an [`EventStream`], as described above.
    //!
    //! Similarly to the [`EventSubscriber`], a [`Subscription`]
    //! returns an _endless_ stream of Events called [`SubscriptionStream`].
    //!
    //! However, [`Subscription`]s are **stateful**: they save the latest
    //! Event sequence number that has been processed through the [`SubscriptionStream`],
    //! by using the [`checkpoint`] method. Later, the [`Subscription`] can be
    //! restarted from where it was left off using the [`resume`] method.
    //!
    //! This module exposes a simple [`Subscription`] implementation:
    //! [`Transient`], for in-memory, one-off subscriptions.
    //!
    //! For a long-running [`Subscription`] implementation,
    //! take a look at persisted subscriptions, such as [`postgres::subscription::Persisted`].
    //!
    //! [`Projection` documentation]: ../trait.Projection.html
    //! [`EventSubscriber`]: trait.EventSubscriber.html
    //! [`EventStore`]: ../store/trait.EventStore.html
    //! [`EventStream`]: type.EventStream.html
    //! [`Subscription`]: trait.Subscription.html
    //! [`SubscriptionStream`]: type.SubscriptionStream.html
    //! [`checkpoint`]: trait.Subscription.html#tymethod.checkpoint
    //! [`resume`]: trait.Subscription.html#tymethod.resume
    //! [`Transient`]: struct.Transient.html
    //! [`postgres::subscription::Persisted`]: ../postgres/subscription/struct.Persisted.html

    pub use eventually_core::subscription::*;
}

pub mod optional {
    //! Module for the Aggregate extension trait using an `Option` state.
    //!
    //! For more information, take a look at the [relevant `aggregate` documentation section]
    //! on the [`Optional`] aggregate trait.
    //!
    //! [relevant `aggregate` documentation section]: ../aggregate/index.html#note-on-state
    //! [`Optional`]: trait.Aggregate.html

    pub use eventually_util::optional::*;
}

pub mod inmemory {
    //! Module containing utilities using in-memory backend strategy.

    pub use eventually_util::inmemory::*;
}

pub mod sync {
    //! Module containing the synchronization primitives used by the library.

    pub use eventually_util::sync::*;
}

#[cfg(feature = "postgres")]
pub mod postgres {
    //! Module containing Event Store support using PostgreSQL backend.

    pub use eventually_postgres::*;
}