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 Serilog.ILogger _logger; private readonly IDictionary _channels; private readonly object _lock; public ChannelManager(UserStore users, Database database, Serilog.ILogger logger) { _users = users; _database = database; _logger = logger; _channels = new ConcurrentDictionary(); _lock = new object(); } public async Task Add(string userId) { var user = _users.Get(userId); if (user == null) { return null; } lock (_lock) { if (_channels.ContainsKey(userId)) { return null; } } var chatters = new ChatterStore(userId, _database, _logger); var policies = new PolicyStore(userId, _database, _logger); await Task.WhenAll([ chatters.Load(), policies.Load(), ]); var channel = new Channel() { Id = userId, User = user, Chatters = chatters, Policies = policies }; lock (_lock) { _channels.Add(userId, channel); } return 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(), ]); } 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(), ]); } } } }