From 425d0eb88c1b04e93bc32fcd900d8fcfa3a29410 Mon Sep 17 00:00:00 2001 From: Rory& Date: Tue, 15 Apr 2025 18:13:56 +0200 Subject: Fix session store --- MatrixUtils.Web/Classes/RmuSessionStore.cs | 105 ++++++++++++++++------------- MatrixUtils.Web/Pages/Index.razor | 12 ++-- MatrixUtils.Web/Shared/MainLayout.razor | 52 +++++--------- 3 files changed, 82 insertions(+), 87 deletions(-) diff --git a/MatrixUtils.Web/Classes/RmuSessionStore.cs b/MatrixUtils.Web/Classes/RmuSessionStore.cs index 14aa1db..7e5b155 100644 --- a/MatrixUtils.Web/Classes/RmuSessionStore.cs +++ b/MatrixUtils.Web/Classes/RmuSessionStore.cs @@ -15,47 +15,19 @@ public class RmuSessionStore( private SessionInfo? CurrentSession { get; set; } private Dictionary SessionCache { get; set; } = []; - private bool _isInitialized = false; + private bool _isInitialized; private static readonly SemaphoreSlim InitSemaphore = new(1, 1); - public async Task EnsureInitialized() { - if (_isInitialized) return; - await InitSemaphore.WaitAsync(); - if (_isInitialized) { - InitSemaphore.Release(); - return; - } - - try { - await RunMigrations(); - SessionCache = (await GetAllSessions()) - .Select(x => (x.Key, Value: new SessionInfo { - SessionId = x.Key, - Auth = x.Value.Auth - })).ToDictionary(x => x.Key, x => x.Value); - CurrentSession = await GetCurrentSession(); - } - catch (Exception e) { - logger.LogError("Failed to initialize RmuSessionStore: {e}", e); - } - finally { - _isInitialized = true; - InitSemaphore.Release(); - } - } - #region Sessions -#region Session implementation details - -#endregion - public async Task> GetAllSessions() { + await LoadStorage(); logger.LogTrace("Getting all tokens."); return SessionCache; } public async Task GetSession(string sessionId) { + await LoadStorage(); if (SessionCache.TryGetValue(sessionId, out var cachedSession)) return cachedSession; @@ -64,6 +36,7 @@ public class RmuSessionStore( } public async Task GetCurrentSession(bool log = true) { + await LoadStorage(); if (log) logger.LogTrace("Getting current token."); if (CurrentSession is not null) return CurrentSession; @@ -72,28 +45,23 @@ public class RmuSessionStore( } public async Task AddSession(UserAuth auth) { + await LoadStorage(); logger.LogTrace("Adding token."); - // var sessions = await GetAllSessions() ?? []; var sessionId = auth.GetHashCode().ToString(); - // sessions.Add(sessionId, auth); SessionCache[sessionId] = new() { Auth = auth, SessionId = sessionId }; - await storageService.DataStorageProvider!.SaveObjectAsync("rmu.sessions", - SessionCache.ToDictionary( - x => x.Key, - x => x.Value.Auth - ) - ); if (CurrentSession == null) await SetCurrentSession(sessionId); + else await SaveStorage(); return sessionId; } public async Task RemoveSession(string sessionId) { + await LoadStorage(); logger.LogTrace("Removing session {sessionId}.", sessionId); var tokens = await GetAllSessions(); if (tokens == null) { @@ -104,13 +72,14 @@ public class RmuSessionStore( await SetCurrentSession(tokens.First(x => x.Key != sessionId).Key); if (tokens.Remove(sessionId)) - await storageService.DataStorageProvider!.SaveObjectAsync("rmu.tokens", tokens); + await SaveStorage(); } public async Task SetCurrentSession(string? sessionId) { + await LoadStorage(); logger.LogTrace("Setting current session to {sessionId}.", sessionId); CurrentSession = await GetSession(sessionId); - await storageService.DataStorageProvider!.SaveObjectAsync("rmu.session", sessionId); + await SaveStorage(); } #endregion @@ -118,6 +87,7 @@ public class RmuSessionStore( #region Homeservers public async Task GetHomeserver(string session, bool log = true) { + await LoadStorage(); if (log) logger.LogTrace("Getting session."); if (!SessionCache.TryGetValue(session, out var cachedSession)) return null; if (cachedSession.Homeserver is not null) return cachedSession.Homeserver; @@ -137,6 +107,7 @@ public class RmuSessionStore( } public async Task GetCurrentHomeserver(bool log = true, bool navigateOnFailure = false) { + await LoadStorage(); if (log) logger.LogTrace("Getting current session."); if (CurrentSession?.Homeserver is not null) return CurrentSession.Homeserver; @@ -167,16 +138,59 @@ public class RmuSessionStore( #endregion -#region Internal +#region Storage + + private async Task LoadStorage(bool hasMigrated = false) { + if (!await storageService.DataStorageProvider!.ObjectExistsAsync("rmu.sessions") || !await storageService.DataStorageProvider.ObjectExistsAsync("rmu.session")) { + if (!hasMigrated) + await MigrateFromMRU(); + else + logger.LogWarning("No sessions found in storage."); + return; + } + + SessionCache = (await storageService.DataStorageProvider.LoadObjectAsync>("rmu.sessions") ?? throw new Exception("Failed to load sessions")) + .ToDictionary(x => x.Key, x => new SessionInfo { + SessionId = x.Key, + Auth = x.Value + }); + + var currentSessionId = await storageService.DataStorageProvider.LoadObjectAsync("rmu.session"); + if (currentSessionId == null) { + logger.LogWarning("No current session found in storage."); + return; + } + + if (!SessionCache.TryGetValue(currentSessionId, out var currentSession)) { + logger.LogWarning("Current session {currentSessionId} not found in storage.", currentSessionId); + return; + } + + CurrentSession = currentSession; + } + + private async Task SaveStorage() { + await storageService.DataStorageProvider!.SaveObjectAsync("rmu.sessions", + SessionCache.ToDictionary( + x => x.Key, + x => x.Value.Auth + ) + ); + await storageService.DataStorageProvider.SaveObjectAsync("rmu.session", CurrentSession?.SessionId); + } + +#endregion + +#region Migrations public async Task RunMigrations() { + await LoadStorage(); await MigrateFromMRU(); await MigrateAccountsToKeyedStorage(); } -#region Migrations - private async Task MigrateFromMRU() { + await LoadStorage(); logger.LogInformation("Migrating from MRU token namespace!"); var dsp = storageService.DataStorageProvider!; if (await dsp.ObjectExistsAsync("token")) { @@ -205,6 +219,7 @@ public class RmuSessionStore( } private async Task MigrateAccountsToKeyedStorage() { + await LoadStorage(); logger.LogInformation("Migrating accounts to keyed storage!"); var dsp = storageService.DataStorageProvider!; if (await dsp.ObjectExistsAsync("rmu.tokens")) { @@ -232,8 +247,6 @@ public class RmuSessionStore( } } -#endregion - #endregion public class Settings { diff --git a/MatrixUtils.Web/Pages/Index.razor b/MatrixUtils.Web/Pages/Index.razor index 7103dc5..7de4613 100644 --- a/MatrixUtils.Web/Pages/Index.razor +++ b/MatrixUtils.Web/Pages/Index.razor @@ -158,14 +158,14 @@ Small collection of tools to do not-so-everyday things. _currentSession = await sessionStore.GetCurrentSession(); _sessions.Clear(); _offlineSessions.Clear(); - var tokens = await sessionStore.GetAllSessions(); + var sessions = await sessionStore.GetAllSessions(); scannedSessions = 0; - totalSessions = tokens.Count; + totalSessions = sessions.Count; logger.LogDebug("Found {0} tokens", totalSessions); - if (tokens is not { Count: > 0 }) { + if (sessions is not { Count: > 0 }) { Console.WriteLine("No tokens found, trying migration from MRU..."); - tokens = await sessionStore.GetAllSessions(); - if (tokens is not { Count: > 0 }) { + sessions = await sessionStore.GetAllSessions(); + if (sessions is not { Count: > 0 }) { Console.WriteLine("No tokens found"); return; } @@ -174,7 +174,7 @@ Small collection of tools to do not-so-everyday things. List offlineServers = []; var sema = new SemaphoreSlim(8, 8); var updateSw = Stopwatch.StartNew(); - var tasks = tokens.Select(async session => { + var tasks = sessions.Select(async session => { await sema.WaitAsync(); var token = session.Value.Auth; diff --git a/MatrixUtils.Web/Shared/MainLayout.razor b/MatrixUtils.Web/Shared/MainLayout.razor index c06fe5a..b32735f 100644 --- a/MatrixUtils.Web/Shared/MainLayout.razor +++ b/MatrixUtils.Web/Shared/MainLayout.razor @@ -1,41 +1,23 @@ @inherits LayoutComponentBase -@if (_isLoaded) { -
- - -
-
- @* *@ - @* *@ - Git - Matrix -
- -
- @Body -
- - -
+
+ -} -else { -

Attaching session store, please wait...

-} - - -@code { - - private bool _isLoaded; +
+
+ @* *@ + @* *@ + Git + Matrix +
- protected override async Task OnInitializedAsync() { - await sessionStore.EnsureInitialized(); - _isLoaded = true; - } +
+ @Body +
+
+
-} \ No newline at end of file + -- cgit 1.5.1