Ejemplo n.º 1
0
        async Task InvokeAfterReceiveTimeoutTrue()
        {
            const int ReceiveTimeoutInSeconds = 15;

            Log("Testing EventProcessorHost with InvokeProcessorAfterReceiveTimeout=true");

            var emptyBatchReceiveEvents = new ConcurrentDictionary <string, AsyncAutoResetEvent>();

            foreach (var partitionId in PartitionIds)
            {
                emptyBatchReceiveEvents[partitionId] = new AsyncAutoResetEvent(false);
            }

            var eventProcessorHost = new EventProcessorHost(
                string.Empty,
                PartitionReceiver.DefaultConsumerGroupName,
                this.EventHubConnectionString,
                this.StorageConnectionString,
                this.LeaseContainerName);

            var processorOptions = new EventProcessorOptions
            {
                ReceiveTimeout = TimeSpan.FromSeconds(ReceiveTimeoutInSeconds),
                InvokeProcessorAfterReceiveTimeout = true,
                MaxBatchSize = 100
            };

            var processorFactory = new TestEventProcessorFactory();

            processorFactory.OnCreateProcessor += (f, createArgs) =>
            {
                var    processor   = createArgs.Item2;
                string partitionId = createArgs.Item1.PartitionId;
                processor.OnOpen          += (_, partitionContext) => Log($"Partition {partitionId} TestEventProcessor opened");
                processor.OnProcessEvents += (_, eventsArgs) =>
                {
                    int eventCount = eventsArgs.Item2.events != null?eventsArgs.Item2.events.Count() : 0;

                    Log($"Partition {partitionId} TestEventProcessor processing {eventCount} event(s)");
                    if (eventCount == 0)
                    {
                        var emptyBatchReceiveEvent = emptyBatchReceiveEvents[partitionId];
                        emptyBatchReceiveEvent.Set();
                    }
                };
            };

            await eventProcessorHost.RegisterEventProcessorFactoryAsync(processorFactory, processorOptions);

            try
            {
                Log("Waiting for each partition to receive an empty batch of events...");
                foreach (var partitionId in PartitionIds)
                {
                    var  emptyBatchReceiveEvent = emptyBatchReceiveEvents[partitionId];
                    bool emptyBatchReceived     = await emptyBatchReceiveEvent.WaitAsync(TimeSpan.FromSeconds(ReceiveTimeoutInSeconds * 2));

                    Assert.True(emptyBatchReceived, $"Partition {partitionId} didn't receive an empty batch!");
                }
            }
            finally
            {
                Log("Calling UnregisterEventProcessorAsync");
                await eventProcessorHost.UnregisterEventProcessorAsync();
            }
        }
Ejemplo n.º 2
0
        async Task MultipleConsumerGroups()
        {
            var customConsumerGroupName = "cgroup1";

            // Generate a new lease container name that will be used through out the test.
            string leaseContainerName = Guid.NewGuid().ToString();

            var consumerGroupNames = new[]  { PartitionReceiver.DefaultConsumerGroupName, customConsumerGroupName };
            var processorOptions   = new EventProcessorOptions
            {
                ReceiveTimeout = TimeSpan.FromSeconds(15),
                MaxBatchSize   = 100
            };
            var processorFactory       = new TestEventProcessorFactory();
            var partitionReceiveEvents = new ConcurrentDictionary <string, AsyncAutoResetEvent>();
            var hosts = new List <EventProcessorHost>();

            // Confirm that custom consumer group exists before starting hosts.
            try
            {
                // Create a receiver on the consumer group and try to receive.
                // Receive call will fail if consumer group is missing.
                var ehClient = EventHubClient.CreateFromConnectionString(this.EventHubConnectionString);
                var receiver = ehClient.CreateReceiver(customConsumerGroupName, this.PartitionIds.First(), PartitionReceiver.StartOfStream);
                await receiver.ReceiveAsync(1, TimeSpan.FromSeconds(5));
            }
            catch (MessagingEntityNotFoundException)
            {
                throw new Exception($"Cunsumer group {customConsumerGroupName} cannot be found. MultipleConsumerGroups unit test requires consumer group '{customConsumerGroupName}' to be created before running the test.");
            }

            processorFactory.OnCreateProcessor += (f, createArgs) =>
            {
                var    processor         = createArgs.Item2;
                string partitionId       = createArgs.Item1.PartitionId;
                string hostName          = createArgs.Item1.Owner;
                string consumerGroupName = createArgs.Item1.ConsumerGroupName;
                processor.OnOpen          += (_, partitionContext) => Log($"{hostName} > {consumerGroupName} > Partition {partitionId} TestEventProcessor opened");
                processor.OnClose         += (_, closeArgs) => Log($"{hostName} > {consumerGroupName} > Partition {partitionId} TestEventProcessor closing: {closeArgs.Item2}");
                processor.OnProcessError  += (_, errorArgs) => Log($"{hostName} > {consumerGroupName} > Partition {partitionId} TestEventProcessor process error {errorArgs.Item2.Message}");
                processor.OnProcessEvents += (_, eventsArgs) =>
                {
                    int eventCount = eventsArgs.Item2 != null?eventsArgs.Item2.events.Count() : 0;

                    Log($"{hostName} > {consumerGroupName} > Partition {partitionId} TestEventProcessor processing {eventCount} event(s)");
                    if (eventCount > 0)
                    {
                        var receivedEvent = partitionReceiveEvents[consumerGroupName + "-" + partitionId];
                        receivedEvent.Set();
                    }
                };
            };

            try
            {
                // Register a new host for each consumer group.
                foreach (var consumerGroupName in consumerGroupNames)
                {
                    var eventProcessorHost = new EventProcessorHost(
                        string.Empty,
                        consumerGroupName,
                        this.EventHubConnectionString,
                        this.StorageConnectionString,
                        leaseContainerName);

                    Log($"Calling RegisterEventProcessorAsync on consumer group {consumerGroupName}");

                    foreach (var partitionId in PartitionIds)
                    {
                        partitionReceiveEvents[consumerGroupName + "-" + partitionId] = new AsyncAutoResetEvent(false);
                    }

                    await eventProcessorHost.RegisterEventProcessorFactoryAsync(processorFactory, processorOptions);

                    hosts.Add(eventProcessorHost);
                }

                Log("Sending an event to each partition");
                var sendTasks = new List <Task>();
                foreach (var partitionId in PartitionIds)
                {
                    sendTasks.Add(this.SendToPartitionAsync(partitionId, $"{partitionId} event.", this.ConnectionStringBuilder.ToString()));
                }

                await Task.WhenAll(sendTasks);

                Log("Verifying an event was received by each partition for each consumer group");
                foreach (var consumerGroupName in consumerGroupNames)
                {
                    foreach (var partitionId in PartitionIds)
                    {
                        var  receivedEvent            = partitionReceiveEvents[consumerGroupName + "-" + partitionId];
                        bool partitionReceivedMessage = await receivedEvent.WaitAsync(TimeSpan.FromSeconds(30));

                        Assert.True(partitionReceivedMessage, $"ConsumerGroup {consumerGroupName} > Partition {partitionId} didn't receive any message!");
                    }
                }

                Log("Success");
            }
            finally
            {
                Log("Calling UnregisterEventProcessorAsync on both hosts.");
                foreach (var eph in hosts)
                {
                    await eph.UnregisterEventProcessorAsync();
                }
            }
        }
