/// <summary> /// Retrieves information about a specific partition for an Event Hub, including elements that describe the available /// events in the partition event stream. /// </summary> /// /// <param name="partitionId">The unique identifier of a partition associated with the Event Hub.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>The set of information for the requested partition under the Event Hub this client is associated with.</returns> /// public override async Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId, CancellationToken cancellationToken) { Guard.ArgumentNotNullOrEmpty(nameof(partitionId), partitionId); // Since the AMQP objects do not honor the cancellation token, manually check for cancellation between operation steps. cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); try { EventHubsEventSource.Log.GetPartitionPropertiesStart(EventHubName, partitionId); // Create the request message and the management link. var token = await AquireAccessTokenAsync(cancellationToken).ConfigureAwait(false); using var request = MessageConverter.CreatePartitionPropertiesRequest(EventHubName, partitionId, token); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var stopWatch = Stopwatch.StartNew(); var link = await ManagementLink.GetOrCreateAsync(_tryTimeout).ConfigureAwait(false); // Send the request and wait for the response. stopWatch.Stop(); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); using var response = await link.RequestAsync(request, _tryTimeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); // Process the response. cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); ThrowIfErrorResponse(response, EventHubName); return(MessageConverter.CreatePartitionPropertiesFromResponse(response)); } catch (Exception ex) { EventHubsEventSource.Log.GetPartitionPropertiesError(EventHubName, partitionId, ex.Message); throw; } finally { EventHubsEventSource.Log.GetPartitionPropertiesComplete(EventHubName, partitionId); } }
/// <summary> /// Retrieves information about a specific partition for an Event Hub, including elements that describe the available /// events in the partition event stream. /// </summary> /// /// <param name="partitionId">The unique identifier of a partition associated with the Event Hub.</param> /// <param name="retryPolicy">The retry policy to use as the basis for retrieving the information.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>The set of information for the requested partition under the Event Hub this client is associated with.</returns> /// public override async Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId, EventHubRetryPolicy retryPolicy, CancellationToken cancellationToken) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); Argument.AssertNotNullOrEmpty(partitionId, nameof(partitionId)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); var failedAttemptCount = 0; var retryDelay = default(TimeSpan?); var token = default(string); var link = default(RequestResponseAmqpLink); var stopWatch = Stopwatch.StartNew(); try { var tryTimeout = retryPolicy.CalculateTryTimeout(0); while (!cancellationToken.IsCancellationRequested) { try { EventHubsEventSource.Log.GetPartitionPropertiesStart(EventHubName, partitionId); // Create the request message and the management link. token = await AquireAccessTokenAsync(cancellationToken).ConfigureAwait(false); using AmqpMessage request = MessageConverter.CreatePartitionPropertiesRequest(EventHubName, partitionId, token); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); link = await ManagementLink.GetOrCreateAsync(UseMinimum(ConnectionScope.SessionTimeout, tryTimeout.CalculateRemaining(stopWatch.Elapsed))).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Send the request and wait for the response. using AmqpMessage response = await link.RequestAsync(request, tryTimeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); stopWatch.Stop(); // Process the response. AmqpError.ThrowIfErrorResponse(response, EventHubName); return(MessageConverter.CreatePartitionPropertiesFromResponse(response)); } catch (Exception ex) { // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop. // Otherwise, mark the exception as active and break out of the loop. ++failedAttemptCount; retryDelay = retryPolicy.CalculateRetryDelay(ex, failedAttemptCount); if ((retryDelay.HasValue) && (!ConnectionScope.IsDisposed) && (!cancellationToken.IsCancellationRequested)) { EventHubsEventSource.Log.GetPartitionPropertiesError(EventHubName, partitionId, ex.Message); await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false); tryTimeout = retryPolicy.CalculateTryTimeout(failedAttemptCount); stopWatch.Reset(); } else { throw; } } } // If no value has been returned nor exception thrown by this point, // then cancellation has been requested. throw new TaskCanceledException(); } catch (Exception ex) { EventHubsEventSource.Log.GetPartitionPropertiesError(EventHubName, partitionId, ex.Message); throw; } finally { stopWatch.Stop(); EventHubsEventSource.Log.GetPartitionPropertiesComplete(EventHubName, partitionId); } }