batch37 task4 implement group C message carriers and consumer signaling
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using System.Threading.Channels;
|
||||
using ZB.MOM.NatsNet.Server.Internal;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
internal sealed partial class NatsStream
|
||||
{
|
||||
private readonly object _consumersSync = new();
|
||||
private readonly Dictionary<string, NatsConsumer> _consumers = new(StringComparer.Ordinal);
|
||||
private List<NatsConsumer> _consumerList = [];
|
||||
private readonly IpQueue<CMsg> _sigQueue = new("js-signal");
|
||||
private readonly Channel<bool> _signalWake = Channel.CreateBounded<bool>(1);
|
||||
private readonly Channel<bool> _internalWake = Channel.CreateBounded<bool>(1);
|
||||
private readonly JsOutQ _outq = new();
|
||||
|
||||
internal static CMsg NewCMsg(string subject, ulong seq)
|
||||
{
|
||||
var msg = CMsg.Rent();
|
||||
msg.Subject = subject;
|
||||
msg.Seq = seq;
|
||||
return msg;
|
||||
}
|
||||
|
||||
internal void SignalConsumersLoop(CancellationToken cancellationToken = default)
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (!_signalWake.Reader.TryRead(out _))
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
var messages = _sigQueue.Pop();
|
||||
if (messages == null)
|
||||
continue;
|
||||
|
||||
foreach (var msg in messages)
|
||||
{
|
||||
SignalConsumers(msg.Subject, msg.Seq);
|
||||
msg.ReturnToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SignalConsumers(string subject, ulong seq)
|
||||
{
|
||||
_ = subject;
|
||||
_ = seq;
|
||||
|
||||
lock (_consumersSync)
|
||||
{
|
||||
_ = _consumerList.Count;
|
||||
}
|
||||
}
|
||||
|
||||
internal static JsPubMsg NewJSPubMsg(string destinationSubject, string subject, string? reply, byte[]? hdr, byte[]? msg, NatsConsumer? consumer, ulong seq)
|
||||
{
|
||||
var pub = GetJSPubMsgFromPool();
|
||||
pub.Subject = destinationSubject;
|
||||
pub.Reply = reply;
|
||||
pub.Hdr = hdr;
|
||||
pub.Msg = msg;
|
||||
pub.Pa = new StoreMsg
|
||||
{
|
||||
Subject = subject,
|
||||
Seq = seq,
|
||||
Hdr = hdr ?? [],
|
||||
Msg = msg ?? [],
|
||||
Buf = [],
|
||||
};
|
||||
pub.Sync = consumer;
|
||||
return pub;
|
||||
}
|
||||
|
||||
internal static JsPubMsg GetJSPubMsgFromPool() => JsPubMsg.Rent();
|
||||
|
||||
internal void SetupSendCapabilities()
|
||||
{
|
||||
_ = _outq;
|
||||
_signalWake.Writer.TryWrite(true);
|
||||
}
|
||||
|
||||
internal string AccName() => Account.Name;
|
||||
|
||||
internal string NameLocked() => Name;
|
||||
|
||||
internal void InternalLoop(CancellationToken cancellationToken = default)
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (!_internalWake.Reader.TryRead(out _))
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
var messages = _sigQueue.Pop();
|
||||
if (messages == null)
|
||||
continue;
|
||||
|
||||
foreach (var msg in messages)
|
||||
{
|
||||
SignalConsumers(msg.Subject, msg.Seq);
|
||||
msg.ReturnToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void ResetAndWaitOnConsumers()
|
||||
{
|
||||
List<NatsConsumer> snapshot;
|
||||
lock (_consumersSync)
|
||||
{
|
||||
snapshot = [.. _consumerList];
|
||||
}
|
||||
|
||||
foreach (var consumer in snapshot)
|
||||
consumer.Stop();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user