diff options
Diffstat (limited to 'LibMatrix/Helpers')
-rw-r--r-- | LibMatrix/Helpers/SyncHelper.cs | 34 | ||||
-rw-r--r-- | LibMatrix/Helpers/SyncStateResolver.cs | 13 |
2 files changed, 34 insertions, 13 deletions
diff --git a/LibMatrix/Helpers/SyncHelper.cs b/LibMatrix/Helpers/SyncHelper.cs index 1833bd0..07c3bb0 100644 --- a/LibMatrix/Helpers/SyncHelper.cs +++ b/LibMatrix/Helpers/SyncHelper.cs @@ -3,12 +3,13 @@ using System.Net.Http.Json; using ArcaneLibs.Extensions; using LibMatrix.Filters; using LibMatrix.Homeservers; +using LibMatrix.Interfaces.Services; using LibMatrix.Responses; using Microsoft.Extensions.Logging; namespace LibMatrix.Helpers; -public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logger = null) { +public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logger = null, IStorageProvider? storageProvider = null) { private SyncFilter? _filter; private string? _namedFilterName; private bool _filterIsDirty = false; @@ -51,7 +52,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg public TimeSpan MinimumDelay { get; set; } = new(0); - private async Task updateFilterAsync() { + private async Task UpdateFilterAsync() { if (!string.IsNullOrWhiteSpace(NamedFilterName)) { _filterId = await homeserver.NamedCaches.FilterCache.GetOrSetValueAsync(NamedFilterName); if (_filterId is null) @@ -74,8 +75,27 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg throw new ArgumentNullException(nameof(homeserver.ClientHttpClient), "Null passed as homeserver for SyncHelper!"); } + if (storageProvider is null) return await SyncAsyncInternal(cancellationToken); + + var key = Since ?? "init"; + if (await storageProvider.ObjectExistsAsync(key)) { + var cached = await storageProvider.LoadObjectAsync<SyncResponse>(key); + // We explicitly check that NextBatch doesn't match since to prevent infinite loops... + if (cached is not null && cached.NextBatch != Since) { + logger?.LogInformation("SyncHelper: Using cached sync response for {}", key); + return cached; + } + } + + var sync = await SyncAsyncInternal(cancellationToken); + // Ditto here. + if (sync is not null && sync.NextBatch != Since) await storageProvider.SaveObjectAsync(key, sync); + return sync; + } + + private async Task<SyncResponse?> SyncAsyncInternal(CancellationToken? cancellationToken = null) { var sw = Stopwatch.StartNew(); - if (_filterIsDirty) await updateFilterAsync(); + if (_filterIsDirty) await UpdateFilterAsync(); var url = $"/_matrix/client/v3/sync?timeout={Timeout}&set_presence={SetPresence}&full_state={(FullState ? "true" : "false")}"; if (!string.IsNullOrWhiteSpace(Since)) url += $"&since={Since}"; @@ -86,11 +106,11 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg try { var httpResp = await homeserver.ClientHttpClient.GetAsync(url, cancellationToken ?? CancellationToken.None); if (httpResp is null) throw new NullReferenceException("Failed to send HTTP request"); - logger?.LogInformation("Got sync response: {} bytes, {} elapsed", httpResp.Content.Headers.ContentLength ?? -1, sw.Elapsed); + logger?.LogInformation("Got sync response: {} bytes, {} elapsed", httpResp.GetContentLength(), sw.Elapsed); var deserializeSw = Stopwatch.StartNew(); - var resp = await httpResp.Content.ReadFromJsonAsync<SyncResponse>(cancellationToken: cancellationToken ?? CancellationToken.None, + var resp = await httpResp.Content.ReadFromJsonAsync(cancellationToken: cancellationToken ?? CancellationToken.None, jsonTypeInfo: SyncResponseSerializerContext.Default.SyncResponse); - logger?.LogInformation("Deserialized sync response: {} bytes, {} elapsed, {} total", httpResp.Content.Headers.ContentLength ?? -1, deserializeSw.Elapsed, sw.Elapsed); + logger?.LogInformation("Deserialized sync response: {} bytes, {} elapsed, {} total", httpResp.GetContentLength(), deserializeSw.Elapsed, sw.Elapsed); var timeToWait = MinimumDelay.Subtract(sw.Elapsed); if (timeToWait.TotalMilliseconds > 0) await Task.Delay(timeToWait); @@ -210,7 +230,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg /// Event fired when an account data event is received /// </summary> public List<Func<StateEventResponse, Task>> AccountDataReceivedHandlers { get; } = new(); - + private void Log(string message) { if (logger is null) Console.WriteLine(message); else logger.LogInformation(message); diff --git a/LibMatrix/Helpers/SyncStateResolver.cs b/LibMatrix/Helpers/SyncStateResolver.cs index fcb23c2..0daccec 100644 --- a/LibMatrix/Helpers/SyncStateResolver.cs +++ b/LibMatrix/Helpers/SyncStateResolver.cs @@ -17,7 +17,7 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge public SyncResponse? MergedState { get; set; } - private SyncHelper _syncHelper = new(homeserver, logger); + private SyncHelper _syncHelper = new(homeserver, logger, storageProvider); public async Task<(SyncResponse next, SyncResponse merged)> ContinueAsync(CancellationToken? cancellationToken = null) { // copy properties @@ -27,13 +27,14 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge _syncHelper.Filter = Filter; _syncHelper.FullState = FullState; // run sync or grab from storage if available - var sync = storageProvider != null && await storageProvider.ObjectExistsAsync(Since ?? "init") - ? await storageProvider.LoadObjectAsync<SyncResponse>(Since ?? "init") - : await _syncHelper.SyncAsync(cancellationToken); + // var sync = storageProvider != null && await storageProvider.ObjectExistsAsync(Since ?? "init") + // ? await storageProvider.LoadObjectAsync<SyncResponse>(Since ?? "init") + // : await _syncHelper.SyncAsync(cancellationToken); + var sync = await _syncHelper.SyncAsync(cancellationToken); if (sync is null) return await ContinueAsync(cancellationToken); - if (storageProvider != null && !await storageProvider.ObjectExistsAsync(Since ?? "init")) - await storageProvider.SaveObjectAsync(Since ?? "init", sync); + // if (storageProvider != null && !await storageProvider.ObjectExistsAsync(Since ?? "init")) + // await storageProvider.SaveObjectAsync(Since ?? "init", sync); if (MergedState is null) MergedState = sync; else MergedState = MergeSyncs(MergedState, sync); |