using System; using System.Collections.Generic; namespace Svrnty.CQRS.Events.ConsumerGroups.Abstractions; /// /// Configuration options for consumer group behavior. /// public class ConsumerGroupOptions { /// /// Number of events to fetch in each batch from the stream. /// Higher values improve throughput but increase memory usage. /// Default: 100. /// public int BatchSize { get; set; } = 100; /// /// Polling interval when no events are available in the stream. /// The consumer will sleep for this duration before checking for new events. /// Default: 1 second. /// public TimeSpan PollingInterval { get; set; } = TimeSpan.FromSeconds(1); /// /// Offset commit strategy. /// Determines when and how offsets are committed. /// Default: AfterBatch. /// public OffsetCommitStrategy CommitStrategy { get; set; } = OffsetCommitStrategy.AfterBatch; /// /// Interval for periodic offset commits when using OffsetCommitStrategy.Periodic. /// Ignored for other commit strategies. /// Default: 5 seconds. /// public TimeSpan PeriodicCommitInterval { get; set; } = TimeSpan.FromSeconds(5); /// /// Heartbeat interval for consumer liveness. /// The consumer will send heartbeats at this interval to signal it's alive. /// Must be less than SessionTimeout. /// Default: 10 seconds. /// public TimeSpan HeartbeatInterval { get; set; } = TimeSpan.FromSeconds(10); /// /// Consumer session timeout. /// If a consumer doesn't send a heartbeat within this period, it's considered dead /// and will be removed from the group. /// Must be greater than HeartbeatInterval. /// Default: 30 seconds. /// public TimeSpan SessionTimeout { get; set; } = TimeSpan.FromSeconds(30); /// /// Whether to start from the beginning of the stream if no offset has been committed. /// If false, starts from the current end of the stream (only new events). /// Default: true (start from beginning). /// public bool StartFromBeginning { get; set; } = true; /// /// Optional metadata to include with consumer registration. /// Useful for debugging and monitoring (e.g., hostname, version, environment). /// public IReadOnlyDictionary? Metadata { get; set; } /// /// Validates the options and throws if invalid. /// /// Thrown if options are invalid. public void Validate() { if (BatchSize <= 0) throw new ArgumentException("BatchSize must be greater than 0", nameof(BatchSize)); if (PollingInterval <= TimeSpan.Zero) throw new ArgumentException("PollingInterval must be greater than 0", nameof(PollingInterval)); if (HeartbeatInterval <= TimeSpan.Zero) throw new ArgumentException("HeartbeatInterval must be greater than 0", nameof(HeartbeatInterval)); if (SessionTimeout <= HeartbeatInterval) throw new ArgumentException( "SessionTimeout must be greater than HeartbeatInterval", nameof(SessionTimeout)); if (CommitStrategy == OffsetCommitStrategy.Periodic && PeriodicCommitInterval <= TimeSpan.Zero) throw new ArgumentException( "PeriodicCommitInterval must be greater than 0 when using Periodic commit strategy", nameof(PeriodicCommitInterval)); } }