private async Task PerformEnqueue(EventHubBufferedProducerClient producer, CancellationToken cancellationToken) { var events = EventGenerator.CreateEvents(_testConfiguration.MaximumEventListSize, _testConfiguration.EventEnqueueListSize, _testConfiguration.LargeMessageRandomFactorPercent, _testConfiguration.PublishingBodyMinBytes, _testConfiguration.PublishingBodyRegularMaxBytes); try { await producer.EnqueueEventsAsync(events, cancellationToken).ConfigureAwait(false); _metrics.Client.GetMetric(_metrics.EventsEnqueued).TrackValue(_testConfiguration.EventEnqueueListSize); } catch (TaskCanceledException) { // Run is completed. } catch (Exception ex) { var eventProperties = new Dictionary <String, String>(); // Track that the exception took place during the enqueuing of an event eventProperties.Add("Process", "Enqueue"); _metrics.Client.TrackException(ex, eventProperties); } }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// This setup will take place once for each instance, running after the global setup has /// completed. /// </summary> /// public override async Task SetupAsync() { await base.SetupAsync(); Scope = await EventHubScope.CreateAsync(Options.PartitionCount).ConfigureAwait(false); var producerOptions = new EventHubBufferedProducerClientOptions { MaximumWaitTime = (Options.MaximumWaitTimeMilliseconds.HasValue) ? TimeSpan.FromMilliseconds(Options.MaximumWaitTimeMilliseconds.Value) : null, MaximumEventBufferLengthPerPartition = Options.MaximumBufferLength, MaximumConcurrentSendsPerPartition = Options.MaximumConcurrentSendsPerPartition }; if (Options.MaximumConcurrentSends.HasValue) { producerOptions.MaximumConcurrentSends = Options.MaximumConcurrentSends.Value; } _producer = new EventHubBufferedProducerClient(TestEnvironment.EventHubsConnectionString, Scope.EventHubName, producerOptions); // Create the handlers that call into the performance test infrastructure to // report when errors and events are observed. _producer.SendEventBatchFailedAsync += args => { // Do not flag cancellation as a failure; it is expected for in-flight batches when // the test run is cleaning up. if (!typeof(OperationCanceledException).IsAssignableFrom(args.Exception.GetType())) { ErrorRaised(args.Exception); } return(Task.CompletedTask); }; _producer.SendEventBatchSucceededAsync += args => { for (var index = 0; index < args.EventBatch.Count; ++index) { EventRaised(); } return(Task.CompletedTask); }; // Read the available partitions and buffer a single events to establish the // connection and link and start reading the buffers. Partitions = await _producer.GetPartitionIdsAsync().ConfigureAwait(false); await _producer.EnqueueEventsAsync(EventGenerator.CreateEvents(1)).ConfigureAwait(false); // Start the background publishing task. _backgroundCancellationSource = new CancellationTokenSource(); _backgroundBufferingTask = EnqueueEvents(_backgroundCancellationSource.Token); }
/// <summary> /// Enqueues events into the buffer to be published. /// </summary> /// /// <param name="testOptions">The set of options governing test execution.</param> /// private async Task EnqueueEvents(CancellationToken cancellationToken) { var eventBody = EventGenerator.CreateRandomBody(Options.BodySize); try { while (!cancellationToken.IsCancellationRequested) { var enqueueOptions = CreateEnqueueOptions(); // Generate events using the same body. This will result in publishing a set of events // of equal size. The events will only differ by the id property that is assigned to them. if (Options.BatchSize > 1) { await _producer.EnqueueEventsAsync(EventGenerator.CreateEventsFromBody(Options.BatchSize, eventBody), enqueueOptions, cancellationToken).ConfigureAwait(false); } else { await _producer.EnqueueEventAsync(EventGenerator.CreateEventFromBody(eventBody), enqueueOptions, cancellationToken).ConfigureAwait(false); } } } catch (OperationCanceledException) { // Expected } catch (EventHubsException ex) when((cancellationToken.IsCancellationRequested) && (ex.IsTransient)) { // If the enqueue is canceled during a retry loop, the most recent exception is thrown. // If the exception is transient, it should be ignored. } catch (Exception ex) { ErrorRaised(ex); } }