Files
natsnet/dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamLifecycle.cs
2026-02-28 22:52:06 -05:00

72 lines
2.7 KiB
C#

using System.Text.Json;
namespace ZB.MOM.NatsNet.Server;
public sealed partial class Account
{
internal (NatsStream? Stream, Exception? Error) AddStream(StreamConfig config) =>
AddStreamWithAssignment(config, null, null, pedantic: false);
internal (NatsStream? Stream, Exception? Error) AddStreamWithStore(StreamConfig config, FileStoreConfig? fileStoreConfig) =>
AddStreamWithAssignment(config, fileStoreConfig, null, pedantic: false);
internal (NatsStream? Stream, Exception? Error) AddStreamPedantic(StreamConfig config, bool pedantic) =>
AddStreamWithAssignment(config, null, null, pedantic);
internal (NatsStream? Stream, Exception? Error) AddStreamWithAssignment(
StreamConfig config,
FileStoreConfig? fileStoreConfig,
StreamAssignment? assignment,
bool pedantic)
{
if (config == null)
return (null, new ArgumentNullException(nameof(config)));
var (server, jsa, error) = CheckForJetStream();
if (error != null || server == null || jsa == null)
return (null, error ?? new InvalidOperationException("jetstream not enabled for account"));
if (string.IsNullOrWhiteSpace(config.Name))
return (null, new InvalidOperationException("stream name is required"));
var normalized = config.Clone();
if (normalized.Subjects == null || normalized.Subjects.Length == 0)
normalized.Subjects = [$"{normalized.Name}.>"];
_ = pedantic;
_ = fileStoreConfig;
jsa.Lock.EnterWriteLock();
try
{
if (jsa.Streams.TryGetValue(normalized.Name, out var existingObject) && existingObject is NatsStream existing)
{
if (StreamConfigsEqual(existing.Config, normalized))
{
if (assignment != null)
existing.SetStreamAssignment(assignment);
return (existing, null);
}
return (null, new InvalidOperationException("stream name already in use"));
}
IStreamStore store = new JetStreamMemStore(normalized.Clone());
var stream = NatsStream.Create(this, normalized, jsa, store, assignment, server);
if (stream == null)
return (null, new InvalidOperationException("stream creation failed"));
jsa.Streams[normalized.Name] = stream;
return (stream, null);
}
finally
{
jsa.Lock.ExitWriteLock();
}
}
private static bool StreamConfigsEqual(StreamConfig left, StreamConfig right)
=> string.Equals(JsonSerializer.Serialize(left), JsonSerializer.Serialize(right), StringComparison.Ordinal);
}