simple_throttle 1.0.3 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88bc1f488ffad8621894918d48bbde5df0c68ef498ddaaf359d91f81914a27c5
4
- data.tar.gz: c219a0b2a6b66e1e5427bdab8260dcfc4f0121618fd8c340a3e892f92dad1192
3
+ metadata.gz: 30c315dd33f7e175c0e74b4dfd8344e889d7e856c96c786b87ebac29d07fcc3a
4
+ data.tar.gz: acfb600e437eb125b9bf279dd95315ce7fa40612f836f887003b360ae2aacceb
5
5
  SHA512:
6
- metadata.gz: 9e30ae0a0a4dbfb09778fc1cfcd02d3376b020fc83d4166a2ab6066725a4c2c0e8680f38ac26c127b6b0952ed4558ff9c3e82e0301dda0dc4db9bf831cb8c383
7
- data.tar.gz: 5cfb1b4e72a4b1014a131b50ddb028e41289b102016b54ba2a5eef4c03d2f7a5edd66b21c84924be54df1e01796d0c1c2c963a7cf8072bfc1ca7951bab983a47
6
+ metadata.gz: 89d1b64043ee7f6460be93bb12ac50728e31ede360bcaa68191cb84087d50fe7db4386d8d24eba380c37a9426df78cb26c0685da75d7f6610e244e332be2821c
7
+ data.tar.gz: 47598bdce624ab1effbefbfc36d8860f3e017a7ecb2213cdd46d8c67e681583df62bdaf1270f77f6d4e83a88de0c0222c92c3a141fb9bfc3340cbee3bf0914a3
data/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 1.0.5
8
+
9
+ ### Added
10
+ - Make loading lua script play better with Redis clusters.
11
+ - Handle failures loading lua script on Redis server to prevent infinite loop.
12
+
13
+ ## 1.0.4
14
+
15
+ ### Fixed
16
+ - Fix wait_time method to match the documentation from [bc-swoop](https://github.com/bc-swoop)
17
+
7
18
  ## 1.0.3
8
19
 
9
20
  ### Changed
data/README.md CHANGED
@@ -60,7 +60,7 @@ $ gem install simple_throttle
60
60
 
61
61
  ## Contributing
62
62
 
63
- Open a pull request on GitHub.
63
+ Fork the repository and open a pull request on GitHub.
64
64
 
65
65
  Please use the [standardrb](https://github.com/testdouble/standard) syntax and lint your code with `standardrb --fix` before submitting.
66
66
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.0.5
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "redis"
4
+
4
5
  # Create a simple throttle that can be used to limit the number of request for a resouce
5
6
  # per time period. These objects are thread safe.
6
7
  class SimpleThrottle
@@ -41,7 +42,15 @@ class SimpleThrottle
41
42
 
42
43
  class << self
43
44
  # Add a global throttle that can be referenced later with the [] method.
44
- def add(name, limit:, ttl:, redis: nil)
45
+ # This can be used to configure global throttles that you want to setup once
46
+ # and then use in multiple places.
47
+ #
48
+ # @param name [String] unique name for the throttle
49
+ # @param ttl [Numeric] number of seconds that the throttle will remain active
50
+ # @param limit [Integer] number of allowed requests within the throttle ttl
51
+ # @param redis [Redis, Proc] Redis instance to use or a Proc that yields a Redos instance
52
+ # @return [void]
53
+ def add(name, ttl:, limit:, redis: nil)
45
54
  @lock.synchronize do
46
55
  @throttles ||= {}
47
56
  @throttles[name.to_s] = new(name, limit: limit, ttl: ttl, redis: redis)
@@ -49,6 +58,9 @@ class SimpleThrottle
49
58
  end
50
59
 
51
60
  # Returns a globally defined throttle with the specfied name.
61
+ #
62
+ # @param name [String, Symbol] name of the throttle
63
+ # @return [SimpleThrottle]
52
64
  def [](name)
53
65
  if defined?(@throttles) && @throttles
54
66
  @throttles[name.to_s]
@@ -60,11 +72,17 @@ class SimpleThrottle
60
72
  # it will be invoked at runtime to get the instance. Use this method if your Redis instance
61
73
  # isn't constant (for example if you're in a forking environment and re-initialize connections
62
74
  # on fork)
75
+ #
76
+ # @param client [Redis, Proc]
77
+ # @yieldreturn [Redis]
78
+ # @return [void]
63
79
  def set_redis(client = nil, &block)
64
80
  @redis_client = (client || block)
65
81
  end
66
82
 
67
83
  # Return the Redis instance where the throttles are stored.
84
+ #
85
+ # @return [Redis]
68
86
  def redis
69
87
  @redis_client ||= Redis.new
70
88
  if @redis_client.is_a?(Proc)
@@ -77,12 +95,16 @@ class SimpleThrottle
77
95
  private
78
96
 
79
97
  def execute_lua_script(redis:, keys:, args:)
80
- @script_sha_1 ||= redis.script(:load, LUA_SCRIPT)
98
+ client = redis
99
+ @script_sha_1 ||= client.script(:load, LUA_SCRIPT)
100
+ attempts = 0
101
+
81
102
  begin
82
- redis.evalsha(@script_sha_1, Array(keys), Array(args))
103
+ client.evalsha(@script_sha_1, Array(keys), Array(args))
83
104
  rescue Redis::CommandError => e
84
- if e.message.include?("NOSCRIPT")
85
- @script_sha_1 = redis.script(:load, LUA_SCRIPT)
105
+ if e.message.include?("NOSCRIPT") && attempts < 2
106
+ @script_sha_1 = client.script(:load, LUA_SCRIPT)
107
+ attempts += 1
86
108
  retry
87
109
  else
88
110
  raise e
@@ -93,11 +115,12 @@ class SimpleThrottle
93
115
 
94
116
  attr_reader :name, :limit, :ttl
95
117
 
96
- # Create a new throttle
118
+ # Create a new throttle.
119
+ #
97
120
  # @param name [String] unique name for the throttle
98
121
  # @param ttl [Numeric] number of seconds that the throttle will remain active
99
122
  # @param limit [Integer] number of allowed requests within the throttle ttl
100
- # @param redis [Redis] Redis client to use
123
+ # @param redis [Redis, Proc] Redis instance to use or a Proc that yields a Redos instance
101
124
  def initialize(name, ttl:, limit:, redis: nil)
102
125
  @name = name.to_s
103
126
  @name = name.dup.freeze unless name.frozen?
@@ -108,17 +131,23 @@ class SimpleThrottle
108
131
 
109
132
  # Returns true if the limit for the throttle has not been reached yet. This method
110
133
  # will also track the throttled resource as having been invoked on each call.
134
+ #
135
+ # @return [Boolean]
111
136
  def allowed!
112
137
  size = current_size(true)
113
138
  size < limit
114
139
  end
115
140
 
116
141
  # Reset a throttle back to zero.
142
+ #
143
+ # @return [void]
117
144
  def reset!
118
145
  redis_client.del(redis_key)
119
146
  end
120
147
 
121
148
  # Peek at the current number for throttled calls being tracked.
149
+ #
150
+ # @return [Integer]
122
151
  def peek
123
152
  current_size(false)
124
153
  end
@@ -126,6 +155,8 @@ class SimpleThrottle
126
155
  # Returns when the next resource call should be allowed. Note that this doesn't guarantee that
127
156
  # calling allow! will return true if the wait time is zero since other processes or threads can
128
157
  # claim the resource.
158
+ #
159
+ # @return [Float]
129
160
  def wait_time
130
161
  if peek < limit
131
162
  0.0
@@ -133,7 +164,7 @@ class SimpleThrottle
133
164
  first = redis_client.lindex(redis_key, 0).to_f / 1000.0
134
165
  delta = Time.now.to_f - first
135
166
  delta = 0.0 if delta < 0
136
- delta
167
+ ttl - delta
137
168
  end
138
169
  end
139
170
 
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_throttle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - We Heart It
8
8
  - Brian Durand
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-09-14 00:00:00.000000000 Z
12
+ date: 2023-03-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -39,7 +39,7 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
- description:
42
+ description:
43
43
  email:
44
44
  - dev@weheartit.com
45
45
  - bbdurand@gmail.com
@@ -57,7 +57,7 @@ homepage: https://github.com/weheartit/simple_throttle
57
57
  licenses:
58
58
  - MIT
59
59
  metadata: {}
60
- post_install_message:
60
+ post_install_message:
61
61
  rdoc_options: []
62
62
  require_paths:
63
63
  - lib
@@ -72,8 +72,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
72
  - !ruby/object:Gem::Version
73
73
  version: '0'
74
74
  requirements: []
75
- rubygems_version: 3.0.3
76
- signing_key:
75
+ rubygems_version: 3.2.22
76
+ signing_key:
77
77
  specification_version: 4
78
78
  summary: Simple redis backed throttling mechanism to limit access to a resource
79
79
  test_files: []