feat: add remote control plane and whitelist reads
Build web service image / build (push) Successful in 1m53s
Build web service image / build (push) Successful in 1m53s
This commit is contained in:
@@ -1,23 +1,35 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Channels;
|
||||
using WxAgent.Core;
|
||||
|
||||
namespace WxAgent.Service;
|
||||
|
||||
public sealed record AgentEvent(string EventId, string AccountId, string? Session, string Kind, string Summary, DateTimeOffset At);
|
||||
public sealed record AgentEvent(
|
||||
string EventId,
|
||||
string AccountId,
|
||||
string? Session,
|
||||
string Kind,
|
||||
string Summary,
|
||||
DateTimeOffset At,
|
||||
[property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] string? ChatId = null,
|
||||
[property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] ReportingChatType? ChatType = null,
|
||||
[property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] string? Content = null);
|
||||
|
||||
public sealed class EventHub
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, Subscription> subscriptions = new();
|
||||
private readonly object gate = new();
|
||||
private readonly Queue<AgentEvent> history = new();
|
||||
private readonly Queue<HistoryEntry> history = new();
|
||||
private const int MaxHistory = 200;
|
||||
|
||||
public (string SubscriptionId, IReadOnlyList<AgentEvent> Replay, bool Gap) Subscribe(string principal, string? after)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
var replay = after is null ? [] : history.SkipWhile(e => e.EventId != after).Skip(1).ToArray();
|
||||
var gap = after is not null && !history.Any(e => e.EventId == after);
|
||||
var scopedHistory = history.Where(entry => entry.Principal == principal).Select(entry => entry.Event).ToArray();
|
||||
var replay = after is null ? [] : scopedHistory.SkipWhile(e => e.EventId != after).Skip(1).ToArray();
|
||||
var gap = after is not null && !scopedHistory.Any(e => e.EventId == after);
|
||||
var id = Convert.ToHexString(System.Security.Cryptography.RandomNumberGenerator.GetBytes(16));
|
||||
subscriptions[id] = new Subscription(principal);
|
||||
return (id, replay, gap);
|
||||
@@ -28,7 +40,7 @@ public sealed class EventHub
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
history.Enqueue(value);
|
||||
history.Enqueue(new HistoryEntry(principal, value));
|
||||
while (history.Count > MaxHistory) history.Dequeue();
|
||||
foreach (var subscription in subscriptions.Values.Where(s => s.Principal == principal))
|
||||
{
|
||||
@@ -47,6 +59,8 @@ public sealed class EventHub
|
||||
|
||||
public void Remove(string id) => subscriptions.TryRemove(id, out _);
|
||||
|
||||
private sealed record HistoryEntry(string Principal, AgentEvent Event);
|
||||
|
||||
public sealed class Subscription(string principal)
|
||||
{
|
||||
public string Principal { get; } = principal;
|
||||
|
||||
Reference in New Issue
Block a user