mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-11 10:26:57 +02:00
Don't respect rate limits optimistically
This commit is contained in:
parent
b3a1cbf635
commit
c7023b38db
1 changed files with 1 additions and 35 deletions
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
@ -43,44 +42,11 @@ public class DiscordClient(string token)
|
||||||
tokenKind == TokenKind.Bot ? $"Bot {token}" : token
|
tokenKind == TokenKind.Bot ? $"Bot {token}" : token
|
||||||
);
|
);
|
||||||
|
|
||||||
var response = await Http.Client.SendAsync(
|
return await Http.Client.SendAsync(
|
||||||
request,
|
request,
|
||||||
HttpCompletionOption.ResponseHeadersRead,
|
HttpCompletionOption.ResponseHeadersRead,
|
||||||
innerCancellationToken
|
innerCancellationToken
|
||||||
);
|
);
|
||||||
|
|
||||||
// If this was the last request available before hitting the rate limit,
|
|
||||||
// wait out the reset time so that future requests can succeed.
|
|
||||||
// This may add an unnecessary delay in case the user doesn't intend to
|
|
||||||
// make any more requests, but implementing a smarter solution would
|
|
||||||
// require properly keeping track of Discord's global/per-route/per-resource
|
|
||||||
// rate limits and that's just way too much effort.
|
|
||||||
// https://discord.com/developers/docs/topics/rate-limits
|
|
||||||
var remainingRequestCount = response
|
|
||||||
.Headers
|
|
||||||
.TryGetValue("X-RateLimit-Remaining")
|
|
||||||
?.Pipe(s => int.Parse(s, CultureInfo.InvariantCulture));
|
|
||||||
|
|
||||||
var resetAfterDelay = response
|
|
||||||
.Headers
|
|
||||||
.TryGetValue("X-RateLimit-Reset-After")
|
|
||||||
?.Pipe(s => double.Parse(s, CultureInfo.InvariantCulture))
|
|
||||||
.Pipe(TimeSpan.FromSeconds);
|
|
||||||
|
|
||||||
if (remainingRequestCount <= 0 && resetAfterDelay is not null)
|
|
||||||
{
|
|
||||||
var delay =
|
|
||||||
// Adding a small buffer to the reset time reduces the chance of getting
|
|
||||||
// rate limited again, because it allows for more requests to be released.
|
|
||||||
(resetAfterDelay.Value + TimeSpan.FromSeconds(1))
|
|
||||||
// Sometimes Discord returns an absurdly high value for the reset time, which
|
|
||||||
// is not actually enforced by the server. So we cap it at a reasonable value.
|
|
||||||
.Clamp(TimeSpan.Zero, TimeSpan.FromSeconds(60));
|
|
||||||
|
|
||||||
await Task.Delay(delay, innerCancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
},
|
},
|
||||||
cancellationToken
|
cancellationToken
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue