mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-11 08:22:53 +00:00
Added RateLimitGroup option
This commit is contained in:
@@ -3,6 +3,7 @@ using CryptoExchange.Net.Converters.MessageParsing.DynamicConverters;
|
||||
using CryptoExchange.Net.Converters.SystemTextJson;
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using CryptoExchange.Net.Objects;
|
||||
using CryptoExchange.Net.RateLimiting;
|
||||
using CryptoExchange.Net.SharedApis;
|
||||
using CryptoExchange.Net.Testing.Implementations;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -47,11 +48,12 @@ namespace CryptoExchange.Net.UnitTests.Implementations
|
||||
RequestFactory = factory;
|
||||
}
|
||||
|
||||
internal async Task<WebCallResult<T>> GetResponseAsync<T>(HttpMethod? httpMethod = null, ParameterCollection? collection = null)
|
||||
internal async Task<WebCallResult<T>> GetResponseAsync<T>(HttpMethod? httpMethod = null, ParameterCollection? collection = null, RateLimitGate? rateLimitGate = null)
|
||||
{
|
||||
var definition = new RequestDefinition("/path", httpMethod ?? HttpMethod.Get)
|
||||
{
|
||||
Weight = 0
|
||||
Weight = 1,
|
||||
RateLimitGate = rateLimitGate
|
||||
};
|
||||
return await SendAsync<T>(BaseAddress, definition, collection ?? new ParameterCollection(), default);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ using CryptoExchange.Net.RateLimiting;
|
||||
using CryptoExchange.Net.RateLimiting.Filters;
|
||||
using CryptoExchange.Net.RateLimiting.Guards;
|
||||
using CryptoExchange.Net.RateLimiting.Interfaces;
|
||||
using CryptoExchange.Net.UnitTests.Implementations;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -285,5 +287,39 @@ namespace CryptoExchange.Net.UnitTests
|
||||
// assert
|
||||
Assert.That(evnt, Is.Not.Null);
|
||||
}
|
||||
|
||||
[TestCase(null, null, true)]
|
||||
[TestCase("Group1", null, false)]
|
||||
[TestCase(null, "Group2", false)]
|
||||
[TestCase("Group1", "Group2", false)]
|
||||
[TestCase("Group3", "Group3", true)]
|
||||
public async Task RateLimiterWithDifferentGroups_Should_AllowNotRateLimit(string? group1, string? group2, bool expectLimited)
|
||||
{
|
||||
// arrange
|
||||
var data = JsonSerializer.Serialize(new TestObject { });
|
||||
var client1 = new TestRestClient(x =>
|
||||
{
|
||||
x.RateLimitGroup = group1;
|
||||
});
|
||||
client1.ApiClient1.SetNextResponse(data, System.Net.HttpStatusCode.OK);
|
||||
var client2 = new TestRestClient(x =>
|
||||
{
|
||||
x.RateLimitGroup = group2;
|
||||
});
|
||||
client2.ApiClient1.SetNextResponse(data, System.Net.HttpStatusCode.OK);
|
||||
|
||||
var rateLimiter = new RateLimitGate("Test");
|
||||
rateLimiter.AddGuard(new RateLimitGuard(RateLimitGuard.PerHost, new LimitItemTypeFilter(RateLimitItemType.Request), 1, TimeSpan.FromSeconds(2), RateLimitWindowType.Fixed));
|
||||
|
||||
RateLimitEvent? evnt = null;
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
|
||||
// act
|
||||
var result1 = await client1.ApiClient1.GetResponseAsync<TestObject>(rateLimitGate: rateLimiter);
|
||||
var result2 = await client2.ApiClient1.GetResponseAsync<TestObject>(rateLimitGate: rateLimiter);
|
||||
|
||||
// assert
|
||||
Assert.That(evnt != null, Is.EqualTo(expectLimited));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ namespace CryptoExchange.Net.Clients
|
||||
GetAuthenticationProvider()?.Key,
|
||||
requestWeight,
|
||||
ClientOptions.RateLimitingBehaviour,
|
||||
rateLimitKeySuffix,
|
||||
rateLimitKeySuffix + ClientOptions.RateLimitGroup,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
if (!limitResult)
|
||||
return limitResult.Error!;
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
/// Note that this comes at a performance cost
|
||||
/// </summary>
|
||||
public bool OutputOriginalData { get; set; } = false;
|
||||
/// <summary>
|
||||
/// A group name to use for client side rate limiting. Requests with the same group name will be counted together for rate limiting purposes. If null all requests will be counted together.
|
||||
/// </summary>
|
||||
public string? RateLimitGroup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The max time a request is allowed to take
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
item.RequestTimeout = RequestTimeout;
|
||||
item.RateLimiterEnabled = RateLimiterEnabled;
|
||||
item.RateLimitingBehaviour = RateLimitingBehaviour;
|
||||
item.RateLimitGroup = RateLimitGroup;
|
||||
item.CachingEnabled = CachingEnabled;
|
||||
item.CachingMaxAge = CachingMaxAge;
|
||||
item.HttpVersion = HttpVersion;
|
||||
|
||||
@@ -104,6 +104,7 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
item.RequestTimeout = RequestTimeout;
|
||||
item.RateLimitingBehaviour = RateLimitingBehaviour;
|
||||
item.RateLimiterEnabled = RateLimiterEnabled;
|
||||
item.RateLimitGroup = RateLimitGroup;
|
||||
item.ReceiveBufferSize = ReceiveBufferSize;
|
||||
return item;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user