Implement Go-parity background flush loop (coalesce 16KB/8ms) in MsgBlock/FileStore, replace O(n) GetStateAsync with incremental counters, skip PruneExpired/LoadAsync/ PrunePerSubject when not needed, and bypass RAFT for single-replica streams. Fix counter tracking bugs in RemoveMsg/EraseMsg/TTL expiry and ObjectDisposedException races in flush loop disposal. FileStore optimizations verified with 3112/3112 JetStream tests passing; async publish benchmark remains at ~174 msg/s due to E2E protocol path bottleneck.
43 lines
1.3 KiB
C#
43 lines
1.3 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace NATS.Server.JetStream.Models;
|
|
|
|
// Go: server/stream.go — counterMsgPayload struct { Value string `json:"val"` }
|
|
// Reference: golang/nats-server/server/stream.go:20759
|
|
public sealed class CounterValue
|
|
{
|
|
[JsonPropertyName("val")]
|
|
public string Value { get; set; } = "0";
|
|
|
|
public long AsLong() => long.TryParse(Value, out var v) ? v : 0;
|
|
|
|
public static CounterValue FromLong(long value) => new() { Value = value.ToString() };
|
|
|
|
public byte[] ToPayload() => JsonSerializer.SerializeToUtf8Bytes(this);
|
|
|
|
public static CounterValue FromPayload(ReadOnlySpan<byte> payload)
|
|
{
|
|
if (payload.IsEmpty)
|
|
return new CounterValue();
|
|
|
|
try
|
|
{
|
|
return JsonSerializer.Deserialize<CounterValue>(payload) ?? new CounterValue();
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
return new CounterValue();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Go: NATS header constants for counter messages.
|
|
// Reference: golang/nats-server/server/stream.go — counter header constants.
|
|
public static class CounterHeaders
|
|
{
|
|
public const string NatsIncr = "Nats-Incr";
|
|
public const string NatsCounterSources = "Nats-Counter-Sources";
|
|
public const string NatsStreamSource = "Nats-Stream-Source";
|
|
}
|