Chief-of-state (COS) is an Open Source clustered persistence tool for building event sourced applications. COS supports CQRS and event-sourcing through simple, language-agnostic interfaces via gRPC, and it allows developers to describe their schema with Protobuf. Under the hood, COS leverages Akka to scale out and guarantee performant, reliable persistence.
Chief-of-state was built by Namely with the following principles:
- Wire format should be the same as persistence
- Scaling should not require re-architecture
- Developers shouldn't face race conditions or database locks
- Rules should be enforced with interfaces
- Event sourcing is valuable, but challenging to implement
- An ideal event-sourcing datastore would offer random access by key, streaming, and atomic writes
Developers implement two gRPC interfaces: a write handler for building state and, optionally, many read handlers for reacting to state changes.
The main entry point of a chief-of-state based application is the Service. Developers will interact with chief of state via:
ProcessCommand
is used by the application to send commands to process via Write Handler.GetState
is used by the application to retrieve the current state of a persistent entity
Developers describe state mutations by implementing two RPC’s in the WriteSideHandlerService:
HandleCommand
accepts a command and the prior state of an entity and returns an Event. For example, given a command to UpdateUserEmail and a User, this RPC might return UserEmailUpdated.HandleEvent
accepts an event and the prior state of an entity and returns a new state. For example, given a UserEmailUpdated event and a User, this RPC would return a new User instance with the email updated.
In response to state mutations, COS is able to send changes to many ReadSideHandlerService implementations, which may take any action. COS guarantees at-least-once delivery of events and resulting state to each read side in the order they were persisted.
Some potential read side handlers might:
- Write state changes to a special data store like elastic
- Publish changes to kafka topics
- Send notifications to users in response to specific events
- Journal and Snapshot serialization using google protocol buffer message format
- Preconfigured Akka clustering and domain entity sharding with the split-brain-resolver algorithm
- Automatic caching and entity passivation
- Automatic configuration of postgres storage on boot
- Opentelemetry integration for tracing and prometheus metrics
- Direct integration to Kubernetes to form a cluster
The following docs are available:
You can join these groups and chat to discuss and ask Chief Of State related questions on:
Contributions are welcome!
If you see an issue that you'd like to see fixed, the best way to make it happen is to help out by submitting a pull request implementing it. To test your implementation locally follow the steps below:
# install earthly cli
brew install earthly/earthly/earthly (for mac users)
# locally build the image
earthly +build-image
# run tests
earthly -P --no-output +test-local