65 lines
2.1 KiB
C#
65 lines
2.1 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Threading.Channels;
|
|
using Fleet.Core;
|
|
using MoShiro.Protocol;
|
|
|
|
namespace MoShiro.Backend.Application;
|
|
|
|
/// <summary>发布到 SSE 订阅者的信号。SSE 只负责“更快地获得变化”,推送的内容都能由 REST 查询重建。</summary>
|
|
public abstract record LiveSignal;
|
|
|
|
/// <summary>节点上下线等。</summary>
|
|
public sealed record NodeSignal(string Kind, string Id, bool Online, long AtMs) : LiveSignal;
|
|
|
|
/// <summary>某条序列有新的原始块入库。</summary>
|
|
public sealed record ChunkSignal(NodeId AgentId, string Series) : LiveSignal;
|
|
|
|
public sealed record TestSignal(TestId TestId) : LiveSignal;
|
|
|
|
/// <summary>某个 Agent 的主机资源占用有了新的快照(实时推给展示页)。</summary>
|
|
public sealed record HostSignal(NodeId Node, HostSnapshot Host) : LiveSignal;
|
|
|
|
public sealed class LiveSubscription : IDisposable
|
|
{
|
|
private readonly LiveHub _hub;
|
|
private readonly Channel<LiveSignal> _channel = Channel.CreateBounded<LiveSignal>(new BoundedChannelOptions(256) { FullMode = BoundedChannelFullMode.DropOldest });
|
|
|
|
internal LiveSubscription(LiveHub hub)
|
|
{
|
|
_hub = hub;
|
|
}
|
|
|
|
public ChannelReader<LiveSignal> Reader => _channel.Reader;
|
|
|
|
internal void Post(LiveSignal signal) => _channel.Writer.TryWrite(signal);
|
|
|
|
public void Dispose()
|
|
{
|
|
_hub.Remove(this);
|
|
_channel.Writer.TryComplete();
|
|
}
|
|
}
|
|
|
|
/// <summary>内存中的发布订阅:入库、节点上下线、测试状态变化都经过这里。</summary>
|
|
public sealed class LiveHub
|
|
{
|
|
private readonly ConcurrentDictionary<LiveSubscription, byte> _subscriptions = new();
|
|
|
|
public LiveSubscription Subscribe()
|
|
{
|
|
var subscription = new LiveSubscription(this);
|
|
_subscriptions[subscription] = 0;
|
|
return subscription;
|
|
}
|
|
|
|
public void Publish(LiveSignal signal)
|
|
{
|
|
foreach (LiveSubscription subscription in _subscriptions.Keys)
|
|
{
|
|
subscription.Post(signal);
|
|
}
|
|
}
|
|
|
|
internal void Remove(LiveSubscription subscription) => _subscriptions.TryRemove(subscription, out _);
|
|
}
|