task3: implement batch38 group B lifecycle and advisories
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
using System.Text;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
internal sealed partial class NatsConsumer
|
||||
{
|
||||
private string? _lastAdvisorySubject;
|
||||
private byte[]? _lastAdvisoryPayload;
|
||||
private DateTime _lastAdvisorySent;
|
||||
|
||||
internal bool SendAdvisory(string subject, object advisory)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(subject) || advisory is null)
|
||||
return false;
|
||||
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
_lastAdvisorySubject = subject;
|
||||
_lastAdvisoryPayload = Encoding.UTF8.GetBytes(advisory.ToString() ?? string.Empty);
|
||||
_lastAdvisorySent = DateTime.UtcNow;
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool SendDeleteAdvisoryLocked() =>
|
||||
SendAdvisory($"{JsApiSubjects.JsAdvisoryConsumerDeleted}.{Stream}.{Name}", new { action = "delete" });
|
||||
|
||||
internal bool SendPinnedAdvisoryLocked(string pinId) =>
|
||||
SendAdvisory($"{JsApiSubjects.JsAdvisoryConsumerPinned}.{Stream}.{Name}", new { pin = pinId });
|
||||
|
||||
internal bool SendUnpinnedAdvisoryLocked(string pinId) =>
|
||||
SendAdvisory($"{JsApiSubjects.JsAdvisoryConsumerUnpinned}.{Stream}.{Name}", new { pin = pinId });
|
||||
|
||||
internal bool SendCreateAdvisory() =>
|
||||
SendAdvisory($"{JsApiSubjects.JsAdvisoryConsumerCreated}.{Stream}.{Name}", new { action = "create" });
|
||||
|
||||
internal bool SendPauseAdvisoryLocked(DateTime pauseUntil) =>
|
||||
SendAdvisory($"{JsApiSubjects.JsAdvisoryConsumerPause}.{Stream}.{Name}", new { pauseUntil });
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
internal sealed partial class NatsConsumer
|
||||
{
|
||||
private readonly HashSet<string> _internalSubscriptions = new(StringComparer.Ordinal);
|
||||
private readonly Channel<bool> _updateChannel = Channel.CreateBounded<bool>(4);
|
||||
private Channel<bool>? _monitorQuitChannel = Channel.CreateBounded<bool>(1);
|
||||
|
||||
internal ChannelReader<bool>? MonitorQuitC()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return _monitorQuitChannel?.Reader;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SignalMonitorQuit()
|
||||
{
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
var channel = _monitorQuitChannel;
|
||||
if (channel is null)
|
||||
return;
|
||||
|
||||
channel.Writer.TryWrite(true);
|
||||
channel.Writer.TryComplete();
|
||||
_monitorQuitChannel = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal ChannelReader<bool> UpdateC() => _updateChannel.Reader;
|
||||
|
||||
internal bool CheckQueueInterest(string? queue = null)
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
if (_closed)
|
||||
return false;
|
||||
|
||||
if (_internalSubscriptions.Count > 0)
|
||||
return true;
|
||||
|
||||
return !string.IsNullOrWhiteSpace(queue) && _internalSubscriptions.Contains(queue);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal void ClearNode() => ClearRaftNode();
|
||||
|
||||
internal bool IsLeaderInternal() => IsLeader();
|
||||
|
||||
internal ConsumerInfo? HandleClusterConsumerInfoRequest() =>
|
||||
IsLeader() && !_closed ? GetInfo() : null;
|
||||
|
||||
internal bool SubscribeInternal(string subject)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(subject))
|
||||
return false;
|
||||
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
var added = _internalSubscriptions.Add(subject);
|
||||
if (added)
|
||||
_updateChannel.Writer.TryWrite(true);
|
||||
return added;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Unsubscribe(string subject)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(subject))
|
||||
return false;
|
||||
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
var removed = _internalSubscriptions.Remove(subject);
|
||||
if (removed)
|
||||
_updateChannel.Writer.TryWrite(true);
|
||||
return removed;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal DateTime CreatedTime()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return Created;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetCreatedTime(DateTime created)
|
||||
{
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
Created = created;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasDeliveryInterest()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
if (_closed || string.IsNullOrWhiteSpace(Config.DeliverSubject))
|
||||
return false;
|
||||
|
||||
return _internalSubscriptions.Contains(Config.DeliverSubject!);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user