Example #1
0
 public static IEventObservable <TEvent, IEventContext, TModel> GetEventObservable <TEvent, TModel>(this IRouter <TModel> router, IEventHoldingStrategy <TEvent, TModel> strategy)
     where TEvent : IIdentifiableEvent
     where TModel : IHeldEventStore
 {
     return(EventObservable.Create <TEvent, IEventContext, TModel>(
                o =>
     {
         var heldEvents = new Dictionary <Guid, HeldEventData <TEvent> >();
         var releasedEvents = new HashSet <Guid>();
         var disposables = new CollectionDisposable();
         disposables.Add(router.GetEventObservable <TEvent>(ObservationStage.Preview).Observe((e, c, m) =>
         {
             // Have we already re-published this event? If so we don't want to hold it again.
             if (releasedEvents.Contains(e.Id))
             {
                 releasedEvents.Remove(e.Id);
                 o.OnNext(e, c, m);
             }
             else
             {
                 var shouldHoldEvent = strategy.ShouldHold(e, c, m);
                 if (shouldHoldEvent)
                 {
                     // Cancel the event so no other observers will receive it.
                     c.Cancel();
                     // Model that we've cancelled it, other code can now reflect the newly modelled values.
                     // That is other code needs to determine what to do with these held events on the model.
                     // When it figures that out it should raise a HeldEventActionEvent so we can proceed here.
                     IEventDescription eventDescription = strategy.GetEventDescription(e, m);
                     m.AddHeldEventDescription(eventDescription);
                     // finally we hold the event locally
                     heldEvents.Add(e.Id, new HeldEventData <TEvent>(eventDescription, e));
                 }
             }
         }));
         disposables.Add(router.GetEventObservable <HeldEventActionEvent>().Observe((e, c, m) =>
         {
             HeldEventData <TEvent> heldEventData;
             // Since we're listening to a pipe of all events we need to filter out anything we don't know about.
             if (heldEvents.TryGetValue(e.EventId, out heldEventData))
             {
                 // We're received an event to clean up.
                 heldEvents.Remove(e.EventId);
                 m.RemoveHeldEventDescription(heldEventData.EventDescription);
                 if (e.Action == HeldEventAction.Release)
                 {
                     // Temporarily store the event we're republishing so we don't re-hold it
                     releasedEvents.Add(e.EventId);
                     router.PublishEvent(heldEventData.Event);
                 }
             }
         }));
         return disposables;
     }
                ));
 }
Example #2
0
 private static IEventObservable <TEvent, TContext, TModel> MergeInternal <TEvent, TContext, TModel>(IEnumerable <IEventObservable <TEvent, TContext, TModel> > sources)
 {
     return(Create <TEvent, TContext, TModel>(
                o =>
     {
         var disposables = new CollectionDisposable();
         foreach (IEventObservable <TEvent, TContext, TModel> source in sources)
         {
             disposables.Add(source.Observe(o));
         }
         return disposables;
     }
                ));
 }