using System.Collections.Concurrent; using HermesSocketLibrary.db; using HermesSocketServer.Models; using HermesSocketServer.Store; namespace HermesSocketServer.Services { public class ChannelManager { private readonly UserStore _users; private readonly Database _database; private readonly ServerConfiguration _configuration; private readonly Serilog.ILogger _logger; private readonly IDictionary _channels; private readonly object _lock; public ChannelManager(UserStore users, Database database, ServerConfiguration configuration, Serilog.ILogger logger) { _users = users; _database = database; _configuration = configuration; _logger = logger; _channels = new ConcurrentDictionary(); _lock = new object(); } public Task Add(string userId) { var user = _users.Get(userId); if (user == null) return Task.FromResult(null); lock (_lock) { if (_channels.ContainsKey(userId)) return Task.FromResult(null); var actionTable = _configuration.Database.Tables["Action"]; var chatterTable = _configuration.Database.Tables["Chatter"]; var policyTable = _configuration.Database.Tables["Policy"]; var redemptionTable = _configuration.Database.Tables["Redemption"]; var ttsFilterTable = _configuration.Database.Tables["TtsFilter"]; var chatters = new ChatterStore(userId, chatterTable, _database, _logger); var policies = new PolicyStore(userId, policyTable, _database, _logger); var filters = new TTSFilterStore(userId, ttsFilterTable, _database, _logger); var actions = new ActionStore(userId, actionTable, _database, _logger); var redemptions = new RedemptionStore(userId, redemptionTable, _database, _logger); Task.WaitAll([ chatters.Load(), policies.Load(), filters.Load(), actions.Load(), redemptions.Load(), ]); var channel = new Channel() { Id = userId, User = user, Chatters = chatters, Policies = policies, Filters = filters, Actions = actions, Redemptions = redemptions, }; _channels.Add(userId, channel); return Task.FromResult(channel); } } public Channel? Get(string channelId) { if (_channels.TryGetValue(channelId, out var channel)) return channel; return null; } public async Task Save(string userId) { if (!_channels.TryGetValue(userId, out var channel)) return; await Task.WhenAll([ channel.Chatters.Save(), channel.Policies.Save(), channel.Filters.Save(), channel.Actions.Save(), channel.Redemptions.Save(), ]); } public async Task Save() { foreach (var channel in _channels.Values) { _logger.Debug($"Saving channel data to database [channel id: {channel.Id}][channel name: {channel.User.Name}]"); await Task.WhenAll([ channel.Chatters.Save(), channel.Policies.Save(), channel.Filters.Save(), channel.Actions.Save(), channel.Redemptions.Save(), ]); } } } }