You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
eGo is a minimal library that help build event-sourcing and CQRS application through a simple interface, and it allows developers to describe their **_commands_**, **_events_** and **_states_****_are defined using google protocol buffers_**.
10
-
Under the hood, ego leverages [Go-Akt](https://github.com/Tochemey/goakt) to scale out and guarantee performant, reliable persistence.
9
+
eGo is a minimal library that help build event-sourcing and CQRS application through a simple interface, and it allows
10
+
developers to describe their **_commands_**, **_events_** and **_states_****_are defined using google protocol buffers_
11
+
**.
12
+
Under the hood, ego leverages [Go-Akt](https://github.com/Tochemey/goakt) to scale out and guarantee performant,
-[Durable State Behavior](#durable-state-behavior)
25
+
-[State Store](#state-store)
26
+
-[Howto](#howto-1)
27
+
-[State Stream](#events-stream-1)
25
28
26
29
## Features
27
30
28
31
### Event Sourced Behavior
29
32
30
-
The [`EventSourcedBehavior`](./behavior.go) is crucial for maintaining data consistency, especially in distributed systems. It defines how to handle the various commands (requests to perform actions) that are always directed at the event sourced entity.
31
-
In eGo commands sent to the [`EventSourcedBehavior`](./behavior.go) are processed in order. When a command is processed, it may result in the generation of events, which are then stored in an event store. Every event persisted has a revision number
32
-
and timestamp that can help track it. The [`EventSourcedBehavior`](./behavior.go) in eGo is responsible for defining how to handle events that are the result of command handlers.
33
-
The end result of events handling is to build the new state of the event sourced entity. When running in cluster mode, aggregate root are sharded.
33
+
The [`EventSourcedBehavior`](./behavior.go) is crucial for maintaining data consistency, especially in distributed
34
+
systems. It defines how to handle the various commands (requests to perform actions) that are always directed at the
35
+
event sourced entity.
36
+
In eGo commands sent to the [`EventSourcedBehavior`](./behavior.go) are processed in order. When a command is processed,
37
+
it may result in the generation of events, which are then stored in an event store. Every event persisted has a revision
38
+
number
39
+
and timestamp that can help track it. The [`EventSourcedBehavior`](./behavior.go) in eGo is responsible for defining how
40
+
to handle events that are the result of command handlers.
41
+
The end result of events handling is to build the new state of the event sourced entity. When running in cluster mode,
42
+
aggregate root are sharded.
34
43
35
44
-`Commands handler`: The command handlers define how to handle each incoming command,
36
-
which validations must be applied, and finally, which events will be persisted if any. When there is no event to be persisted a nil can
45
+
which validations must be applied, and finally, which events will be persisted if any. When there is no event to be
46
+
persisted a nil can
37
47
be returned as a no-op. Command handlers are the meat of the event sourced actor.
38
-
They encode the business rules of your event sourced actor and act as a guardian of the event sourced entity consistency.
48
+
They encode the business rules of your event sourced actor and act as a guardian of the event sourced entity
49
+
consistency.
39
50
The command handler must first validate that the incoming command can be applied to the current model state.
40
51
Any decision should be solely based on the data passed in the commands and the state of the Behavior.
41
-
In case of successful validation, one or more events expressing the mutations are persisted. Once the events are persisted, they are applied to the state producing a new valid state.
42
-
-`Events handler`: The event handlers are used to mutate the state of the event sourced entity by applying the events to it.
43
-
Event handlers must be pure functions as they will be used when instantiating the event sourced entity and replaying the event store.
52
+
In case of successful validation, one or more events expressing the mutations are persisted. Once the events are
53
+
persisted, they are applied to the state producing a new valid state.
54
+
-`Events handler`: The event handlers are used to mutate the state of the event sourced entity by applying the events
55
+
to it.
56
+
Event handlers must be pure functions as they will be used when instantiating the event sourced entity and replaying
57
+
the event store.
44
58
45
59
#### Howto
46
60
47
61
To define an event sourced entity, one needs to:
62
+
48
63
1. define the state of the event sourced entity using google protocol buffers message
49
64
2. define the various commands that will be handled by the event sourced entity
50
-
3. define the various events that are result of the command handlers and that will be handled by the event sourced entity to return the new state of the event sourced entity
65
+
3. define the various events that are result of the command handlers and that will be handled by the event sourced
66
+
entity to return the new state of the event sourced entity
51
67
4. implement the [`EventSourcedBehavior`](./behavior.go) interface.
52
68
5. call the `Entity` method of eGo [engine](./engine.go)
53
69
54
70
#### Events Stream
55
71
56
-
Every event handled by event sourced entity are pushed to an events stream. That enables real-time processing of events without having to interact with the events store.
57
-
Just use `Subscribe` method of [Engine](./engine.go) and start iterating through the messages and cast every message to the [Event](./protos/ego/v3/ego.proto).
72
+
Every event handled by event sourced entity are pushed to an events stream. That enables real-time processing of events
73
+
without having to interact with the events store.
74
+
Just use `Subscribe` method of [Engine](./engine.go) and start iterating through the messages and cast every message to
75
+
the [Event](./protos/ego/v3/ego.proto).
58
76
59
77
#### Projection
60
78
61
-
One can add a projection to the eGo engine to help build a read model. Projections in eGo rely on an offset store to track how far they have consumed events
79
+
One can add a projection to the eGo engine to help build a read model. Projections in eGo rely on an offset store to
80
+
track how far they have consumed events
62
81
persisted by the write model. The offset used in eGo is a timestamp-based offset. One can also:
82
+
63
83
- remove a given projection: this will stop the projection and remove it from the system
64
84
- check the status of a given projection
65
85
66
86
#### Events Store
67
87
68
-
One can implement a custom events store. See [EventsStore](persistence/events_store.go). eGo comes packaged with two events store:
88
+
One can implement a custom events store. See [EventsStore](persistence/events_store.go). eGo comes packaged with two
89
+
events store:
90
+
69
91
-[Postgres](plugins/eventstore/postgres/postgres.go): Schema can be found [here](./resources/eventstore_postgres.sql)
The [`DurableStateBehavior`](./behavior.go) represents a type of Actor that persists its full state after processing each command instead of using event sourcing.
81
-
This type of Actor keeps its current state in memory during command handling and based upon the command response persists its full state into a durable store. The store can be a SQL or NoSQL database.
82
-
The whole concept is given the current state of the actor and a command produce a new state with a higher version as shown in this diagram: (State, Command) => State
83
-
[`DurableStateBehavior`](./behavior.go) reacts to commands which result in a new version of the actor state. Only the latest version of the actor state is persisted to the durable store.
104
+
The [`DurableStateBehavior`](./behavior.go) represents a type of Actor that persists its full state after processing
105
+
each command instead of using event sourcing.
106
+
This type of Actor keeps its current state in memory during command handling and based upon the command response
107
+
persists its full state into a durable store. The store can be a SQL or NoSQL database.
108
+
The whole concept is given the current state of the actor and a command produce a new state with a higher version as
109
+
shown in this diagram: (State, Command) => State
110
+
[`DurableStateBehavior`](./behavior.go) reacts to commands which result in a new version of the actor state. Only the
111
+
latest version of the actor state is persisted to the durable store.
84
112
There is no concept of history regarding the actor state since this is not an event sourced actor.
85
-
However, one can rely on the _version number_ of the actor state and exactly know how the actor state has evolved overtime.
86
-
[`DurableStateBehavior`](./behavior.go) version number are numerically incremented by the command handler which means it is imperative that the newer version of the state is greater than the current version by one.
113
+
However, one can rely on the _version number_ of the actor state and exactly know how the actor state has evolved
114
+
overtime.
115
+
[`DurableStateBehavior`](./behavior.go) version number are numerically incremented by the command handler which means it
116
+
is imperative that the newer version of the state is greater than the current version by one.
87
117
[`DurableStateBehavior`](./behavior.go) will attempt to recover its state whenever available from the durable state.
88
-
During a normal shutdown process, it will persist its current state to the durable store prior to shutting down. This behavior help maintain some consistency across the actor state evolution.
118
+
During a normal shutdown process, it will persist its current state to the durable store prior to shutting down. This
119
+
behavior help maintain some consistency across the actor state evolution.
89
120
90
121
#### State Store
91
122
92
-
One can implement a custom state store. See [StateStore](persistence/state_store.go). eGo comes packaged with two state stores:
123
+
One can implement a custom state store. See [StateStore](persistence/state_store.go). eGo comes packaged with two state
124
+
stores:
125
+
93
126
-[Postgres](plugins/statestore/postgres/postgres.go): Schema can be found [here](./resources/durablestore_postgres.sql)
1. define the state of the entity using google protocol buffers message
100
134
2. define the various commands that will be handled by the entity
101
135
3. implements the [`DurableStateBehavior`](./behavior.go) interface
@@ -104,9 +138,10 @@ To define a durable state entity, one needs to:
104
138
105
139
#### Events Stream
106
140
107
-
[`DurableStateBehavior`](./behavior.go) full state is pushed to an events stream.
141
+
[`DurableStateBehavior`](./behavior.go) full state is pushed to an events stream.
108
142
That enables real-time processing of state without having to interact with the state store.
109
-
Just use `Subscribe` method of [Engine](./engine.go) and start iterating through the messages and cast every message to the [DurableState](./protos/ego/v3/ego.proto).
143
+
Just use `Subscribe` method of [Engine](./engine.go) and start iterating through the messages and cast every message to
144
+
the [DurableState](./protos/ego/v3/ego.proto).
110
145
111
146
### Cluster
112
147
@@ -279,25 +314,28 @@ The version system adopted in eGo deviates a bit from the standard semantic vers
279
314
The version format is as follows:
280
315
281
316
- The `MAJOR` part of the version will stay at `v3` for the meantime.
282
-
- The `MINOR` part of the version will cater for any new _features_, _breaking changes_ with a note on the breaking changes.
317
+
- The `MINOR` part of the version will cater for any new _features_, _breaking changes_ with a note on the breaking
318
+
changes.
283
319
- The `PATCH` part of the version will cater for dependencies upgrades, bug fixes, security patches and co.
284
320
285
321
The versioning will remain like `v3.x.x` until further notice.
286
322
287
323
### Contribution
288
324
289
325
Contributions are welcome!
290
-
The project adheres to [Semantic Versioning](https://semver.org) and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
326
+
The project adheres to [Semantic Versioning](https://semver.org)
327
+
and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
291
328
This repo uses [Earthly](https://earthly.dev/get-earthly).
292
329
293
330
There are two ways you can become a contributor:
294
331
295
332
1. Request to become a collaborator, and then you can just open pull requests against the repository without forking it.
296
333
2. Follow these steps
297
-
- Fork the repository
298
-
- Create a feature branch
299
-
- Set your docker credentials on your fork using the following secret names: `DOCKER_USER` and `DOCKER_PASS`
300
-
- Submit a [pull request](https://help.github.com/articles/using-pull-requests)
334
+
335
+
- Fork the repository
336
+
- Create a feature branch
337
+
- Set your docker credentials on your fork using the following secret names: `DOCKER_USER` and `DOCKER_PASS`
338
+
- Submit a [pull request](https://help.github.com/articles/using-pull-requests)
0 commit comments