public async Task ProducerCannotSendWhenClosed(bool sync) { await using (EventHubScope scope = await EventHubScope.CreateAsync(1)) { var connectionString = TestEnvironment.BuildConnectionStringForEventHub(scope.EventHubName); await using (var client = new EventHubClient(connectionString)) await using (EventHubProducer producer = client.CreateProducer()) { EventData[] events = new[] { new EventData(Encoding.UTF8.GetBytes("Dummy event")) }; Assert.That(async() => await producer.SendAsync(events), Throws.Nothing); if (sync) { producer.Close(); } else { await producer.CloseAsync(); } Assert.That(async() => await producer.SendAsync(events), Throws.TypeOf <EventHubsClientClosedException>().Or.TypeOf <ObjectDisposedException>()); } } }
public async Task CloseAsyncClosesTheTransportProducer() { var transportProducer = new ObservableTransportProducerMock(); var producer = new EventHubProducer(transportProducer, "dummy", new EventHubProducerOptions(), Mock.Of <EventHubRetryPolicy>()); await producer.CloseAsync(); Assert.That(transportProducer.WasCloseCalled, Is.True); }
/// <summary> /// Closes the producers in the pool and performs any cleanup necessary /// for resources used by the <see cref="TransportProducerPool" />. /// </summary> /// /// <returns>A task to be resolved on when the operation has completed.</returns> /// public virtual async Task CloseAsync(CancellationToken cancellationToken = default) { try { ExpirationTimer.Dispose(); } catch (Exception) { } var pendingCloses = new List <Task>(); pendingCloses.Add(EventHubProducer.CloseAsync(cancellationToken)); foreach (var poolItem in Pool.Values) { pendingCloses.Add(poolItem.PartitionProducer.CloseAsync(cancellationToken)); } Pool.Clear(); await Task.WhenAll(pendingCloses).ConfigureAwait(false); }
/// <summary> /// Closes the producer. /// </summary> /// /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A task to be resolved on when the operation has completed.</returns> /// public virtual async Task CloseAsync(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); if (IsClosed) { return; } IsClosed = true; var identifier = GetHashCode().ToString(); EventHubsEventSource.Log.ClientCloseStart(typeof(EventHubProducerClient), EventHubName, identifier); // Attempt to close the active transport producers. In the event that an exception is encountered, // it should not impact the attempt to close the connection, assuming ownership. var transportProducerException = default(Exception); try { await EventHubProducer.CloseAsync(cancellationToken).ConfigureAwait(false); var pendingCloses = new List <Task>(); foreach (var producer in PartitionProducers.Values) { pendingCloses.Add(producer.CloseAsync(CancellationToken.None)); } PartitionProducers.Clear(); await Task.WhenAll(pendingCloses).ConfigureAwait(false); } catch (Exception ex) { EventHubsEventSource.Log.ClientCloseError(typeof(EventHubProducerClient), EventHubName, identifier, ex.Message); transportProducerException = ex; } // An exception when closing the connection supersedes one observed when closing the // individual transport clients. try { if (OwnsConnection) { await Connection.CloseAsync().ConfigureAwait(false); } } catch (Exception ex) { EventHubsEventSource.Log.ClientCloseError(typeof(EventHubProducerClient), EventHubName, identifier, ex.Message); throw; } finally { EventHubsEventSource.Log.ClientCloseComplete(typeof(EventHubProducerClient), EventHubName, identifier); } // If there was an active exception pending from closing the individual // transport producers, surface it now. if (transportProducerException != default) { ExceptionDispatchInfo.Capture(transportProducerException).Throw(); } }