ruby_rolling_rate_limiter 0.1.1 → 0.1.3
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 707ecff1e33f4f609cc8399cdebab57ad206daca
|
4
|
+
data.tar.gz: 89273199718232705e954c41decdaa1923e10a98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41bd11d653038fb3008c62e15289a031b3390ea797d8f38bfa1c1a602420ae5ca7c38459bc117e600b35eb2db9bc20b328ff71f82c4c91ae7d00b5bd59491a58
|
7
|
+
data.tar.gz: f683ecb68d5c63da9aa0eae3b3d1fd648f89d4ea7517f82ab39edf3cd0eb6c15ab3eacd56ecfbe50e9614ff6bce6274c3189e071b0927499f6ff3abe17a5ce6d
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "ruby_rolling_rate_limiter/version"
|
2
2
|
require "ruby_rolling_rate_limiter/errors"
|
3
3
|
require "redis"
|
4
|
-
require '
|
4
|
+
require 'redlock'
|
5
5
|
require "date"
|
6
6
|
|
7
7
|
class RubyRollingRateLimiter
|
@@ -14,12 +14,13 @@ class RubyRollingRateLimiter
|
|
14
14
|
@max_calls_per_interval = max_calls_per_interval
|
15
15
|
@min_distance_between_calls_in_seconds = min_distance_between_calls_in_seconds
|
16
16
|
@redis_connection = redis_connection
|
17
|
-
|
18
17
|
#Check to ensure args are good.
|
19
18
|
validate_arguments
|
20
19
|
|
21
20
|
# Check Redis is there
|
22
21
|
check_redis_is_available
|
22
|
+
# Setup the Lock Manager
|
23
|
+
@lock_manager ||= Redlock::Client.new([redis_connection])
|
23
24
|
|
24
25
|
end
|
25
26
|
|
@@ -42,24 +43,40 @@ class RubyRollingRateLimiter
|
|
42
43
|
|
43
44
|
clear_before = now - interval
|
44
45
|
# Begin multi redis
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
max_retry_counter = 0
|
47
|
+
begin
|
48
|
+
if max_retry_counter <= 100
|
49
|
+
@lock_manager.lock("#{key}-lock", 10000) do |locked|
|
50
|
+
if locked
|
51
|
+
@redis_connection.multi
|
52
|
+
@redis_connection.zremrangebyscore(key, 0, clear_before.to_s)
|
53
|
+
@redis_connection.zrange(key, 0, -1)
|
54
|
+
cur = @redis_connection.exec
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
+
if (cur[1].count <= @max_calls_per_interval) && ((cur[1].count+call_size) <= @max_calls_per_interval) && ((@min_distance_between_calls_in_seconds * 1000 * 1000) && (now - cur[1].last.to_i) > (@min_distance_between_calls_in_seconds * 1000 * 1000))
|
57
|
+
@redis_connection.multi
|
58
|
+
@redis_connection.zrange(key, 0, -1)
|
59
|
+
call_size.times do
|
60
|
+
@redis_connection.zadd(key, now.to_s, now.to_s)
|
61
|
+
end
|
62
|
+
@redis_connection.expire(key, @interval_in_seconds)
|
63
|
+
results = @redis_connection.exec
|
64
|
+
else
|
65
|
+
results = [cur[1]]
|
66
|
+
end
|
67
|
+
else
|
68
|
+
raise Errors::LockWaiting, "Could not aquire lock"
|
69
|
+
end
|
56
70
|
end
|
57
|
-
@redis_connection.expire(key, @interval_in_seconds)
|
58
|
-
results = @redis_connection.exec
|
59
71
|
else
|
60
|
-
|
72
|
+
raise Errors::MaxRetryReachedOnLockAcquire, "Unable to acquire lock for rate limit after 100 attempts"
|
61
73
|
end
|
74
|
+
rescue Errors::LockWaiting
|
75
|
+
sleep 0.2
|
76
|
+
max_retry_counter +=1
|
77
|
+
retry
|
62
78
|
end
|
79
|
+
|
63
80
|
if results
|
64
81
|
call_set = results[0]
|
65
82
|
too_many_in_interval = call_set.count >= @max_calls_per_interval
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_rolling_rate_limiter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karl Kloppenborg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,19 +81,19 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.2'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: redlock
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 0.1.5
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 0.1.5
|
97
97
|
description: Often Redis is used for rate limiting purposes. Usually the rate limit
|
98
98
|
packages available count how many times something happens on a certain second or
|
99
99
|
a certain minute. When the clock ticks to the next minute, rate limit counter is
|