attempt to switch ident service to redis

This commit is contained in:
rootdarkarchon
2023-01-08 14:51:56 +01:00
parent 61111d387a
commit a182f36485
23 changed files with 118 additions and 683 deletions

View File

@@ -82,12 +82,12 @@ public partial class MareHub
public async Task<List<OnlineUserDto>> AdminGetOnlineUsers()
{
var users = await _dbContext.Users.AsNoTracking().ToListAsync().ConfigureAwait(false);
return users.Where(c => !string.IsNullOrEmpty(_clientIdentService.GetCharacterIdentForUid(c.UID))).Select(b => new OnlineUserDto
return users.Select(user => new { user, GetIdentFromUidFromRedis(user.UID).Result }).Where(a => !string.IsNullOrEmpty(a.Result)).Select(b => new OnlineUserDto
{
CharacterNameHash = _clientIdentService.GetCharacterIdentForUid(b.UID),
UID = b.UID,
IsModerator = b.IsModerator,
IsAdmin = b.IsAdmin
CharacterNameHash = b.Result,
UID = b.user.UID,
IsModerator = b.user.IsModerator,
IsAdmin = b.user.IsAdmin
}).ToList();
}

View File

@@ -7,6 +7,27 @@ namespace MareSynchronosServer.Hubs;
public partial class MareHub
{
private async Task UpdateUserOnRedis()
{
await _redis.StringSetAsync("UID:" + UserUID, UserCharaIdent, TimeSpan.FromSeconds(60), flags: StackExchange.Redis.CommandFlags.FireAndForget).ConfigureAwait(false);
await _redis.StringSetAsync("IDENT:" + UserCharaIdent, UserUID, TimeSpan.FromSeconds(60), flags: StackExchange.Redis.CommandFlags.FireAndForget).ConfigureAwait(false);
}
private async Task RemoveUserFromRedis()
{
await _redis.StringGetDeleteAsync("UID:" + UserUID).ConfigureAwait(false);
await _redis.StringGetDeleteAsync("IDENT:" + UserCharaIdent).ConfigureAwait(false);
}
public async Task<string> GetIdentFromUidFromRedis(string uid)
{
return await _redis.StringGetAsync("UID:" + uid).ConfigureAwait(false);
}
public async Task<string> GetUidFromIdentFromRedis(string ident)
{
return await _redis.StringGetAsync("IDENT:" + ident).ConfigureAwait(false);
}
private async Task<List<PausedEntry>> GetAllPairedClientsWithPauseState(string? uid = null)
{
uid ??= UserUID;
@@ -81,7 +102,7 @@ public partial class MareHub
if (userPair.IsPausedPerGroup is PauseInfo.Unpaused) return;
}
var groupUserIdent = _clientIdentService.GetCharacterIdentForUid(groupUserPair.GroupUserUID);
var groupUserIdent = await GetIdentFromUidFromRedis(groupUserPair.GroupUserUID).ConfigureAwait(false);
if (!string.IsNullOrEmpty(groupUserIdent))
{
await Clients.User(uid).Client_UserChangePairedPlayer(groupUserIdent, false).ConfigureAwait(false);
@@ -93,7 +114,7 @@ public partial class MareHub
{
foreach (var pair in groupUsers)
{
var pairIdent = _clientIdentService.GetCharacterIdentForUid(pair.GroupUserUID);
var pairIdent = await GetIdentFromUidFromRedis(pair.GroupUserUID).ConfigureAwait(false);
if (string.IsNullOrEmpty(pairIdent)) continue;
var pairs = await GetAllPairedClientsWithPauseState(pair.GroupUserUID).ConfigureAwait(false);

View File

@@ -232,7 +232,7 @@ public partial class MareHub
if (userPair.IsPausedExcludingGroup(gid) is PauseInfo.Unpaused) continue;
if (userPair.IsPausedPerGroup is PauseInfo.Paused) continue;
var groupUserIdent = _clientIdentService.GetCharacterIdentForUid(groupUserPair.GroupUserUID);
var groupUserIdent = await GetIdentFromUidFromRedis(groupUserPair.GroupUserUID).ConfigureAwait(false);
if (!string.IsNullOrEmpty(groupUserIdent))
{
await Clients.User(UserUID).Client_UserChangePairedPlayer(groupUserIdent, true).ConfigureAwait(false);
@@ -403,7 +403,7 @@ public partial class MareHub
if (userPair.IsOtherPausedForSpecificGroup(gid) is PauseInfo.Paused) continue;
}
var groupUserIdent = _clientIdentService.GetCharacterIdentForUid(groupUserPair.GroupUserUID);
var groupUserIdent = await GetIdentFromUidFromRedis(groupUserPair.GroupUserUID).ConfigureAwait(false);
if (!string.IsNullOrEmpty(groupUserIdent))
{
await Clients.User(UserUID).Client_UserChangePairedPlayer(groupUserIdent, !isPaused).ConfigureAwait(false);
@@ -437,7 +437,7 @@ public partial class MareHub
UserUID = uid,
}).ConfigureAwait(false);
var userIdent = _clientIdentService.GetCharacterIdentForUid(uid);
var userIdent = await GetIdentFromUidFromRedis(uid).ConfigureAwait(false);
if (userIdent == null) return;
await Clients.User(uid).Client_GroupChange(new GroupDto()
@@ -683,7 +683,7 @@ public partial class MareHub
UserUID = pair.GroupUserUID
}).ConfigureAwait(false);
var pairIdent = _clientIdentService.GetCharacterIdentForUid(pair.GroupUserUID);
var pairIdent = await GetIdentFromUidFromRedis(pair.GroupUserUID).ConfigureAwait(false);
if (string.IsNullOrEmpty(pairIdent)) continue;
var allUserPairs = await GetAllPairedClientsWithPauseState(pair.GroupUserUID).ConfigureAwait(false);

View File

@@ -64,7 +64,7 @@ public partial class MareHub
_logger.LogCallInfo();
var usersToSendOnlineTo = await SendOnlineToAllPairedUsers(UserCharaIdent).ConfigureAwait(false);
return usersToSendOnlineTo.Select(e => _clientIdentService.GetCharacterIdentForUid(e)).Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToList();
return usersToSendOnlineTo.Select(e => GetIdentFromUidFromRedis(e).Result).Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToList();
}
[Authorize(Policy = "Identified")]
@@ -147,7 +147,7 @@ public partial class MareHub
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
var allPairedUsersDict = allPairedUsers.ToDictionary(f => f, f => _clientIdentService.GetCharacterIdentForUid(f), StringComparer.Ordinal)
var allPairedUsersDict = allPairedUsers.ToDictionary(f => f, f => GetIdentFromUidFromRedis(f).Result, StringComparer.Ordinal)
.Where(f => visibleCharacterIds.Contains(f.Value, StringComparer.Ordinal));
_logger.LogCallInfo(MareHubLogger.Args(visibleCharacterIds.Count, allPairedUsersDict.Count()));
@@ -209,7 +209,7 @@ public partial class MareHub
if (otherEntry == null) return;
// check if other user is online
var otherIdent = _clientIdentService.GetCharacterIdentForUid(otherUser.UID);
var otherIdent = await GetIdentFromUidFromRedis(otherUser.UID).ConfigureAwait(false);
if (otherIdent == null) return;
// send push with update to other user if other user is online
@@ -224,7 +224,7 @@ public partial class MareHub
}).ConfigureAwait(false);
// get own ident and all pairs
var userIdent = _clientIdentService.GetCharacterIdentForUid(user.UID);
var userIdent = await GetIdentFromUidFromRedis(user.UID).ConfigureAwait(false);
var allUserPairs = await GetAllPairedClientsWithPauseState().ConfigureAwait(false);
// if the other user has paused the main user and there was no previous group connection don't send anything
@@ -270,7 +270,7 @@ public partial class MareHub
IsSynced = true
}).ConfigureAwait(false);
var otherCharaIdent = _clientIdentService.GetCharacterIdentForUid(pair.OtherUserUID);
var otherCharaIdent = await GetIdentFromUidFromRedis(pair.OtherUserUID).ConfigureAwait(false);
if (UserCharaIdent == null || otherCharaIdent == null || otherEntry.IsPaused) return;
@@ -310,7 +310,7 @@ public partial class MareHub
if (oppositeClientPair == null) return;
// check if other user is online, if no then there is no need to do anything further
var otherIdent = _clientIdentService.GetCharacterIdentForUid(otherUserUid);
var otherIdent = await GetIdentFromUidFromRedis(otherUserUid).ConfigureAwait(false);
if (otherIdent == null) return;
// get own ident and

