I'm working on an event-driven system and I'm facing a problem I never considered before.
There is a particular user command - let's call it "A" - that must be processed possibly with a delay of 10 minutes because user wants to be able to cancel that action issuing a new command - say "C" - until that delay has passed. Obviously, if the user issues "C", the delayed event must not produce any effect. This mechanism resembles the unsend message feature of Gmail.
My problem is mainly how to cancel the unwanted event, because events are immutable and cannot be deleted. The following scenario, for example, would fail even if I would check the current status of all the entities involved:
- User issues command "A" → created event "EA1" with 10 mins delayed effect
- After 8 mins, user issues action "C" → created regular event "EC"
- Immediately after, user issues action "A" again → created another event "EA2" with 10 mins delayed effect
- After 2 mins, the event "EA1" will produce its effect, but 8 minutes early from the user's point of view, and I cannot avoid it because the status of the entities involved is the same of after point 1.
Is there a best practice to manage cancellable actions in an event-driven architecture?
Thanks.