internal void CreateSequenceStores(int count) { for (int i = 0; i < count; i++) { if (SequenceStores.Count <= i) { SequenceStores.Add(ServiceProvider.GetRequiredService <ISequenceStore>()); } } }
/// <summary> /// Returns the <see cref="ISequenceStore" /> to be used to store the pending sequences. /// </summary> /// <param name="offset"> /// The offset may determine which store is being used. For example a dedicated sequence store is used per /// each Kafka partition, since they may be processed concurrently. /// </param> /// <returns> /// The <see cref="ISequenceStore" />. /// </returns> protected virtual ISequenceStore GetSequenceStore(IOffset offset) { if (SequenceStores.Count == 0) { lock (SequenceStores) SequenceStores.Add(ServiceProvider.GetRequiredService <ISequenceStore>()); } return(SequenceStores.FirstOrDefault() ?? throw new InvalidOperationException("The sequence store is not initialized.")); }
internal void OnPartitionsRevoked() { lock (_channelsLock) { StopCore(); AsyncHelper.RunSynchronously(() => WaitUntilConsumingStoppedAsync(CancellationToken.None)); if (!Endpoint.Configuration.IsAutoCommitEnabled) { CommitOffsets(); } } SequenceStores.ForEach(store => store.Dispose()); SequenceStores.Clear(); }
/// <summary> /// Gets the <see cref="ISequenceStore" /> instances used by this consumer. Some brokers will require /// multiple stores (e.g. the <c>KafkaConsumer</c> will create a store per each assigned partition). /// </summary> /// <returns> /// The list of <see cref="ISequenceStore" />. /// </returns> public IReadOnlyList <ISequenceStore> GetCurrentSequenceStores() => SequenceStores.AsReadOnlyList();
/// <inheritdoc cref="IConsumer.DisconnectAsync" /> public async Task DisconnectAsync() { if (!IsConnected) { return; } IsDisconnecting = true; // Ensure that StopCore is called in any case to avoid deadlocks (when the consumer loop is initialized // but not started) if (IsConsuming) { Stop(); } else { StopCore(); } if (SequenceStores.Count > 0) { await SequenceStores .SelectMany(store => store) .ToList() .ForEachAsync(sequence => sequence.AbortAsync(SequenceAbortReason.ConsumerAborted)) .ConfigureAwait(false); } using (var cancellationTokenSource = new CancellationTokenSource(ConsumerStopWaitTimeout)) { _logger.LogTrace(IntegrationEventIds.LowLevelTracing, "Waiting until consumer stops..."); try { await WaitUntilConsumingStoppedAsync(cancellationTokenSource.Token).ConfigureAwait(false); _logger.LogTrace(IntegrationEventIds.LowLevelTracing, "Consumer stopped."); } catch (OperationCanceledException) { _logger.LogError( IntegrationEventIds.LowLevelTracing, "The timeout elapsed before the consumer stopped."); } } await DisconnectCoreAsync().ConfigureAwait(false); SequenceStores.ForEach(store => store.Dispose()); SequenceStores.Clear(); IsConnected = false; _statusInfo.SetDisconnected(); _logger.LogDebug( IntegrationEventIds.ConsumerDisconnected, "Disconnected consumer from endpoint {endpoint}.", Endpoint.Name); IsDisconnecting = false; }