Best source for learning?

I’m sold. Now, where are the keys? :slight_smile:

I’ve downloaded the binaries and am experimenting with the command line but I have a TON of questions, some related to the architecture of my app (how ES will change it) and some related to the ES itself - recommended configurations, admin console etc.

I want to tackle the second piece first, are their tutorials for configuring this thing, getting the admin portal up and running, using it in code?

The docs on the wiki are very light on “how to use” and very heavy on the cool looking projections feature - which I also have questions about.

What is the best place to start from?

Will

Hi,

In terms of the architecture of your system, our docs are deliberately light here :slight_smile: I’d suggest looking at some of the great resources which are already out there, from dddcqrs.com through the many hours of videos on Vimeo etc. The Event Store won’t change the architecture of your system in and of itself - we don’t try to be a framework.

In a typical line-of-business application using event sourcing and the CQRS pattern, there will likely only be three touch-points with the Event Store:

  • one in your repository (the implementation of which depends on your event sourcing infrastructure - there’s an example for Jon Oliver’s CommonDomain project here (followed up here) and Yves’ AggregateSource project includes a repository implementation targeting the Event Store out the box).

  • one on whatever is creating your read models (this might be several processes). Some example code for doing that is here: https://gist.github.com/jen20/5395928

So the surface area is actually pretty small (read/write from a stream, subscribe to a stream).

Some instructions for running are here: https://github.com/EventStore/EventStore/wiki/Running-the-Event-Store - this is basically all the configuration there is for the open source version (there is more around clustering etc in the commercial editions).

We’re about to do a big (major version bump) release which includes a couple of breaking changes to the client API (as is valid to do in a major version release). This includes things like authentication, authorisation etc but hasn’t been released yet, as well as stabilising the API for projections (at which point we’ll document it properly rather than just in blog posts).

In terms of recommended configuration etc, what other sort of things are you looking for? Perhaps we can answer your questions and improve the docs at the same time!

Cheers,

James

Thanks James.

In terms of architecture, understood on the “light”. The part that I am trying to figure out is where the events are raised - is the store itself behind a queue and does it fire events?

I have a message-base architecture, clients only communicate through the bus, manager services only communicate via bus.

I also have requirements that resource access services are not allowed to queue calls.

Clients -> Managers -> Engines -> (maybe) ResourceAccess

-> ResourceAccess -> Resource

My thought is I would encapsulate ES inside the ResourceAccess so that my RAs can still look the way I need them to look.

Client -> TransferFunds()

BankAccountManager.TransferFunds() <-- Command Handler

calls BankAccountResourceAccess.DebitAccount()

AccountDebitedEvent

BankAccountResourceAccess.CreditAccount()

AccountCreditedEvent

TransferCompletedEvent

BankAccountResourceAccess.DebitAccount <- this is where it is fuzzy for me in the switch to DDD, CQRS and ESing. It seems like when switching to ESing, the need for the RA goes away since we are only simply storing the serialized events.

Does that mean I now only need Clients, Managers, Engines and a single RA that looks like a repository?

Thoughts?

Thanks!

Will

It’s fortunate that you bring up this use case rather than any other, since Szymon has an excellent blog post series describing exactly that scenario :slight_smile:

Part 1 - http://simon-says-architecture.com/2013/03/07/modelling-accounting-ledger-event-driven/

Part 2 - http://simon-says-architecture.com/2013/03/22/modelling-accounting-ledger-event-driven-2/

The issue you’ll run into with the design you outline below is that we don’t allow transactions between streams (what would happen if they were distributed?). The general rule with CQRS+ES is only touch one aggregate per command.

Hope this helps!

James

In terms of what I am looking for:

Recommendations for setup in a typical e-comm package that features catalog, cart, order management (billing, shipping, etc), with the option for single or multi-tenancy.

One big event store (single repository implementation) for all? One per aggregate root? Etc.

I see benefits of a single event stream but also have concerns - what if it dies?

Backup scenarios.

Hosting, scaling options.

How to put data in SQL Server or some other storage if files aren’t acceptable.

You know, the book that you guys will eventually write and sell for $50. :slight_smile:

Will

Will, let me try answer some of these for you:

How to put data in SQL Server or some other storage if files aren't acceptable.

The Event Store is a database in its own right. It doesn't support storing data in anything except our own file format on disk.

Backup scenarios.

Backing up is a case of copying the database files to a backup device. It's important to copy the *.chk files *before* the rest.

One big event store (single repository implementation) for all? One per aggregate root? Etc.
I see benefits of a single event stream but also have concerns - what if it dies?

Hosting, scaling options.

