designing event streams

Hi there,

to evaluate,review and better understanding of the design of event streams, projections and state transitions in a web applications that uses EventStore, I want to try a more complex scenario.

Specs are

  • as a promoter, I want to create a limited ticket pool (e.g. for a live concert) by unique name, a number of available tickets and a price, for sale to customer

  • as a promoter, I want to ticket overbooking rate should tend to 0, to minimize support and user satisfaction

  • as a promoter, I want to cancel/stop all ticket sales during the sale, to react instantly on

  • as a customer, I want to buy one or more (max 4 pieces) available tickets, to attend the event

  • as a customer, I want to show the current number of sold and available tickets in the sale process like shopping cart, to show demand transparent with no customer disappointment

nice to have for sales and marketing

  • the price rises gradually by sold percentage

  • the price drops gradually by time span in relationship to event date/time

  • instantly changing the gradually during sales process by promoter

my first considerations

  • implement the specs (behavior and state) into an aggregate that manage business rules and their state consistency

  • dehydrate the current state of aggregate by calling his methods from event stream by using client side projection framework and eventType pattern matching

  • post a “claimed” event for each valid customer demand, one per ticket

  • post a “bought” event for each valid customer purchase, one per ticket

my second considerations

  • create an view model instance (that only hold state) per promoter ticket sale process and dehydrate the current state from event stream by using client side projection framework

  • increment and decrement the available ticket states in view model for current sales process by eventType pattern matching and easy peasy calculations

my lack of understanding

both, aggregate and view model, will update in period by the projection implementation by ajax polling requests?

how handle expected version conflicts? throw?

how handle business rule conflicts, e.g. no more tickets as X available, within commands / commandhandlers? throw?

how move javascript projections closer to eventstore and how “transfer” aggregated state by projections in this case?

how … did not think about anything to end - more questions can follow :wink:

Can I make it easier e.g. my view is my view model?

cheers, Mike

I had missed this email sorry for delay.

both, aggregate and view model, will update in period by the projection implementation by ajax polling requests?

how handle expected version conflicts? throw?

An aggregate would be allowed to throw. It is being told to do something. A projection is not allowed to throw (its a bug) as he is being told something has happened

how handle business rule conflicts, e.g. no more tickets as X available, within commands / commandhandlers? throw?

Throw or merge are the two common ways of handling this. Throw is generally a simple one. There is an hour long video online of handling merges in your

code on the skillsmatter website http://skillsmatter.com/podcast/design-architecture/cqrs-not-just-for-server-systems

how move javascript projections closer to eventstore and how “transfer” aggregated state by projections in this case?

how … did not think about anything to end - more questions can follow :wink:

I will put up an example of this as its probably the easiest way.

Looking forward to see it. It will capture a lot of interesting aspects in a small concise example.

Me too, sorry for delay :wink: Thx, helps a bit.

Integrity checks in merge handlers (store-and-forwars concept) - mhh, nice variation into dehydration respectively projection process. Specs (all or partial logic and algorithms) could implemented in this process. … might make sense as a own concern and makes that easier. But, workload on EventStore could be massively increased. Pub/Sub for change notifications can helps a bit.

thank you for the thoughtful abutting…

cheers, Mike

Greg. I have really enjoyed that video, watched it again, and am planning my client architecture to follow the principle this way…

  1. Assume I am offline, even cache event calls to have the occasionally connect paradigm in place.

  2. Treat wirting to stream as a Command that writes to a queue and updates stateObj with queued event

  3. Do a fresh read of the stream(s) before any writing, to see if a merge is needed

– simple event # being out of sync is first test… if true…

– look at properties changed to detect conflicts. If none, merge. If true…

— present UI modal to user to resolve, or apply stomps where possible, putting prevailing event after other which assigns state in fold func.

==> problem for me is here… since I have already updated state from queue…

–> I have to go back to the split between local and remote. Going backwards in state seems impossible, as my design is continual JS object mutation

–>>> Do I just need to rebuild state from event 0 again or a pre-split snapshot?

— >> or is it better to just take the remote events and alter the local ones before writing?

======> I am thinking the latter, since anything I post is coming back as new events anyway.

  1. Post altered queued events to stream.

It is all a bit odd, as I want state to never stop reflecting local changes, therefore I have to deal with queued events (in state) and post them, knowing they will come back on next read and alter state again. I worry about chasing complexity here.