diff --git a/Docker/run/compose/mare-standalone.yml b/Docker/run/compose/mare-standalone.yml index cfbd3ae..1eb866c 100644 --- a/Docker/run/compose/mare-standalone.yml +++ b/Docker/run/compose/mare-standalone.yml @@ -1,6 +1,7 @@ services: postgres: image: postgres:latest + command: ["postgres", "-c", "log_statement=all"] restart: always ports: - 5432:5432/tcp diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs index 7affb18..b2f29c2 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs @@ -7,6 +7,7 @@ using MareSynchronos.API.Data; using MareSynchronos.API.Dto.Group; using MareSynchronosShared.Metrics; using Microsoft.AspNetCore.SignalR; +using MareSynchronosShared.Data; namespace MareSynchronosServer.Hubs; @@ -70,16 +71,13 @@ public partial class MareHub _dbContext.Users.Remove(user); _dbContext.Auth.Remove(auth); await _dbContext.SaveChangesAsync().ConfigureAwait(false); - - _cacheService.ClearCache(user.UID); - _cacheService.MarkAsStale(null, user.UID); } private async Task> GetAllPairedUnpausedUsers(string? uid = null) { uid ??= UserUID; - return (await _cacheService.GetAllPairs(UserUID, _dbContext).ConfigureAwait(false)) + return (await GetAllPairInfo(UserUID).ConfigureAwait(false)) .Where(u => !u.Value.OwnPermissions.IsPaused && u.Value.OtherPermissions != null && !u.Value.OtherPermissions.IsPaused) .Select(u => u.Key).ToList(); } @@ -173,7 +171,7 @@ public partial class MareHub private async Task UserGroupLeave(GroupPair groupUserPair, string userIdent, string? uid = null) { uid ??= UserUID; - var allUserPairs = await _cacheService.GetAllPairs(uid, _dbContext).ConfigureAwait(false); + var allUserPairs = await GetAllPairInfo(uid).ConfigureAwait(false); if (!allUserPairs.TryGetValue(groupUserPair.GroupUserUID, out var info) || !info.IsSynced) { var groupUserIdent = await GetUserIdent(groupUserPair.GroupUserUID).ConfigureAwait(false); @@ -238,7 +236,6 @@ public partial class MareHub } await _dbContext.SaveChangesAsync().ConfigureAwait(false); - _cacheService.MarkAsStale(userUid, null); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); @@ -252,6 +249,126 @@ public partial class MareHub } } - public record UserQueryPermissionEntry(UserQueryEntry OtherUser, UserPermissionSet OwnPermissions, UserPermissionSet? OtherPermissions); - public record UserQueryEntry(string UID, bool IsPaired, string GID, string Alias); + private async Task GetPairInfo(string uid, string otheruid) + { + var query = _dbContext.ClientPairs.Where(u => u.UserUID == uid && u.OtherUserUID == otheruid) + .Join(_dbContext.ClientPairs.Where(u => u.UserUID == otheruid && u.OtherUserUID == uid), + user => user.OtherUserUID, user => user.UserUID, (user, otheruser) => + new + { + UserUID = user.UserUID, + OtherUserUID = user.OtherUserUID, + Gid = string.Empty, + Synced = otheruser != null + }); + + var query2 = _dbContext.GroupPairs.Where(u => u.GroupUserUID == uid) + .Join(_dbContext.GroupPairs.Where(u => u.GroupUserUID == otheruid), + ownPair => ownPair.GroupGID, otherPair => otherPair.GroupGID, + (ownPair, otherPair) => + new + { + UserUID = ownPair.GroupUserUID, + OtherUserUID = otherPair.GroupUserUID, + Gid = ownPair.GroupGID, + Synced = true, + }); + + var result = from user in query.Union(query2) + join u in _dbContext.Users on user.OtherUserUID equals u.UID + join o in _dbContext.Permissions + on new { user.UserUID, user.OtherUserUID } + equals new { o.UserUID, o.OtherUserUID } + into ownperms + from ownperm in ownperms.DefaultIfEmpty() + join p in _dbContext.Permissions + on new { UserUID = user.OtherUserUID, OtherUserUID = user.UserUID } + equals new { p.UserUID, p.OtherUserUID } + into otherperms + from otherperm in otherperms.DefaultIfEmpty() + select new + { + UserUID = user.UserUID, + OtherUserUID = user.OtherUserUID, + OtherUserAlias = u.Alias, + GID = user.Gid, + Synced = user.Synced, + OwnPermissions = ownperm, + OtherPermissions = otherperm + }; + + var resultList = await result.AsNoTracking().ToListAsync().ConfigureAwait(false); + + if (!resultList.Any()) return null; + + var groups = resultList.Select(g => g.GID).ToList(); + return new UserInfo(resultList[0].OtherUserAlias, + resultList.SingleOrDefault(p => string.IsNullOrEmpty(p.GID))?.Synced ?? false, + resultList.Max(p => p.Synced), + resultList.Select(p => string.IsNullOrEmpty(p.GID) ? Constants.IndividualKeyword : p.GID).ToList(), + resultList[0].OwnPermissions, + resultList[0].OtherPermissions); + } + + private async Task> GetAllPairInfo(string uid) + { + var query = _dbContext.ClientPairs.Where(u => u.UserUID == uid) + .Join(_dbContext.ClientPairs.Where(u => u.OtherUserUID == uid), + user => user.OtherUserUID, user => user.UserUID, (user, otheruser) => + new + { + UserUID = Convert.ToString(user.UserUID), + OtherUserUID = Convert.ToString(user.OtherUserUID), + Gid = string.Empty, + Synced = otheruser != null + }); + + var query2 = _dbContext.GroupPairs.Where(u => u.GroupUserUID == uid) + .Join(_dbContext.GroupPairs.Where(u => u.GroupUserUID != uid), + ownPair => ownPair.GroupGID, otherPair => otherPair.GroupGID, + (ownPair, otherPair) => + new + { + UserUID = Convert.ToString(ownPair.GroupUserUID), + OtherUserUID = Convert.ToString(otherPair.GroupUserUID), + Gid = Convert.ToString(ownPair.GroupGID), + Synced = true, + }); + + var result = from user in query.Union(query2) + join u in _dbContext.Users on user.OtherUserUID equals Convert.ToString(u.UID) + join o in _dbContext.Permissions + on new { UserUID = user.UserUID, OtherUserUID = user.OtherUserUID } + equals new { UserUID = Convert.ToString(o.UserUID), OtherUserUID = Convert.ToString(o.OtherUserUID) } + into ownperms + from ownperm in ownperms.DefaultIfEmpty() + join p in _dbContext.Permissions + on new { UserUID = user.OtherUserUID, OtherUserUID = user.UserUID } + equals new { UserUID = Convert.ToString(p.UserUID), OtherUserUID = Convert.ToString(p.OtherUserUID) } + into otherperms + from otherperm in otherperms.DefaultIfEmpty() + select new + { + UserUID = user.UserUID, + OtherUserUID = user.OtherUserUID, + OtherUserAlias = u.Alias, + GID = user.Gid, + Synced = user.Synced, + OwnPermissions = ownperm, + OtherPermissions = otherperm + }; + + var resultList = await result.AsNoTracking().ToListAsync().ConfigureAwait(false); + return resultList.GroupBy(g => g.OtherUserUID, StringComparer.Ordinal).ToDictionary(g => g.Key, g => + { + return new UserInfo(g.First().OtherUserAlias, + g.SingleOrDefault(p => string.IsNullOrEmpty(p.GID))?.Synced ?? false, + g.Max(p => p.Synced), + g.Select(p => string.IsNullOrEmpty(p.GID) ? Constants.IndividualKeyword : p.GID).ToList(), + g.First().OwnPermissions, + g.First().OtherPermissions); + }, StringComparer.Ordinal); + } + + public record UserInfo(string Alias, bool IndividuallyPaired, bool IsSynced, List GIDs, UserPermissionSet? OwnPermissions, UserPermissionSet? OtherPermissions); } \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs index 84def2b..cc82a9d 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs @@ -81,7 +81,7 @@ public partial class MareHub groupPreferredPermissions.DisableVFX = dto.GroupPairPermissions.IsDisableVFX(); // set the permissions for every group pair that is not sticky - var allPairs = (await _cacheService.GetAllPairs(UserUID, _dbContext).ConfigureAwait(false)) + var allPairs = (await GetAllPairInfo(UserUID).ConfigureAwait(false)) .Where(u => !u.Value.OwnPermissions.Sticky) .ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal); @@ -100,11 +100,6 @@ public partial class MareHub } await _dbContext.SaveChangesAsync().ConfigureAwait(false); - foreach (var item in affectedGroupPairs) - { - _cacheService.MarkAsStale(UserUID, item.Key); - } - // send messages UserPermissions permissions = UserPermissions.NoneSet; permissions.SetPaused(groupPreferredPermissions.IsPaused); @@ -228,10 +223,6 @@ public partial class MareHub } await _dbContext.SaveChangesAsync().ConfigureAwait(false); - foreach (var user in notPinned) - { - _cacheService.MarkAsStale(user.GroupUserUID, null); - } } [Authorize(Policy = "Identified")] @@ -432,8 +423,7 @@ public partial class MareHub return false; // get all pairs before we join - var allUserPairs = (await _cacheService.GetAllPairs(UserUID, _dbContext).ConfigureAwait(false)) - .ToDictionary(u => u.Key, u => u.Value, StringComparer.Ordinal); + var allUserPairs = (await GetAllPairInfo(UserUID).ConfigureAwait(false)); if (oneTimeInvite != null) { @@ -485,7 +475,7 @@ public partial class MareHub var groupPairs = await _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == group.GID && p.GroupUserUID != UserUID).ToListAsync().ConfigureAwait(false); - var userPairsAfterJoin = await _cacheService.GetAllPairs(UserUID, _dbContext, true).ConfigureAwait(false); + var userPairsAfterJoin = await GetAllPairInfo(UserUID).ConfigureAwait(false); foreach (var pair in groupPairs) { @@ -584,11 +574,6 @@ public partial class MareHub await _dbContext.SaveChangesAsync().ConfigureAwait(false); - foreach (var pair in groupPairs) - { - _cacheService.MarkAsStale(UserUID, pair.GroupUserUID); - } - return true; } @@ -631,7 +616,6 @@ public partial class MareHub foreach (var groupUserPair in groupPairs) { await UserGroupLeave(groupUserPair, userIdent, dto.User.UID).ConfigureAwait(false); - _cacheService.MarkAsStale(dto.User.UID, groupUserPair.GroupUserUID); } } diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs index c00687d..8d71956 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs @@ -65,8 +65,7 @@ public partial class MareHub }; await _dbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false); - _cacheService.MarkAsStale(UserUID, otherUser.UID); - var existingData = await _cacheService.GetPairData(UserUID, otherUser.UID, _dbContext).ConfigureAwait(false); + var existingData = await GetPairInfo(UserUID, otherUser.UID).ConfigureAwait(false); var permissions = existingData?.OwnPermissions; if (permissions == null || !permissions.Sticky) @@ -102,7 +101,6 @@ public partial class MareHub } await _dbContext.SaveChangesAsync().ConfigureAwait(false); - _cacheService.MarkAsStale(UserUID, otherUser.UID); // get the opposite entry of the client pair var otherEntry = OppositeEntry(otherUser.UID); @@ -171,7 +169,7 @@ public partial class MareHub { _logger.LogCallInfo(); - var pairs = await _cacheService.GetAllPairs(UserUID, _dbContext, true).ConfigureAwait(false); + var pairs = await GetAllPairInfo(UserUID).ConfigureAwait(false); return pairs.Select(p => { return new UserFullPairDto(new UserData(p.Key, p.Value.Alias), @@ -263,7 +261,7 @@ public partial class MareHub + string.Join(Environment.NewLine, invalidFileSwapPaths.Select(p => "Invalid FileSwap Path: " + p))); } - var allPairs = await _cacheService.GetAllPairs(UserUID, _dbContext).ConfigureAwait(false); + var allPairs = await GetAllPairInfo(UserUID).ConfigureAwait(false); allPairs.Where(p => !p.Value.OwnPermissions.IsPaused && p.Value.OtherPermissions != null && !p.Value.OtherPermissions.IsPaused).ToList(); var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false); @@ -291,12 +289,11 @@ public partial class MareHub await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false); if (callerPair == null) return; - var pairData = await _cacheService.GetPairData(UserUID, dto.User.UID, _dbContext).ConfigureAwait(false); + var pairData = await GetPairInfo(UserUID, dto.User.UID).ConfigureAwait(false); // delete from database, send update info to users pair list _dbContext.ClientPairs.Remove(callerPair); await _dbContext.SaveChangesAsync().ConfigureAwait(false); - _cacheService.MarkAsStale(UserUID, dto.User.UID); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); @@ -323,7 +320,7 @@ public partial class MareHub // if the either had paused, do nothing if (callerHadPaused && otherHadPaused) return; - var currentPairData = await _cacheService.GetPairData(UserUID, dto.User.UID, _dbContext).ConfigureAwait(false); + var currentPairData = await GetPairInfo(UserUID, dto.User.UID).ConfigureAwait(false); // if neither user had paused each other and either is not in an unpaused group with each other, change state to offline if (!currentPairData?.IsSynced ?? true) @@ -384,7 +381,7 @@ public partial class MareHub UserPermissionSet prevPermissions = await _dbContext.Permissions.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false); if (prevPermissions == null) return; // you always should have permissions to another user - var oldPairData = await _cacheService.GetPairData(UserUID, dto.User.UID, _dbContext).ConfigureAwait(false); + var oldPairData = await GetPairInfo(UserUID, dto.User.UID).ConfigureAwait(false); bool setSticky = false; if (!oldPairData.GIDs.Contains(Constants.IndividualKeyword, StringComparer.Ordinal)) { @@ -404,7 +401,6 @@ public partial class MareHub prevPermissions.Sticky = dto.Permissions.IsSticky() || setSticky; _dbContext.Update(prevPermissions); await _dbContext.SaveChangesAsync().ConfigureAwait(false); - _cacheService.MarkAsStale(UserUID, dto.User.UID); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); @@ -414,7 +410,7 @@ public partial class MareHub await Clients.User(UserUID).Client_UserUpdateSelfPairPermissions(new UserPermissionsDto(dto.User, permCopy)).ConfigureAwait(false); await Clients.User(dto.User.UID).Client_UserUpdateOtherPairPermissions(new UserPermissionsDto(new UserData(UserUID), dto.Permissions)).ConfigureAwait(false); - var newPairData = await _cacheService.GetPairData(UserUID, dto.User.UID, _dbContext).ConfigureAwait(false); + var newPairData = await GetPairInfo(UserUID, dto.User.UID).ConfigureAwait(false); if (newPairData.OwnPermissions.IsPaused != oldPairData.OwnPermissions.IsPaused) { diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs index 4ba5a08..f91950f 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs @@ -30,14 +30,13 @@ public partial class MareHub : Hub, IMareHub private readonly int _maxJoinedGroupsByUser; private readonly int _maxGroupUserCount; private readonly IRedisDatabase _redis; - private readonly UserPairCacheService _cacheService; private readonly Uri _fileServerAddress; private readonly Version _expectedClientVersion; public MareHub(MareMetrics mareMetrics, MareDbContext mareDbContext, ILogger logger, SystemInfoService systemInfoService, IConfigurationService configuration, IHttpContextAccessor contextAccessor, - IRedisDatabase redisDb, UserPairCacheService cacheService) + IRedisDatabase redisDb) { _mareMetrics = mareMetrics; _systemInfoService = systemInfoService; @@ -49,7 +48,6 @@ public partial class MareHub : Hub, IMareHub _expectedClientVersion = configuration.GetValueOrDefault(nameof(ServerConfiguration.ExpectedClientVersion), new Version(0, 0, 0)); _contextAccessor = contextAccessor; _redis = redisDb; - _cacheService = cacheService; _logger = new MareHubLogger(this, logger); _dbContext = mareDbContext; } @@ -144,7 +142,6 @@ public partial class MareHub : Hub, IMareHub _logger.LogCallWarning(MareHubLogger.Args(_contextAccessor.GetIpAddress(), exception.Message, exception.StackTrace)); await RemoveUserFromRedis().ConfigureAwait(false); - _cacheService.ClearCache(UserUID); await SendOfflineToAllPairedUsers().ConfigureAwait(false); diff --git a/MareSynchronosServer/MareSynchronosServer/Services/UserPairCacheService.cs b/MareSynchronosServer/MareSynchronosServer/Services/UserPairCacheService.cs deleted file mode 100644 index 1c5dd61..0000000 --- a/MareSynchronosServer/MareSynchronosServer/Services/UserPairCacheService.cs +++ /dev/null @@ -1,217 +0,0 @@ -using MareSynchronos.API.Data; -using MareSynchronosShared.Data; -using MareSynchronosShared.Models; -using Microsoft.EntityFrameworkCore; -using System.Collections.Concurrent; - -namespace MareSynchronosServer.Services; - -public class UserPairCacheService : IHostedService -{ - private readonly ConcurrentDictionary> _cache; - private readonly ILogger _logger; - private readonly IDbContextFactory _dbContextFactory; - private readonly ConcurrentQueue<(string? UID, string? OtherUID)> _staleUserData; - public UserPairCacheService(ILogger logger, IDbContextFactory dbContextFactory) - { - _logger = logger; - _dbContextFactory = dbContextFactory; - _staleUserData = new(); - _cache = new(StringComparer.OrdinalIgnoreCase); - } - - public void ClearCache(string uid) - { - _cache.TryRemove(uid, out _); - } - - public async Task> GetAllPairs(string uid, MareDbContext dbContext, bool ignoreCache = false) - { - if (ignoreCache) - { - _cache[uid] = await BuildFullCache(dbContext, uid).ConfigureAwait(false); - return _cache[uid]; - } - - await WaitForProcessing(uid).ConfigureAwait(false); - - if (!_cache.ContainsKey(uid)) - { - _logger.LogDebug("Building full cache: Did not find PairData for {uid}", uid); - - _cache[uid] = await BuildFullCache(dbContext, uid).ConfigureAwait(false); - } - - return _cache[uid]; - } - - public async Task GetPairData(string uid, string otheruid, MareDbContext dbContext) - { - await WaitForProcessing(uid, otheruid).ConfigureAwait(false); - - if (!_cache.TryGetValue(uid, out var cachedInfos)) - { - _logger.LogDebug("Building full cache: Did not find PairData for {uid}:{otheruid}", uid, otheruid); - try - { - _cache[uid] = cachedInfos = await BuildFullCache(dbContext, uid).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error during full PairCache calculation of {uid}:{otheruid}", uid, otheruid); - return null; - } - } - - if (!cachedInfos.TryGetValue(otheruid, out var info)) - { - _logger.LogDebug("Building individual cache: Did not find PairData for {uid}:{otheruid}", uid, otheruid); - try - { - info = await BuildIndividualCache(dbContext, uid, otheruid).ConfigureAwait(false); - _cache[uid][otheruid] = info; - } - catch (Exception ex) - { - _logger.LogError(ex, "Error during individual PairCache calculation of {uid}:{otheruid}", uid, otheruid); - return null; - } - } - - return info; - } - - public void MarkAsStale(string? uid, string? otheruid) - { - if (!_staleUserData.Any(u => string.Equals(u.UID, uid, StringComparison.Ordinal) - && string.Equals(u.OtherUID, otheruid, StringComparison.OrdinalIgnoreCase))) - { - _staleUserData.Enqueue((uid, otheruid)); - } - } - - public Task StartAsync(CancellationToken cancellationToken) - { - _ = ProcessStaleEntries(); - return Task.CompletedTask; - } - - public Task StopAsync(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - private async Task> BuildFullCache(MareDbContext dbContext, string uid) - { - var pairs = await dbContext.GetAllPairsForUser(uid).ToListAsync().ConfigureAwait(false); - - var pairsDict = pairs.GroupBy(g => g.OtherUserUID, StringComparer.Ordinal) - .ToDictionary(g => g.Key, g => - { - return new UserInfo(g.First().Alias, - g.SingleOrDefault(p => string.IsNullOrEmpty(p.GID))?.Synced ?? false, - g.Max(p => p.Synced), - g.Select(p => string.IsNullOrEmpty(p.GID) ? Constants.IndividualKeyword : p.GID).ToList(), - g.First().OwnPermissions, - g.First().OtherPermissions); - }, StringComparer.OrdinalIgnoreCase); - - return pairsDict.Where(p => p.Value.OwnPermissions != null).ToDictionary(u => u.Key, u => u.Value, StringComparer.Ordinal); - } - - private async Task BuildIndividualCache(MareDbContext dbContext, string uid, string otheruid) - { - var pairs = (await dbContext.GetAllPairsForUser(uid).ToListAsync().ConfigureAwait(false)).Where(u => string.Equals(u.OtherUserUID, otheruid, StringComparison.Ordinal)).ToList(); - - if (!pairs.Any()) return null; - - var groups = pairs.Select(g => g.GID).ToList(); - var userInfo = new UserInfo(pairs[0].Alias, - pairs.SingleOrDefault(p => string.IsNullOrEmpty(p.GID))?.Synced ?? false, - pairs.Max(p => p.Synced), - pairs.Select(p => string.IsNullOrEmpty(p.GID) ? Constants.IndividualKeyword : p.GID).ToList(), - pairs[0].OwnPermissions, - pairs[0].OtherPermissions); - - return userInfo.OwnPermissions == null ? null : userInfo; - } - - private async Task ProcessStaleEntries() - { - while (true) - { - await Task.Delay(250).ConfigureAwait(false); - if (_staleUserData.Any()) - { - _logger.LogDebug("Processing Stale Entries"); - - using var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false); - while (_staleUserData.TryDequeue(out var staleUserPair)) - { - try - { - if (staleUserPair.UID == null) - { - foreach (var entry in _cache.Where(c => c.Value.ContainsKey(staleUserPair.OtherUID)).Select(k => k.Key).Distinct(StringComparer.Ordinal).ToList()) - { - _logger.LogDebug("UID is null; Building Individual Cache for {user}:{user2}", staleUserPair.UID, entry); - _staleUserData.Enqueue(new(staleUserPair.OtherUID, entry)); - } - } - else if (staleUserPair.OtherUID == null) - { - foreach (var entry in _cache.Where(c => c.Value.ContainsKey(staleUserPair.UID)).Select(k => k.Key).Distinct(StringComparer.Ordinal).ToList()) - { - _logger.LogDebug("OtherUID is null; Building Individual Cache for {user}:{user2}", staleUserPair.UID, entry); - _staleUserData.Enqueue(new(staleUserPair.UID, entry)); - } - } - else - { - if (_cache.ContainsKey(staleUserPair.UID)) - { - _logger.LogDebug("Building Individual Cache for {user}:{user2}", staleUserPair.UID, staleUserPair.OtherUID); - - var userInfo = await BuildIndividualCache(dbContext, staleUserPair.UID, staleUserPair.OtherUID).ConfigureAwait(false); - - if (userInfo == null) _cache[staleUserPair.UID].Remove(staleUserPair.OtherUID); - else _cache[staleUserPair.UID][staleUserPair.OtherUID] = userInfo; - - if (_cache.ContainsKey(staleUserPair.OtherUID)) - { - _logger.LogDebug("Building Individual Cache for {user}:{user2}", staleUserPair.OtherUID, staleUserPair.UID); - var otherUserInfo = await BuildIndividualCache(dbContext, staleUserPair.OtherUID, staleUserPair.UID).ConfigureAwait(false); - if (otherUserInfo == null) _cache[staleUserPair.OtherUID].Remove(staleUserPair.UID); - else _cache[staleUserPair.OtherUID][staleUserPair.UID] = otherUserInfo; - } - } - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Error during Stale entry processing"); - } - } - - } - } - } - - private async Task WaitForProcessing(string uid) - { - while (_staleUserData.Any(u => string.Equals(u.UID, uid, StringComparison.Ordinal))) - { - await Task.Delay(50).ConfigureAwait(false); - } - } - - private async Task WaitForProcessing(string uid, string otheruid) - { - while (_staleUserData.Any(u => string.Equals(u.UID, uid, StringComparison.Ordinal) && string.Equals(u.OtherUID, otheruid, StringComparison.Ordinal))) - { - await Task.Delay(50).ConfigureAwait(false); - } - } - - public record UserInfo(string Alias, bool IndividuallyPaired, bool IsSynced, List GIDs, UserPermissionSet? OwnPermissions, UserPermissionSet? OtherPermissions); -} diff --git a/MareSynchronosServer/MareSynchronosServer/Startup.cs b/MareSynchronosServer/MareSynchronosServer/Startup.cs index 71bb0f8..c7add52 100644 --- a/MareSynchronosServer/MareSynchronosServer/Startup.cs +++ b/MareSynchronosServer/MareSynchronosServer/Startup.cs @@ -90,9 +90,7 @@ public class Startup services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddHostedService(provider => provider.GetService()); - services.AddHostedService(p => p.GetService()); // configure services based on main server status ConfigureServicesBasedOnShardType(services, mareConfig, isMainServer); diff --git a/MareSynchronosServer/MareSynchronosServer/Utils/Extensions.cs b/MareSynchronosServer/MareSynchronosServer/Utils/Extensions.cs index 773cc0b..e6e9a24 100644 --- a/MareSynchronosServer/MareSynchronosServer/Utils/Extensions.cs +++ b/MareSynchronosServer/MareSynchronosServer/Utils/Extensions.cs @@ -2,7 +2,7 @@ using MareSynchronos.API.Data.Enum; using MareSynchronos.API.Data.Extensions; using MareSynchronosShared.Models; -using static MareSynchronosServer.Services.UserPairCacheService; +using static MareSynchronosServer.Hubs.MareHub; namespace MareSynchronosServer.Utils;