/// <inheritdoc />
        protected sealed override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            Logger.LogInformation("Started execution loop");

            // Once the initial tasks are completed indicate the service is now available
            IsContainerAvailable = true;

            var checkpointStoreRoot      = Environment.GetEnvironmentVariable("CheckpointStore");
            var eventHubConnectionString = await GetEventHubConnectionStringAsync().ConfigureAwait(false);

            var checkpointConnectionString = await GetStorageConnectionStringAsync().ConfigureAwait(false);

            var consumerGroupName       = Environment.GetEnvironmentVariable("ConsumerGroup");
            var checkpointContainerName = Environment.GetEnvironmentVariable("CheckpointContainerName");
            var epochContainerName      = Environment.GetEnvironmentVariable("EpochContainerName");
            var eventProcessorHostName  = Environment.GetEnvironmentVariable("EventProcessorHostName");


            if (!int.TryParse(Environment.GetEnvironmentVariable("LeaseDurationSeconds"), out int leaseDurationSeconds) || leaseDurationSeconds < 20)
            {
                leaseDurationSeconds = 20;
            }
            if (!int.TryParse(Environment.GetEnvironmentVariable("LeaseRenewalSeconds"), out int leaseRenewalSeconds) || leaseRenewalSeconds < 10 || leaseRenewalSeconds >= leaseDurationSeconds)
            {
                leaseRenewalSeconds = 10;
            }
            if (!int.TryParse(Environment.GetEnvironmentVariable("ReceiveTimeoutSeconds"), out int receiveTimeout) || receiveTimeout < 5)
            {
                receiveTimeout = 60;
            }
            if (!int.TryParse(Environment.GetEnvironmentVariable("PrefetchCount"), out int prefetchCount) || prefetchCount < 0)
            {
                prefetchCount = 0;
            }
            if (!int.TryParse(Environment.GetEnvironmentVariable("MaxBatchSize"), out int maxBatchSize) || maxBatchSize < 1)
            {
                maxBatchSize = 1;
            }
            if (!int.TryParse(Environment.GetEnvironmentVariable("IterationSeconds"), out int iterationSeconds) || iterationSeconds < 1)
            {
                iterationSeconds = 1;
            }

            var iterationDelay = TimeSpan.FromSeconds(iterationSeconds);

            Logger.LogInformation("Creating fixed partition manager");
            _partitionManager = new FixedPartitionManager(_loggerFactory.CreateLogger(PartitionManagerLoggerName), eventHubConnectionString, KubernetesStatefulSetIndex.Value);

            Logger.LogInformation("Initializing fixed partition manager");
            await _partitionManager.InitializeAsync(KubernetesDesiredReplicaCount.Value).ConfigureAwait(true);

            Logger.LogInformation("Creating epoch reader");
            var epochRecorder = new AzureStorageEpochRecorder(_loggerFactory.CreateLogger(EpochRecorderLoggerName), MetricFactory, consumerGroupName, checkpointConnectionString, epochContainerName, null);

            Logger.LogInformation("Creating fixed lease manager");
            var leaseManager = new FixedLeaseManager(_loggerFactory.CreateLogger(LeaseManagerLoggerName), _partitionManager, epochRecorder);

            Logger.LogInformation("Creating Azure storage checkpoint manager");
            var checkpointManager = new AzureStorageCheckpointManager(_loggerFactory.CreateLogger(CheckpointManagerLoggerName), MetricFactory, checkpointConnectionString, checkpointContainerName, null);

            Logger.LogInformation("Building connection string");
            var builder = new EventHubsConnectionStringBuilder(eventHubConnectionString);

            Logger.LogInformation("Creating event processor host");
            var host = new EventProcessorHost(eventProcessorHostName, builder.EntityPath, consumerGroupName, builder.ToString(), checkpointManager, leaseManager)
            {
                PartitionManagerOptions = new PartitionManagerOptions
                {
                    RenewInterval = TimeSpan.FromSeconds(leaseRenewalSeconds),
                    LeaseDuration = TimeSpan.FromSeconds(leaseDurationSeconds)
                }
            };

            Logger.LogInformation("Initializing checkpoint manager");
            checkpointManager.Initialize(host);

            Logger.LogInformation("Initializing lease manager");
            await leaseManager.InitializeAsync(host).ConfigureAwait(true);

            Logger.LogInformation("Receive timeout is set to: {receiveTimeout} seconds", receiveTimeout);

            var processorOptions = new EventProcessorOptions
            {
                InitialOffsetProvider = (partitionId) => _startPosition,
                InvokeProcessorAfterReceiveTimeout = true,
                MaxBatchSize   = maxBatchSize,
                PrefetchCount  = prefetchCount,
                ReceiveTimeout = TimeSpan.FromSeconds(receiveTimeout)
            };

            Logger.LogInformation("Registering event processor host");

            await host.RegisterEventProcessorFactoryAsync(this, processorOptions).ConfigureAwait(false);

            Logger.LogInformation("Starting loop");

            while (!ContainerCancellationToken.IsCancellationRequested)
            {
                await Task.WhenAny(Task.Delay(iterationDelay), ContainerTask).ConfigureAwait(false);

                _iterationCounter.Increment();
                Logger.LogDebug("Derived Iteration completed");
            }

            Logger.LogWarning("Unregistering event processory");
            await host.UnregisterEventProcessorAsync().ConfigureAwait(true);


            // Service should be flagged as no longer available before any cleanup tasks
            IsContainerAvailable = false;

            Logger.LogWarning("Ending execution loop");
        }
