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.
130 lines
5.4 KiB
C#
130 lines
5.4 KiB
C#
namespace NATS.Server.JetStream.Models;
|
|
|
|
public sealed class StreamConfig
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public string Description { get; set; } = string.Empty;
|
|
public List<string> Subjects { get; set; } = [];
|
|
public int MaxMsgs { get; set; }
|
|
public long MaxBytes { get; set; }
|
|
public int MaxMsgsPer { get; set; }
|
|
[System.Text.Json.Serialization.JsonIgnore]
|
|
public int MaxAgeMs { get; set; }
|
|
|
|
/// <summary>
|
|
/// MaxAge in nanoseconds for JSON wire compatibility with Go server.
|
|
/// Go reference: StreamConfig.MaxAge is a time.Duration (nanoseconds in JSON).
|
|
/// </summary>
|
|
public long MaxAge
|
|
{
|
|
get => (long)MaxAgeMs * 1_000_000L;
|
|
set => MaxAgeMs = (int)(value / 1_000_000);
|
|
}
|
|
public int MaxMsgSize { get; set; }
|
|
public int MaxConsumers { get; set; }
|
|
public int DuplicateWindowMs { get; set; }
|
|
public bool Sealed { get; set; }
|
|
public bool DenyDelete { get; set; }
|
|
public bool DenyPurge { get; set; }
|
|
public bool AllowDirect { get; set; }
|
|
// Go: StreamConfig.AllowMsgTTL — per-message TTL header support
|
|
public bool AllowMsgTtl { get; set; }
|
|
// Go: StreamConfig.FirstSeq — initial sequence number for the stream
|
|
public ulong FirstSeq { get; set; }
|
|
public RetentionPolicy Retention { get; set; } = RetentionPolicy.Limits;
|
|
public DiscardPolicy Discard { get; set; } = DiscardPolicy.Old;
|
|
public StorageType Storage { get; set; } = StorageType.Memory;
|
|
public int Replicas { get; set; } = 1;
|
|
public string? Mirror { get; set; }
|
|
public string? Source { get; set; }
|
|
public List<StreamSourceConfig> Sources { get; set; } = [];
|
|
|
|
// Go: StreamConfig.SubjectTransform — transforms inbound message subjects on store.
|
|
// Source and Dest follow the same token-wildcard rules as NATS subject transforms.
|
|
// Go reference: server/stream.go:352 (SubjectTransform field in StreamConfig)
|
|
public string? SubjectTransformSource { get; set; }
|
|
public string? SubjectTransformDest { get; set; }
|
|
|
|
// Go: StreamConfig.RePublish — re-publish stored messages on a separate subject.
|
|
// Source is the filter (empty = match all); Dest is the target subject pattern.
|
|
// Go reference: server/stream.go:356 (RePublish field in StreamConfig)
|
|
public string? RePublishSource { get; set; }
|
|
public string? RePublishDest { get; set; }
|
|
// Go: RePublish.HeadersOnly — republished copy omits message body.
|
|
public bool RePublishHeadersOnly { get; set; }
|
|
|
|
// Go: StreamConfig.SubjectDeleteMarkerTTL — duration to retain delete markers.
|
|
// When > 0 and AllowMsgTTL is true, expired messages emit a delete-marker msg.
|
|
// Incompatible with Mirror config.
|
|
// Go reference: server/stream.go:361 (SubjectDeleteMarkerTTL field)
|
|
public int SubjectDeleteMarkerTtlMs { get; set; }
|
|
|
|
// Go: StreamConfig.AllowMsgSchedules — enables scheduled publish headers.
|
|
// Incompatible with Mirror and Sources.
|
|
// Go reference: server/stream.go:369 (AllowMsgSchedules field)
|
|
public bool AllowMsgSchedules { get; set; }
|
|
|
|
// Go: StreamConfig.AllowMsgCounter — enables CRDT counter semantics on messages.
|
|
// Added in v2.12, requires API level 2.
|
|
// Go reference: server/stream.go:365 (AllowMsgCounter field)
|
|
public bool AllowMsgCounter { get; set; }
|
|
|
|
// Go: StreamConfig.AllowAtomicPublish — enables atomic batch publishing.
|
|
// Added in v2.12, requires API level 2.
|
|
// Go reference: server/stream.go:367 (AllowAtomicPublish field)
|
|
public bool AllowAtomicPublish { get; set; }
|
|
|
|
// Go: StreamConfig.PersistMode — async vs sync storage persistence.
|
|
// AsyncPersistMode requires API level 2.
|
|
// Go reference: server/stream.go:375 (PersistMode field)
|
|
public PersistMode PersistMode { get; set; } = PersistMode.Sync;
|
|
|
|
// Go: StreamConfig.Metadata — user-supplied and server-managed key/value metadata.
|
|
// The server automatically sets _nats.req.level, _nats.ver, _nats.level.
|
|
// Go reference: server/stream.go:380 (Metadata field)
|
|
public Dictionary<string, string>? Metadata { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Persistence mode for the stream.
|
|
/// Go reference: server/stream.go — AsyncPersistMode constant.
|
|
/// </summary>
|
|
public enum PersistMode
|
|
{
|
|
Sync = 0,
|
|
Async = 1,
|
|
}
|
|
|
|
public enum StorageType
|
|
{
|
|
Memory,
|
|
File,
|
|
}
|
|
|
|
public sealed class StreamSourceConfig
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public string? SubjectTransformPrefix { get; set; }
|
|
public string? SourceAccount { get; set; }
|
|
|
|
// Go: StreamSource.FilterSubject — only forward messages matching this subject filter.
|
|
public string? FilterSubject { get; set; }
|
|
|
|
// Deduplication window in milliseconds for Nats-Msg-Id header-based dedup.
|
|
// Defaults to 0 (disabled). When > 0, duplicate messages with the same Nats-Msg-Id
|
|
// within this window are silently dropped.
|
|
public int DuplicateWindowMs { get; set; }
|
|
|
|
// Go: StreamSource.SubjectTransforms — per-source subject transforms.
|
|
// Reference: golang/nats-server/server/stream.go — SubjectTransforms field.
|
|
public List<SubjectTransformConfig> SubjectTransforms { get; set; } = [];
|
|
}
|
|
|
|
// Go: SubjectTransformConfig — source/destination subject transform pair.
|
|
// Reference: golang/nats-server/server/stream.go — SubjectTransformConfig struct.
|
|
public sealed class SubjectTransformConfig
|
|
{
|
|
public string Source { get; set; } = string.Empty;
|
|
public string Destination { get; set; } = string.Empty;
|
|
}
|