idk if this will help but this is a certified attempt

This commit is contained in:
rootdarkarchon
2023-10-19 02:02:20 +02:00
parent 272f1afd9e
commit 8ae9967970
8 changed files with 138 additions and 262 deletions

View File

@@ -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<List<string>> 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<UserInfo?> 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<Dictionary<string, UserInfo>> 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<string> GIDs, UserPermissionSet? OwnPermissions, UserPermissionSet? OtherPermissions);
}

View File

@@ -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);
}
}

View File

@@ -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)
{

View File

@@ -30,14 +30,13 @@ public partial class MareHub : Hub<IMareHub>, 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<MareHub> logger, SystemInfoService systemInfoService,
IConfigurationService<ServerConfiguration> configuration, IHttpContextAccessor contextAccessor,
IRedisDatabase redisDb, UserPairCacheService cacheService)
IRedisDatabase redisDb)
{
_mareMetrics = mareMetrics;
_systemInfoService = systemInfoService;
@@ -49,7 +48,6 @@ public partial class MareHub : Hub<IMareHub>, 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>, IMareHub
_logger.LogCallWarning(MareHubLogger.Args(_contextAccessor.GetIpAddress(), exception.Message, exception.StackTrace));
await RemoveUserFromRedis().ConfigureAwait(false);
_cacheService.ClearCache(UserUID);
await SendOfflineToAllPairedUsers().ConfigureAwait(false);

View File

@@ -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<string, Dictionary<string, UserInfo>> _cache;
private readonly ILogger<UserPairCacheService> _logger;
private readonly IDbContextFactory<MareDbContext> _dbContextFactory;
private readonly ConcurrentQueue<(string? UID, string? OtherUID)> _staleUserData;
public UserPairCacheService(ILogger<UserPairCacheService> logger, IDbContextFactory<MareDbContext> dbContextFactory)
{
_logger = logger;
_dbContextFactory = dbContextFactory;
_staleUserData = new();
_cache = new(StringComparer.OrdinalIgnoreCase);
}
public void ClearCache(string uid)
{
_cache.TryRemove(uid, out _);
}
public async Task<Dictionary<string, UserInfo>> 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<UserInfo?> 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<Dictionary<string, UserInfo>> 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<UserInfo?> 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<string> GIDs, UserPermissionSet? OwnPermissions, UserPermissionSet? OtherPermissions);
}

View File

@@ -90,9 +90,7 @@ public class Startup
services.AddSingleton<ServerTokenGenerator>();
services.AddSingleton<SystemInfoService>();
services.AddSingleton<UserPairCacheService>();
services.AddHostedService(provider => provider.GetService<SystemInfoService>());
services.AddHostedService(p => p.GetService<UserPairCacheService>());
// configure services based on main server status
ConfigureServicesBasedOnShardType(services, mareConfig, isMainServer);

View File

@@ -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;