We supply ES as an app which can run on .NET/Windows or Linux/Mono. On Linux you'll probably want to use something like daemonize to make ES run in the background as a daemon, on Windows either svcany, ServiceEx, AlwaysUp or one of the alternatives people have posted to this list to achieve the same. We'll probably add the option to host as a service to the open source version at some point (but it's not scheduled to be included in 2.0.0 right now - that's focusing on getting all API breaking changes done in one go).

In terms of scaling, if you need more data without more performance, add disk space :slight_smile:

If you need a high availability cluster ("if it dies"), we have a commercial product named Event Store HA - you can find out more about that here (http://geteventstore.com/enterprise/).

For horizontal scaling (i.e. running a cluster of clusters with consistent hashing to determine which server each partition ends up on), we will soon have a separate commercial product named Event Store Blaze (at least that's its name for now!).

Recommendations for setup in a typical e-comm package that features catalog, cart, order management (billing, shipping, etc), with the option for single or multi-tenancy.

It's worth considering which areas of your application you'll actually get some advantage from event sourcing. I find it unlikely (though not impossible) for example that you'll derive an advantage from having a domain model around your product catalogue at all.

Does this help?

James

The general rule with CQRS+ES is only touch one aggregate per command.

So, in this case, a potential solution would be an Account Transfer Saga (in my architecture I would call this an AccountWorkflowManager) The steps in the process are volatile so I want them encapsulated.

Basically the saga (workflow manager) handles TransferFundsCommand which causes it to issue a DebitAccountCommand handled by the BankAccountManager (which fires AccountDebitedEvent).

Workflow manager subscribes to AccountDebitedEvent and then issues CreditAccountCommand. Saga then gets AccountCreditedEvent and finally raises a TransferCompletedEvent.

DebitAccount and CreditAccount would exist on an AccountManager (clients can interact directly with them, if a user wanted to make a deposit or withdrawal).

To do the persistence AccountManager would utilize AccountResourceAccess (which encapsulates an event store).

  1. Client issues TransferFundsCommand

  2. AccountWorkflowManager handles TransferFundsCommand by issuing a DebitAccountCommand

  3. AccountManager handles DebitAccountCommand by calling AccountResourceAccess.DebitAccount() <- which is event sourced

  4. AccountManager fires AccountDebitedEvent

  5. AccountWorkflowManager hears AccountDebited and issues CreditAccountCommand

Done

Something like that would then limit to one aggregate per command Is this the general idea?

My current sticking point is what is passed to the resource access. My old way would be that AccountRA.DebitAccount would be passed a DebitAccountDTO containing account number, amount and whatever other relevant information.

In an ESd application, would it still be the same (in which case the “events” themselves would be declared in the resource access layer. Or should a manager call a more generic “EventsResourceAccess”?

Question overload.

Will

I find it unlikely (though not impossible) for example that you’ll derive an advantage from having a domain model around your product catalogue at all.

Maybe I am trying the whole square-peg-round-hole trick but my design for this system is such that the “shape” of a product (and the contents of a catalog) are going to change over time.

It will be very valuable to be able to say, “What did this book look like back on 1-1-2012 when it was purchased by Will?”

Also, I am very much a fan of homogenous instead of heterogenous environments. Given a small number of developers, I’d rather them all be thinking the same way than to have to context switch between CRUD and ES. Given a bigger team where multiple BCs are in dev at the same time, this could be relaxed quite a bit.

In general, my thought is that IF most of the aggregates in the system are only going to have one version, and there is little competition on that record, then ES won’t hurt anything. :slight_smile:

In fact, breaking the impedance mismatch between the code and the data (as CQRS and ES encourages) is probably worth it all by itself.

I’m sure I’ll run into scenarios where it won’t want to use it, but for today, it’s shiny, new, and my best friend. :slight_smile:

Will

Part 1 - http://simon-says-architecture.com/2013/03/07/modelling-accounting-ledger-event-driven/

Part 2 - http://simon-says-architecture.com/2013/03/22/modelling-accounting-ledger-event-driven-2/

McAfee does not seem to like these. :frowning:

They look OK from here. Not my domain though and I don’t use McAfee so can’t help there :slight_smile:

Able to read them from phone. :slight_smile:

Interesting - the level of complexity. But that transfer example actually solves any kind of transfer where consistency is required.

Thanks!

Ah cool, yes it’s fortunate that thats the exact scenario you described.

Worth noting that most situations like this in the real world (e.g. banks) don’t have full consistency on things like transfers. It seems to be some university-level myth about database transactions that transfers between bank accounts are an appropriate use of them!

Cheers,

James

And projections?

I just read through all of the blogs there and using them to raise other events seems… Wrong.

To me that seem akin to performing business logic directly in the database.

Or am I looking at it the wrong way?

Also, what are the implications on throughput if we start running a lot of projections from the ES?

Thanks!

Will

Most systems will not have a lot of long running projections.nmost might have say 5. Then use external read models for most queries.