feat: enforce jetstream retention and limits

This commit is contained in:
Joseph Doherty
2026-02-23 06:04:23 -05:00
parent 95691fa9e7
commit d73e7e2f88
6 changed files with 107 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
using System.Collections.Concurrent;
using NATS.Server.JetStream.Api;
using NATS.Server.JetStream.Models;
using NATS.Server.JetStream.Publish;
using NATS.Server.JetStream.Storage;
using NATS.Server.Subscriptions;
@@ -37,6 +38,14 @@ public sealed class StreamManager
public bool TryGet(string name, out StreamHandle handle) => _streams.TryGetValue(name, out handle!);
public ValueTask<StreamState> GetStateAsync(string name, CancellationToken ct)
{
if (_streams.TryGetValue(name, out var stream))
return stream.Store.GetStateAsync(ct);
return ValueTask.FromResult(new StreamState());
}
public StreamHandle? FindBySubject(string subject)
{
foreach (var stream in _streams.Values)
@@ -48,6 +57,22 @@ public sealed class StreamManager
return null;
}
public PubAck? Capture(string subject, ReadOnlyMemory<byte> payload)
{
var stream = FindBySubject(subject);
if (stream == null)
return null;
var seq = stream.Store.AppendAsync(subject, payload, default).GetAwaiter().GetResult();
EnforceLimits(stream);
return new PubAck
{
Stream = stream.Config.Name,
Seq = seq,
};
}
private static StreamConfig NormalizeConfig(StreamConfig config)
{
var copy = new StreamConfig
@@ -73,6 +98,22 @@ public sealed class StreamManager
},
};
}
private static void EnforceLimits(StreamHandle stream)
{
if (stream.Config.MaxMsgs <= 0)
return;
var maxMessages = (ulong)stream.Config.MaxMsgs;
if (stream.Store is MemStore memStore)
{
memStore.TrimToMaxMessages(maxMessages);
return;
}
if (stream.Store is FileStore fileStore)
fileStore.TrimToMaxMessages(maxMessages);
}
}
public sealed record StreamHandle(StreamConfig Config, IStreamStore Store);