private async void HandleWork() { foreach (var messages in _workQueue.GetConsumingEnumerable()) { foreach (var message in messages) { try { if (IsFaulted) { await message.NotAcknowledge(); continue; } await _onEventReceived(message.Content); await message.Acknowledge(); } catch (Exception exception) { Logger?.LogError(exception, $"An exception occured during the message consumption process: {message.ToJson()}"); this.LastError = exception; await message.NotAcknowledge(); if (_dispatchQueueConfiguration.CrashAppOnError) { IsFaulted = true; _workQueue.SetAddingCompleted(); var remainingMessages = _workQueue.Flush(); try { while (remainingMessages.TryDequeue(out var remainingMessage)) { await remainingMessage.NotAcknowledge(); } } catch { } finally { _killSwitch.KillProcess(exception); } } } } } }
protected override IDisposable ConnectToEventStream(IEventStoreConnection connection) { void stopSubscription() { if (null != _eventStoreCatchupSubscription) { _eventStoreCatchupSubscription.Stop(); } } void onEvent(EventStoreCatchUpSubscription _, ResolvedEvent resolvedEvent) { Logger?.LogDebug($"{Id} => onEvent - {resolvedEvent.Event.EventId} {resolvedEvent.Event.EventStreamId} {resolvedEvent.Event.EventNumber}"); OnResolvedEvent(resolvedEvent); } void onSubscriptionDropped(EventStoreCatchUpSubscription _, SubscriptionDropReason subscriptionDropReason, Exception exception) { switch (subscriptionDropReason) { case SubscriptionDropReason.UserInitiated: break; case SubscriptionDropReason.ConnectionClosed: case SubscriptionDropReason.NotAuthenticated: case SubscriptionDropReason.AccessDenied: case SubscriptionDropReason.SubscribingError: case SubscriptionDropReason.ServerError: case SubscriptionDropReason.CatchUpError: case SubscriptionDropReason.ProcessingQueueOverflow: case SubscriptionDropReason.EventHandlerException: case SubscriptionDropReason.MaxSubscribersReached: case SubscriptionDropReason.PersistentSubscriptionDeleted: case SubscriptionDropReason.Unknown: case SubscriptionDropReason.NotFound: default: Logger?.LogError(exception, $"{nameof(SubscriptionDropReason)}: [{subscriptionDropReason}] throwed the consumer in an invalid state"); if (_eventStoreStreamConfiguration.DoAppCrashOnFailure) { _killSwitch.KillProcess(exception); } else { createNewCatchupSubscription(); } break; } } void onCaughtUp(EventStoreCatchUpSubscription _) { } void createNewCatchupSubscription() { stopSubscription(); Logger?.LogInformation($"{Id} => SubscribeToStreamFrom - StreamId: {_volatileSubscribeToOneStreamEventStoreStreamConfiguration.StreamId} - StreamPosition: {_streamPosition}"); _eventStoreCatchupSubscription = connection.SubscribeToStreamFrom( _volatileSubscribeToOneStreamEventStoreStreamConfiguration.StreamId, _streamPosition, _volatileSubscribeToOneStreamEventStoreStreamConfiguration.CatchUpSubscriptionFilteredSettings, eventAppeared: onEvent, liveProcessingStarted: onCaughtUp, subscriptionDropped: onSubscriptionDropped, userCredentials: _volatileSubscribeToOneStreamEventStoreStreamConfiguration.UserCredentials); } createNewCatchupSubscription(); return(Disposable.Create(() => { stopSubscription(); })); }
protected override IDisposable ConnectToEventStream(IEventStoreConnection connection) { void stopSubscription() { if (null != _eventStoreAllFilteredCatchUpSubscription) { _eventStoreAllFilteredCatchUpSubscription.Stop(); } } Task onEvent(EventStoreCatchUpSubscription _, ResolvedEvent resolvedEvent) { Logger?.LogDebug($"{Id} => onEvent - {resolvedEvent.Event.EventId} {resolvedEvent.Event.EventStreamId} {resolvedEvent.Event.EventNumber}"); OnResolvedEvent(resolvedEvent); return(Task.CompletedTask); } void onSubscriptionDropped(EventStoreCatchUpSubscription _, SubscriptionDropReason subscriptionDropReason, Exception exception) { switch (subscriptionDropReason) { case SubscriptionDropReason.UserInitiated: break; case SubscriptionDropReason.ConnectionClosed: case SubscriptionDropReason.NotAuthenticated: case SubscriptionDropReason.AccessDenied: case SubscriptionDropReason.SubscribingError: case SubscriptionDropReason.ServerError: case SubscriptionDropReason.CatchUpError: case SubscriptionDropReason.ProcessingQueueOverflow: case SubscriptionDropReason.EventHandlerException: case SubscriptionDropReason.MaxSubscribersReached: case SubscriptionDropReason.PersistentSubscriptionDeleted: case SubscriptionDropReason.Unknown: case SubscriptionDropReason.NotFound: default: Logger?.LogError(exception, $"{nameof(SubscriptionDropReason)}: [{subscriptionDropReason}] throwed the consumer in an invalid state"); if (_eventStoreStreamConfiguration.DoAppCrashOnFailure) { _killSwitch.KillProcess(exception); } else { createNewFilteredCatchupSubscription(); } break; } } void onCaughtUp(EventStoreCatchUpSubscription _) { } void createNewFilteredCatchupSubscription() { stopSubscription(); var eventTypeFilter = _eventTypeProvider.GetAll().Select(type => type.FullName).ToArray(); var filter = Filter.EventType.Prefix(eventTypeFilter); var position = Position.End; Logger?.LogInformation($"{Id} => {nameof(SubscribeFromEndToAllEventStoreStream)} - FilteredSubscribeToAllFrom - Position: {position} Filters: [{string.Join("|", eventTypeFilter)}]"); _eventStoreAllFilteredCatchUpSubscription = connection.FilteredSubscribeToAllFrom( position, filter, _volatileEventStoreStreamConfiguration.CatchUpSubscriptionFilteredSettings, eventAppeared: onEvent, liveProcessingStarted: onCaughtUp, subscriptionDropped: onSubscriptionDropped, userCredentials: _volatileEventStoreStreamConfiguration.UserCredentials); } createNewFilteredCatchupSubscription(); return(Disposable.Create(() => { stopSubscription(); })); }
protected override IDisposable ConnectToEventStream(IEventStoreConnection connection) { void stopSubscription() { if (null != _eventStorePersistentSubscription) { _eventStorePersistentSubscription.Stop(TimeSpan.FromSeconds(5)); } } void onEvent(EventStorePersistentSubscriptionBase _, ResolvedEvent resolvedEvent) { Logger?.LogDebug($"{Id} => onEvent - {resolvedEvent.Event.EventId}"); OnResolvedEvent(resolvedEvent); } void onSubscriptionDropped(EventStorePersistentSubscriptionBase _, SubscriptionDropReason subscriptionDropReason, Exception exception) { switch (subscriptionDropReason) { case SubscriptionDropReason.UserInitiated: break; case SubscriptionDropReason.ConnectionClosed: case SubscriptionDropReason.NotAuthenticated: case SubscriptionDropReason.AccessDenied: case SubscriptionDropReason.SubscribingError: case SubscriptionDropReason.ServerError: case SubscriptionDropReason.CatchUpError: case SubscriptionDropReason.ProcessingQueueOverflow: case SubscriptionDropReason.EventHandlerException: case SubscriptionDropReason.MaxSubscribersReached: case SubscriptionDropReason.PersistentSubscriptionDeleted: case SubscriptionDropReason.Unknown: case SubscriptionDropReason.NotFound: default: Logger?.LogError(exception, $"{nameof(SubscriptionDropReason)}: [{subscriptionDropReason}] throwed the consumer in an invalid state"); if (_eventStoreStreamConfiguration.DoAppCrashOnFailure) { _killSwitch.KillProcess(exception); } else { createNewPersistentSubscription().Wait(); } break; } } async Task createNewPersistentSubscription() { stopSubscription(); Logger?.LogInformation($"{Id} => {nameof(PersistentSubscriptionEventStoreStream)} - StreamId: {_persistentEventStoreStreamConfiguration.StreamId} - GroupId: {_persistentEventStoreStreamConfiguration.GroupId}"); _eventStorePersistentSubscription = await connection.ConnectToPersistentSubscriptionAsync( _persistentEventStoreStreamConfiguration.StreamId, _persistentEventStoreStreamConfiguration.GroupId, eventAppeared : onEvent, subscriptionDropped : onSubscriptionDropped, userCredentials : _persistentEventStoreStreamConfiguration.UserCredentials, _persistentEventStoreStreamConfiguration.BufferSize, _persistentEventStoreStreamConfiguration.AutoAck); }; createNewPersistentSubscription().Wait(); return(Disposable.Create(() => { stopSubscription(); })); }