From 11c7786ea23d82d31cc54abe57d35fdd74cf1bd5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 13 May 2024 23:54:10 +0200 Subject: Clearer error messages, fix bug in hs resolution --- LibMatrix/RoomTypes/GenericRoom.cs | 36 ++++++++++++------------- LibMatrix/Services/HomeserverProviderService.cs | 29 +++++++++++++------- LibMatrix/Services/HomeserverResolverService.cs | 29 +++++++++++--------- 3 files changed, 55 insertions(+), 39 deletions(-) (limited to 'LibMatrix') diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index 742f5d9..f15327c 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -228,43 +228,43 @@ public class GenericRoom { } public async IAsyncEnumerable GetMembersEnumerableAsync(bool joinedOnly = true) { - var sw = Stopwatch.StartNew(); + // var sw = Stopwatch.StartNew(); var res = await Homeserver.ClientHttpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/members"); - if (sw.ElapsedMilliseconds > 1000) - Console.WriteLine($"Members call responded in {sw.GetElapsedAndRestart()}"); - else sw.Restart(); + // if (sw.ElapsedMilliseconds > 1000) + // Console.WriteLine($"Members call responded in {sw.GetElapsedAndRestart()}"); + // else sw.Restart(); // var resText = await res.Content.ReadAsStringAsync(); // Console.WriteLine($"Members call response read in {sw.GetElapsedAndRestart()}"); var result = await JsonSerializer.DeserializeAsync(await res.Content.ReadAsStreamAsync(), new JsonSerializerOptions() { TypeInfoResolver = ChunkedStateEventResponseSerializerContext.Default }); - if (sw.ElapsedMilliseconds > 100) - Console.WriteLine($"Members call deserialised in {sw.GetElapsedAndRestart()}"); - else sw.Restart(); + // if (sw.ElapsedMilliseconds > 100) + // Console.WriteLine($"Members call deserialised in {sw.GetElapsedAndRestart()}"); + // else sw.Restart(); foreach (var resp in result.Chunk) { if (resp?.Type != "m.room.member") continue; if (joinedOnly && resp.RawContent?["membership"]?.GetValue() != "join") continue; yield return resp; } - if (sw.ElapsedMilliseconds > 100) - Console.WriteLine($"Members call iterated in {sw.GetElapsedAndRestart()}"); + // if (sw.ElapsedMilliseconds > 100) + // Console.WriteLine($"Members call iterated in {sw.GetElapsedAndRestart()}"); } public async Task> GetMembersListAsync(bool joinedOnly = true) { - var sw = Stopwatch.StartNew(); + // var sw = Stopwatch.StartNew(); var res = await Homeserver.ClientHttpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/members"); - if (sw.ElapsedMilliseconds > 1000) - Console.WriteLine($"Members call responded in {sw.GetElapsedAndRestart()}"); - else sw.Restart(); + // if (sw.ElapsedMilliseconds > 1000) + // Console.WriteLine($"Members call responded in {sw.GetElapsedAndRestart()}"); + // else sw.Restart(); // var resText = await res.Content.ReadAsStringAsync(); // Console.WriteLine($"Members call response read in {sw.GetElapsedAndRestart()}"); var result = await JsonSerializer.DeserializeAsync(await res.Content.ReadAsStreamAsync(), new JsonSerializerOptions() { TypeInfoResolver = ChunkedStateEventResponseSerializerContext.Default }); - if (sw.ElapsedMilliseconds > 100) - Console.WriteLine($"Members call deserialised in {sw.GetElapsedAndRestart()}"); - else sw.Restart(); + // if (sw.ElapsedMilliseconds > 100) + // Console.WriteLine($"Members call deserialised in {sw.GetElapsedAndRestart()}"); + // else sw.Restart(); var members = new List(); foreach (var resp in result.Chunk) { if (resp?.Type != "m.room.member") continue; @@ -272,8 +272,8 @@ public class GenericRoom { members.Add(resp); } - if (sw.ElapsedMilliseconds > 100) - Console.WriteLine($"Members call iterated in {sw.GetElapsedAndRestart()}"); + // if (sw.ElapsedMilliseconds > 100) + // Console.WriteLine($"Members call iterated in {sw.GetElapsedAndRestart()}"); return members.ToFrozenSet(); } diff --git a/LibMatrix/Services/HomeserverProviderService.cs b/LibMatrix/Services/HomeserverProviderService.cs index c61ef73..9867184 100644 --- a/LibMatrix/Services/HomeserverProviderService.cs +++ b/LibMatrix/Services/HomeserverProviderService.cs @@ -10,16 +10,19 @@ namespace LibMatrix.Services; public class HomeserverProviderService(ILogger logger, HomeserverResolverService hsResolver) { private static SemaphoreCache AuthenticatedHomeserverCache = new(); private static SemaphoreCache RemoteHomeserverCache = new(); + private static SemaphoreCache FederationClientCache = new(); public async Task GetAuthenticatedWithToken(string homeserver, string accessToken, string? proxy = null, string? impersonatedMxid = null, - bool useGeneric = false) { + bool useGeneric = false, bool enableClient = true, bool enableServer = true) { + if (!enableClient && !enableServer) + throw new ArgumentException("At least one of enableClient or enableServer must be true"); + return await AuthenticatedHomeserverCache.GetOrAdd($"{homeserver}{accessToken}{proxy}{impersonatedMxid}", async () => { - var wellKnownUris = await hsResolver.ResolveHomeserverFromWellKnown(homeserver); + var wellKnownUris = await hsResolver.ResolveHomeserverFromWellKnown(homeserver, enableClient, enableServer); var rhs = new RemoteHomeserver(homeserver, wellKnownUris, ref proxy); - + AuthenticatedHomeserverGeneric? hs = null; - if (!useGeneric) - { + if (!useGeneric) { ClientVersionsResponse? clientVersions = new(); try { clientVersions = await rhs.GetClientVersionsAsync(); @@ -50,7 +53,7 @@ public class HomeserverProviderService(ILogger logger throw; } } - + hs ??= new AuthenticatedHomeserverGeneric(homeserver, wellKnownUris, ref proxy, accessToken); await hs.Initialise(); @@ -62,9 +65,17 @@ public class HomeserverProviderService(ILogger logger }); } - public async Task GetRemoteHomeserver(string homeserver, string? proxy = null) => - await RemoteHomeserverCache.GetOrAdd($"{homeserver}{proxy}", - async () => { return new RemoteHomeserver(homeserver, await hsResolver.ResolveHomeserverFromWellKnown(homeserver), ref proxy); }); + public async Task GetRemoteHomeserver(string homeserver, string? proxy = null, bool useCache = true, bool enableServer = true) => + useCache + ? await RemoteHomeserverCache.GetOrAdd($"{homeserver}{proxy}", + async () => { return new RemoteHomeserver(homeserver, await hsResolver.ResolveHomeserverFromWellKnown(homeserver, enableServer: enableServer), ref proxy); }) + : new RemoteHomeserver(homeserver, await hsResolver.ResolveHomeserverFromWellKnown(homeserver, enableServer: enableServer), ref proxy); + + public async Task GetFederationClient(string homeserver, string keyId, string? proxy = null, bool useCache = true) => + useCache + ? await FederationClientCache.GetOrAdd($"{homeserver}{keyId}{proxy}", + async () => { return new FederationClient((await hsResolver.ResolveHomeserverFromWellKnown(homeserver, enableClient: false)).Server!, proxy); }) + : new FederationClient((await hsResolver.ResolveHomeserverFromWellKnown(homeserver, enableClient: false)).Server!, proxy); public async Task Login(string homeserver, string user, string password, string? proxy = null) { var hs = await GetRemoteHomeserver(homeserver, proxy); diff --git a/LibMatrix/Services/HomeserverResolverService.cs b/LibMatrix/Services/HomeserverResolverService.cs index 42ad0a1..05ce733 100644 --- a/LibMatrix/Services/HomeserverResolverService.cs +++ b/LibMatrix/Services/HomeserverResolverService.cs @@ -14,7 +14,7 @@ namespace LibMatrix.Services; public class HomeserverResolverService { private readonly MatrixHttpClient _httpClient = new() { - Timeout = TimeSpan.FromMilliseconds(10000) + Timeout = TimeSpan.FromSeconds(60) }; private static readonly SemaphoreCache WellKnownCache = new(); @@ -30,40 +30,45 @@ public class HomeserverResolverService { } } - private static SemaphoreSlim _wellKnownSemaphore = new(1, 1); + // private static SemaphoreSlim _wellKnownSemaphore = new(1, 1); - public async Task ResolveHomeserverFromWellKnown(string homeserver) { + public async Task ResolveHomeserverFromWellKnown(string homeserver, bool enableClient = true, bool enableServer = true) { ArgumentNullException.ThrowIfNull(homeserver); return await WellKnownCache.GetOrAdd(homeserver, async () => { - await _wellKnownSemaphore.WaitAsync(); + // await _wellKnownSemaphore.WaitAsync(); _logger.LogTrace($"Resolving homeserver well-knowns: {homeserver}"); - var client = _tryResolveClientEndpoint(homeserver); + var client = enableClient ? _tryResolveClientEndpoint(homeserver) : null; + var server = enableServer ? _tryResolveServerEndpoint(homeserver) : null; var res = new WellKnownUris(); // try { - res.Client = await client ?? throw new Exception("Could not resolve client URL."); + if (client != null) + res.Client = await client ?? throw new Exception($"Could not resolve client URL for {homeserver}."); // } // catch (Exception e) { // _logger.LogError(e, "Error resolving client well-known for {hs}", homeserver); // } - var server = _tryResolveServerEndpoint(homeserver); - // try { - res.Server = await server ?? throw new Exception("Could not resolve server URL."); + if (server != null) + res.Server = await server ?? throw new Exception($"Could not resolve server URL for {homeserver}."); // } // catch (Exception e) { // _logger.LogError(e, "Error resolving server well-known for {hs}", homeserver); // } _logger.LogInformation("Resolved well-knowns for {hs}: {json}", homeserver, res.ToJson(indent: false)); - _wellKnownSemaphore.Release(); + // _wellKnownSemaphore.Release(); return res; }); } + // private async Task InternalResolveHomeserverFromWellKnown(string homeserver) { + + // } + private async Task _tryResolveClientEndpoint(string homeserver) { ArgumentNullException.ThrowIfNull(homeserver); _logger.LogTrace("Resolving client well-known: {homeserver}", homeserver); @@ -90,7 +95,7 @@ public class HomeserverResolverService { if (!string.IsNullOrWhiteSpace(clientWellKnown?.Homeserver.BaseUrl)) return clientWellKnown.Homeserver.BaseUrl; - _logger.LogInformation("No client well-known..."); + _logger.LogInformation("No client well-known for {server}...", homeserver); return null; } @@ -129,7 +134,7 @@ public class HomeserverResolverService { if (clientUrl is not null && await _httpClient.CheckSuccessStatus($"{clientUrl}/_matrix/federation/v1/version")) return clientUrl; - _logger.LogInformation("No server well-known..."); + _logger.LogInformation("No server well-known for {server}...", homeserver); return null; } -- cgit 1.4.1