ruby_rolling_rate_limiter 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ruby_rolling_rate_limiter.rb +7 -7
- data/lib/ruby_rolling_rate_limiter/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b995833dda769c96be7cbb76932d5f5716c44c85
|
4
|
+
data.tar.gz: a133589b2bf5f3f6b8f3c72d2f7c8d09553464d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb3ffd17a1eb967751d3a60c01c5636d1588643c30966f839348d488ef33d74132f7f8c7a2336b514a02f012d8fa28c43df17609050fcdce0c63f610905002c5
|
7
|
+
data.tar.gz: 19c13b72ee927737d8b39cc1ca98cef6ee1d8b52836949886b99cc99fc3de7ee54048a343b7a800bb94816a0202d5bc3786c834c4f0c21f1a0b1e83c67ebe516
|
@@ -8,11 +8,11 @@ class RubyRollingRateLimiter
|
|
8
8
|
# Your code goes here...
|
9
9
|
attr_reader :current_error
|
10
10
|
|
11
|
-
def initialize(limiter_identifier, interval_in_seconds, max_calls_per_interval,
|
11
|
+
def initialize(limiter_identifier, interval_in_seconds, max_calls_per_interval, min_distance_between_calls_in_milliseconds = 1000, redis_connection = $redis)
|
12
12
|
@limiter_identifier = limiter_identifier
|
13
13
|
@interval_in_seconds = interval_in_seconds
|
14
14
|
@max_calls_per_interval = max_calls_per_interval
|
15
|
-
@
|
15
|
+
@min_distance_between_calls_in_milliseconds = min_distance_between_calls_in_milliseconds
|
16
16
|
@redis_connection = redis_connection
|
17
17
|
#Check to ensure args are good.
|
18
18
|
validate_arguments
|
@@ -51,7 +51,7 @@ class RubyRollingRateLimiter
|
|
51
51
|
# Because the resource is locked via redlock, I'm going to remove the multi on this.
|
52
52
|
@redis_connection.zremrangebyscore(key, 0, clear_before.to_s)
|
53
53
|
current_range = @redis_connection.zrange(key, 0, -1)
|
54
|
-
if (current_range.count <= @max_calls_per_interval) && ((current_range.count+call_size) <= @max_calls_per_interval) && ((@
|
54
|
+
if (current_range.count <= @max_calls_per_interval) && ((current_range.count+call_size) <= @max_calls_per_interval) && ((@min_distance_between_calls_in_milliseconds * 1000) && (now - current_range.last.to_i) > (@min_distance_between_calls_in_milliseconds * 1000))
|
55
55
|
results = @redis_connection.zrange(key, 0, -1)
|
56
56
|
call_size.times do
|
57
57
|
@redis_connection.zadd(key, now.to_s, now.to_s)
|
@@ -79,7 +79,7 @@ class RubyRollingRateLimiter
|
|
79
79
|
if results
|
80
80
|
call_set = results
|
81
81
|
too_many_in_interval = call_set.count >= @max_calls_per_interval
|
82
|
-
time_since_last_request = (@
|
82
|
+
time_since_last_request = (@min_distance_between_calls_in_milliseconds * 1000) && (now - call_set.last.to_i)
|
83
83
|
|
84
84
|
if too_many_in_interval
|
85
85
|
@current_error = {code: 1, result: false, error: "Too many requests", retry_in: (call_set.first.to_i - now + interval) / 1000 / 1000, retry_in_micro: (call_set.first.to_i - now + interval)}
|
@@ -87,8 +87,8 @@ class RubyRollingRateLimiter
|
|
87
87
|
elsif (call_set.count+call_size) > @max_calls_per_interval
|
88
88
|
@current_error = {code: 2, result: false, error: "Call Size too big for available access, trying to make #{call_size} with only #{call_set.count} calls available in window", retry_in: (call_set.first.to_i - now + interval) / 1000 / 1000, retry_in_micro: (call_set.first.to_i - now + interval)}
|
89
89
|
return false
|
90
|
-
elsif time_since_last_request < (@
|
91
|
-
@current_error = {code: 3, result: false, error: "Attempting to thrash faster than the minimal distance between calls", retry_in: @
|
90
|
+
elsif time_since_last_request < (@min_distance_between_calls_in_milliseconds * 1000)
|
91
|
+
@current_error = {code: 3, result: false, error: "Attempting to thrash faster than the minimal distance between calls", retry_in: @min_distance_between_calls_in_milliseconds / 1000, retry_in_micro: (@min_distance_between_calls_in_milliseconds * 1000)}
|
92
92
|
return false
|
93
93
|
end
|
94
94
|
return true
|
@@ -101,7 +101,7 @@ class RubyRollingRateLimiter
|
|
101
101
|
raise Errors::ArgumentInvalid, "limiter_identifier argument must be 1 or more characters long" unless @limiter_identifier.length > 0
|
102
102
|
raise Errors::ArgumentInvalid, "interval_in_seconds argument must be an integer, this is specified in seconds" unless @interval_in_seconds.is_a? Integer and @interval_in_seconds > 0
|
103
103
|
raise Errors::ArgumentInvalid, "max_calls_per_interval argument must be an integer, this is the amount of calls that can be made during the rolling window." unless @max_calls_per_interval.is_a? Integer and @max_calls_per_interval > 0
|
104
|
-
raise Errors::ArgumentInvalid, "
|
104
|
+
raise Errors::ArgumentInvalid, "min_distance_between_calls_in_milliseconds argument must be an integer, this is the buffer between each call during the rolling window" unless (@min_distance_between_calls_in_milliseconds.is_a? Integer or @min_distance_between_calls_in_milliseconds.is_a? Float)and @min_distance_between_calls_in_milliseconds > 0
|
105
105
|
end
|
106
106
|
|
107
107
|
#
|