Files
SNote/Server/Security/PeerCache.cs
T
2026-06-01 05:09:20 +10:00

54 lines
1.6 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace SNote.Server.Security;
public class PeerCache
{
private readonly ConcurrentDictionary<string, byte> _downstreamPeers = new(StringComparer.OrdinalIgnoreCase);
private readonly ConcurrentDictionary<string, DateTime> _recentBroadcastIds = new(StringComparer.OrdinalIgnoreCase);
public void RegisterPeer(string peerUrl)
{
if (string.IsNullOrWhiteSpace(peerUrl)) return;
var cleanUrl = peerUrl.Trim().TrimEnd('/');
_downstreamPeers.TryAdd(cleanUrl, 0);
Console.WriteLine($"[PeerCache] Registered downstream peer node: {cleanUrl}");
}
public void RemovePeer(string peerUrl)
{
if (string.IsNullOrWhiteSpace(peerUrl)) return;
var cleanUrl = peerUrl.Trim().TrimEnd('/');
if (_downstreamPeers.TryRemove(cleanUrl, out _))
{
Console.WriteLine($"[PeerCache] Evicted offline peer node: {cleanUrl}");
}
}
public List<string> GetPeers()
{
return new List<string>(_downstreamPeers.Keys);
}
public bool TryProcessBroadcast(string broadcastId)
{
if (string.IsNullOrWhiteSpace(broadcastId)) return false;
// Clean up old entries to prevent infinite memory growth (older than 10 minutes)
var cutoff = DateTime.UtcNow.AddMinutes(-10);
foreach (var kvp in _recentBroadcastIds)
{
if (kvp.Value < cutoff)
{
_recentBroadcastIds.TryRemove(kvp.Key, out _);
}
}
return _recentBroadcastIds.TryAdd(broadcastId, DateTime.UtcNow);
}
}