Пример #1
0
        private async Task AbortCoreAsync(SequenceAbortReason reason, Exception?exception)
        {
            bool alreadyAborted;

            lock (_abortLockObject)
            {
                alreadyAborted = IsAborted;

                if (!alreadyAborted)
                {
                    _abortingTaskCompletionSource = new TaskCompletionSource <bool>();

                    if (reason > AbortReason)
                    {
                        AbortReason    = reason;
                        AbortException = exception;
                    }
                }
            }

            if (alreadyAborted)
            {
                // Multiple calls to AbortAsync should await until the sequence is aborted for real,
                // otherwise the TransactionHandlerConsumerBehavior could continue before the abort
                // is done, preventing the error policies to be correctly and successfully applied.
                await _abortingTaskCompletionSource !.Task.ConfigureAwait(false);
                return;
            }

            _logger.LogTrace(
                IntegrationEventIds.LowLevelTracing,
                AbortException,
                "Aborting {sequenceType} '{sequenceId}' ({abortReason})...",
                GetType().Name,
                SequenceId,
                AbortReason);

            _timeoutCancellationTokenSource?.Cancel();

            await Context.SequenceStore.RemoveAsync(SequenceId).ConfigureAwait(false);

            if (await HandleExceptionAsync(exception).ConfigureAwait(false))
            {
                _logger.LogSequenceAborted(Context.Envelope, this, AbortReason, AbortException);
            }

            _streamProvider.Abort();

            _abortCancellationTokenSource.Cancel();
            _abortingTaskCompletionSource?.SetResult(true);
        }
Пример #2
0
        /// <inheritdoc cref="ISequence.AbortAsync" />
        public Task AbortAsync(SequenceAbortReason reason, Exception?exception = null)
        {
            if (reason == SequenceAbortReason.None)
            {
                throw new ArgumentOutOfRangeException(nameof(reason), reason, "Reason not specified.");
            }

            if (reason == SequenceAbortReason.Error && exception == null)
            {
                throw new ArgumentNullException(
                          nameof(exception),
                          "The exception must be specified if the reason is Error.");
            }

            return(AbortCoreAsync(reason, exception));
        }
Пример #3
0
        public void LogSequenceAborted(
            ConsumerPipelineContext context,
            ISequence sequence,
            SequenceAbortReason reason,
            Exception?exception)
        {
            switch (reason)
            {
            case SequenceAbortReason.Error:
                LogWithMessageInfo(
                    LogLevel.Warning,
                    IntegrationEventIds.ErrorProcessingInboundMessage,
                    exception,
                    "Error occurred processing the inbound sequence of messages.",
                    context.Envelope,
                    sequence,
                    context.Consumer.Id);
                break;

            case SequenceAbortReason.IncompleteSequence:
                LogWithMessageInfo(
                    LogLevel.Warning,
                    IntegrationEventIds.IncompleteSequenceDiscarded,
                    null,
                    "The incomplete sequence is discarded.",
                    context.Envelope,
                    sequence,
                    context.Consumer.Id);
                break;

            case SequenceAbortReason.EnumerationAborted:
            case SequenceAbortReason.ConsumerAborted:
            case SequenceAbortReason.Disposing:
                LogWithMessageInfo(
                    LogLevel.Debug,
                    IntegrationEventIds.SequenceProcessingAborted,
                    null,
                    $"The sequence processing has been aborted (reason: {reason}).",
                    context.Envelope,
                    sequence,
                    context.Consumer.Id);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(reason), reason, null);
            }
        }
Пример #4
0
        public static Task DisposeAllAsync(
            this IEnumerable <ISequenceStore> stores,
            SequenceAbortReason abortReason) =>
        stores
        .SelectMany(store => store)
        .ToList()
        .ParallelForEachAsync(
            async sequence =>
        {
            if (sequence.IsPending)
            {
                await sequence.AbortAsync(abortReason)
                .ConfigureAwait(false);
            }

            await sequence.AwaitProcessingAsync(false).ConfigureAwait(false);
        });
Пример #5
0
        public static void LogSequenceAborted(
            this ISilverbackLogger logger,
            ISequence sequence,
            SequenceAbortReason reason)
        {
            if (!logger.IsEnabled(IntegrationLogEvents.SequenceProcessingAborted))
            {
                return;
            }

            SequenceProcessingAborted(
                logger.InnerLogger,
                sequence.GetType().Name,
                sequence.SequenceId,
                sequence.Length,
                reason,
                null);
        }