Skip to content

Replay

A reactor sees the same event twice for different reasons: once as it happens, and again whenever its observer is replayed. Those often call for different work — a confirmation that should go out once when an order is placed has no business going out again while a read model is being rebuilt.

Mark a second handler for the same event type with the Replay attribute and it takes over for the duration of the replay.

using Cratis.Chronicle.Events;
using Cratis.Chronicle.Reactors;
[EventType]
public record ReplayAwareOrderPlaced(string OrderId);
public class ReplayAwareOrderReactor : IReactor
{
public void SendConfirmation(ReplayAwareOrderPlaced @event)
{
// Runs as the event happens.
}
[Replay]
public void RebuildProjectionCache(ReplayAwareOrderPlaced @event)
{
// Runs instead of SendConfirmation while the observer is replaying.
}
}

The rules are:

  • With a Replay handler, only it runs during a replay — the regular handler does not also run.
  • Without one, the regular handler runs during a replay exactly as it always has, so adding this to one event type changes nothing for the others.
  • An event type handled only by a Replay handler is still subscribed to, so the replay it exists for delivers it.

Reach for OnceOnly instead when the side effect should simply not happen again. Use Replay when a replay needs to do something different rather than nothing. Neither covers the re-delivery that follows a failed partition being recovered — for that, see Delivery identity.