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(); }
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(); }
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); } } } }
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)); } } } } } }
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); } }); }
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); } } }); }
private async Task HandleEventAsync(IEventSubscription subscription, StoredEvent storedEvent) { if (subscription == currentSubscription) { await eventSubscriber.OnEventAsync(this, storedEvent); position = storedEvent.EventPosition; } }
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); }
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(); } }); }
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); } })); }
public async Task OnEventAsync(IEventSubscription subscription, StoredEvent storedEvent) { await eventSubscriber.OnEventAsync(subscription, storedEvent); }
public Task OnEventAsync(IEventSubscription subscription, StoredEvent storedEvent) { return(currentSubscriber.OnEventAsync(subscription, storedEvent)); }
private Task OnEventAsync(IEventSubscription subscriber, StoredEvent ev) { return(sutSubscriber.OnEventAsync(subscriber, ev)); }