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();
            }));
        }
示例#3
0
        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();
            }));
        }