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 this.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 (var 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) { if (AmqpExceptionHelper.TryTranslateToRetriableException(ex, out var retriableEx)) { throw retriableEx; } throw; } } catch (Exception ex) { // Evaluate retry condition? TimeSpan?retryInterval = this.RetryPolicy.GetNextRetryInterval(ex, timeoutHelper.RemainingTime(), ++retryCount); if (retryInterval != null && !this.IsClosed && !this.EventHubClient.IsClosed) { await Task.Delay(retryInterval.Value).ConfigureAwait(false); shouldRetry = true; } else { // Handle EventHubsTimeoutException explicitly. // We don't really want to throw EventHubsTimeoutException on this call. if (ex is EventHubsTimeoutException) { break; } throw; } } } while (shouldRetry); // No messages to deliver. return(null); }
protected override async Task OnSendAsync(IEnumerable <EventData> eventDatas, string partitionKey) { bool shouldRetry; int retryCount = 0; var timeoutHelper = new TimeoutHelper(this.EventHubClient.ConnectionStringBuilder.OperationTimeout, startTimeout: true); do { using (AmqpMessage amqpMessage = AmqpMessageConverter.EventDatasToAmqpMessage(eventDatas, partitionKey)) { shouldRetry = false; try { try { // Always use default timeout for AMQP sesssion. var amqpLink = await this.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, this.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) { if (AmqpExceptionHelper.TryTranslateToRetriableException(ex, out var retriableEx)) { throw retriableEx; } throw; } } catch (Exception ex) { // Evaluate retry condition? TimeSpan?retryInterval = this.RetryPolicy.GetNextRetryInterval(ex, timeoutHelper.RemainingTime(), ++retryCount); if (retryInterval != null && !this.IsClosed && !this.EventHubClient.IsClosed) { await Task.Delay(retryInterval.Value).ConfigureAwait(false); shouldRetry = true; } else { throw; } } } } while (shouldRetry); }