Beispiel #1
0
        public async Task <IEventStream> SubscribeAsync(
            IEventDescription eventReference)
        {
            if (eventReference == null)
            {
                throw new ArgumentNullException(nameof(eventReference));
            }

            await _semaphore.WaitAsync();

            try
            {
                if (!_streams.TryGetValue(eventReference, out var subscribers))
                {
                    subscribers = new List <InMemoryEventStream>();
                    _streams[eventReference] = subscribers;
                }

                var eventMessage = new EventMessage(eventReference);
                var stream       = new InMemoryEventStream(eventMessage);
                stream.Completed += (s, e) => Unsubscribe(eventMessage, stream);
                subscribers.Add(stream);
                return(stream);
            }
            finally
            {
                _semaphore.Release();
            }
        }
Beispiel #2
0
        public void Subscribe(string objectId, IEventDescription eventDescription, ISerializer serializer,
                              Delegate handler, object proxy)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(EventHandlersRepository));
            }

            var eventId = new EventId
            {
                ObjectId  = objectId,
                EventName = eventDescription.Name
            };

            lock (_events)
            {
                if (!_events.TryGetValue(eventId, out var subscriptionRepository))
                {
                    var subscribeMessage = new SubscribeEventMessage(_clientHostAddress, objectId, eventDescription.Name);
                    _outputChannel.SendWithAck(subscribeMessage);

                    subscriptionRepository = new SubscriptionRepository(eventDescription, serializer, _eloquentClient);
                    _events.Add(eventId, subscriptionRepository);
                }

                subscriptionRepository.Subscribe(handler, proxy);
            }
        }
        private async Task <IEventStream> SubscribeInternalAsync(
            IEventDescription eventDescription)
        {
            await _semaphore.WaitAsync().ConfigureAwait(false);

            try
            {
                if (!_streams.TryGetValue(eventDescription,
                                          out List <InMemoryEventStream> subscribers))
                {
                    subscribers = new List <InMemoryEventStream>();
                    _streams[eventDescription] = subscribers;
                }

                var eventMessage = new EventMessage(eventDescription);
                var stream       = new InMemoryEventStream();
                stream.Completed += (s, e) => Unsubscribe(eventMessage, stream);
                subscribers.Add(stream);
                return(stream);
            }
            finally
            {
                _semaphore.Release();
            }
        }
Beispiel #4
0
 public RedisEventStream(
     IEventDescription eventDescription,
     ChannelMessageQueue channel,
     IPayloadSerializer serializer)
 {
     _eventDescription = eventDescription;
     _channel          = channel;
     _serializer       = serializer;
 }
Beispiel #5
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;
     }
                ));
 }
        public Task <IEventStream> SubscribeAsync(
            IEventDescription eventDescription)
        {
            if (eventDescription == null)
            {
                throw new ArgumentNullException(nameof(eventDescription));
            }

            return(SubscribeInternalAsync(eventDescription));
        }
        public ValueTask <IEventStream> SubscribeAsync(
            IEventDescription eventDescription,
            CancellationToken cancellationToken = default)
        {
            if (eventDescription is null)
            {
                throw new ArgumentNullException(nameof(eventDescription));
            }

            return(SubscribeInternalAsync(eventDescription));
        }
Beispiel #8
0
        public async Task <IEventStream> SubscribeAsync(
            IEventDescription eventDescription)
        {
            ISubscriber subscriber = _connection.GetSubscriber();

            ChannelMessageQueue channel = await subscriber
                                          .SubscribeAsync(eventDescription.ToString())
                                          .ConfigureAwait(false);

            return(new RedisEventStream(eventDescription, channel, _serializer));
        }
Beispiel #9
0
        private static Task <IEventStream> SubscribeAsync(
            IServiceProvider services,
            IEventDescription @event)
        {
            var eventRegistry = (IEventRegistry)services
                                .GetService(typeof(IEventRegistry));

            if (eventRegistry == null)
            {
                throw new QueryException(new QueryError(CoreResources
                                                        .SubscriptionExecutionStrategy_NoEventRegistry));
            }

            return(eventRegistry.SubscribeAsync(@event));
        }
Beispiel #10
0
        private static Task <IEventStream> SubscribeAsync(
            IServiceProvider services,
            IEventDescription @event)
        {
            var eventRegistry = services.GetService <IEventRegistry>();

            if (eventRegistry == null)
            {
                throw new QueryException(
                          ErrorBuilder.New()
                          .SetMessage(CoreResources.SubscriptionExecutionStrategy_NoEventRegistry)
                          .Build());
            }

            return(eventRegistry.SubscribeAsync(@event));
        }
 public void AddEventDescription(IEventDescription ev)
 {
     _events.Add(ev);
 }
Beispiel #12
0
 public HeldEventData(IEventDescription eventDescription, TEvent @event)
 {
     EventDescription = eventDescription;
     Event            = @event;
 }
Beispiel #13
0
 public SubscriptionRepository(IEventDescription eventDescription, ISerializer serializer, EloquentClient eloquentClient)
 {
     _eventDescription = eventDescription;
     _serializer       = serializer;
     _eloquentClient   = eloquentClient;
 }
Beispiel #14
0
 public void RemoveHeldEventDescription(IEventDescription e)
 {
     HeldEvents.Remove(e);
 }
Beispiel #15
0
 public void AddHeldEventDescription(IEventDescription e)
 {
     HeldEvents.Add(e);
 }
 public EventMessage(IEventDescription eventDescription)
 {
     Event = eventDescription
             ?? throw new ArgumentNullException(nameof(eventDescription));
 }
 public EventMessage(IEventDescription eventDescription, object payload)
 {
     Event = eventDescription
             ?? throw new ArgumentNullException(nameof(eventDescription));
     Payload = payload;
 }
 public EventMessage(IEventDescription eventDescription)
     : this(eventDescription, null)
 {
 }