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:
@@ -16,8 +16,50 @@ service FileService {
|
||||
rpc DeleteFiles (DeleteFilesRequest) returns (Empty);
|
||||
}
|
||||
|
||||
service IdentificationService {
|
||||
rpc GetOnlineUserCount (ServerMessage) returns (OnlineUserCountResponse);
|
||||
rpc RemoveIdentForUid (RemoveIdentMessage) returns (Empty);
|
||||
rpc SetIdentForUid (SetIdentMessage) returns (Empty);
|
||||
rpc GetUidForCharacterIdent (CharacterIdentMessage) returns (UidMessage);
|
||||
rpc GetIdentForUid (UidMessage) returns (CharacterIdentMessage);
|
||||
rpc ClearIdentsForServer (ServerMessage) returns (Empty);
|
||||
rpc RecreateServerIdents (ServerIdentMessage) returns (Empty);
|
||||
}
|
||||
|
||||
message Empty { }
|
||||
|
||||
message ServerIdentMessage {
|
||||
repeated SetIdentMessage idents = 1;
|
||||
}
|
||||
|
||||
message ServerMessage {
|
||||
string server_id = 1;
|
||||
}
|
||||
|
||||
message OnlineUserCountResponse {
|
||||
int64 count = 1;
|
||||
}
|
||||
|
||||
message RemoveIdentMessage {
|
||||
string uid = 1;
|
||||
string server_id = 2;
|
||||
}
|
||||
|
||||
message SetIdentMessage {
|
||||
string uid = 1;
|
||||
string server_id = 2;
|
||||
string ident = 3;
|
||||
}
|
||||
|
||||
message CharacterIdentMessage {
|
||||
string server_id = 1;
|
||||
string ident = 2;
|
||||
}
|
||||
|
||||
message UidMessage {
|
||||
string uid = 1;
|
||||
}
|
||||
|
||||
message UploadFileRequest {
|
||||
string hash = 1;
|
||||
string uploader = 2;
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
using MareSynchronosShared.Metrics;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public abstract class BaseClientIdentificationService : IClientIdentificationService
|
||||
{
|
||||
private readonly MareMetrics metrics;
|
||||
protected ConcurrentDictionary<string, string> OnlineClients = new();
|
||||
protected BaseClientIdentificationService(MareMetrics metrics)
|
||||
{
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
public virtual Task<int> GetOnlineUsers()
|
||||
{
|
||||
return Task.FromResult(OnlineClients.Count);
|
||||
}
|
||||
|
||||
public Task<string?> GetUidForCharacterIdent(string characterIdent)
|
||||
{
|
||||
var result = OnlineClients.SingleOrDefault(u =>
|
||||
string.Compare(u.Value, characterIdent, StringComparison.InvariantCultureIgnoreCase) == 0);
|
||||
return Task.FromResult(result.Equals(new KeyValuePair<string, string>()) ? null : result.Key);
|
||||
}
|
||||
|
||||
public virtual Task<string?> GetCharacterIdentForUid(string uid)
|
||||
{
|
||||
if (!OnlineClients.TryGetValue(uid, out var result))
|
||||
{
|
||||
return Task.FromResult((string?)null);
|
||||
}
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public virtual Task MarkUserOnline(string uid, string charaIdent)
|
||||
{
|
||||
OnlineClients[uid] = charaIdent;
|
||||
metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, OnlineClients.Count);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual Task MarkUserOffline(string uid)
|
||||
{
|
||||
if (OnlineClients.TryRemove(uid, out _))
|
||||
{
|
||||
metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, OnlineClients.Count);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, 0);
|
||||
OnlineClients = new();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using System.Text;
|
||||
using MareSynchronosShared.Metrics;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public class DistributedClientIdentificationService : BaseClientIdentificationService
|
||||
{
|
||||
private readonly IDistributedCache distributedCache;
|
||||
private readonly ILogger<DistributedClientIdentificationService> logger;
|
||||
private readonly IConfiguration configuration;
|
||||
private const string RedisPrefix = "uidcache:";
|
||||
|
||||
public DistributedClientIdentificationService(MareMetrics metrics, IDistributedCache distributedCache, IConfiguration configuration, ILogger<DistributedClientIdentificationService> logger) : base(metrics)
|
||||
{
|
||||
this.distributedCache = distributedCache;
|
||||
this.logger = logger;
|
||||
this.configuration = configuration.GetSection("MareSynchronos");
|
||||
}
|
||||
|
||||
public override async Task<int> GetOnlineUsers()
|
||||
{
|
||||
try
|
||||
{
|
||||
var redis = configuration.GetValue<string>("RedisConnectionString");
|
||||
var conn = await ConnectionMultiplexer.ConnectAsync(redis).ConfigureAwait(false);
|
||||
var endpoint = conn.GetEndPoints().First();
|
||||
return await conn.GetServer(endpoint).KeysAsync(pattern: "*" + RedisPrefix + "*").CountAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Error during GetOnlineUsers");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<string?> GetCharacterIdentForUid(string uid)
|
||||
{
|
||||
var localIdent = await base.GetCharacterIdentForUid(uid).ConfigureAwait(false);
|
||||
if (localIdent != null) return localIdent;
|
||||
var cachedIdent = await distributedCache.GetStringAsync(RedisPrefix + uid).ConfigureAwait(false);
|
||||
return cachedIdent ?? null;
|
||||
}
|
||||
|
||||
public override async Task MarkUserOffline(string uid)
|
||||
{
|
||||
await base.MarkUserOffline(uid).ConfigureAwait(false);
|
||||
await distributedCache.RemoveAsync(RedisPrefix + uid).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public override async Task MarkUserOnline(string uid, string charaIdent)
|
||||
{
|
||||
await base.MarkUserOnline(uid, charaIdent).ConfigureAwait(false);
|
||||
await distributedCache.SetAsync(RedisPrefix + uid, Encoding.UTF8.GetBytes(charaIdent), new DistributedCacheEntryOptions()
|
||||
{
|
||||
AbsoluteExpiration = DateTime.Now.AddDays(7)
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public override Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var uid in OnlineClients)
|
||||
{
|
||||
distributedCache.Remove(RedisPrefix + uid.Key);
|
||||
}
|
||||
return base.StopAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public interface IClientIdentificationService : IHostedService
|
||||
{
|
||||
Task<int> GetOnlineUsers();
|
||||
Task<string?> GetUidForCharacterIdent(string characterIdent);
|
||||
Task<string?> GetCharacterIdentForUid(string uid);
|
||||
Task MarkUserOnline(string uid, string charaIdent);
|
||||
Task MarkUserOffline(string uid);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using MareSynchronosShared.Metrics;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public class LocalClientIdentificationService : BaseClientIdentificationService
|
||||
{
|
||||
public LocalClientIdentificationService(MareMetrics metrics) : base(metrics)
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user