perf: Phase 1 JetStream async file publish optimizations
- Add cached state properties (LastSeq, MessageCount, TotalBytes, FirstSeq) to IStreamStore/FileStore/MemStore — eliminates GetStateAsync on publish path - Add Capture(StreamHandle, ...) overload to StreamManager — eliminates double FindBySubject lookup (once in JetStreamPublisher, once in Capture) - Remove _messageIndexes dictionary from FileStore write path — all lookups now use _messages directly, saving ~48B allocation per message - Add JetStreamPubAckFormatter for hand-rolled UTF-8 success ack formatting — avoids JsonSerializer overhead on the hot publish path - Switch flush loop to exponential backoff (1→2→4→8ms) matching Go server
This commit is contained in:
@@ -1399,8 +1399,19 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
// Go reference: server/jetstream.go — jsPubAckResponse sent to reply.
|
||||
if (replyTo != null)
|
||||
{
|
||||
var ackData = JsonSerializer.SerializeToUtf8Bytes(pubAck, s_jetStreamJsonOptions);
|
||||
ProcessMessage(replyTo, null, default, ackData, sender);
|
||||
if (JetStream.Publish.JetStreamPubAckFormatter.IsSimpleSuccess(pubAck))
|
||||
{
|
||||
// Fast path: hand-rolled UTF-8 formatter avoids JsonSerializer overhead.
|
||||
Span<byte> ackBuf = stackalloc byte[256];
|
||||
var ackLen = JetStream.Publish.JetStreamPubAckFormatter.FormatSuccess(ackBuf, pubAck.Stream, pubAck.Seq);
|
||||
ProcessMessage(replyTo, null, default, ackBuf[..ackLen].ToArray(), sender);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ackData = JsonSerializer.SerializeToUtf8Bytes(pubAck, s_jetStreamJsonOptions);
|
||||
ProcessMessage(replyTo, null, default, ackData, sender);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user