using HermesSocketLibrary.db; using HermesSocketLibrary.Socket.Data; using ILogger = Serilog.ILogger; namespace HermesSocketServer.Socket.Handlers { public class ChatterHandler : ISocketHandler { private const int CHATTER_BUFFER_SIZE = 2000; public int OperationCode { get; } = 6; private readonly Database _database; private readonly HashSet _chatters; private readonly long[] _array; private readonly ILogger _logger; private readonly Mutex _lock; private int _index; public ChatterHandler(Database database, ILogger logger) { _database = database; _logger = logger; _chatters = new HashSet(CHATTER_BUFFER_SIZE); _array = new long[CHATTER_BUFFER_SIZE]; _index = -1; _lock = new Mutex(); } public async Task Execute(WebSocketUser sender, T message, HermesSocketManager sockets) { if (message is not ChatterMessage data || sender.Id == null) return; try { _lock.WaitOne(); if (_chatters.Contains(data.Id)) return; _chatters.Add(data.Id); if (_index == _array.Length - 1) _index = -1; var previous = _array[++_index]; if (previous != 0) { _chatters.Remove(previous); } _array[_index] = data.Id; } finally { _lock.ReleaseMutex(); } try { string sql = "INSERT INTO \"Chatter\" (id, name) VALUES (@idd, @name) ON CONFLICT (id) DO UPDATE SET name = @name"; await _database.Execute(sql, new Dictionary() { { "idd", data.Id }, { "name", data.Name } }); } catch (Exception e) { _logger.Error(e, "Failed to add chatter."); } } } }