summary refs log tree commit diff
path: root/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs
diff options
context:
space:
mode:
Diffstat (limited to 'extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs')
-rw-r--r--extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs24
1 files changed, 13 insertions, 11 deletions
diff --git a/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs b/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs

index a2008345..db45a895 100644 --- a/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs +++ b/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op12Controller.cs
@@ -1,3 +1,4 @@ +using System.Collections.Frozen; using System.Linq.Expressions; using System.Text.Json; using System.Text.Json.Nodes; @@ -10,6 +11,7 @@ using Spacebar.Interop.Replication.Abstractions; using Spacebar.Models.Db.Contexts; using Spacebar.Models.Db.Models; using Spacebar.Models.Gateway; +using Spacebar.Models.Generic; namespace Spacebar.GatewayOffload.Controllers; @@ -21,7 +23,7 @@ public class Op12Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen public async IAsyncEnumerable<ReplicationMessage> DoGuildSync(List<string> guildIds) { var user = await authService.GetCurrentUserAsync(Request); - guildIds = (await db.Members.Where(x => x.Id == user.Id).Select(x => x.GuildId).ToListAsync()) + guildIds = (await db.Members.AsNoTracking().Where(x => x.Id == user.Id).Select(x => x.GuildId).ToListAsync()) .Intersect(guildIds) .OrderByDescending(gi => db.Members.Count(m => m.GuildId == gi)) .ToList(); @@ -41,44 +43,44 @@ public class Op12Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen } // TODO: figure out how to abstract this to a function without EFCore complaining about not being translatable... - //private static Func<Session, bool> IsOnline = (Session session) => session.Status != "offline" && session.Status != "invisible" && session.Status != "unknown"; + private static Expression<Func<Session, bool>> IsOnline = (Session session) => session.Status != "offline" && session.Status != "invisible" && session.Status != "unknown"; private async Task<GuildSyncResponse> GetGuildSyncAsync(string guildId) { await using var sc = sp.CreateAsyncScope(); var _db = sc.ServiceProvider.GetRequiredService<SpacebarDbContext>(); - var memberCount = await _db.Members.Where(x => x.GuildId == guildId).CountAsync(); + var memberCount = await _db.Members.AsNoTracking().Where(x => x.GuildId == guildId).CountAsync(); var offlineTreshold = DateTime.Now.Subtract(TimeSpan.FromDays(14)); var isLargeGuild = memberCount > 10000; - var members = await _db.Members.Where(x => x.GuildId == guildId) + var members = await _db.Members.AsNoTracking().Where(x => x.GuildId == guildId) .Include(x => x.IdNavigation) .ThenInclude(x => x.Sessions.Where(s => !s.IsAdminSession && ( - // see TODO on IsOnline + // see TODO on IsOnline - somehow need to replicate `IsOnline(s)` s.Status != "offline" && s.Status != "invisible" && s.Status != "unknown" ) && (!isLargeGuild || s.LastSeen >= offlineTreshold))) .Where(x => x.IdNavigation.Sessions.Count > 0) // ignore members without sessions .ToListAsync(); - var mappedPartialUsers = members.Select(x => x.IdNavigation).ToDictionary(x => x.Id, x => x.ToPartialUser()); - var mappedMembers = members.ToDictionary(m => m.Id, m => m.ToPublicMember(mappedPartialUsers[m.Id])); + var mappedPartialUsers = members.Select(x => x.IdNavigation).ToFrozenDictionary(x => x.Id, x => x.ToPartialUser()); + var mappedMembers = members.ToFrozenDictionary(m => m.Id, m => m.ToPublicMember(mappedPartialUsers[m.Id])); - var presences = members.Select(x => x.IdNavigation).Where(x => x.Sessions.Count > 0).ToDictionary(x => x.Id, x => + var presences = members.Select(x => x.IdNavigation).Where(x => x.Sessions.Count > 0).ToFrozenDictionary(x => x.Id, x => { var sortedSessions = x.Sessions.OrderByDescending(s => s.LastSeen).ToList(); - return new PresenceResponse() + return new Presence() { GuildId = guildId, User = mappedPartialUsers[x.Id], Activities = x.Sessions.Where(s => s.Status is not ("offline" or "invisible" or "unknown")) .SelectMany(s => JsonSerializer.Deserialize<JsonObject[]>(s.Activities) ?? []).ToList(), Status = sortedSessions.FirstOrDefault(s => !string.IsNullOrWhiteSpace(s.Status))?.Status ?? "offline", - ClientStatus = JsonSerializer.Deserialize<PresenceResponse.ClientStatuses>(sortedSessions.First(s => !string.IsNullOrWhiteSpace(s.ClientStatus)).ClientStatus) ?? + ClientStatus = JsonSerializer.Deserialize<Presence.ClientStatuses>(sortedSessions.First(s => !string.IsNullOrWhiteSpace(s.ClientStatus)).ClientStatus) ?? new() }; - }).Where(x => x.Value.Activities.Count > 0).ToDictionary(); + }).Where(x => x.Value.Activities.Count > 0).ToFrozenDictionary(); var r = new GuildSyncResponse() {