mookid8000 / Cirqus

:x: d60 event sourcing + CQRS framework
MIT License
233 stars 39 forks source link

Sagas/Process Managers #71

Open irium opened 8 years ago

irium commented 8 years ago

I'm using the Cirqus and now I need to implement some sort of Saga/Process Manager. How this could be done in Cirqus? It could be done with view used to persist Saga state, but how to handle replay then? We don't need to generate same commands (and thus consequent events) twice.

mookid8000 commented 8 years ago

I think maybe @asgerhallas has some things to say about this

asgerhallas commented 8 years ago

Yes. I'm a a few weeks into making (and trying out in our project) an alternative to the current style of making views and this features a process manager. It's not done yet, but I have the next few days to complete it for our project. I don't think it will be stable enough to embed into Cirqus just yet, but I can make it public on github for you to either try out or pick from, if you like...

irium commented 8 years ago

@asgerhallas Yes! It could be better for me to see the code ASAP, so I can pick the idea and immediately continue on my project, because I'm in very rush :(

P.S. In fact, my project is in production already. I'm using Cirqus, this is cool piece of code :) Application is evolving and now it needs in some sort of long-running transactions that involves multiple aggregates.

asgerhallas commented 8 years ago

@irium unfortunately it's currently embedded in the product we work on, and I can not publish that. But I can explain what we do, maybe you can use that. Note that we do not use the ViewManagers as they are right now, so I don't know if it can be done within that framework.

We give every view an event stream. When a command is executed we add one extra event on this stream into the unit of work. Upon replay we check if the last sequence number of the view-stream and we don't do any other executions/emits before we are handling events after this point in time.

Unfortunately the current CommandProcessor does not have hooks into the unit of work, so for now we have replicated it's functionality. When we know what exactly we need from the CommandProcessor, I'll issue a patch for it if needed. Note that this implementation implies that the view waits for the command to finish before it continues processing and it optimistically locks other processors of the same view type on other nodes if any. I suggest that this implementation of process managers only have a single instance and is not used as read models, though that would be possible.

irium commented 8 years ago

@asgerhallas

When a command is executed we add one extra event on this stream into the unit of work. Upon replay we check if the last sequence number of the view-stream

Do you mean "when a command is executed" - the command issued by the process manager - it waits until completion, then writes new event into own stream to reflect new state of process manager, right?

asgerhallas commented 8 years ago

@irium yes, that was a little unclear :) ... but yes exactly.

irium commented 8 years ago

@asgerhallas

Hmm... Couldn't it be better not to wait for a command completion, but for some event (from some aggregate) raised in consequence of the command? As I understand the process manager anyway should listen for various events?

asgerhallas commented 8 years ago

@irium Sorry for the delay, I missed the notification. I have to know, during the handling of the event whether the command has been executed or not, so I don't execute it again at replay. I guess I could set up some binding to a specific event that must have been emitted from some aggregate, but it seems easier to have the process manager have its own stream, does it not?. It must be emitted during the handling of the event (not async), or else the process manager would have to know about its own future state on replay - to find out if the command should be re-executed.

davidreynoldsdev commented 8 years ago

We're process managers inter grated into cirqus? Also, do d60 use process managers in they're projects? It seems from the documentation that if modifying multiple aggregates is required then you would suggest doing so in a command handler. Is this the case or would you use a process manager for this kind of thing?

mookid8000 commented 8 years ago

@0davidreynolds0 no, Cirqus never got any process manager mechanism built in... and d60 does not really use any explicit process manager mechanisms anywhere