View File

@@ -9,6 +9,7 @@ using MareSynchronosShared.Services;
using MareSynchronosShared.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using StackExchange.Redis;
namespace MareSynchronosServer.Hubs;
@@ -19,7 +20,6 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
private readonly FileService.FileServiceClient _fileServiceClient;
private readonly SystemInfoService _systemInfoService;
private readonly IHttpContextAccessor _contextAccessor;
private readonly IClientIdentificationService _clientIdentService;
private readonly MareHubLogger _logger;
private readonly MareDbContext _dbContext;
private readonly Uri _mainCdnFullUrl;
@@ -28,11 +28,12 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
private readonly int _maxJoinedGroupsByUser;
private readonly int _maxGroupUserCount;
private readonly IConfigurationService<ServerConfiguration> _configurationService;
private readonly IDatabase _redis;
public MareHub(MareMetrics mareMetrics, FileService.FileServiceClient fileServiceClient,
MareDbContext mareDbContext, ILogger<MareHub> logger, SystemInfoService systemInfoService,
IConfigurationService<ServerConfiguration> configuration, IHttpContextAccessor contextAccessor,
IClientIdentificationService clientIdentService)
IConnectionMultiplexer connectionMultiplexer)
{
_mareMetrics = mareMetrics;
_fileServiceClient = fileServiceClient;
@@ -44,7 +45,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
_maxJoinedGroupsByUser = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxJoinedGroupsByUser), 6);
_maxGroupUserCount = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxGroupUserCount), 100);
_contextAccessor = contextAccessor;
_clientIdentService = clientIdentService;
_redis = connectionMultiplexer.GetDatabase();
_logger = new MareHubLogger(this, logger);
_dbContext = mareDbContext;
}
@@ -92,14 +93,9 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
[Authorize(Policy = "Authenticated")]
public async Task<bool> CheckClientHealth()
{
var needsReconnect = !_clientIdentService.IsOnCurrentServer(UserUID);
if (needsReconnect)
{
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Warning, "Internal server state corruption detected, reconnecting you automatically to fix the issue.").ConfigureAwait(false);
_logger.LogCallWarning(MareHubLogger.Args(needsReconnect));
}
await UpdateUserOnRedis().ConfigureAwait(false);
return needsReconnect;
return false;
}
[Authorize(Policy = "Authenticated")]
@@ -111,7 +107,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
{
_logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent));
_clientIdentService.MarkUserOnline(UserUID, UserCharaIdent);
await UpdateUserOnRedis().ConfigureAwait(false);
}
catch { }
@@ -127,7 +123,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
{
_logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent));
_clientIdentService.MarkUserOffline(UserUID);
await RemoveUserFromRedis().ConfigureAwait(false);
await SendOfflineToAllPairedUsers(UserCharaIdent).ConfigureAwait(false);