PluralKit/Myriad/Rest/Ratelimit/DiscordRateLimitPolicy.cs

40 lines
1.5 KiB
C#
Raw Normal View History

2020-12-22 12:15:26 +00:00
using Polly;
namespace Myriad.Rest.Ratelimit;
public class DiscordRateLimitPolicy: AsyncPolicy<HttpResponseMessage>
2020-12-22 12:15:26 +00:00
{
public const string EndpointContextKey = "Endpoint";
public const string MajorContextKey = "Major";
2020-12-22 12:15:26 +00:00
private readonly Ratelimiter _ratelimiter;
2020-12-22 12:15:26 +00:00
public DiscordRateLimitPolicy(Ratelimiter ratelimiter, PolicyBuilder<HttpResponseMessage>? policyBuilder = null)
: base(policyBuilder)
{
_ratelimiter = ratelimiter;
}
2020-12-22 12:15:26 +00:00
protected override async Task<HttpResponseMessage> ImplementationAsync(
Func<Context, CancellationToken, Task<HttpResponseMessage>> action, Context context, CancellationToken ct,
bool continueOnCapturedContext)
{
if (!context.TryGetValue(EndpointContextKey, out var endpointObj) || !(endpointObj is string endpoint))
throw new ArgumentException("Must provide endpoint in Polly context");
2020-12-22 12:15:26 +00:00
if (!context.TryGetValue(MajorContextKey, out var majorObj) || !(majorObj is ulong major))
throw new ArgumentException("Must provide major in Polly context");
2020-12-22 12:15:26 +00:00
// Check rate limit, throw if we're not allowed...
_ratelimiter.AllowRequestOrThrow(endpoint, major, DateTimeOffset.Now);
2020-12-22 12:15:26 +00:00
// We're OK, push it through
var response = await action(context, ct).ConfigureAwait(continueOnCapturedContext);
2020-12-22 12:15:26 +00:00
// Update rate limit state with headers
var headers = RatelimitHeaders.Parse(response);
_ratelimiter.HandleResponse(headers, endpoint, major);
2020-12-22 12:15:26 +00:00
return response;
2020-12-22 12:15:26 +00:00
}
}