private async Task ProcessMessages(ReceiverContext receiverContext) { TimeSpan backoffAmount = _backoffTime; while (!_cts.IsCancellationRequested) { try { var messages = await receiverContext.Receiver.ReceiveBatchAsync( ReceiverContext.ReceiveBatchSize, receiverContext.ReceiveTimeout); receiverContext.OnMessage(messages); // Reset the receive timeout if it changed receiverContext.ReceiveTimeout = DefaultReadTimeout; continue; } catch (OperationCanceledException) { // This means the channel is closed _trace.TraceError("Receiving messages from the service bus threw an OperationCanceledException, most likely due to a closed channel."); return; } catch (MessagingEntityNotFoundException ex) { try { await receiverContext.Receiver.CloseAsync(); } catch { } receiverContext.OnError(ex); var ignored = TryCreateSubscription(receiverContext); return; } catch (ServerBusyException ex) { receiverContext.OnError(ex); } catch (Exception ex) { receiverContext.OnError(ex); // TODO: Exponential backoff backoffAmount = ErrorBackOffAmount; // After an error, we want to adjust the timeout so that we // can recover as quickly as possible even if there's no message receiverContext.ReceiveTimeout = ErrorReadTimeout; } // back off for ServerBusyException and other exceptions not handled is a specific way await Task.Delay(backoffAmount); } }
private bool ContinueReceiving(IAsyncResult asyncResult, ReceiverContext receiverContext) { bool shouldContinue = true; TimeSpan backoffAmount = BackoffAmount; try { IEnumerable <BrokeredMessage> messages = receiverContext.Receiver.EndReceiveBatch(asyncResult); receiverContext.OnMessage(messages); // Reset the receive timeout if it changed receiverContext.ReceiveTimeout = DefaultReadTimeout; } catch (ServerBusyException ex) { receiverContext.OnError(ex); // Too busy so back off shouldContinue = false; } catch (OperationCanceledException) { // This means the channel is closed _trace.TraceError("Receiving messages from the service bus threw an OperationCanceledException, most likely due to a closed channel."); return(false); } catch (Exception ex) { receiverContext.OnError(ex); shouldContinue = false; // TODO: Exponential backoff backoffAmount = ErrorBackOffAmount; // After an error, we want to adjust the timeout so that we // can recover as quickly as possible even if there's no message receiverContext.ReceiveTimeout = ErrorReadTimeout; } if (!shouldContinue) { TaskAsyncHelper.Delay(backoffAmount) .Then(ctx => ProcessMessages(ctx), receiverContext); return(false); } return(true); }
private bool ContinueReceiving(IAsyncResult asyncResult, ReceiverContext receiverContext) { bool shouldContinue = true; TimeSpan backoffAmount = BackoffAmount; try { IEnumerable<BrokeredMessage> messages = receiverContext.Receiver.EndReceiveBatch(asyncResult); receiverContext.OnMessage(messages); // Reset the receive timeout if it changed receiverContext.ReceiveTimeout = DefaultReadTimeout; } catch (ServerBusyException ex) { receiverContext.OnError(ex); // Too busy so back off shouldContinue = false; } catch (OperationCanceledException) { // This means the channel is closed _trace.TraceError("Receiving messages from the service bus threw an OperationCanceledException, most likely due to a closed channel."); return false; } catch (MessagingEntityNotFoundException ex) { receiverContext.Receiver.CloseAsync().Catch(); receiverContext.OnError(ex); TaskAsyncHelper.Delay(RetryDelay) .Then(() => Retry(() => CreateSubscription(receiverContext.ConnectionContext, receiverContext.TopicIndex))); return false; } catch (Exception ex) { receiverContext.OnError(ex); shouldContinue = false; // TODO: Exponential backoff backoffAmount = ErrorBackOffAmount; // After an error, we want to adjust the timeout so that we // can recover as quickly as possible even if there's no message receiverContext.ReceiveTimeout = ErrorReadTimeout; } if (!shouldContinue) { TaskAsyncHelper.Delay(backoffAmount) .Then(ctx => ProcessMessages(ctx), receiverContext); return false; } return true; }
private bool ContinueReceiving(IAsyncResult asyncResult, ReceiverContext receiverContext) { bool shouldContinue = true; TimeSpan backoffAmount = BackoffAmount; try { IEnumerable<BrokeredMessage> messages = receiverContext.Receiver.EndReceiveBatch(asyncResult); receiverContext.OnMessage(messages); // Reset the receive timeout if it changed receiverContext.ReceiveTimeout = DefaultReadTimeout; } catch (ServerBusyException ex) { receiverContext.OnError(ex); // Too busy so back off shouldContinue = false; } catch (OperationCanceledException) { // This means the channel is closed return false; } catch (Exception ex) { receiverContext.OnError(ex); shouldContinue = false; // TODO: Exponential backoff backoffAmount = ErrorBackOffAmount; // After an error, we want to adjust the timeout so that we // can recover as quickly as possible even if there's no message receiverContext.ReceiveTimeout = ErrorReadTimeout; } if (!shouldContinue) { TaskAsyncHelper.Delay(backoffAmount) .Then(ctx => ProcessMessages(ctx), receiverContext); return false; } return true; }
private bool ContinueReceiving(IAsyncResult asyncResult, ReceiverContext receiverContext) { bool shouldContinue = true; TimeSpan backoffAmount = _backoffTime; try { IEnumerable <BrokeredMessage> messages = receiverContext.Receiver.EndReceiveBatch(asyncResult); receiverContext.OnMessage(messages); // Reset the receive timeout if it changed receiverContext.ReceiveTimeout = DefaultReadTimeout; } catch (ServerBusyException ex) { receiverContext.OnError(ex); // Too busy so back off shouldContinue = false; } catch (OperationCanceledException) { // This means the channel is closed _logger.LogError("Receiving messages from the service bus threw an OperationCanceledException, most likely due to a closed channel."); return(false); } catch (MessagingEntityNotFoundException ex) { receiverContext.Receiver.CloseAsync() .ContinueWith(t => _logger.LogInformation("{0}", t.Exception.ToString()), TaskContinuationOptions.OnlyOnFaulted); receiverContext.OnError(ex); Task.Run(async() => { await Task.Delay(RetryDelay); Retry(() => CreateSubscription(receiverContext.ConnectionContext, receiverContext.TopicIndex)); }); return(false); } catch (Exception ex) { receiverContext.OnError(ex); shouldContinue = false; // TODO: Exponential backoff backoffAmount = ErrorBackOffAmount; // After an error, we want to adjust the timeout so that we // can recover as quickly as possible even if there's no message receiverContext.ReceiveTimeout = ErrorReadTimeout; } if (!shouldContinue) { Task.Run(async() => { await Task.Delay(backoffAmount); ProcessMessages(receiverContext); }); return(false); } return(true); }