slashdotdash
Building Conduit - Applying CQRS/ES to an Elixir and Phoenix web app (self-published)
I’m working on a CQRS/ES and Phoenix book for those interested in building an event driven application using Elixir.
The full source code for the application, Conduit, is available on GitHub.
Most Liked
slashdotdash
Yes, it will be finished. It’s a stuggle to find the time in addition to consultancy, releasing the next versions of Commanded and EventStore libraries, writing documentation and providing support.
slashdotdash
You have a few options for tracking unsuccessful events:
- Create failure events (e.g.
AuthenticationFailed) which are included in your event store. Here’s an example in Commanded’s aggregate guide where a failure event (AccountOverdrawn) is created during withdrawal. - Audit your incoming commands, including whether the command was successfully handled or not. You can use Commanded audit middleware to do this. It also tracks causation and correlation identifiers between commands and events allowing you to follow the flow of messages in your app.
In an aggregate, you build state by replaying the events which allows you to track historical values. As an example, if you had a bank account aggregate you could capture the current account balance over time by recording each time it changes (due to deposit or withdrawal events). Similarly, to support a user query you could build a read model from those same events with the balance shown over time as a list of transactions.
The performance will likely depend upon your chosen event serialization format and how fast your Postgres database can write to disk. Appending events is done using a multirow INSERT statement, so it’s relatively fast. The only reliable way to answer the question “is it fast enough for my usage” is by simulating your expected load in your own deployment environment. To get a rough idea you can run the EventStore benchmark suite (MIX_ENV=bench mix do es.reset, app.start, bench) to see how fast it runs. EventStore writes 4,000-8,000 events/sec and can read 26,000-27,000 events/sec on my laptop.
It’s not possible to replay events by aggregate type - it only supports by aggregate identity or all events - nor read a stream backwards. But you likely wouldn’t use an event store for this purpose. Instead you would project the events into a denormalised read model designed to support the querying needs of your administrators. You could even use an event handler to push the events to an external system, such as Elasticsearch, Logstash, and Kibana, in real-time purely for admin purposes.
Hope that helps you out.
slashdotdash
I’m using GraphQL for a CQRS/ES Elixir app where mutations are mapped to commands and dispatched. I’m using Commanded, which has async eventually consistent handlers (e.g. read model), but it allows you to simulate strong consistency during command dispatch. This is the approach I currently use.
Another approach is to not return any data from your mutation, but instead use a subscription to have the server push data to the client after it has been updated. If you use Commanded’s Ecto projections library it provides an after_update callback function which would be the ideal integration point to push to an Absinthe subscription.
Popular in Books
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










