async Task IBrokeredMessageReceiver.Handle(Message message, Action <ReceiveContext> contextCallback) { var context = new ServiceBusReceiveContext(_inputAddress, message, _receiveEndpointContext); contextCallback?.Invoke(context); context.TryGetPayload <Microsoft.Azure.ServiceBus.Core.IReceiverClient>(out var messageReceiver); try { await _receiveEndpointContext.ReceiveObservers.PreReceive(context).ConfigureAwait(false); if (message.SystemProperties.LockedUntilUtc <= DateTime.UtcNow) { throw new MessageLockExpiredException(_inputAddress, $"The message lock expired: {message.MessageId}"); } if (message.ExpiresAtUtc < DateTime.UtcNow) { throw new MessageTimeToLiveExpiredException(_inputAddress, $"The message TTL expired: {message.MessageId}"); } await _receiveEndpointContext.ReceivePipe.Send(context).ConfigureAwait(false); await context.ReceiveCompleted.ConfigureAwait(false); if (messageReceiver != null) { await messageReceiver.CompleteAsync(message.SystemProperties.LockToken).ConfigureAwait(false); } await _receiveEndpointContext.ReceiveObservers.PostReceive(context).ConfigureAwait(false); } catch (Exception ex) { await _receiveEndpointContext.ReceiveObservers.ReceiveFault(context, ex).ConfigureAwait(false); if (messageReceiver == null) { throw; } try { await messageReceiver.AbandonAsync(message.SystemProperties.LockToken).ConfigureAwait(false); } catch (Exception exception) { if (_log.IsWarnEnabled) { _log.Warn($"Abandon message faulted: {message.MessageId}", exception); } } } finally { context.Dispose(); } }
async Task IBrokeredMessageReceiver.Handle(Message message, Action <ReceiveContext> contextCallback) { var context = new ServiceBusReceiveContext(message, _context); contextCallback?.Invoke(context); var receiveLock = context.TryGetPayload <MessageLockContext>(out var lockContext) ? new MessageLockContextReceiveLock(lockContext, context) : default;
async Task IMessageSessionAsyncHandler.OnMessageAsync(MessageSession session, BrokeredMessage message) { if (_receiver.IsShuttingDown) { await WaitAndAbandonMessage(message).ConfigureAwait(false); return; } using (var delivery = _tracker.BeginDelivery()) { if (_log.IsDebugEnabled) { _log.DebugFormat("Receiving {0}:{1}({3}) - {2}", delivery.Id, message.MessageId, _receiver.QueuePath, session.SessionId); } var context = new ServiceBusReceiveContext(_receiver.InputAddress, message, _context, _sendEndpointProvider, _publishEndpointProvider); context.GetOrAddPayload <MessageSessionContext>(() => new BrokeredMessageSessionContext(session)); context.GetOrAddPayload(() => _context); try { await _context.PreReceive(context).ConfigureAwait(false); await _receiver.ReceivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _context.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) { _log.DebugFormat("Receive completed: {0}", message.MessageId); } } catch (Exception ex) { if (_log.IsErrorEnabled) { _log.Error($"Received faulted: {message.MessageId}", ex); } await message.AbandonAsync().ConfigureAwait(false); await _context.ReceiveFault(context, ex).ConfigureAwait(false); } finally { context.Dispose(); } } }
async Task IMessageSessionAsyncHandler.OnMessageAsync(MessageSession session, BrokeredMessage message) { if (_receiver.IsShuttingDown) { await WaitAndAbandonMessage(message).ConfigureAwait(false); return; } var deliveryCount = _receiver.IncrementDeliveryCount(); if (_log.IsDebugEnabled) { _log.DebugFormat("Receiving {0}:{1}({3}) - {2}", deliveryCount, message.MessageId, _receiver.QueuePath, session.SessionId); } var context = new ServiceBusReceiveContext(_receiver.InputAddress, message, _receiver.ReceiveObserver); context.GetOrAddPayload <MessageSessionContext>(() => new BrokeredMessageSessionContext(session)); try { await _receiver.ReceiveObserver.PreReceive(context).ConfigureAwait(false); await _receiver.ReceivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _receiver.ReceiveObserver.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) { _log.DebugFormat("Receive completed: {0}", message.MessageId); } } catch (Exception ex) { if (_log.IsErrorEnabled) { _log.Error($"Received faulted: {message.MessageId}", ex); } await message.AbandonAsync().ConfigureAwait(false); await _receiver.ReceiveObserver.ReceiveFault(context, ex).ConfigureAwait(false); } finally { _receiver.DeliveryComplete(); } }
async Task IBrokeredMessageReceiver.Handle(BrokeredMessage message, Action <ReceiveContext> contextCallback) { var context = new ServiceBusReceiveContext(_inputAddress, message, _receiveObservers, _receiveTopology); contextCallback?.Invoke(context); try { await _receiveObservers.PreReceive(context).ConfigureAwait(false); if (message.LockedUntilUtc <= DateTime.UtcNow) { throw new MessageLockExpiredException(_inputAddress, $"The message lock expired: {message.MessageId}"); } if (message.ExpiresAtUtc < DateTime.UtcNow) { throw new MessageTimeToLiveExpiredException(_inputAddress, $"The message TTL expired: {message.MessageId}"); } await _receivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _receiveObservers.PostReceive(context).ConfigureAwait(false); } catch (Exception ex) { try { await message.AbandonAsync().ConfigureAwait(false); } catch (Exception exception) { if (_log.IsWarnEnabled) { _log.Warn($"Abandon message faulted: {message.MessageId}", exception); } } await _receiveObservers.ReceiveFault(context, ex).ConfigureAwait(false); } finally { context.Dispose(); } }
async Task IBrokeredMessageReceiver.Handle(Message message, CancellationToken cancellationToken, Action <ReceiveContext> contextCallback) { var context = new ServiceBusReceiveContext(message, _context); contextCallback?.Invoke(context); CancellationTokenRegistration registration = default; if (cancellationToken.CanBeCanceled) { registration = cancellationToken.Register(context.Cancel); } var receiveLock = context.TryGetPayload <MessageLockContext>(out var lockContext) ? new MessageLockContextReceiveLock(lockContext, context) : default;
async Task IMessageSessionAsyncHandler.OnMessageAsync(MessageSession session, BrokeredMessage message) { if (_receiver.IsShuttingDown) { await WaitAndAbandonMessage(message).ConfigureAwait(false); return; } using (var delivery = _tracker.BeginDelivery()) { if (_log.IsDebugEnabled) _log.DebugFormat("Receiving {0}:{1}({3}) - {2}", delivery.Id, message.MessageId, _receiver.QueuePath, session.SessionId); var context = new ServiceBusReceiveContext(_receiver.InputAddress, message, _context, _sendEndpointProvider, _publishEndpointProvider); context.GetOrAddPayload<MessageSessionContext>(() => new BrokeredMessageSessionContext(session)); context.GetOrAddPayload(() => _context); try { await _context.PreReceive(context).ConfigureAwait(false); await _receiver.ReceivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _context.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) _log.DebugFormat("Receive completed: {0}", message.MessageId); } catch (Exception ex) { if (_log.IsErrorEnabled) _log.Error($"Received faulted: {message.MessageId}", ex); await message.AbandonAsync().ConfigureAwait(false); await _context.ReceiveFault(context, ex).ConfigureAwait(false); } finally { context.Dispose(); } } }
void QueueReceiver() { if (_enabled == false) { return; } lock (_locker) { if (_receiverCount > 0) { return; } if (_consumerCount >= _maximumThreadCount) { return; } // if (_log.IsDebugEnabled) // _log.DebugFormat("Queueing receiver for {0}", _bus.Endpoint.Address.Uri); var context = new ServiceBusReceiveContext(_bus, _eventChannel, _receiveTimeout); Interlocked.Increment(ref _receiverCount); Interlocked.Increment(ref _consumerCount); try { ThreadPool.QueueUserWorkItem(x => context.ReceiveFromEndpoint()); } catch (Exception ex) { _log.Error("Unable to queue consumer to thread pool", ex); Interlocked.Decrement(ref _receiverCount); Interlocked.Decrement(ref _consumerCount); } } _eventChannel.Send(new ReceiverQueued { ReceiverCount = _receiverCount, ConsumerCount = _consumerCount, }); }
async Task IMessageSessionAsyncHandler.OnMessageAsync(MessageSession session, BrokeredMessage message) { if (_receiver.IsShuttingDown) { await WaitAndAbandonMessage(message).ConfigureAwait(false); return; } var deliveryCount = _receiver.IncrementDeliveryCount(); if (_log.IsDebugEnabled) _log.DebugFormat("Receiving {0}:{1}({3}) - {2}", deliveryCount, message.MessageId, _receiver.QueuePath, session.SessionId); var context = new ServiceBusReceiveContext(_receiver.InputAddress, message, _receiver.ReceiveObserver); context.GetOrAddPayload<MessageSessionContext>(() => new BrokeredMessageSessionContext(session)); try { await _receiver.ReceiveObserver.PreReceive(context).ConfigureAwait(false); await _receiver.ReceivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _receiver.ReceiveObserver.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) _log.DebugFormat("Receive completed: {0}", message.MessageId); } catch (Exception ex) { if (_log.IsErrorEnabled) _log.Error($"Received faulted: {message.MessageId}", ex); await message.AbandonAsync().ConfigureAwait(false); await _receiver.ReceiveObserver.ReceiveFault(context, ex).ConfigureAwait(false); } finally { _receiver.DeliveryComplete(); } }
void QueueReceiver() { if (_enabled == false) return; lock (_locker) { if (_receiverCount > 0) return; if (_consumerCount >= _maximumThreadCount) return; if (_log.IsDebugEnabled) _log.DebugFormat("Queueing receiver for {0}", _bus.Endpoint.Address.Uri); var context = new ServiceBusReceiveContext(_bus, _eventChannel, _receiveTimeout); Interlocked.Increment(ref _receiverCount); Interlocked.Increment(ref _consumerCount); try { ThreadPool.QueueUserWorkItem(x => context.ReceiveFromEndpoint()); } catch (Exception ex) { _log.Error("Unable to queue consumer to thread pool", ex); Interlocked.Decrement(ref _receiverCount); Interlocked.Decrement(ref _consumerCount); } } _eventChannel.Send(new ReceiverQueued { ReceiverCount = _receiverCount, ConsumerCount = _consumerCount, }); }
async Task OnMessage(BrokeredMessage message) { int current = Interlocked.Increment(ref _currentPendingDeliveryCount); while (current > _maxPendingDeliveryCount) { Interlocked.CompareExchange(ref _maxPendingDeliveryCount, current, _maxPendingDeliveryCount); } long deliveryCount = Interlocked.Increment(ref _deliveryCount); if (_log.IsDebugEnabled) { _log.DebugFormat("Receiving {0}:{1} - {2}", deliveryCount, message.MessageId, _receiveSettings.QueueDescription.Path); } Exception exception = null; var context = new ServiceBusReceiveContext(_inputAddress, message, _receiveObserver); try { if (_shuttingDown) { await _completeTask.Task; throw new TransportException(_inputAddress, "Transport shutdown in progress, abandoning message"); } await _receiveObserver.PreReceive(context); await _receivePipe.Send(context); await context.CompleteTask; await message.CompleteAsync(); await _receiveObserver.PostReceive(context); if (_log.IsDebugEnabled) { _log.DebugFormat("Receive completed: {0}", message.MessageId); } } catch (Exception ex) { exception = ex; if (_log.IsErrorEnabled) { _log.Error($"Received faulted: {message.MessageId}", ex); } } try { if (exception != null) { await message.AbandonAsync(); await _receiveObserver.ReceiveFault(context, exception); } } finally { int pendingCount = Interlocked.Decrement(ref _currentPendingDeliveryCount); if (pendingCount == 0 && _shuttingDown) { _completeTask.TrySetResult(this); } } }
async Task OnMessage(BrokeredMessage message) { if (_shuttingDown) { await WaitAndAbandonMessage(message).ConfigureAwait(false); return; } using (var delivery = _tracker.BeginDelivery()) { if (_log.IsDebugEnabled) { _log.DebugFormat("Receiving {0}:{1} - {2}", delivery.Id, message.MessageId, _clientSettings.Path); } var context = new ServiceBusReceiveContext(_clientContext.InputAddress, message, _context, _topology); context.GetOrAddPayload(() => _context); try { await _context.PreReceive(context).ConfigureAwait(false); if (message.LockedUntilUtc <= DateTime.UtcNow) { throw new MessageLockExpiredException(_clientContext.InputAddress, $"The message lock expired: {message.MessageId}"); } if (message.ExpiresAtUtc < DateTime.UtcNow) { throw new MessageTimeToLiveExpiredException(_clientContext.InputAddress, $"The message TTL expired: {message.MessageId}"); } await _receivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _context.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) { _log.DebugFormat("Receive completed: {0}", message.MessageId); } } catch (Exception ex) { if (_log.IsErrorEnabled) { _log.Error($"Received faulted: {message.MessageId}", ex); } await AbandonMessage(message).ConfigureAwait(false); await _context.ReceiveFault(context, ex).ConfigureAwait(false); } finally { context.Dispose(); } } }
async Task IBrokeredMessageReceiver.Handle(Message message, Action <ReceiveContext> contextCallback) { LogContext.Current = _context.LogContext; var context = new ServiceBusReceiveContext(_inputAddress, message, _context); contextCallback?.Invoke(context); context.TryGetPayload <MessageLockContext>(out var lockContext); var activity = LogContext.IfEnabled(OperationName.Transport.Receive)?.StartActivity(); activity.AddReceiveContextHeaders(context); try { if (_context.ReceiveObservers.Count > 0) { await _context.ReceiveObservers.PreReceive(context).ConfigureAwait(false); } if (message.SystemProperties.LockedUntilUtc <= DateTime.UtcNow) { throw new MessageLockExpiredException(_inputAddress, $"The message lock expired: {message.MessageId}"); } if (message.ExpiresAtUtc < DateTime.UtcNow) { throw new MessageTimeToLiveExpiredException(_inputAddress, $"The message TTL expired: {message.MessageId}"); } await _context.ReceivePipe.Send(context).ConfigureAwait(false); await context.ReceiveCompleted.ConfigureAwait(false); if (lockContext != null) { await lockContext.Complete().ConfigureAwait(false); } if (_context.ReceiveObservers.Count > 0) { await _context.ReceiveObservers.PostReceive(context).ConfigureAwait(false); } } catch (SessionLockLostException ex) { LogContext.Warning?.Log(ex, "Session Lock Lost: {MessageId", message.MessageId); if (_context.ReceiveObservers.Count > 0) { await _context.ReceiveObservers.ReceiveFault(context, ex).ConfigureAwait(false); } } catch (MessageLockLostException ex) { LogContext.Warning?.Log(ex, "Session Lock Lost: {MessageId", message.MessageId); if (_context.ReceiveObservers.Count > 0) { await _context.ReceiveObservers.ReceiveFault(context, ex).ConfigureAwait(false); } } catch (Exception ex) { if (_context.ReceiveObservers.Count > 0) { await _context.ReceiveObservers.ReceiveFault(context, ex).ConfigureAwait(false); } if (lockContext == null) { throw; } try { await lockContext.Abandon(ex).ConfigureAwait(false); } catch (Exception exception) { LogContext.Warning?.Log(exception, "Abandon message faulted: {MessageId", message.MessageId); } } finally { activity?.Stop(); context.Dispose(); } }
async Task OnMessage(BrokeredMessage message) { if (_shuttingDown) { await WaitAndAbandonMessage(message); return; } var current = Interlocked.Increment(ref _currentPendingDeliveryCount); while (current > _maxPendingDeliveryCount) Interlocked.CompareExchange(ref _maxPendingDeliveryCount, current, _maxPendingDeliveryCount); var deliveryCount = Interlocked.Increment(ref _deliveryCount); if (_log.IsDebugEnabled) _log.DebugFormat("Receiving {0}:{1} - {2}", deliveryCount, message.MessageId, _receiveSettings.QueueDescription.Path); var context = new ServiceBusReceiveContext(_inputAddress, message, _receiveObserver); try { await _receiveObserver.PreReceive(context).ConfigureAwait(false); await _receivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _receiveObserver.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) _log.DebugFormat("Receive completed: {0}", message.MessageId); } catch (Exception ex) { if (_log.IsErrorEnabled) _log.Error($"Received faulted: {message.MessageId}", ex); await message.AbandonAsync().ConfigureAwait(false); await _receiveObserver.ReceiveFault(context, ex).ConfigureAwait(false); } finally { var pendingCount = Interlocked.Decrement(ref _currentPendingDeliveryCount); if (pendingCount == 0 && _shuttingDown) { if (_log.IsDebugEnabled) _log.DebugFormat("Receiver shutdown completed: {0}", _inputAddress); _participant.SetComplete(); } } }
async Task OnMessage(BrokeredMessage message) { if (_shuttingDown) { await WaitAndAbandonMessage(message).ConfigureAwait(false); return; } var current = Interlocked.Increment(ref _currentPendingDeliveryCount); while (current > _maxPendingDeliveryCount) { Interlocked.CompareExchange(ref _maxPendingDeliveryCount, current, _maxPendingDeliveryCount); } var deliveryCount = Interlocked.Increment(ref _deliveryCount); if (_log.IsDebugEnabled) { _log.DebugFormat("Receiving {0}:{1} - {2}", deliveryCount, message.MessageId, _receiveSettings.QueueDescription.Path); } var context = new ServiceBusReceiveContext(_inputAddress, message, _receiveObserver); try { await _receiveObserver.PreReceive(context).ConfigureAwait(false); await _receivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _receiveObserver.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) { _log.DebugFormat("Receive completed: {0}", message.MessageId); } } catch (Exception ex) { if (_log.IsErrorEnabled) { _log.Error($"Received faulted: {message.MessageId}", ex); } await message.AbandonAsync().ConfigureAwait(false); await _receiveObserver.ReceiveFault(context, ex).ConfigureAwait(false); } finally { var pendingCount = Interlocked.Decrement(ref _currentPendingDeliveryCount); if (pendingCount == 0 && _shuttingDown) { if (_log.IsDebugEnabled) { _log.DebugFormat("Receiver shutdown completed: {0}", _inputAddress); } _participant.SetComplete(); } } }
public async Task Should_be_configured_and_working() { var settings = new TestAzureServiceBusAccountSettings(); var provider = new SharedAccessKeyTokenProvider(settings); TokenProvider tokenProvider = provider.GetTokenProvider(); Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", "masstransit-build", "MassTransit.AzureServiceBusTransport.Tests"); var namespaceManager = new NamespaceManager(serviceUri, tokenProvider); CreateQueue(namespaceManager, serviceUri, "TestClient"); CreateHostQueue(tokenProvider); var mfs = new MessagingFactorySettings { TokenProvider = tokenProvider, OperationTimeout = TimeSpan.FromSeconds(30), TransportType = TransportType.Amqp, AmqpTransportSettings = new AmqpTransportSettings { BatchFlushInterval = TimeSpan.FromMilliseconds(50), }, }; MessagingFactory factory = MessagingFactory.Create( ServiceBusEnvironment.CreateServiceUri("sb", "masstransit-build", Environment.MachineName), mfs); MessageReceiver receiver = await factory.CreateMessageReceiverAsync("Control"); receiver.PrefetchCount = 100; var done = new TaskCompletionSource<bool>(); int count = 0; const int limit = 1000; receiver.OnMessageAsync(async message => { var receiveContext = new ServiceBusReceiveContext(new Uri("sb://localhost/queue"), message, new ReceiveObservable()); await message.CompleteAsync(); int received = Interlocked.Increment(ref count); if (received == limit) done.TrySetResult(true); }, new OnMessageOptions { AutoComplete = false, MaxConcurrentCalls = 100, AutoRenewTimeout = TimeSpan.FromSeconds(60), }); MessageSender client = await factory.CreateMessageSenderAsync("Control"); Stopwatch stopwatch = Stopwatch.StartNew(); Task[] tasks = new Task[limit]; for (int i = 0; i < limit; i++) { tasks[i] = SendAMessage(client); } await done.Task; stopwatch.Stop(); await Task.WhenAll(tasks); await receiver.CloseAsync(); Console.WriteLine("Performance: {0:F2}/s", limit * 1000 / stopwatch.ElapsedMilliseconds); }
public MessageLockContextReceiveLock(MessageLockContext lockContext, ServiceBusReceiveContext message) { _lockContext = lockContext; _message = message; }
public async void Should_be_configured_and_working() { var settings = new TestAzureServiceBusAccountSettings(); var provider = new SharedAccessKeyTokenProvider(settings); TokenProvider tokenProvider = provider.GetTokenProvider(); Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", "masstransit-build", "MassTransit.AzureServiceBusTransport.Tests"); var namespaceManager = new NamespaceManager(serviceUri, tokenProvider); CreateQueue(namespaceManager, serviceUri, "TestClient"); CreateHostQueue(tokenProvider); var mfs = new MessagingFactorySettings { TokenProvider = tokenProvider, OperationTimeout = TimeSpan.FromSeconds(30), TransportType = TransportType.Amqp, AmqpTransportSettings = new AmqpTransportSettings { BatchFlushInterval = TimeSpan.FromMilliseconds(50), }, }; MessagingFactory factory = MessagingFactory.Create( ServiceBusEnvironment.CreateServiceUri("sb", "masstransit-build", Environment.MachineName), mfs); MessageReceiver receiver = await factory.CreateMessageReceiverAsync("Control"); receiver.PrefetchCount = 100; var done = new TaskCompletionSource <bool>(); int count = 0; const int limit = 1000; receiver.OnMessageAsync(async message => { var receiveContext = new ServiceBusReceiveContext(new Uri("sb://localhost/queue"), message, new ReceiveObservable()); await message.CompleteAsync(); int received = Interlocked.Increment(ref count); if (received == limit) { done.TrySetResult(true); } }, new OnMessageOptions { AutoComplete = false, MaxConcurrentCalls = 100, AutoRenewTimeout = TimeSpan.FromSeconds(60), }); MessageSender client = await factory.CreateMessageSenderAsync("Control"); Stopwatch stopwatch = Stopwatch.StartNew(); Task[] tasks = new Task[limit]; for (int i = 0; i < limit; i++) { tasks[i] = SendAMessage(client); } await done.Task; stopwatch.Stop(); await Task.WhenAll(tasks); await receiver.CloseAsync(); Console.WriteLine("Performance: {0:F2}/s", limit * 1000 / stopwatch.ElapsedMilliseconds); }
async Task OnMessage(BrokeredMessage message) { int current = Interlocked.Increment(ref _currentPendingDeliveryCount); while (current > _maxPendingDeliveryCount) Interlocked.CompareExchange(ref _maxPendingDeliveryCount, current, _maxPendingDeliveryCount); long deliveryCount = Interlocked.Increment(ref _deliveryCount); if (_log.IsDebugEnabled) _log.DebugFormat("Receiving {0}:{1} - {2}", deliveryCount, message.MessageId, _receiveSettings.QueueDescription.Path); var context = new ServiceBusReceiveContext(_inputAddress, message, _receiveObserver); try { if (_shuttingDown) { await _completeTask.Task.ConfigureAwait(false); throw new TransportException(_inputAddress, "Transport shutdown in progress, abandoning message"); } await _receiveObserver.PreReceive(context).ConfigureAwait(false); await _receivePipe.Send(context).ConfigureAwait(false); await context.CompleteTask.ConfigureAwait(false); await message.CompleteAsync().ConfigureAwait(false); await _receiveObserver.PostReceive(context).ConfigureAwait(false); if (_log.IsDebugEnabled) _log.DebugFormat("Receive completed: {0}", message.MessageId); } catch (Exception ex) { if (_log.IsErrorEnabled) _log.Error($"Received faulted: {message.MessageId}", ex); await message.AbandonAsync().ConfigureAwait(false); await _receiveObserver.ReceiveFault(context, ex).ConfigureAwait(false); } finally { int pendingCount = Interlocked.Decrement(ref _currentPendingDeliveryCount); if (pendingCount == 0 && _shuttingDown) _completeTask.TrySetResult(this); } }