Improve XML documentation coverage across core server components and refresh checker reports.
This commit is contained in:
@@ -30,13 +30,25 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// </summary>
|
||||
public StreamManager? StreamManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates the consumer manager for stream-scoped durable/ephemeral consumers.
|
||||
/// </summary>
|
||||
/// <param name="metaGroup">Optional JetStream meta group reference for cluster-aware operations.</param>
|
||||
public ConsumerManager(JetStreamMetaGroup? metaGroup = null)
|
||||
{
|
||||
_metaGroup = metaGroup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of registered consumers across all streams.
|
||||
/// </summary>
|
||||
public int ConsumerCount => _consumers.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new consumer or updates an existing durable consumer configuration.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream for the consumer.</param>
|
||||
/// <param name="config">Requested consumer configuration from the JetStream API request.</param>
|
||||
public JetStreamApiResponse CreateOrUpdate(string stream, ConsumerConfig config)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config.DurableName))
|
||||
@@ -92,6 +104,11 @@ public sealed class ConsumerManager : IDisposable
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns API info payload for a specific stream consumer.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public JetStreamApiResponse GetInfo(string stream, string durableName)
|
||||
{
|
||||
if (_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -110,15 +127,30 @@ public sealed class ConsumerManager : IDisposable
|
||||
return JetStreamApiResponse.NotFound($"$JS.API.CONSUMER.INFO.{stream}.{durableName}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to resolve a consumer handle by stream and durable name.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="handle">Resolved in-memory consumer handle when found.</param>
|
||||
public bool TryGet(string stream, string durableName, out ConsumerHandle handle)
|
||||
=> _consumers.TryGetValue((stream, durableName), out handle!);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a consumer and clears any pending auto-resume timer.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public bool Delete(string stream, string durableName)
|
||||
{
|
||||
CancelResumeTimer((stream, durableName));
|
||||
return _consumers.TryRemove((stream, durableName), out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lists consumer durable names for a stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name to list consumers from.</param>
|
||||
public IReadOnlyList<string> ListNames(string stream)
|
||||
=> _consumers.Keys
|
||||
.Where(k => string.Equals(k.Stream, stream, StringComparison.Ordinal))
|
||||
@@ -126,6 +158,10 @@ public sealed class ConsumerManager : IDisposable
|
||||
.OrderBy(x => x, StringComparer.Ordinal)
|
||||
.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Lists API consumer info objects for a stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name to list consumer details from.</param>
|
||||
public IReadOnlyList<JetStreamConsumerInfo> ListConsumerInfos(string stream)
|
||||
=> _consumers
|
||||
.Where(kv => string.Equals(kv.Key.Stream, stream, StringComparison.Ordinal))
|
||||
@@ -133,6 +169,12 @@ public sealed class ConsumerManager : IDisposable
|
||||
.Select(kv => new JetStreamConsumerInfo { Name = kv.Value.Config.DurableName, StreamName = stream, Config = kv.Value.Config })
|
||||
.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Pauses or unpauses a consumer immediately.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="paused"><see langword="true"/> to pause delivery; <see langword="false"/> to resume immediately.</param>
|
||||
public bool Pause(string stream, string durableName, bool paused)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -152,6 +194,9 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// A background timer will auto-resume the consumer when the deadline passes.
|
||||
/// Go reference: consumer.go (pauseConsumer).
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name containing the consumer.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="pauseUntilUtc">UTC deadline for automatic resume.</param>
|
||||
public bool Pause(string stream, string durableName, DateTime pauseUntilUtc)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -184,6 +229,8 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// Explicitly resume a paused consumer, cancelling any pending auto-resume timer.
|
||||
/// Go reference: consumer.go (resumeConsumer).
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name containing the consumer.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public bool Resume(string stream, string durableName)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -200,6 +247,8 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// If the deadline has passed, auto-resumes the consumer and returns false.
|
||||
/// Go reference: consumer.go (isPaused).
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name containing the consumer.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public bool IsPaused(string stream, string durableName)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -221,6 +270,8 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// Returns the UTC deadline until which the consumer is paused, or null.
|
||||
/// Go reference: consumer.go (pauseUntil).
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name containing the consumer.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public DateTime? GetPauseUntil(string stream, string durableName)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -246,6 +297,9 @@ public sealed class ConsumerManager : IDisposable
|
||||
timer.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes active resume timers and clears timer registry.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var timer in _resumeTimers.Values)
|
||||
@@ -253,6 +307,11 @@ public sealed class ConsumerManager : IDisposable
|
||||
_resumeTimers.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets consumer sequence and pending queue to initial state.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public bool Reset(string stream, string durableName)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -268,6 +327,9 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// Clears pending acks and redelivery state.
|
||||
/// Go reference: consumer.go:4241 processResetReq.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name containing the consumer.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="sequence">Next sequence to resume delivery from.</param>
|
||||
public bool ResetToSequence(string stream, string durableName, ulong sequence)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -285,14 +347,35 @@ public sealed class ConsumerManager : IDisposable
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a consumer exists for unpin-style API semantics.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public bool Unpin(string stream, string durableName)
|
||||
{
|
||||
return _consumers.ContainsKey((stream, durableName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a pull batch using a simple batch-size request.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="batch">Maximum number of messages requested.</param>
|
||||
/// <param name="streamManager">Stream registry used to resolve the source stream handle.</param>
|
||||
/// <param name="ct">Cancellation token for wait and fetch operations.</param>
|
||||
public async ValueTask<PullFetchBatch> FetchAsync(string stream, string durableName, int batch, StreamManager streamManager, CancellationToken ct)
|
||||
=> await FetchAsync(stream, durableName, new PullFetchRequest { Batch = batch }, streamManager, ct);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a pull batch for a consumer using a detailed pull request.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="request">Pull request options such as batch size, expiry, and byte limits.</param>
|
||||
/// <param name="streamManager">Stream registry used to resolve the source stream handle.</param>
|
||||
/// <param name="ct">Cancellation token for wait and fetch operations.</param>
|
||||
public async ValueTask<PullFetchBatch> FetchAsync(string stream, string durableName, PullFetchRequest request, StreamManager streamManager, CancellationToken ct)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var consumer))
|
||||
@@ -304,6 +387,12 @@ public sealed class ConsumerManager : IDisposable
|
||||
return await _pullConsumerEngine.FetchAsync(streamHandle, consumer, request, ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Acknowledges all pending entries up to the specified sequence.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
/// <param name="sequence">Inclusive stream sequence that advances the ack floor.</param>
|
||||
public bool AckAll(string stream, string durableName, ulong sequence)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -314,6 +403,11 @@ public sealed class ConsumerManager : IDisposable
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns pending-ack count for a consumer.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public int GetPendingCount(string stream, string durableName)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var handle))
|
||||
@@ -326,9 +420,15 @@ public sealed class ConsumerManager : IDisposable
|
||||
/// Returns true if there are any consumers registered for the given stream.
|
||||
/// Used to short-circuit the LoadAsync call on the publish hot path.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name to check.</param>
|
||||
public bool HasConsumersForStream(string stream)
|
||||
=> _consumers.Keys.Any(k => string.Equals(k.Stream, stream, StringComparison.Ordinal));
|
||||
|
||||
/// <summary>
|
||||
/// Handles a newly stored stream message for push-consumer fan-out.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name for the published message.</param>
|
||||
/// <param name="message">Stored message metadata and payload to fan out.</param>
|
||||
public void OnPublished(string stream, StoredMessage message)
|
||||
{
|
||||
foreach (var handle in _consumers.Values.Where(c => c.Stream == stream && c.Config.Push))
|
||||
@@ -343,6 +443,11 @@ public sealed class ConsumerManager : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next available push frame for a consumer when release time has arrived.
|
||||
/// </summary>
|
||||
/// <param name="stream">Owning stream name.</param>
|
||||
/// <param name="durableName">Consumer durable name.</param>
|
||||
public PushFrame? ReadPushFrame(string stream, string durableName)
|
||||
{
|
||||
if (!_consumers.TryGetValue((stream, durableName), out var consumer))
|
||||
@@ -369,6 +474,10 @@ public sealed class ConsumerManager : IDisposable
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets stream-level ack floor derived from consumer acknowledgements.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream name whose ack floor should be returned.</param>
|
||||
internal ulong GetAckFloor(string stream)
|
||||
=> _ackFloors.TryGetValue(stream, out var ackFloor) ? ackFloor : 0;
|
||||
}
|
||||
@@ -384,6 +493,9 @@ public sealed record ConsumerHandle(string Stream, ConsumerConfig Config)
|
||||
private Consumers.CompiledFilter? _compiledFilter;
|
||||
private string? _compiledFilterSubject;
|
||||
private int _compiledFilterSubjectsCount;
|
||||
/// <summary>
|
||||
/// Gets cached compiled subject filter for this consumer configuration.
|
||||
/// </summary>
|
||||
public Consumers.CompiledFilter CompiledFilter
|
||||
{
|
||||
get
|
||||
@@ -401,7 +513,14 @@ public sealed record ConsumerHandle(string Stream, ConsumerConfig Config)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets next stream sequence to deliver.
|
||||
/// </summary>
|
||||
public ulong NextSequence { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether delivery is currently paused.
|
||||
/// </summary>
|
||||
public bool Paused { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -409,9 +528,24 @@ public sealed record ConsumerHandle(string Stream, ConsumerConfig Config)
|
||||
/// (until explicitly resumed). Go reference: consumer.go pauseUntil field.
|
||||
/// </summary>
|
||||
public DateTime? PauseUntilUtc { get; set; }
|
||||
/// <summary>
|
||||
/// Gets pending stored messages queued for this consumer.
|
||||
/// </summary>
|
||||
public Queue<StoredMessage> Pending { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets queued push frames waiting for delivery window release.
|
||||
/// </summary>
|
||||
public Queue<PushFrame> PushFrames { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets ack processor state for pending and ack-floor tracking.
|
||||
/// </summary>
|
||||
public AckProcessor AckProcessor { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets next UTC time when push data can be delivered.
|
||||
/// </summary>
|
||||
public DateTime NextPushDataAvailableAtUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user