/// <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"); }
/// <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); }