protected override async Task OnSendAsync(IEnumerable <EventData> eventDatas, string partitionKey) { bool shouldRetry; int retryCount = 0; var timeoutHelper = new TimeoutHelper(EventHubClient.ConnectionStringBuilder.OperationTimeout, startTimeout: true); do { using (AmqpMessage amqpMessage = AmqpMessageConverter.EventDatasToAmqpMessage(eventDatas, partitionKey)) { shouldRetry = false; try { try { // Always use default timeout for AMQP sesssion. SendingAmqpLink amqpLink = await SendLinkManager.GetOrCreateAsync( TimeSpan.FromSeconds(AmqpClientConstants.AmqpSessionTimeoutInSeconds)).ConfigureAwait(false); if (amqpLink.Settings.MaxMessageSize.HasValue) { ulong size = (ulong)amqpMessage.SerializedMessageSize; if (size > amqpLink.Settings.MaxMessageSize.Value) { throw new MessageSizeExceededException(amqpMessage.DeliveryId.Value, size, amqpLink.Settings.MaxMessageSize.Value); } } Outcome outcome = await amqpLink.SendMessageAsync( amqpMessage, GetNextDeliveryTag(), AmqpConstants.NullBinary, timeoutHelper.RemainingTime()).ConfigureAwait(false); if (outcome.DescriptorCode != Accepted.Code) { Rejected rejected = (Rejected)outcome; throw new AmqpException(rejected.Error); } } catch (AmqpException amqpException) { throw AmqpExceptionHelper.ToMessagingContract(amqpException.Error); } } catch (Exception ex) { // Evaluate retry condition? TimeSpan?retryInterval = RetryPolicy.GetNextRetryInterval(ex, timeoutHelper.RemainingTime(), ++retryCount); if (retryInterval != null && !EventHubClient.CloseCalled) { await Task.Delay(retryInterval.Value).ConfigureAwait(false); shouldRetry = true; } else { throw; } } } } while (shouldRetry); }
public void ValidateRetryPolicyBuiltIn() { int retryCount = 0; RetryPolicy retry = RetryPolicy.Default; TimeSpan?firstRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("firstRetryInterval: " + firstRetryInterval); Assert.True(firstRetryInterval != null); TimeSpan?secondRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("secondRetryInterval: " + secondRetryInterval); Assert.True(secondRetryInterval != null); Assert.True(secondRetryInterval?.TotalMilliseconds > firstRetryInterval?.TotalMilliseconds); TimeSpan?thirdRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("thirdRetryInterval: " + thirdRetryInterval); Assert.True(thirdRetryInterval != null); Assert.True(thirdRetryInterval?.TotalMilliseconds > secondRetryInterval?.TotalMilliseconds); TimeSpan?fourthRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("fourthRetryInterval: " + fourthRetryInterval); Assert.True(fourthRetryInterval != null); Assert.True(fourthRetryInterval?.TotalMilliseconds > thirdRetryInterval?.TotalMilliseconds); TimeSpan?fifthRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("fifthRetryInterval: " + fifthRetryInterval); Assert.True(fifthRetryInterval != null); Assert.True(fifthRetryInterval?.TotalMilliseconds > fourthRetryInterval?.TotalMilliseconds); TimeSpan?sixthRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("sixthRetryInterval: " + sixthRetryInterval); Assert.True(sixthRetryInterval != null); Assert.True(sixthRetryInterval?.TotalMilliseconds > fifthRetryInterval?.TotalMilliseconds); TimeSpan?seventhRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); TestUtility.Log("seventhRetryInterval: " + seventhRetryInterval); Assert.True(seventhRetryInterval != null); Assert.True(seventhRetryInterval?.TotalMilliseconds > sixthRetryInterval?.TotalMilliseconds); TimeSpan?nextRetryInterval = retry.GetNextRetryInterval(new EventHubsException(false), TimeSpan.FromSeconds(60), ++retryCount); Assert.True(nextRetryInterval == null); retryCount = 0; TimeSpan?firstRetryIntervalAfterReset = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); Assert.True(firstRetryInterval.Equals(firstRetryIntervalAfterReset)); retry = RetryPolicy.NoRetry; TimeSpan?noRetryInterval = retry.GetNextRetryInterval(new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60), ++retryCount); Assert.True(noRetryInterval == null); }
void ValidateRetryPolicyBuiltIn() { String clientId = "someClientEntity"; RetryPolicy retry = RetryPolicy.Default; retry.IncrementRetryCount(clientId); TimeSpan?firstRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("firstRetryInterval: " + firstRetryInterval); Assert.True(firstRetryInterval != null); retry.IncrementRetryCount(clientId); TimeSpan?secondRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("secondRetryInterval: " + secondRetryInterval); Assert.True(secondRetryInterval != null); Assert.True(secondRetryInterval?.TotalMilliseconds > firstRetryInterval?.TotalMilliseconds); retry.IncrementRetryCount(clientId); TimeSpan?thirdRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("thirdRetryInterval: " + thirdRetryInterval); Assert.True(thirdRetryInterval != null); Assert.True(thirdRetryInterval?.TotalMilliseconds > secondRetryInterval?.TotalMilliseconds); retry.IncrementRetryCount(clientId); TimeSpan?fourthRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("fourthRetryInterval: " + fourthRetryInterval); Assert.True(fourthRetryInterval != null); Assert.True(fourthRetryInterval?.TotalMilliseconds > thirdRetryInterval?.TotalMilliseconds); retry.IncrementRetryCount(clientId); TimeSpan?fifthRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("fifthRetryInterval: " + fifthRetryInterval); Assert.True(fifthRetryInterval != null); Assert.True(fifthRetryInterval?.TotalMilliseconds > fourthRetryInterval?.TotalMilliseconds); retry.IncrementRetryCount(clientId); TimeSpan?sixthRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("sixthRetryInterval: " + sixthRetryInterval); Assert.True(sixthRetryInterval != null); Assert.True(sixthRetryInterval?.TotalMilliseconds > fifthRetryInterval?.TotalMilliseconds); retry.IncrementRetryCount(clientId); TimeSpan?seventhRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Log("seventhRetryInterval: " + seventhRetryInterval); Assert.True(seventhRetryInterval != null); Assert.True(seventhRetryInterval?.TotalMilliseconds > sixthRetryInterval?.TotalMilliseconds); retry.IncrementRetryCount(clientId); TimeSpan?nextRetryInterval = retry.GetNextRetryInterval(clientId, new EventHubsException(false), TimeSpan.FromSeconds(60)); Assert.True(nextRetryInterval == null); retry.ResetRetryCount(clientId); retry.IncrementRetryCount(clientId); TimeSpan?firstRetryIntervalAfterReset = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Assert.True(firstRetryInterval.Equals(firstRetryIntervalAfterReset)); retry = RetryPolicy.NoRetry; retry.IncrementRetryCount(clientId); TimeSpan?noRetryInterval = retry.GetNextRetryInterval(clientId, new ServerBusyException(string.Empty), TimeSpan.FromSeconds(60)); Assert.True(noRetryInterval == null); }
protected override async Task <IList <EventData> > OnReceiveAsync(int maxMessageCount, TimeSpan waitTime) { bool shouldRetry; int retryCount = 0; var timeoutHelper = new TimeoutHelper(waitTime, true); do { shouldRetry = false; try { try { // Always use default timeout for AMQP sesssion. ReceivingAmqpLink receiveLink = await ReceiveLinkManager.GetOrCreateAsync( TimeSpan.FromSeconds(AmqpClientConstants.AmqpSessionTimeoutInSeconds)).ConfigureAwait(false); IEnumerable <AmqpMessage> amqpMessages = null; bool hasMessages = await Task.Factory.FromAsync( (c, s) => receiveLink.BeginReceiveMessages(maxMessageCount, timeoutHelper.RemainingTime(), c, s), a => receiveLink.EndReceiveMessages(a, out amqpMessages), this).ConfigureAwait(false); if (receiveLink.TerminalException != null) { throw receiveLink.TerminalException; } if (hasMessages && amqpMessages != null) { IList <EventData> eventDatas = null; foreach (AmqpMessage amqpMessage in amqpMessages) { if (eventDatas == null) { eventDatas = new List <EventData>(); } receiveLink.DisposeDelivery(amqpMessage, true, AmqpConstants.AcceptedOutcome); eventDatas.Add(AmqpMessageConverter.AmqpMessageToEventData(amqpMessage)); } return(eventDatas); } } catch (AmqpException amqpException) { throw AmqpExceptionHelper.ToMessagingContract(amqpException.Error); } } catch (Exception ex) { // Evaluate retry condition? TimeSpan?retryInterval = RetryPolicy.GetNextRetryInterval(ex, timeoutHelper.RemainingTime(), ++retryCount); if (retryInterval != null && !EventHubClient.CloseCalled) { await Task.Delay(retryInterval.Value).ConfigureAwait(false); shouldRetry = true; } else { // Handle EventHubsTimeoutException explicitly. // We don't really want to to throw EventHubsTimeoutException on this call. if (ex is EventHubsTimeoutException) { break; } throw; } } } while (shouldRetry); // No messages to deliver. return(null); }