Пример #1
0
        public async Task Should_forward_event_from_inner_subscription()
        {
            var ev = new StoredEvent("Stream", "1", 2, new EventData("Type", new EnvelopeHeaders(), "Payload"));

            await OnEventAsync(eventSubscription, ev);

            sut.Unsubscribe();

            A.CallTo(() => eventSubscriber.OnEventAsync(eventSubscription, ev))
            .MustHaveHappened();
        }
Пример #2
0
        public async Task Should_forward_event_from_inner_subscription()
        {
            var ev = new StoredEvent("1", 2, new EventData());

            await OnEventAsync(eventSubscription, ev);

            await sut.StopAsync();

            A.CallTo(() => eventSubscriber.OnEventAsync(sut, ev))
            .MustHaveHappened();
        }
Пример #3
0
        private async Task QueryCurrentAsync(string?streamFilter, StreamPosition lastPosition)
        {
            BsonDocument?resumeToken = null;

            var start =
                lastPosition.Timestamp.Timestamp > 0 ?
                lastPosition.Timestamp.Timestamp - 30 :
                SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromSeconds(30)).ToUnixTimeSeconds();

            var changePipeline = Match(streamFilter);
            var changeStart    = new BsonTimestamp((int)start, 0);

            while (!stopToken.IsCancellationRequested)
            {
                var changeOptions = new ChangeStreamOptions();

                if (resumeToken != null)
                {
                    changeOptions.StartAfter = resumeToken;
                }
                else
                {
                    changeOptions.StartAtOperationTime = changeStart;
                }

                using (var cursor = eventStore.TypedCollection.Watch(changePipeline, changeOptions, stopToken.Token))
                {
                    var isRead = false;

                    await cursor.ForEachAsync(async change =>
                    {
                        if (change.OperationType == ChangeStreamOperationType.Insert)
                        {
                            foreach (var storedEvent in change.FullDocument.Filtered(lastPosition))
                            {
                                await eventSubscriber.OnEventAsync(this, storedEvent);
                            }
                        }

                        isRead = true;
                    }, stopToken.Token);

                    resumeToken = cursor.GetResumeToken();

                    if (!isRead)
                    {
                        await Task.Delay(1000);
                    }
                }
            }
        }
