Exemplo n.º 1
0
        /// <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);
            }
        }
Exemplo n.º 2
0
        /// <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);
            }
        }