Hey Steven,
Thank you for the response, again, it opened a door to the opportunity for manual token association which may help me in the future.
The issue i had, i resolved by re-modelling few parts of my application so it feels more natural and even if i re-send the command the aggregates ensure the consistency of the system so the events wont be published so at the worst case scenario i would just have bunch of dummy commands. The creation thing i’ve solved by introducing the UUID v3/v5 approach which generates me UUID that is linked to specific namespace which in my cases is basically the ‘parent identifier’ so the creation commands are idempotent this way.
However I’d like to point out another thing which might not be related to the main issue i’ve described but i dont think creating another thread for it would be viable since it still holds to the saga context.
The problem I’m facing right now are past events and their associacions.
My overall idea of saga is that it can used to basically compose list of events in a way so they ‘automate’ intended use-case, because well, i can send commands one by one based on the query model from the application service, but to make it domain automated behavior i should put it inside saga. So every management of for example Player creation when the User has been registered is handled by the saga.
Such automation is clean and nice if event that has the root cause eg. UserCreated is about to be followed by dispatching PlayerCreate which would have idempotent identifier of player composed from user id.
Things start to get messy if some creation event depend on multiple events that do not have predictable associations, let me clarify that by simple example:
Consider Aggregates:
User, Ticket
Consider Events:
UserCreated, TicketCreated
Consider behavior:
Give the Ticket to every user when the Ticket has been created
Now, this fits under the umbrella of BulkUpdate, because i should send out UserGiveTicked(ticketId) to every user that has been created and will be created.
It seems like this behavior fits into domain service that would track the events and persist what has occured in the system which i could obviously do by introducing additional write model but here’s a tricky solution too:
Create saga that ignores the association property, or just accepts first (which is not supported)
The ignore association is simply done by creating association resolver that just accepts all so the saga looks like:
@Start + @Association(userid) -> UserCreated -> Persist User Id
@AcceptAll -> TicketCreated -> GiveTicket(evt.ticket, persistedUser)
Above works for previously created accounts, since it accepts ticket created events after user has been created
To solve for newly created users i need to flip the logic.
@Start + @Association(ticketId) -> TicketCreated -> Persist Ticket Id
@AcceptAll -> UserCreated -> GiveTicket(evt.user, persistedTicket)
Now, the problem with that is first it would create infinite saga that would never end, and second it would create alot of thoose sagas for the previously created users (each user waits for the ticket creation so we can give one to him)
If i had a chance to compose the association properties such that it would start the saga by the UserCreated event or TicketCreated event but then succeeding events would create new saga instance that still has the start state persisted it would be golden.
Because in such way i would have clear solution to the issues where i need to create/modify something in a system using events that are not linked together by any means, it brings coupling to one place which is nice and also the sagas would end as they should.
But yeah, this is me finding myself a problems, i might be horribly wrong so if anyone has a tip on how to compose disconnected events/components together it would make my life alot easier. (But yes i do not want to introduce any new persistance for the handling as i mentioned by the domain service approach)