task2: implement batch38 group A consumer lifecycle features

This commit is contained in:
Joseph Doherty
2026-03-01 00:11:47 -05:00
parent ad3a1bbb38
commit fce6bd7dca
13 changed files with 725 additions and 3 deletions

View File

@@ -0,0 +1,80 @@
namespace ZB.MOM.NatsNet.Server;
internal sealed partial class NatsStream
{
internal (NatsConsumer? Consumer, Exception? Error) AddConsumerWithAction(
ConsumerConfig config,
string oname,
ConsumerAction action,
bool pedantic = false) =>
AddConsumerWithAssignment(config, oname, null, isRecovering: false, action, pedantic);
internal (NatsConsumer? Consumer, Exception? Error) AddConsumer(
ConsumerConfig config,
string oname,
bool pedantic = false) =>
AddConsumerWithAssignment(config, oname, null, isRecovering: false, ConsumerAction.CreateOrUpdate, pedantic);
internal (NatsConsumer? Consumer, Exception? Error) AddConsumerWithAssignment(
ConsumerConfig config,
string oname,
ConsumerAssignment? assignment,
bool isRecovering,
ConsumerAction action,
bool pedantic = false)
{
ArgumentNullException.ThrowIfNull(config);
_mu.EnterWriteLock();
try
{
if (_closed)
return (null, new InvalidOperationException("stream closed"));
var name = !string.IsNullOrWhiteSpace(oname)
? oname
: (!string.IsNullOrWhiteSpace(config.Name) ? config.Name! : (config.Durable ?? string.Empty));
if (string.IsNullOrWhiteSpace(name))
return (null, new InvalidOperationException("consumer name required"));
config.Name = name;
config.Durable ??= name;
var defaultsErr = NatsConsumer.SetConsumerConfigDefaults(config, Config, null, pedantic);
if (defaultsErr is not null)
return (null, new InvalidOperationException(defaultsErr.Description ?? "consumer defaults invalid"));
var cfgErr = NatsConsumer.CheckConsumerCfg(config, Config, null, isRecovering);
if (cfgErr is not null)
return (null, new InvalidOperationException(cfgErr.Description ?? "consumer config invalid"));
if (_consumers.TryGetValue(name, out var existing))
{
if (action == ConsumerAction.Create)
return (null, new InvalidOperationException(JsApiErrors.NewJSConsumerAlreadyExistsError().Description ?? "consumer exists"));
existing.UpdateConfig(config);
if (assignment is not null)
existing.SetConsumerAssignment(assignment);
return (existing, null);
}
if (action == ConsumerAction.Update)
return (null, new InvalidOperationException(JsApiErrors.NewJSConsumerDoesNotExistError().Description ?? "consumer does not exist"));
var consumer = NatsConsumer.Create(this, config, action, assignment);
if (consumer is null)
return (null, new InvalidOperationException("consumer create failed"));
consumer.SetConsumerAssignment(assignment);
consumer.UpdateInactiveThreshold(config);
consumer.UpdatePauseState(config);
_consumers[name] = consumer;
return (consumer, null);
}
finally
{
_mu.ExitWriteLock();
}
}
}