Пример #4
0
        public async Task ProcessChangesAsync(IChangeFeedObserverContext context, IReadOnlyList <Document> docs, CancellationToken cancellationToken)
        {
            if (!processorStopRequested.Task.IsCompleted)
            {
                foreach (var document in docs)
                {
                    if (!processorStopRequested.Task.IsCompleted)
                    {
                        var streamName = document.GetPropertyValue <string>("eventStream");

                        if (regex == null || regex.IsMatch(streamName))
                        {
                            var commit = JsonConvert.DeserializeObject <CosmosDbEventCommit>(document.ToString(), store.SerializerSettings);

                            var eventStreamOffset = (int)commit.EventStreamOffset;

                            foreach (var @event in commit.Events)
                            {
                                eventStreamOffset++;

                                var eventData = @event.ToEventData();

                                await subscriber.OnEventAsync(this, new StoredEvent(commit.EventStream, hostName, eventStreamOffset, eventData));
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
        public PollingSubscription(
            IEventStore eventStore,
            IEventSubscriber eventSubscriber,
            string?streamFilter,
            string?position)
        {
            Guard.NotNull(eventStore, nameof(eventStore));
            Guard.NotNull(eventSubscriber, nameof(eventSubscriber));

            timer = new CompletionTimer(5000, async ct =>
            {
                try
                {
                    await foreach (var storedEvent in eventStore.QueryAllAsync(streamFilter, position, ct: ct))
                    {
                        await eventSubscriber.OnEventAsync(this, storedEvent);

                        position = storedEvent.EventPosition;
                    }
                }
                catch (Exception ex)
                {
                    await eventSubscriber.OnErrorAsync(this, ex);
                }
            });
        }
Пример #6
0
        public PollingSubscription(
            IEventStore eventStore,
            IEventSubscriber eventSubscriber,
            string?streamFilter,
            string?position)
        {
            Guard.NotNull(eventStore);
            Guard.NotNull(eventSubscriber);

            timer = new CompletionTimer(5000, async ct =>
            {
                try
                {
                    await eventStore.QueryAsync(async storedEvent =>
                    {
                        await eventSubscriber.OnEventAsync(this, storedEvent);

                        position = storedEvent.EventPosition;
                    }, streamFilter, position, ct);
                }
                catch (Exception ex)
                {
                    if (!ex.Is <OperationCanceledException>())
                    {
                        await eventSubscriber.OnErrorAsync(this, ex);
                    }
                }
            });
        }
Пример #7
0
        private async Task HandleEventAsync(IEventSubscription subscription, StoredEvent storedEvent)
        {
            if (subscription == currentSubscription)
            {
                await eventSubscriber.OnEventAsync(this, storedEvent);

                position = storedEvent.EventPosition;
            }
        }
Пример #8
0
        public GetEventStoreSubscription(
            IEventSubscriber subscriber,
            EventStoreClient client,
            EventStoreProjectionClient projectionClient,
            IJsonSerializer serializer,
            string?position,
            string?prefix,
            string?streamFilter)
        {
            Task.Run(async() =>
            {
                var ct = cts.Token;

                var streamName = await projectionClient.CreateProjectionAsync(streamFilter);

                async Task OnEvent(StreamSubscription subscription, ResolvedEvent @event,
                                   CancellationToken ct)
                {
                    var storedEvent = Formatter.Read(@event, prefix, serializer);

                    await subscriber.OnEventAsync(this, storedEvent);
                }

                void OnError(StreamSubscription subscription, SubscriptionDroppedReason reason, Exception? ex)
                {
                    if (reason != SubscriptionDroppedReason.Disposed &&
                        reason != SubscriptionDroppedReason.SubscriberError)
                    {
                        ex ??= new InvalidOperationException($"Subscription closed with reason {reason}.");

                        subscriber.OnErrorAsync(this, ex);
                    }
                }

                if (!string.IsNullOrWhiteSpace(position))
                {
                    var streamPosition = position.ToPosition(true);

                    subscription = await client.SubscribeToStreamAsync(streamName, streamPosition,
                                                                       OnEvent, true,
                                                                       OnError,
                                                                       cancellationToken: ct);
                }
                else
                {
                    subscription = await client.SubscribeToStreamAsync(streamName,
                                                                       OnEvent, true,
                                                                       OnError,
                                                                       cancellationToken: ct);
                }
            }, cts.Token);
        }
Пример #9
0
        public PollingSubscription(
            IEventStore eventStore,
            IEventNotifier eventNotifier,
            IEventSubscriber eventSubscriber,
            string streamFilter,
            string position)
        {
            Guard.NotNull(eventStore, nameof(eventStore));
            Guard.NotNull(eventNotifier, nameof(eventNotifier));
            Guard.NotNull(eventSubscriber, nameof(eventSubscriber));

            this.position        = position;
            this.eventNotifier   = eventNotifier;
            this.eventStore      = eventStore;
            this.eventSubscriber = eventSubscriber;
            this.streamFilter    = streamFilter;

            streamRegex = new Regex(streamFilter);

            timer = new CompletionTimer(5000, async ct =>
            {
                try
                {
                    await eventStore.GetEventsAsync(async storedEvent =>
                    {
                        await eventSubscriber.OnEventAsync(this, storedEvent);

                        position = storedEvent.EventPosition;
                    }, ct, streamFilter, position);
                }
                catch (Exception ex)
                {
                    if (!ex.Is <OperationCanceledException>())
                    {
                        await eventSubscriber.OnErrorAsync(this, ex);
                    }
                }
            });

            notification = eventNotifier.Subscribe(streamName =>
            {
                if (streamRegex.IsMatch(streamName))
                {
                    timer.SkipCurrentDelay();
                }
            });
        }
Пример #10
0
        private EventStoreCatchUpSubscription SubscribeToStream(string streamName)
        {
            var settings = CatchUpSubscriptionSettings.Default;

            return(connection.SubscribeToStreamFrom(streamName, position, settings,
                                                    (s, e) =>
            {
                var storedEvent = Formatter.Read(e);

                subscriber.OnEventAsync(this, storedEvent).Wait();
            }, null,
                                                    (s, reason, ex) =>
            {
                if (reason != SubscriptionDropReason.ConnectionClosed &&
                    reason != SubscriptionDropReason.UserInitiated)
                {
                    ex = ex ?? new ConnectionClosedException($"Subscription closed with reason {reason}.");

                    subscriber.OnErrorAsync(this, ex);
                }
            }));
        }
Пример #11
0
 public async Task OnEventAsync(IEventSubscription subscription, StoredEvent storedEvent)
 {
     await eventSubscriber.OnEventAsync(subscription, storedEvent);
 }
Пример #12
0
 public Task OnEventAsync(IEventSubscription subscription, StoredEvent storedEvent)
 {
     return(currentSubscriber.OnEventAsync(subscription, storedEvent));
 }
Пример #13
0
 private Task OnEventAsync(IEventSubscription subscriber, StoredEvent ev)
 {
     return(sutSubscriber.OnEventAsync(subscriber, ev));
 }