Exemplo n.º 1
0
        public Task StartReceive(CancellationToken cancellationToken = default)
        {
            maxConcurrency = limitations.MaxConcurrency;

            var prefetchCount = maxConcurrency * transportSettings.PrefetchMultiplier;

            if (transportSettings.PrefetchCount.HasValue)
            {
                prefetchCount = transportSettings.PrefetchCount.Value;
            }

            var receiveOptions = new ServiceBusReceiverOptions()
            {
                PrefetchCount = prefetchCount,
                ReceiveMode   = transportSettings.TransportTransactionMode == TransportTransactionMode.None
                    ? ServiceBusReceiveMode.ReceiveAndDelete
                    : ServiceBusReceiveMode.PeekLock
            };

            receiver = serviceBusClient.CreateReceiver(ReceiveAddress, receiveOptions);

            concurrencyLimiter = new SemaphoreSlim(maxConcurrency, maxConcurrency);

            messageReceivingCancellationTokenSource  = new CancellationTokenSource();
            messageProcessingCancellationTokenSource = new CancellationTokenSource();

            circuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker($"'{receiveSettings.ReceiveAddress}'", transportSettings.TimeToWaitBeforeTriggeringCircuitBreaker, ex => criticalErrorAction("Failed to receive message from Azure Service Bus.", ex, messageProcessingCancellationTokenSource.Token));

            // no Task.Run() here because ReceiveMessagesAndSwallowExceptions immediately yields with an await
            messageReceivingTask = ReceiveMessagesAndSwallowExceptions(messageReceivingCancellationTokenSource.Token);

            return(Task.CompletedTask);
        }
        public Task Init(Func <MessageContext, Task> pump, Func <ErrorContext, Task <ErrorHandleResult> > onError, CriticalError criticalError, PushSettings pushSettings)
        {
            topologyOperator = DetermineTopologyOperator(pushSettings.InputQueue);

            messagePump = pump;
            var name = $"MessagePump on the queue `{pushSettings.InputQueue}`";

            circuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker(name, timeToWaitBeforeTriggering, ex => criticalError.Raise("Failed to receive message from Azure Service Bus.", ex));

            if (pushSettings.PurgeOnStartup)
            {
                throw new InvalidOperationException("Azure Service Bus transport doesn't support PurgeOnStartup behavior");
            }

            inputQueue = pushSettings.InputQueue;


            topologyOperator.OnIncomingMessage(async(incoming, receiveContext) =>
            {
                if (circuitBreaker == null || throttler == null) /* can be disposed by fody injected logic, in theory */
                {
                    return;
                }

                var tokenSource = new CancellationTokenSource();
                receiveContext.CancellationToken = tokenSource.Token;

                circuitBreaker.Success();

                var transportTransaction = new TransportTransaction();
                transportTransaction.Set(receiveContext);

                await throttler.WaitAsync(receiveContext.CancellationToken).ConfigureAwait(false);

                try
                {
                    await messagePump(new MessageContext(incoming.MessageId, incoming.Headers, incoming.Body, transportTransaction, tokenSource, new ContextBag())).ConfigureAwait(false);
                }
                finally
                {
                    throttler.Release();
                }
            });

            topologyOperator.OnError(exception => circuitBreaker?.Failure(exception));
            topologyOperator.OnProcessingFailure(onError);
            topologyOperator.SetCriticalError(criticalError);

            return(TaskEx.Completed);
        }
Exemplo n.º 3
0
        public Task Init(Func <MessageContext, Task> onMessage, Func <ErrorContext, Task <ErrorHandleResult> > onError, CriticalError criticalError, PushSettings settings)
        {
            if (settings.PurgeOnStartup)
            {
                throw new Exception("Azure Service Bus transport doesn't support PurgeOnStartup behavior");
            }

            this.onMessage = onMessage;
            this.onError   = onError;
            pushSettings   = settings;

            circuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker($"'{settings.InputQueue}'", timeToWaitBeforeTriggeringCircuitBreaker, criticalError);

            return(Task.CompletedTask);
        }