-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to recover from domain events written to the stream but not published due to failure? #46
Comments
You can subscribe from the event stream and only publish messages from
there. Going this way also allows you to rebuild and start from event 1
again.
…On Mon, Aug 10, 2020, 10:07 webDEVILopers ***@***.***> wrote:
Here are some suggestions made by @Shuttle <https://github.com/Shuttle>
and @xpmatteo <https://github.com/xpmatteo> e.g. using an "Event outbox":
-
https://stackoverflow.com/questions/43436458/is-it-safe-to-publish-domain-event-before-persisting-the-aggregate
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#46 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADAJPHSZISWIPQQHZ6VJMLR775INANCNFSM4PZ7XQFA>
.
|
Thank you for your feedback. Indeed @JulianMay suggested that approach too on Twitter:
|
@Federkun also suggested the "Outbox pattern" (for NServiceBus):
Thanks to twitter's algorithm one of the next tweets by @cer dealed with the same topic:
|
If I understand the pattern correctly then I think it can be achieved in the PHP world using the symfony messenger and the doctrine transport / transaction middleware.
Is that correct @weaverryan? From the symfony docs example:
|
This outbox pattern is quite interesting. However, in the nservicebus presentation, I don't quite see how, in the second transactional phase of the process, the step 2 and 3 could actually run in the same transaction. Step 2 is most-likely achieved against a message broker and step 3 against a RDBMS. Once a message has been published, AFAIK it would be very painfull, if not impossible, to unpublish it if step 3 were failing. What am I missing here, please? |
It's been over 5 years since I worked with NServiceBus, but IIRC it was relying on guarantees on the underlying provider. In our case we were using MSSQL and MSMQ, so the MSDTC was responsible for enforcing atomic transactions. I hope this helps :) |
Thanks @JulianMay for your clarifications. This pattern seems very technology-specific as it requires this special piece of software called the Distributed Transaction Coordinator. Sounds like there is a couple of options: Use a projector to dispatch events in the busPros
Cons
Dispatch the events in the bus right after the aggregate transaction has been committed (example)Pros
Cons
Have I summed up correctly? |
To be clear: NServiceBus is technology-specific, the Outbox Pattern is not Good summation, but I think there's more to say on the cons regarding "Dispatch the events in the bus right after the aggregate transaction has been committed": Even if you manually recovered events, you might not be able to "actually recover", because ordering could matter to downstream consumers. Something like a "first one to finish gets a bonus"-policy could be problematic. Deterministic ordering is crucial if you want the option to rehydrate event-projected readmodels to the same state, in an event sourced system this is really important in order to make versioning and iterating less painful. |
Great feedback @gquemener and @JulianMay, thanks!
Most of our process managers are simple event listeners that synchronously build a new command and send it to the bus. The only possible "error" can occur while building the new command. Normally this should not happen since the data from the original aggregate event should always have a "valid state" to process. But I must confess that we do not have tests for this part yet. So when adding new features we might miss something in the command and the error occurs. |
We've spend soo much of 2018 writing and running "data-patching tools" in 2018 because of consistency issues, hence my (over) emphasis on that issue 😅 FWIW: I personally don't have async between I wrote some stuff about what I learned so far regarding these kind of issues ( |
Indeed, I've already read that, as a rule of thumb, not a doctrine, only events should be considered for asynchronous handling, not commands. AFAIR, it had to do with being able to immediately respond to error while handling commands. But I digress, feel free to open an other issue on this specific topic if you think it's appropriate :) |
Regardless of what event-bus to use - at this point of the code the events have already been written to the stream, correct? What if dispatching fails here for some reason? How can an app recover from the domain event not being published?
For instance a console command that re-dispatches / publishes the events? Or am I thinking "too carefully"?!
/cc @bas @prolic
Discussion on Twitter:
The text was updated successfully, but these errors were encountered: