fix: correct MaxBytes enforcement and consumer start sequence after purge
StreamManager.Capture now accounts for full message size (subject + payload + 16-byte overhead) when checking MaxBytes, matching Go's memStoreMsgSize. PullConsumerEngine uses stream FirstSeq instead of hardcoded 1 for DeliverAll after purge. Fix 6 tests with Go parity assertions and updated MaxBytes values.
This commit is contained in:
@@ -263,7 +263,9 @@ public sealed class PullConsumerEngine
|
||||
DeliverPolicy.ByStartSequence when config.OptStartSeq > 0 => config.OptStartSeq,
|
||||
DeliverPolicy.ByStartTime when config.OptStartTimeUtc is { } startTime => await ResolveByStartTimeAsync(stream, startTime, ct),
|
||||
DeliverPolicy.LastPerSubject => await ResolveLastPerSubjectAsync(stream, config, state.LastSeq, ct),
|
||||
_ => 1,
|
||||
// Go: consumer.go — DeliverAll starts from stream's FirstSeq (not always 1).
|
||||
// After purge, FirstSeq advances past deleted messages.
|
||||
_ => state.FirstSeq > 0 ? state.FirstSeq : 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -299,8 +299,11 @@ public sealed class StreamManager
|
||||
|
||||
PruneExpiredMessages(stream, DateTime.UtcNow);
|
||||
|
||||
// Go: memStoreMsgSize — full message size includes subject + headers + payload + 16 bytes overhead.
|
||||
var msgSize = subject.Length + payload.Length + 16;
|
||||
|
||||
var stateBefore = stream.Store.GetStateAsync(default).GetAwaiter().GetResult();
|
||||
if (stream.Config.MaxBytes > 0 && (long)stateBefore.Bytes + payload.Length > stream.Config.MaxBytes)
|
||||
if (stream.Config.MaxBytes > 0 && (long)stateBefore.Bytes + msgSize > stream.Config.MaxBytes)
|
||||
{
|
||||
if (stream.Config.Discard == DiscardPolicy.New)
|
||||
{
|
||||
@@ -311,7 +314,7 @@ public sealed class StreamManager
|
||||
};
|
||||
}
|
||||
|
||||
while ((long)stateBefore.Bytes + payload.Length > stream.Config.MaxBytes && stateBefore.FirstSeq > 0)
|
||||
while ((long)stateBefore.Bytes + msgSize > stream.Config.MaxBytes && stateBefore.FirstSeq > 0)
|
||||
{
|
||||
stream.Store.RemoveAsync(stateBefore.FirstSeq, default).GetAwaiter().GetResult();
|
||||
stateBefore = stream.Store.GetStateAsync(default).GetAwaiter().GetResult();
|
||||
|
||||
Reference in New Issue
Block a user