about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-05-08 23:02:05 +0200
committerRory& <root@rory.gay>2025-05-08 23:02:05 +0200
commitbcd408ce15dc5f364de48517f6d6f499405078de (patch)
tree091551ede75e369cbc5e4b3deb6862230270ad7e
parentMSC4222 emulation for joined rooms? (diff)
downloadLibMatrix-bcd408ce15dc5f364de48517f6d6f499405078de.tar.xz
Retry http requests up to 5 times, add support for unstable state_after
-rw-r--r--LibMatrix/Extensions/MatrixHttpClient.Single.cs23
-rw-r--r--LibMatrix/Responses/SyncResponse.cs23
2 files changed, 33 insertions, 13 deletions
diff --git a/LibMatrix/Extensions/MatrixHttpClient.Single.cs b/LibMatrix/Extensions/MatrixHttpClient.Single.cs

index bfc3f3b..baa4a2c 100644 --- a/LibMatrix/Extensions/MatrixHttpClient.Single.cs +++ b/LibMatrix/Extensions/MatrixHttpClient.Single.cs
@@ -70,7 +70,7 @@ public class MatrixHttpClient { return options; } - public async Task<HttpResponseMessage> SendUnhandledAsync(HttpRequestMessage request, CancellationToken cancellationToken) { + public async Task<HttpResponseMessage> SendUnhandledAsync(HttpRequestMessage request, CancellationToken cancellationToken, int attempt = 0) { if (request.RequestUri is null) throw new NullReferenceException("RequestUri is null"); // if (!request.RequestUri.IsAbsoluteUri) request.RequestUri = request.RequestUri.EnsureAbsolute(BaseAddress!); @@ -84,7 +84,7 @@ public class MatrixHttpClient { request.RequestUri = new Uri(BaseAddress ?? throw new InvalidOperationException("Relative URI passed, but no BaseAddress is specified!"), request.RequestUri); swWait.Stop(); var swExec = Stopwatch.StartNew(); - + foreach (var (key, value) in AdditionalQueryParameters) request.RequestUri = request.RequestUri.AddQuery(key, value); foreach (var (key, value) in DefaultRequestHeaders) { if (request.Headers.Contains(key)) continue; @@ -101,16 +101,23 @@ public class MatrixHttpClient { responseMessage = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); } catch (Exception e) { - if (e is TaskCanceledException or TimeoutException) { + if (attempt >= 5) { + Console.WriteLine( + $"Failed to send request {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.Content?.Headers.ContentLength ?? 0)}):\n{e}"); + throw; + } + + if (e is TaskCanceledException or TimeoutException or HttpRequestException) { if (request.Method == HttpMethod.Get && !cancellationToken.IsCancellationRequested) { await Task.Delay(Random.Shared.Next(500, 2500), cancellationToken); request.ResetSendStatus(); - return await SendAsync(request, cancellationToken); + return await SendUnhandledAsync(request, cancellationToken, attempt + 1); } } else if (!e.ToString().StartsWith("TypeError: NetworkError")) Console.WriteLine( $"Failed to send request {request.Method} {BaseAddress}{request.RequestUri} ({Util.BytesToString(request.Content?.Headers.ContentLength ?? 0)}):\n{e}"); + throw; } #if SYNC_HTTPCLIENT @@ -149,8 +156,8 @@ public class MatrixHttpClient { //retry on gateway timeout // if (responseMessage.StatusCode == HttpStatusCode.GatewayTimeout) { - // request.ResetSendStatus(); - // return await SendAsync(request, cancellationToken); + // request.ResetSendStatus(); + // return await SendAsync(request, cancellationToken); // } //error handling @@ -160,7 +167,7 @@ public class MatrixHttpClient { ErrorCode = "M_UNKNOWN", Error = "Unknown error, server returned no content" }; - + // if (!content.StartsWith('{')) throw new InvalidDataException("Encountered invalid data:\n" + content); if (!content.TrimStart().StartsWith('{')) { responseMessage.EnsureSuccessStatusCode(); @@ -291,4 +298,4 @@ public class MatrixHttpClient { return await SendAsync(request); } } -#endif +#endif \ No newline at end of file diff --git a/LibMatrix/Responses/SyncResponse.cs b/LibMatrix/Responses/SyncResponse.cs
index a7aebda..47fb753 100644 --- a/LibMatrix/Responses/SyncResponse.cs +++ b/LibMatrix/Responses/SyncResponse.cs
@@ -28,7 +28,7 @@ public class SyncResponse { [JsonPropertyName("device_lists")] public DeviceListsDataStructure? DeviceLists { get; set; } - + [JsonPropertyName("gay.rory.libmatrix.msc4222_sync_type")] public Msc4222SyncType Msc4222Method { get; set; } = Msc4222SyncType.None; @@ -65,10 +65,16 @@ public class SyncResponse { [JsonPropertyName("state")] public EventList? State { get; set; } - + [JsonPropertyName("state_after")] public EventList? StateAfter { get; set; } + [Obsolete("This property is only used for de/serialisation")] + [JsonPropertyName("org.matrix.msc4222.state_after")] + public EventList? StateAfterUnstable { + get => StateAfter; + set => StateAfter = value; + } public override string ToString() { var lastEvent = Timeline?.Events?.LastOrDefault(x => x.Type == "m.room.member"); @@ -83,10 +89,17 @@ public class SyncResponse { [JsonPropertyName("state")] public EventList? State { get; set; } - + [JsonPropertyName("state_after")] public EventList? StateAfter { get; set; } + [Obsolete("This property is only used for de/serialisation")] + [JsonPropertyName("org.matrix.msc4222.state_after")] + public EventList? StateAfterUnstable { + get => StateAfter; + set => StateAfter = value; + } + [JsonPropertyName("account_data")] public EventList? AccountData { get; set; } @@ -153,11 +166,11 @@ public class SyncResponse { Rooms?.Leave?.Values?.Max(x => x.Timeline?.Events?.Max(y => y.OriginServerTs)) ?? 0 ]).Max(); } - + [JsonConverter(typeof(JsonStringEnumConverter))] public enum Msc4222SyncType { None, Server, Emulated } -} +} \ No newline at end of file