Looking for some feedback on an Event Dispatcher

Its an observation. If you need transactional behaviour instead of
idempotency just store that variable with whatever is writing. Then
full transactional behaviour is achieved. The problem with doing that
is often its slower. If performance becomes a problem then look at
idempotency.

I am not sure how to achieve idempotency. If events are cumulative how is that possible? Unless my application of the term is off…

Projections for example are idempotent. Lets say you receive an event
"LedgerItemAdded" it just means you have to check if you have
processed it before. If you are say adding them to a table this is
relatively easy. query to see if one with that id already exists.
Where this is more difficult is when you are updating something such
as updating a count. In this case it can be harder to make the
operation idempotent. Luckily is such situations by simply saving that
variable you don't need to worry about it :slight_smile:

Guys,

As Greg pointed I have some projections which are more difficult: "when you are updating something such

as updating a count."

And my worst I didn’t build my projections with idempotent concept in mind, so you could imagine that I’m having trouble with counting and summing events.

There is any best pratices on how handle this more complex projections?

I’m not using the EventStore Projections Engine.

Kind and regards.

The catchup subscriptions built in to the latest client API can do what you need.

Use the method SubscribeToAllFrom(…) on EventStoreConnection. This takes a Position as a paramater, and will play back all historical events from that point onwards, taking care of the tricky crossover between historical events and new ones coming in over the subscription.

You will get instances of ResolvedEvent passed to your EventAppeared callback, and you can get the next “start from” position off of that event from the OriginalPosition property.

The key to getting at-most-once messaging like you are asking for is to store this value to your data store in the same transaction as whatever work you are doing.

This way if something goes horribly wrong, you have written the position associated with whatever event you last successfully processed. Just load the last processed value you stored, and pass it in to SubscribeToAllFrom to carry on … no missed or duplicate events :slight_smile:

James put up a reasonable example of an event dispatcher a little while ago:

https://gist.github.com/jen20/5395928

You would want to wrap the contents of HandleNewEvent into a single transaction.

If you are just interested in events from a single stream, SubscribeToStreamFrom(…) works in a very similar way, but you will be working based on the Integer position of events within the stream, rather than global Position values.

Thanks you very much!

I think now I can migrate my JO ES.

Hi,

What do you mean by multiple apps?

James

Hi James, I have several sub systems that have some shared data and also with data of their own. I try to create a single event store for them to share with each other.

Because the sub systems can be running seperately, so I think I should create event dispatchers for each to subscribe the events only belong to them?

Regards,

ziwen

2013年7月6日土曜日 5時29分19秒 UTC+9 James Nugent:

In my opinion you will quickly add unnecessary complexity if you add many dispatchers/buses. Why not just have one that all your apps/systems pub/sub on? If you have many then I think you are going to have a really tough time thinking you lost MSG’s when they are just on a diff bus.

Phil

Hi phil. Thank you for your quick response. Yes,that seems more reasonable, but how about the fail over strategy if the dispatcher was down? Any suggestions? Thanks.

Regards,

Ziwen

Well if the apps/systems are distributed you could look into RabbitMQ
or NServiceBus. I think they both support durable messaging...which
means if the bus is down the messages queue locally until connection
is restored.

You can use the eventstore as a durable queue. Putting rabbit in front of it in most cases would be overkill. Why not just use a file at that point?

Also you will find much much better up times with es as a backend than using rabbit clustering etc. it can handle both machine losses and network partitions. If you have five machines so long as any three can talk to each other (say 2x2x1 by data centers) you will be available. The clustering easily handles machine failures and network partitions (we run over a thousand per day eg actual power pulls)

Greg

How would you use ES as a durable message queue (keeping a local checkpoint or publishing "message consumed)?

Keeping local checkpoint or holding the last uri with atom. If you store it transactionally with your interpretation of it you will also reach only once messaging. Eg I have a projection in sqlserver if I store my checkpoint in sqlserver as part of my operation I don’t need to worry about idempotency.

There in the new client API is an object that even handles this for you (including switching servers etc in clustered mode). It’s here https://github.com/EventStore/EventStore/blob/dev/src/EventStore/EventStore.ClientAPI/EventStoreCatchUpSubscription.cs

Cool! Thanks, Greg.

If ES can be used as durable message queue just like service bus for denormalizing read models, could ES also be used as command bus and command handler subscribe to the command streams? like per command stream per Aggregate?

Regards.

Ziwen

Anybody can give some advice about this question? It seems possible if command handler competition can be solved in some kind of ways?

It depends. There are quite a few patterns for dealing with competition (round robin, shortest line, competing consumer, etc). It becomes more true if you are writing events out as typos can allow the same command to be handled multiple times (es is idempotent). What are you trying to setup?

Thank you for your quick response, Greg.

Assume a SOA distributed system. Clients(Silverlight) send commands to a WCF service stands for sending command to ES, and there runs multiple instances of command handler hosted on different servers to subscribe to the same command stream, but the command can be processed by only one handler at the same time and only once. is it possible without use of any other service bus? Thanks.

Regards.

Ziwen