feat: complete final jetstream parity transport and runtime baselines
This commit is contained in:
@@ -48,8 +48,14 @@ public sealed class StreamManager
|
||||
|
||||
var handle = _streams.AddOrUpdate(
|
||||
normalized.Name,
|
||||
_ => new StreamHandle(normalized, new MemStore()),
|
||||
(_, existing) => existing with { Config = normalized });
|
||||
_ => new StreamHandle(normalized, CreateStore(normalized)),
|
||||
(_, existing) =>
|
||||
{
|
||||
if (existing.Config.Storage == normalized.Storage)
|
||||
return existing with { Config = normalized };
|
||||
|
||||
return new StreamHandle(normalized, CreateStore(normalized));
|
||||
});
|
||||
_replicaGroups.AddOrUpdate(
|
||||
normalized.Name,
|
||||
_ => new StreamReplicaGroup(normalized.Name, normalized.Replicas),
|
||||
@@ -150,6 +156,25 @@ public sealed class StreamManager
|
||||
if (stream == null)
|
||||
return null;
|
||||
|
||||
var stateBefore = stream.Store.GetStateAsync(default).GetAwaiter().GetResult();
|
||||
if (stream.Config.MaxBytes > 0 && (long)stateBefore.Bytes + payload.Length > stream.Config.MaxBytes)
|
||||
{
|
||||
if (stream.Config.Discard == DiscardPolicy.New)
|
||||
{
|
||||
return new PubAck
|
||||
{
|
||||
Stream = stream.Config.Name,
|
||||
ErrorCode = 10054,
|
||||
};
|
||||
}
|
||||
|
||||
while ((long)stateBefore.Bytes + payload.Length > stream.Config.MaxBytes && stateBefore.FirstSeq > 0)
|
||||
{
|
||||
stream.Store.RemoveAsync(stateBefore.FirstSeq, default).GetAwaiter().GetResult();
|
||||
stateBefore = stream.Store.GetStateAsync(default).GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
|
||||
if (_replicaGroups.TryGetValue(stream.Config.Name, out var replicaGroup))
|
||||
_ = replicaGroup.ProposeAsync($"PUB {subject}", default).GetAwaiter().GetResult();
|
||||
|
||||
@@ -181,12 +206,17 @@ public sealed class StreamManager
|
||||
Name = config.Name,
|
||||
Subjects = config.Subjects.Count == 0 ? [] : [.. config.Subjects],
|
||||
MaxMsgs = config.MaxMsgs,
|
||||
MaxBytes = config.MaxBytes,
|
||||
MaxMsgsPer = config.MaxMsgsPer,
|
||||
MaxAgeMs = config.MaxAgeMs,
|
||||
MaxConsumers = config.MaxConsumers,
|
||||
Retention = config.Retention,
|
||||
Discard = config.Discard,
|
||||
Storage = config.Storage,
|
||||
Replicas = config.Replicas,
|
||||
Mirror = config.Mirror,
|
||||
Source = config.Source,
|
||||
Sources = config.Sources.Count == 0 ? [] : [.. config.Sources.Select(s => new StreamSourceConfig { Name = s.Name })],
|
||||
};
|
||||
|
||||
return copy;
|
||||
@@ -241,6 +271,18 @@ public sealed class StreamManager
|
||||
var list = _sourcesByOrigin.GetOrAdd(stream.Config.Source, _ => []);
|
||||
list.Add(new SourceCoordinator(stream.Store));
|
||||
}
|
||||
|
||||
if (stream.Config.Sources.Count > 0)
|
||||
{
|
||||
foreach (var source in stream.Config.Sources)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(source.Name) || !_streams.TryGetValue(source.Name, out _))
|
||||
continue;
|
||||
|
||||
var list = _sourcesByOrigin.GetOrAdd(source.Name, _ => []);
|
||||
list.Add(new SourceCoordinator(stream.Store));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +300,30 @@ public sealed class StreamManager
|
||||
source.OnOriginAppendAsync(stored, default).GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStoreBackendType(string streamName)
|
||||
{
|
||||
if (!_streams.TryGetValue(streamName, out var stream))
|
||||
return "missing";
|
||||
|
||||
return stream.Store switch
|
||||
{
|
||||
FileStore => "file",
|
||||
_ => "memory",
|
||||
};
|
||||
}
|
||||
|
||||
private static IStreamStore CreateStore(StreamConfig config)
|
||||
{
|
||||
return config.Storage switch
|
||||
{
|
||||
StorageType.File => new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = Path.Combine(Path.GetTempPath(), "natsdotnet-js-store", config.Name),
|
||||
}),
|
||||
_ => new MemStore(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record StreamHandle(StreamConfig Config, IStreamStore Store);
|
||||
|
||||
Reference in New Issue
Block a user