Esempio n. 2
0
        /// <summary>
        /// An asynchronous version of the entry point to enable asynchronous all the way down
        /// </summary>
        private static async Task MainAsync()
        {
            var processingManagerId = 0;

            var configuration = GetConfiguration(LogLevel.Warning, LogLevel.Information);
            var metricFactory = GetMetricFactory();

            var processorOptions = new EventProcessorOptions
            {
                InitialOffsetProvider = (partitionId) => EventPosition.FromStart(),
                InvokeProcessorAfterReceiveTimeout = true,
                MaxBatchSize   = 100,
                PrefetchCount  = 300,
                ReceiveTimeout = TimeSpan.FromSeconds(15)
            };

            var manager = new FixedPartitionManager(configuration.PartitionManagerLogger, configuration.EventHubConnectionString, processingManagerId);

            await manager.InitializeAsync(2).ConfigureAwait(true);

            var epochRecorder = new AzureStorageEpochRecorder(configuration.EpochRecorderLogger, metricFactory, configuration.ConsumerGroupName, configuration.CheckpointConnectionString, configuration.EpochContainerName, null);

            var leaseManager      = new FixedLeaseManager(configuration.LeaseLogger, manager, epochRecorder);
            var checkpointManager = new AzureStorageCheckpointManager(configuration.CheckpointLogger, metricFactory, configuration.CheckpointConnectionString, configuration.CheckpointContainerName, null);

            var builder = new EventHubsConnectionStringBuilder(configuration.EventHubConnectionString);

            var host = new EventProcessorHost(configuration.EventProcessorHostName, builder.EntityPath, configuration.ConsumerGroupName, builder.ToString(), checkpointManager, leaseManager)
            {
                PartitionManagerOptions = new PartitionManagerOptions()
            };

            host.PartitionManagerOptions.RenewInterval = TimeSpan.FromSeconds(10);
            host.PartitionManagerOptions.LeaseDuration = TimeSpan.FromSeconds(20);

            checkpointManager.Initialize(host);
            await leaseManager.InitializeAsync(host).ConfigureAwait(true);

            await host.RegisterEventProcessorAsync <SampleProcessor>(processorOptions).ConfigureAwait(true);

            string line;

            do
            {
                Console.WriteLine("Event Processor Started. To change the event processor manager count enter a number and press <ENTER> or quit to exit.");
                line = Console.ReadLine();

                if (!string.IsNullOrEmpty(line))
                {
                    line = line.Trim();
                }

                if (!string.IsNullOrEmpty(line))
                {
                    if (int.TryParse(line, out var managerCount))
                    {
                        if (managerCount < 1 || managerCount > 1025)
                        {
                            Console.WriteLine("Valid numbers are 1 to 1025");
                        }
                        else
                        {
                            await manager.UpdateManagerQuantityAsync(managerCount, CancellationToken.None).ConfigureAwait(true);
                        }
                    }
                    else if (!string.Equals(line, "quit", StringComparison.OrdinalIgnoreCase))
                    {
                        Console.WriteLine("Did not recognize entry please try again.");
                    }
                }
            } while (!string.Equals(line, "quit", StringComparison.OrdinalIgnoreCase));

            await host.UnregisterEventProcessorAsync().ConfigureAwait(true);
        }