Ejemplo n.º 3
0
        async Task MultipleProcessorHosts()
        {
            Log("Testing with 2 EventProcessorHost instances");

            var partitionReceiveEvents = new ConcurrentDictionary <string, AsyncAutoResetEvent>();

            foreach (var partitionId in PartitionIds)
            {
                partitionReceiveEvents[partitionId] = new AsyncAutoResetEvent(false);
            }

            int hostCount = 2;
            var hosts     = new List <EventProcessorHost>();

            try
            {
                for (int i = 0; i < hostCount; i++)
                {
                    Log("Creating EventProcessorHost");
                    var eventProcessorHost = new EventProcessorHost(
                        string.Empty, // Passing empty as entity path here rsince path is already in EH connection string.
                        PartitionReceiver.DefaultConsumerGroupName,
                        this.EventHubConnectionString,
                        this.StorageConnectionString,
                        this.LeaseContainerName);
                    hosts.Add(eventProcessorHost);
                    Log($"Calling RegisterEventProcessorAsync");
                    var processorOptions = new EventProcessorOptions
                    {
                        ReceiveTimeout = TimeSpan.FromSeconds(10),
                        InvokeProcessorAfterReceiveTimeout = true,
                        MaxBatchSize = 100
                    };

                    var processorFactory = new TestEventProcessorFactory();
                    processorFactory.OnCreateProcessor += (f, createArgs) =>
                    {
                        var    processor   = createArgs.Item2;
                        string partitionId = createArgs.Item1.PartitionId;
                        string hostName    = createArgs.Item1.Owner;
                        processor.OnOpen          += (_, partitionContext) => Log($"{hostName} > Partition {partitionId} TestEventProcessor opened");
                        processor.OnClose         += (_, closeArgs) => Log($"{hostName} > Partition {partitionId} TestEventProcessor closing: {closeArgs.Item2}");
                        processor.OnProcessError  += (_, errorArgs) => Log($"{hostName} > Partition {partitionId} TestEventProcessor process error {errorArgs.Item2.Message}");
                        processor.OnProcessEvents += (_, eventsArgs) =>
                        {
                            int eventCount = eventsArgs.Item2 != null?eventsArgs.Item2.events.Count() : 0;

                            Log($"{hostName} > Partition {partitionId} TestEventProcessor processing {eventCount} event(s)");
                            if (eventCount > 0)
                            {
                                var receivedEvent = partitionReceiveEvents[partitionId];
                                receivedEvent.Set();
                            }
                        };
                    };

                    await eventProcessorHost.RegisterEventProcessorFactoryAsync(processorFactory, processorOptions);
                }

                Log("Waiting for partition ownership to settle...");
                await Task.Delay(TimeSpan.FromSeconds(30));

                Log("Sending an event to each partition");
                var sendTasks = new List <Task>();
                foreach (var partitionId in PartitionIds)
                {
                    sendTasks.Add(this.SendToPartitionAsync(partitionId, $"{partitionId} event.", this.ConnectionStringBuilder.ToString()));
                }
                await Task.WhenAll(sendTasks);

                Log("Verifying an event was received by each partition");
                foreach (var partitionId in PartitionIds)
                {
                    var  receivedEvent            = partitionReceiveEvents[partitionId];
                    bool partitionReceivedMessage = await receivedEvent.WaitAsync(TimeSpan.FromSeconds(30));

                    Assert.True(partitionReceivedMessage, $"Partition {partitionId} didn't receive any message!");
                }
            }
            finally
            {
                var shutdownTasks = new List <Task>();
                foreach (var host in hosts)
                {
                    Log($"Host {host} Calling UnregisterEventProcessorAsync.");
                    shutdownTasks.Add(host.UnregisterEventProcessorAsync());
                }

                await Task.WhenAll(shutdownTasks);
            }
        }