Exemple #1
0
        public async Task BufferedConfiguration()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample04_BufferedConfiguration

#if SNIPPET
            var connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName     = "<< NAME OF THE EVENT HUB >>";
#else
            var connectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName     = scope.EventHubName;
#endif

            var options = new EventHubBufferedProducerClientOptions
            {
                MaximumWaitTime                      = TimeSpan.FromSeconds(1),
                MaximumConcurrentSends               = 5,
                MaximumConcurrentSendsPerPartition   = 1,
                MaximumEventBufferLengthPerPartition = 5000,
                EnableIdempotentRetries              = true
            };

            var producer = new EventHubBufferedProducerClient(connectionString, eventHubName, options);

            // The failure handler is required and invoked after all allowable
            // retries were applied.

            producer.SendEventBatchFailedAsync += args =>
            {
                Debug.WriteLine($"Publishing failed for { args.EventBatch.Count } events.  Error: '{ args.Exception.Message }'");
                return(Task.CompletedTask);
            };

            // The success handler is optional.

            producer.SendEventBatchSucceededAsync += args =>
            {
                Debug.WriteLine($"{ args.EventBatch.Count } events were published to partition: '{ args.PartitionId }.");
                return(Task.CompletedTask);
            };

            try
            {
                for (var index = 0; index < 5; ++index)
                {
                    var eventData = new EventData($"Event #{ index }");
                    await producer.EnqueueEventAsync(eventData);
                }
            }
            finally
            {
                // Closing the producer will flush any
                // enqueued events that have not been published.

                await producer.CloseAsync();
            }

            #endregion
        }
        public async Task PartitionIdBuffered()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample04_PartitionIdBuffered

#if SNIPPET
            var connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName     = "<< NAME OF THE EVENT HUB >>";
#else
            var connectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName     = scope.EventHubName;
#endif

            var producer = new EventHubBufferedProducerClient(connectionString, eventHubName);

            // The failure handler is required and invoked after all allowable
            // retries were applied.

            producer.SendEventBatchFailedAsync += args =>
            {
                Debug.WriteLine($"Publishing failed for { args.EventBatch.Count } events.  Error: '{ args.Exception.Message }'");
                return(Task.CompletedTask);
            };

            // The success handler is optional.

            producer.SendEventBatchSucceededAsync += args =>
            {
                Debug.WriteLine($"{ args.EventBatch.Count } events were published to partition: '{ args.PartitionId }.");
                return(Task.CompletedTask);
            };

            try
            {
                string firstPartition = (await producer.GetPartitionIdsAsync()).First();

                var enqueueOptions = new EnqueueEventOptions
                {
                    PartitionId = firstPartition
                };

                for (var index = 0; index < 5; ++index)
                {
                    var eventData = new EventData($"Event #{ index }");
                    await producer.EnqueueEventAsync(eventData, enqueueOptions);
                }
            }
            finally
            {
                // Closing the producer will flush any
                // enqueued events that have not been published.

                await producer.CloseAsync();
            }

            #endregion
        }
        public async Task CloseAsyncClosesTheProducer()
        {
            using var cancellationSource = new CancellationTokenSource();

            var mockProducer = new Mock <EventHubProducerClient>("fakeNS", "fakeHub", Mock.Of <TokenCredential>(), new EventHubProducerClientOptions {
                Identifier = "abc123"
            });
            var bufferedProducer = new EventHubBufferedProducerClient(mockProducer.Object);

            await bufferedProducer.CloseAsync(false, cancellationSource.Token);

            mockProducer.Verify(producer => producer.CloseAsync(CancellationToken.None), Times.Once);
        }
Exemple #4
0
        /// <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 before the global cleanup is
        ///   run.
        /// </summary>
        ///

        public override async Task CleanupAsync()
        {
            // Close without flushing; by this point all expected events were sent.

            _backgroundCancellationSource?.Cancel();

            try
            {
                if (_backgroundBufferingTask != null)
                {
                    try
                    {
                        await _backgroundBufferingTask.ConfigureAwait(false);
                    }
                    catch (OperationCanceledException)
                    {
                        // Expected
                    }
                }

                if (_producer != null)
                {
                    try
                    {
                        await _producer.CloseAsync(false).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException)
                    {
                        // Expected
                    }
                }
            }
            finally
            {
                if (Scope != null)
                {
                    await Scope.DisposeAsync().ConfigureAwait(false);
                }
            }

            await base.CleanupAsync().ConfigureAwait(false);
        }
        public async Task CloseAsyncUnregistersTheEventHandlers()
        {
            using var cancellationSource = new CancellationTokenSource();

            var mockProducer = new Mock <EventHubProducerClient>("fakeNS", "fakeHub", Mock.Of <TokenCredential>(), new EventHubProducerClientOptions {
                Identifier = "abc123"
            });
            var bufferedProducer = new EventHubBufferedProducerClient(mockProducer.Object);

            Func <SendEventBatchSucceededEventArgs, Task> successHandler = args => Task.CompletedTask;
            Func <SendEventBatchFailedEventArgs, Task>    failHandler    = args => Task.CompletedTask;

            bufferedProducer.SendEventBatchSucceededAsync += successHandler;
            bufferedProducer.SendEventBatchFailedAsync    += failHandler;

            await bufferedProducer.CloseAsync(false, cancellationSource.Token);

            // The handlers should have been unregistered; attempting to do so again should cause
            // an exception.

            Assert.That(() => bufferedProducer.SendEventBatchSucceededAsync -= successHandler, Throws.InstanceOf <ArgumentException>(), "The success handler should have already been unregistered.");
            Assert.That(() => bufferedProducer.SendEventBatchFailedAsync    -= failHandler, Throws.InstanceOf <ArgumentException>(), "The failure handler should have already been unregistered.");
        }
        public async Task CustomMetadata()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample04_CustomMetadata

