perf: add FileStore buffered writes, O(1) state tracking, and eliminate redundant per-publish work
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.
This commit is contained in:
@@ -283,8 +283,11 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
{
|
||||
if (_jetStreamPublisher != null && _jetStreamPublisher.TryCapture(subject, payload, out ack))
|
||||
{
|
||||
// Only load the stored message for consumer notification when there are
|
||||
// active consumers for this stream. Avoids unnecessary LoadAsync on the hot path.
|
||||
if (ack.ErrorCode == null
|
||||
&& _jetStreamConsumerManager != null
|
||||
&& _jetStreamConsumerManager.HasConsumersForStream(ack.Stream)
|
||||
&& _jetStreamStreamManager != null
|
||||
&& _jetStreamStreamManager.TryGet(ack.Stream, out var streamHandle))
|
||||
{
|
||||
@@ -670,6 +673,7 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
{
|
||||
_jetStreamConsumerManager = new ConsumerManager();
|
||||
_jetStreamStreamManager = new StreamManager(consumerManager: _jetStreamConsumerManager, storeDir: options.JetStream.StoreDir);
|
||||
_jetStreamConsumerManager.StreamManager = _jetStreamStreamManager;
|
||||
var jsClientId = Interlocked.Increment(ref _nextClientId);
|
||||
_jetStreamInternalClient = new InternalClient(jsClientId, ClientKind.JetStream, _systemAccount);
|
||||
_jetStreamService = new JetStreamService(options.JetStream, _jetStreamInternalClient);
|
||||
|
||||
Reference in New Issue
Block a user