Added channel saving. Fixed channel loading. Added policy store to channels.

This commit is contained in:
Tom 2024-10-20 19:32:30 +00:00
parent 5d69c647cf
commit a9cdb65895
6 changed files with 178 additions and 16 deletions

View File

@ -7,5 +7,6 @@ namespace HermesSocketServer.Models
public string Id { get; set; }
public User User { get; set; }
public ChatterStore Chatters { get; set; }
public PolicyStore Policies { get; set; }
}
}

12
Models/Policy.cs Normal file
View File

@ -0,0 +1,12 @@
namespace HermesSocketServer.Store
{
public class Policy
{
public string Id { get; set; }
public string UserId { get; set; }
public string GroupId { get; set; }
public string Path { get; set; }
public int Usage { get; set; }
public TimeSpan Span { get; set; }
}
}

View File

@ -11,6 +11,7 @@ namespace HermesSocketServer.Services
private readonly Database _database;
private readonly Serilog.ILogger _logger;
private readonly IDictionary<string, Channel> _channels;
private readonly object _lock;
public ChannelManager(UserStore users, Database database, Serilog.ILogger logger)
{
@ -18,32 +19,45 @@ namespace HermesSocketServer.Services
_database = database;
_logger = logger;
_channels = new ConcurrentDictionary<string, Channel>();
_lock = new object();
}
public async Task Add(string userId)
public async Task<Channel?> Add(string userId)
{
var user = _users.Get(userId);
if (user == null)
{
return;
return null;
}
if (_channels.ContainsKey(userId))
lock (_lock)
{
return;
if (_channels.ContainsKey(userId))
{
return null;
}
}
var chatters = new ChatterStore(userId, _database, _logger);
await chatters.Load();
var policies = new PolicyStore(userId, _database, _logger);
await Task.WhenAll([
chatters.Load(),
policies.Load(),
]);
var channel = new Channel()
{
Id = userId,
User = user,
Chatters = chatters
Chatters = chatters,
Policies = policies
};
_channels.Add(userId, channel);
lock (_lock)
{
_channels.Add(userId, channel);
}
return channel;
}
public Channel? Get(string channelId)
@ -52,5 +66,28 @@ namespace HermesSocketServer.Services
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(),
]);
}
}
}
}

View File

@ -4,13 +4,15 @@ namespace HermesSocketServer.Services
{
public class DatabaseService : BackgroundService
{
private readonly ChannelManager _channels;
private readonly VoiceStore _voices;
private readonly UserStore _users;
private readonly ServerConfiguration _configuration;
private readonly Serilog.ILogger _logger;
public DatabaseService(VoiceStore voices, UserStore users, ServerConfiguration configuration, Serilog.ILogger logger)
public DatabaseService(ChannelManager channels, VoiceStore voices, UserStore users, ServerConfiguration configuration, Serilog.ILogger logger)
{
_channels = channels;
_voices = voices;
_users = users;
_configuration = configuration;
@ -26,14 +28,16 @@ namespace HermesSocketServer.Services
await Task.Run(async () =>
{
var tasks = new List<Task>();
await Task.Delay(TimeSpan.FromSeconds(_configuration.Database.SaveDelayInSeconds));
while (true)
{
tasks.Add(_voices.Save());
tasks.Add(_users.Save());
tasks.Add(Task.Delay(TimeSpan.FromSeconds(_configuration.Database.SaveDelayInSeconds)));
await Task.WhenAll(tasks);
await Task.WhenAll([
_voices.Save(),
_users.Save(),
_channels.Save(),
Task.Delay(TimeSpan.FromSeconds(_configuration.Database.SaveDelayInSeconds)),
]);
}
});
}

View File

@ -55,11 +55,14 @@ namespace HermesSocketServer.Socket.Handlers
sender.WebLogin = data.WebLogin;
}
await _manager.Add(userId);
var channel = _manager.Get(userId);
if (channel == null)
return;
{
channel = await _manager.Add(userId);
if (channel == null)
return;
}
sender.Name = channel.User.Name;
sender.Admin = channel.User.Role == "ADMIN";

105
Store/PolicyStore.cs Normal file
View File

@ -0,0 +1,105 @@
using HermesSocketLibrary.db;
namespace HermesSocketServer.Store
{
public class PolicyStore : GroupSaveStore<string, Policy>
{
private readonly string _userId;
private readonly Database _database;
private readonly Serilog.ILogger _logger;
private readonly GroupSaveSqlGenerator<Policy> _generator;
public PolicyStore(string userId, Database database, Serilog.ILogger logger) : base(logger)
{
_userId = userId;
_database = database;
_logger = logger;
var ctp = new Dictionary<string, string>
{
{ "id", "Id" },
{ "userId", "UserId" },
{ "groupId", "GroupId" },
{ "path", "Path" },
{ "count", "Usage" },
{ "timespan", "Span" },
};
_generator = new GroupSaveSqlGenerator<Policy>(ctp);
}
public override async Task Load()
{
var data = new Dictionary<string, object>() { { "user", _userId } };
string sql = $"SELECT id, \"groupId\", path, count, timespan FROM \"GroupPermissionPolicy\" WHERE \"userId\" = @user";
await _database.Execute(sql, data, (reader) =>
{
string id = reader.GetString(0).ToString();
_store.Add(id, new Policy()
{
Id = id,
UserId = _userId,
GroupId = reader.GetString(1),
Path = reader.GetString(2),
Usage = reader.GetInt32(3),
Span = TimeSpan.FromMilliseconds(reader.GetInt32(4)),
});
});
_logger.Information($"Loaded {_store.Count} policies from database.");
}
protected override void OnInitialAdd(string key, Policy value)
{
}
protected override void OnInitialModify(string key, Policy value)
{
}
protected override void OnInitialRemove(string key)
{
}
public override async Task<bool> Save()
{
int count = 0;
string sql = string.Empty;
if (_added.Any())
{
lock (_lock)
{
count = _added.Count;
sql = _generator.GenerateInsertSql("GroupPermissionPolicy", _added.Select(a => _store[a]), ["id", "userId", "groupId", "path", "count", "timespan"]);
_added.Clear();
}
_logger.Debug($"GroupPermissionPolicy - Adding {count} rows to database: {sql}");
await _database.ExecuteScalar(sql);
}
if (_modified.Any())
{
lock (_lock)
{
count = _modified.Count;
sql = _generator.GenerateUpdateSql("GroupPermissionPolicy", _modified.Select(m => _store[m]), ["id"], ["userId", "groupId", "path", "count", "timespan"]);
_modified.Clear();
}
_logger.Debug($"GroupPermissionPolicy - Modifying {count} rows in database: {sql}");
await _database.ExecuteScalar(sql);
}
if (_deleted.Any())
{
lock (_lock)
{
count = _deleted.Count;
sql = _generator.GenerateDeleteSql("GroupPermissionPolicy", _deleted, ["id"]);
_deleted.Clear();
}
_logger.Debug($"GroupPermissionPolicy - Deleting {count} rows from database: {sql}");
await _database.ExecuteScalar(sql);
}
return true;
}
}
}