ruby_rolling_rate_limiter 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
#
|