mirror of
				https://github.com/JKorf/CryptoExchange.Net
				synced 2025-10-31 02:17:45 +00:00 
			
		
		
		
	Merge pull request #75 from burakoner/master
Rate Limiter Credits parameter to SendRequest method
This commit is contained in:
		
						commit
						edbca6a680
					
				| @ -1,4 +1,4 @@ | |||||||
| using CryptoExchange.Net.Objects; | using CryptoExchange.Net.Objects; | ||||||
| 
 | 
 | ||||||
| namespace CryptoExchange.Net.Interfaces | namespace CryptoExchange.Net.Interfaces | ||||||
| { | { | ||||||
| @ -13,7 +13,8 @@ namespace CryptoExchange.Net.Interfaces | |||||||
|         /// <param name="client"></param> |         /// <param name="client"></param> | ||||||
|         /// <param name="url"></param> |         /// <param name="url"></param> | ||||||
|         /// <param name="limitBehaviour"></param> |         /// <param name="limitBehaviour"></param> | ||||||
|  |         /// <param name="credits"></param> | ||||||
|         /// <returns></returns> |         /// <returns></returns> | ||||||
|         CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour); |         CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour, int credits=1); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ namespace CryptoExchange.Net.RateLimiter | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour) |         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour, int credits = 1) | ||||||
|         { |         { | ||||||
|             if(client.authProvider?.Credentials?.Key == null) |             if(client.authProvider?.Credentials?.Key == null) | ||||||
|                 return new CallResult<double>(0, null); |                 return new CallResult<double>(0, null); | ||||||
|  | |||||||
							
								
								
									
										65
									
								
								CryptoExchange.Net/RateLimiter/RateLimiterCredit.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								CryptoExchange.Net/RateLimiter/RateLimiterCredit.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | |||||||
|  | using CryptoExchange.Net.Interfaces; | ||||||
|  | using CryptoExchange.Net.Objects; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Threading; | ||||||
|  | 
 | ||||||
|  | namespace CryptoExchange.Net.RateLimiter | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Limits the amount of requests per time period to a certain limit, counts the total amount of requests. | ||||||
|  |     /// </summary> | ||||||
|  |     public class RateLimiterCredit : IRateLimiter | ||||||
|  |     { | ||||||
|  |         internal List<DateTime> history = new List<DateTime>(); | ||||||
|  | 
 | ||||||
|  |         private readonly int limit; | ||||||
|  |         private readonly TimeSpan perTimePeriod; | ||||||
|  |         private readonly object requestLock = new object(); | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Create a new RateLimiterTotal. This rate limiter limits the amount of requests per time period to a certain limit, counts the total amount of requests. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="limit">The amount to limit to</param> | ||||||
|  |         /// <param name="perTimePeriod">The time period over which the limit counts</param> | ||||||
|  |         public RateLimiterCredit(int limit, TimeSpan perTimePeriod) | ||||||
|  |         { | ||||||
|  |             this.limit = limit; | ||||||
|  |             this.perTimePeriod = perTimePeriod; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// <inheritdoc /> | ||||||
|  |         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour, int credits = 1) | ||||||
|  |         { | ||||||
|  |             var sw = Stopwatch.StartNew(); | ||||||
|  |             lock (requestLock) | ||||||
|  |             { | ||||||
|  |                 sw.Stop(); | ||||||
|  |                 double waitTime = 0; | ||||||
|  |                 var checkTime = DateTime.UtcNow; | ||||||
|  |                 history.RemoveAll(d => d < checkTime - perTimePeriod); | ||||||
|  | 
 | ||||||
|  |                 if (history.Count >= limit) | ||||||
|  |                 { | ||||||
|  |                     waitTime = (history.First() - (checkTime - perTimePeriod)).TotalMilliseconds; | ||||||
|  |                     if (waitTime > 0) | ||||||
|  |                     { | ||||||
|  |                         if (limitBehaviour == RateLimitingBehaviour.Fail) | ||||||
|  |                             return new CallResult<double>(waitTime, new RateLimitError($"total limit of {limit} reached")); | ||||||
|  | 
 | ||||||
|  |                         Thread.Sleep(Convert.ToInt32(waitTime)); | ||||||
|  |                         waitTime += sw.ElapsedMilliseconds; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 for (int i = 1; i <= credits; i++) | ||||||
|  |                     history.Add(DateTime.UtcNow); | ||||||
|  | 
 | ||||||
|  |                 history.Sort(); | ||||||
|  |                 return new CallResult<double>(waitTime, null); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -30,7 +30,7 @@ namespace CryptoExchange.Net.RateLimiter | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitingBehaviour) |         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitingBehaviour, int credits = 1) | ||||||
|         { |         { | ||||||
|             int waitTime; |             int waitTime; | ||||||
|             RateLimitObject rlo; |             RateLimitObject rlo; | ||||||
|  | |||||||
| @ -31,7 +31,7 @@ namespace CryptoExchange.Net.RateLimiter | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour) |         public CallResult<double> LimitRequest(RestClient client, string url, RateLimitingBehaviour limitBehaviour, int credits = 1) | ||||||
|         { |         { | ||||||
|             var sw = Stopwatch.StartNew(); |             var sw = Stopwatch.StartNew(); | ||||||
|             lock (requestLock) |             lock (requestLock) | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
| @ -172,7 +172,7 @@ namespace CryptoExchange.Net | |||||||
|         /// <returns></returns> |         /// <returns></returns> | ||||||
|         [return: NotNull] |         [return: NotNull] | ||||||
|         protected virtual async Task<WebCallResult<T>> SendRequest<T>(Uri uri, HttpMethod method, CancellationToken cancellationToken, |         protected virtual async Task<WebCallResult<T>> SendRequest<T>(Uri uri, HttpMethod method, CancellationToken cancellationToken, | ||||||
|             Dictionary<string, object>? parameters = null, bool signed = false, bool checkResult = true, PostParameters? postPosition = null, ArrayParametersSerialization? arraySerialization = null) where T : class |             Dictionary<string, object>? parameters = null, bool signed = false, bool checkResult = true, PostParameters? postPosition = null, ArrayParametersSerialization? arraySerialization = null, int credits=1) where T : class | ||||||
|         { |         { | ||||||
|             var requestId = NextId(); |             var requestId = NextId(); | ||||||
|             log.Write(LogVerbosity.Debug, $"[{requestId}] Creating request for " + uri); |             log.Write(LogVerbosity.Debug, $"[{requestId}] Creating request for " + uri); | ||||||
| @ -185,7 +185,7 @@ namespace CryptoExchange.Net | |||||||
|             var request = ConstructRequest(uri, method, parameters, signed, postPosition ?? postParametersPosition, arraySerialization ?? this.arraySerialization, requestId); |             var request = ConstructRequest(uri, method, parameters, signed, postPosition ?? postParametersPosition, arraySerialization ?? this.arraySerialization, requestId); | ||||||
|             foreach (var limiter in RateLimiters) |             foreach (var limiter in RateLimiters) | ||||||
|             { |             { | ||||||
|                 var limitResult = limiter.LimitRequest(this, uri.AbsolutePath, RateLimitBehaviour); |                 var limitResult = limiter.LimitRequest(this, uri.AbsolutePath, RateLimitBehaviour, credits); | ||||||
|                 if (!limitResult.Success) |                 if (!limitResult.Success) | ||||||
|                 { |                 { | ||||||
|                     log.Write(LogVerbosity.Debug, $"[{requestId}] Request {uri.AbsolutePath} failed because of rate limit"); |                     log.Write(LogVerbosity.Debug, $"[{requestId}] Request {uri.AbsolutePath} failed because of rate limit"); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user