#if SNIPPET
            var connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName     = "<< NAME OF THE EVENT HUB >>";
#else
            var connectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName     = scope.EventHubName;
#endif

            var producer = new EventHubBufferedProducerClient(connectionString, eventHubName);

            // The failure handler is required and invoked after all allowable
            // retries were applied.

            producer.SendEventBatchFailedAsync += args =>
            {
                Debug.WriteLine($"Publishing failed for { args.EventBatch.Count } events.  Error: '{ args.Exception.Message }'");
                return(Task.CompletedTask);
            };

            // The success handler is optional.

            producer.SendEventBatchSucceededAsync += args =>
            {
                Debug.WriteLine($"{ args.EventBatch.Count } events were published to partition: '{ args.PartitionId }.");
                return(Task.CompletedTask);
            };

            try
            {
                var eventData = new EventData("Hello, Event Hubs!")
                {
                    MessageId   = "H1",
                    ContentType = "application/json"
                };

                eventData.Properties.Add("EventType", "com.microsoft.samples.hello-event");
                eventData.Properties.Add("priority", 1);
                eventData.Properties.Add("score", 9.0);

                await producer.EnqueueEventAsync(eventData);

                eventData = new EventData("Goodbye, Event Hubs!")
                {
                    MessageId   = "G1",
                    ContentType = "application/json"
                };

                eventData.Properties.Add("EventType", "com.microsoft.samples.goodbye-event");
                eventData.Properties.Add("priority", "17");
                eventData.Properties.Add("blob", true);

                await producer.EnqueueEventAsync(eventData);
            }
            finally
            {
                // Closing the producer will flush any
                // enqueued events that have not been published.

                await producer.CloseAsync();
            }

            #endregion
        }
Exemple #7
0
        public async Task Start(CancellationToken cancellationToken)
        {
            var enqueueTasks = new List <Task>();

            while (!cancellationToken.IsCancellationRequested)
            {
                using var backgroundCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                // Create the buffered producer client and register the success and failure handlers

                var options = new EventHubBufferedProducerClientOptions
                {
                    RetryOptions = new EventHubsRetryOptions
                    {
                        TryTimeout     = _testConfiguration.SendTimeout,
                        MaximumRetries = 15
                    },
                    MaximumWaitTime = _testConfiguration.MaxWaitTime
                };
                var producer = new EventHubBufferedProducerClient(_connectionString, _eventHubName, options);

                try
                {
                    producer.SendEventBatchSucceededAsync += args =>
                    {
                        var numEvents = args.EventBatch.Count;

                        _metrics.Client.GetMetric(_metrics.SuccessfullySentFromQueue, "PartitionId").TrackValue(numEvents, args.PartitionId);
                        _metrics.Client.GetMetric(_metrics.BatchesPublished).TrackValue(1);

                        return(Task.CompletedTask);
                    };

                    producer.SendEventBatchFailedAsync += args =>
                    {
                        var numEvents = args.EventBatch.Count;

                        _metrics.Client.GetMetric(_metrics.EventsNotSentAfterEnqueue, "PartitionId").TrackValue(numEvents, args.PartitionId);
                        _metrics.Client.TrackException(args.Exception);

                        return(Task.CompletedTask);
                    };

                    // Start concurrent enqueuing tasks

                    if (_testConfiguration.ConcurrentSends > 1)
                    {
                        for (var index = 0; index < _testConfiguration.ConcurrentSends - 1; ++index)
                        {
                            enqueueTasks.Add(Task.Run(async() =>
                            {
                                while (!cancellationToken.IsCancellationRequested)
                                {
                                    await PerformEnqueue(producer, cancellationToken).ConfigureAwait(false);

                                    if ((_testConfiguration.ProducerPublishingDelay.HasValue) && (_testConfiguration.ProducerPublishingDelay.Value > TimeSpan.Zero))
                                    {
                                        await Task.Delay(_testConfiguration.ProducerPublishingDelay.Value, backgroundCancellationSource.Token).ConfigureAwait(false);
                                    }
                                }
                            }));
                        }
                    }
                    // Perform one of the sends in the foreground, which will allow easier detection of a
                    // processor-level issue.

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            await PerformEnqueue(producer, cancellationToken).ConfigureAwait(false);

                            if ((_testConfiguration.ProducerPublishingDelay.HasValue) && (_testConfiguration.ProducerPublishingDelay.Value > TimeSpan.Zero))
                            {
                                await Task.Delay(_testConfiguration.ProducerPublishingDelay.Value, cancellationToken).ConfigureAwait(false);
                            }
                        }
                        catch (TaskCanceledException)
                        {
                            backgroundCancellationSource.Cancel();
                            await Task.WhenAll(enqueueTasks).ConfigureAwait(false);
                        }
                    }
                }
                catch (TaskCanceledException)
                {
                    // No action needed, the cancellation token has been cancelled.
                }
                catch (Exception ex) when
                    (ex is OutOfMemoryException ||
                    ex is StackOverflowException ||
                    ex is ThreadAbortException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    // If this catch is hit, it means the producer has restarted, collect metrics.

                    _metrics.Client.GetMetric(_metrics.ProducerRestarted).TrackValue(1);
                    _metrics.Client.TrackException(ex);
                }
                finally
                {
                    await producer.CloseAsync(false);
                }
            }
        }