Switch to GrpcClientIdentificationService and abolish Redis for Idents (#12)
* add GrpcClientIdentificationService * remove unnecessary gauges * set to no retry policy * initialize metrics Co-authored-by: Stanley Dimant <root.darkarchon@outlook.com>
This commit is contained in:
@@ -12,10 +12,10 @@ using Discord;
|
||||
using Discord.Rest;
|
||||
using Discord.WebSocket;
|
||||
using MareSynchronosServices.Authentication;
|
||||
using MareSynchronosServices.Identity;
|
||||
using MareSynchronosShared.Data;
|
||||
using MareSynchronosShared.Metrics;
|
||||
using MareSynchronosShared.Models;
|
||||
using MareSynchronosShared.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -24,11 +24,11 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MareSynchronosServices.Discord;
|
||||
|
||||
public class DiscordBot : IHostedService
|
||||
internal class DiscordBot : IHostedService
|
||||
{
|
||||
private readonly CleanupService cleanupService;
|
||||
private readonly MareMetrics metrics;
|
||||
private readonly IClientIdentificationService clientService;
|
||||
private readonly IdentityHandler identityHandler;
|
||||
private readonly IServiceProvider services;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger<DiscordBot> logger;
|
||||
@@ -44,16 +44,15 @@ public class DiscordBot : IHostedService
|
||||
private ConcurrentDictionary<ulong, DateTime> LastVanityChange = new();
|
||||
private ConcurrentDictionary<string, DateTime> LastVanityGidChange = new();
|
||||
private ulong vanityCommandId;
|
||||
private ulong vanityGidCommandId;
|
||||
private Task cleanUpUserTask = null;
|
||||
|
||||
private SemaphoreSlim semaphore;
|
||||
|
||||
public DiscordBot(CleanupService cleanupService, MareMetrics metrics, IClientIdentificationService clientService, IServiceProvider services, IConfiguration configuration, ILogger<DiscordBot> logger)
|
||||
public DiscordBot(CleanupService cleanupService, MareMetrics metrics, IdentityHandler identityHandler, IServiceProvider services, IConfiguration configuration, ILogger<DiscordBot> logger)
|
||||
{
|
||||
this.cleanupService = cleanupService;
|
||||
this.metrics = metrics;
|
||||
this.clientService = clientService;
|
||||
this.identityHandler = identityHandler;
|
||||
this.services = services;
|
||||
_configuration = configuration.GetRequiredSection("MareSynchronos");
|
||||
this.logger = logger;
|
||||
@@ -804,7 +803,7 @@ public class DiscordBot : IHostedService
|
||||
updateStatusCts = new();
|
||||
while (!updateStatusCts.IsCancellationRequested)
|
||||
{
|
||||
var onlineUsers = await clientService.GetOnlineUsers();
|
||||
var onlineUsers = identityHandler.GetOnlineUsers(string.Empty);
|
||||
logger.LogInformation("Users online: " + onlineUsers);
|
||||
await discordClient.SetActivityAsync(new Game("Mare for " + onlineUsers + " Users")).ConfigureAwait(false);
|
||||
await Task.Delay(TimeSpan.FromSeconds(15)).ConfigureAwait(false);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MareSynchronosServices.Identity;
|
||||
|
||||
internal class IdentityHandler
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, ServerIdentity> cachedIdentities = new();
|
||||
|
||||
internal Task<string> GetUidForCharacterIdent(string ident, string serverId)
|
||||
{
|
||||
var exists = cachedIdentities.Any(f => f.Value.CharacterIdent == ident && f.Value.ServerId == serverId);
|
||||
return Task.FromResult(exists ? cachedIdentities.FirstOrDefault(f => f.Value.CharacterIdent == ident && f.Value.ServerId == serverId).Key : string.Empty);
|
||||
}
|
||||
|
||||
internal Task<ServerIdentity> GetIdentForuid(string uid)
|
||||
{
|
||||
ServerIdentity result;
|
||||
if (!cachedIdentities.TryGetValue(uid, out result))
|
||||
{
|
||||
result = new ServerIdentity();
|
||||
}
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
internal void SetIdent(string uid, string serverId, string ident)
|
||||
{
|
||||
cachedIdentities[uid] = new ServerIdentity() { ServerId = serverId, CharacterIdent = ident };
|
||||
}
|
||||
|
||||
internal void RemoveIdent(string uid, string serverId)
|
||||
{
|
||||
if (cachedIdentities.ContainsKey(uid) && cachedIdentities[uid].ServerId == serverId)
|
||||
{
|
||||
cachedIdentities.TryRemove(uid, out _);
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetOnlineUsers(string serverId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serverId))
|
||||
return cachedIdentities.Count;
|
||||
return cachedIdentities.Count(c => c.Value.ServerId == serverId);
|
||||
}
|
||||
|
||||
internal void ClearIdentsForServer(string serverId)
|
||||
{
|
||||
var serverIdentities = cachedIdentities.Where(i => i.Value.ServerId == serverId);
|
||||
foreach (var identity in serverIdentities)
|
||||
{
|
||||
cachedIdentities.TryRemove(identity.Key, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal record ServerIdentity
|
||||
{
|
||||
public string ServerId { get; set; } = string.Empty;
|
||||
public string CharacterIdent { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Grpc.Core;
|
||||
using MareSynchronosShared.Protos;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MareSynchronosServices.Identity;
|
||||
|
||||
internal class IdentityService : IdentificationService.IdentificationServiceBase
|
||||
{
|
||||
private readonly ILogger<IdentityService> _logger;
|
||||
private readonly IdentityHandler _handler;
|
||||
|
||||
public IdentityService(ILogger<IdentityService> logger, IdentityHandler handler)
|
||||
{
|
||||
_logger = logger;
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
public override Task<Empty> RemoveIdentForUid(RemoveIdentMessage request, ServerCallContext context)
|
||||
{
|
||||
_handler.RemoveIdent(request.Uid, request.ServerId);
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
public override Task<Empty> SetIdentForUid(SetIdentMessage request, ServerCallContext context)
|
||||
{
|
||||
_handler.SetIdent(request.Uid, request.ServerId, request.Ident);
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
public override async Task<CharacterIdentMessage> GetIdentForUid(UidMessage request, ServerCallContext context)
|
||||
{
|
||||
var result = await _handler.GetIdentForuid(request.Uid);
|
||||
return new CharacterIdentMessage()
|
||||
{
|
||||
Ident = result.CharacterIdent,
|
||||
ServerId = result.ServerId
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task<UidMessage> GetUidForCharacterIdent(CharacterIdentMessage request, ServerCallContext context)
|
||||
{
|
||||
var result = await _handler.GetUidForCharacterIdent(request.Ident, request.ServerId);
|
||||
return new UidMessage()
|
||||
{
|
||||
Uid = result
|
||||
};
|
||||
}
|
||||
|
||||
public override Task<OnlineUserCountResponse> GetOnlineUserCount(ServerMessage request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new OnlineUserCountResponse() { Count = _handler.GetOnlineUsers(request.ServerId) });
|
||||
}
|
||||
|
||||
public override Task<Empty> ClearIdentsForServer(ServerMessage request, ServerCallContext context)
|
||||
{
|
||||
_handler.ClearIdentsForServer(request.ServerId);
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
public override Task<Empty> RecreateServerIdents(ServerIdentMessage request, ServerCallContext context)
|
||||
{
|
||||
foreach (var identMsg in request.Idents)
|
||||
{
|
||||
_handler.SetIdent(identMsg.Uid, identMsg.ServerId, identMsg.Ident);
|
||||
}
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Prometheus;
|
||||
using System.Collections.Generic;
|
||||
using MareSynchronosShared.Services;
|
||||
using MareSynchronosServices.Identity;
|
||||
|
||||
namespace MareSynchronosServices;
|
||||
|
||||
@@ -45,29 +45,12 @@ public class Startup
|
||||
}));
|
||||
|
||||
services.AddSingleton<SecretKeyAuthenticationHandler>();
|
||||
services.AddSingleton<IdentityHandler>();
|
||||
services.AddSingleton<CleanupService>();
|
||||
services.AddTransient(_ => Configuration);
|
||||
services.AddHostedService(provider => provider.GetService<CleanupService>());
|
||||
services.AddHostedService<DiscordBot>();
|
||||
services.AddGrpc();
|
||||
|
||||
// add redis related options
|
||||
var redis = Configuration.GetSection("MareSynchronos").GetValue("RedisConnectionString", string.Empty);
|
||||
if (!string.IsNullOrEmpty(redis))
|
||||
{
|
||||
services.AddStackExchangeRedisCache(opt =>
|
||||
{
|
||||
opt.Configuration = redis;
|
||||
opt.InstanceName = "MareSynchronosCache:";
|
||||
});
|
||||
services.AddSingleton<IClientIdentificationService, DistributedClientIdentificationService>();
|
||||
services.AddHostedService(p => p.GetService<IClientIdentificationService>());
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton<IClientIdentificationService, LocalClientIdentificationService>();
|
||||
services.AddHostedService(p => p.GetService<IClientIdentificationService>());
|
||||
}
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
@@ -80,6 +63,7 @@ public class Startup
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapGrpcService<AuthenticationService>();
|
||||
endpoints.MapGrpcService<IdentityService>();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user