sidekiq-throttler 0.2.0 → 0.3.0
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/.travis.yml +2 -3
- data/CHANGELOG.md +12 -0
- data/README.md +23 -2
- data/lib/sidekiq/throttler/rate_limit.rb +34 -17
- data/lib/sidekiq/throttler/storage/memory.rb +55 -0
- data/lib/sidekiq/throttler/storage/redis.rb +89 -0
- data/lib/sidekiq/throttler/version.rb +1 -1
- data/lib/sidekiq/throttler.rb +9 -4
- data/spec/app/workers/proc_threshold_worker.rb +10 -0
- data/spec/sidekiq/throttler/rate_limit_spec.rb +57 -20
- data/spec/sidekiq/throttler/storage/redis_spec.rb +37 -0
- data/spec/sidekiq/throttler_spec.rb +8 -5
- data/spec/spec_helper.rb +1 -5
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0258db1754f26622f1f38b1875774946a6a1c16e
|
4
|
+
data.tar.gz: 151f57ccb677fd3ad6cd25cd30ed605da04acb97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91440b76579924fc449a60c749ce5b88619c5efacfa5fabc45271b7f3f6a72b7408bc2b9b954e99d5aa33ab0b52a18addc957c9753fe4854b521c82738aec389
|
7
|
+
data.tar.gz: 9b57fbf2ae12af64aaf5667d658da9e2fb6af6ba3099373376eedad86c422a13a879a80137f7f9c8d2244dcb91a7db18bbb01555d43c6a57b37f2af999d5ece5
|
data/.travis.yml
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
+
- 2.0.0
|
3
4
|
- 1.9.3
|
4
5
|
- jruby-19mode
|
5
6
|
- rbx-19mode
|
6
|
-
- 2.0.0
|
7
7
|
branches:
|
8
8
|
only:
|
9
9
|
- master
|
10
10
|
notifications:
|
11
11
|
email:
|
12
12
|
recipients:
|
13
|
-
-
|
13
|
+
- gabe@ga.be
|
14
14
|
matrix:
|
15
15
|
allow_failures:
|
16
16
|
- rvm: jruby-19mode
|
17
17
|
- rvm: rbx-19mode
|
18
|
-
- rvm: 2.0.0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## 0.3.0 (October 3, 2013)
|
2
|
+
|
3
|
+
* Redis is supported as a storage backend for persistence of job execution
|
4
|
+
counters across multiple Sidekiq processes.
|
5
|
+
|
6
|
+
*Louis Simoneau*
|
7
|
+
|
8
|
+
* Only Active Support's `Time` extensions are required. Fixes compatibility with
|
9
|
+
Rails 4.
|
10
|
+
|
11
|
+
*Louis Simoneau*
|
12
|
+
|
1
13
|
## 0.2.0 (June 29, 2013)
|
2
14
|
|
3
15
|
* Now supports using a Proc for `:threshold` argument, similar to how the
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ limit job execution on a per-worker basis.
|
|
8
8
|
|
9
9
|
## Compatibility
|
10
10
|
|
11
|
-
Sidekiq::Throttler is tested against MRI 1.9.3.
|
11
|
+
Sidekiq::Throttler is actively tested against MRI versions 2.0.0 and 1.9.3.
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
@@ -37,6 +37,18 @@ Sidekiq.configure_server do |config|
|
|
37
37
|
end
|
38
38
|
```
|
39
39
|
|
40
|
+
Sidekiq::Throttler defaults to in-memory storage of job execution times. If
|
41
|
+
you have multiple worker processes, or frequently restart your processes, this
|
42
|
+
will be unreliable. Instead, specify the `:redis` storage option:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Sidekiq.configure_server do |config|
|
46
|
+
config.server_middleware do |chain|
|
47
|
+
chain.add Sidekiq::Throttler, storage: :redis
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
40
52
|
## Usage
|
41
53
|
|
42
54
|
In a worker, specify a threshold (maximum jobs) and period for throttling:
|
@@ -66,6 +78,15 @@ sidekiq_options throttle: { threshold: 20, period: 1.day, key: ->{ |user_id| use
|
|
66
78
|
In the above example, jobs are throttled for each user when they exceed 20 in a
|
67
79
|
day.
|
68
80
|
|
81
|
+
Thresholds can be configured based on the arguments passed to your worker's `perform` method,
|
82
|
+
similar to how the `key` option works:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
sidekiq_options throttle: { threshold: -> {|user_id, rate_limit| rate_limit }, period: 1.hour, key: ->{ |user_id, rate_limit| user_id } }
|
86
|
+
```
|
87
|
+
|
88
|
+
In the above example, jobs are throttled for each user when they exceed the rate limit provided in the message. This is useful in cases where each user may have a different rate limit (ex: interacting with external APIs)
|
89
|
+
|
69
90
|
## Contributing
|
70
91
|
|
71
92
|
1. Fork it
|
@@ -76,4 +97,4 @@ day.
|
|
76
97
|
|
77
98
|
## License
|
78
99
|
|
79
|
-
MIT Licensed. See LICENSE.txt for details.
|
100
|
+
MIT Licensed. See LICENSE.txt for details.
|
@@ -32,10 +32,18 @@ module Sidekiq
|
|
32
32
|
#
|
33
33
|
# @param [String] queue
|
34
34
|
# The queue to rate limit.
|
35
|
-
|
35
|
+
#
|
36
|
+
# @option [Symbol] :storage
|
37
|
+
# Either :memory or :redis, the storage backend to use
|
38
|
+
def initialize(worker, payload, queue, options = {})
|
36
39
|
@worker = worker
|
37
40
|
@payload = payload
|
38
41
|
@queue = queue
|
42
|
+
|
43
|
+
unless @storage_class = lookup_storage(options.fetch(:storage, :memory))
|
44
|
+
raise ArgumentError,
|
45
|
+
"Unrecognized storage backend: #{options[:storage].inspect}"
|
46
|
+
end
|
39
47
|
end
|
40
48
|
|
41
49
|
##
|
@@ -68,7 +76,7 @@ module Sidekiq
|
|
68
76
|
# @return [Integer]
|
69
77
|
# The number of jobs that are allowed within the `period`.
|
70
78
|
def threshold
|
71
|
-
@threshold ||= options['threshold'].to_i
|
79
|
+
@threshold ||= (options['threshold'].respond_to?(:call) ? options['threshold'].call(*payload) : options['threshold']).to_i
|
72
80
|
end
|
73
81
|
|
74
82
|
##
|
@@ -79,7 +87,7 @@ module Sidekiq
|
|
79
87
|
end
|
80
88
|
|
81
89
|
##
|
82
|
-
# @return [
|
90
|
+
# @return [String]
|
83
91
|
# The key name used when storing counters for jobs.
|
84
92
|
def key
|
85
93
|
@key ||= if options['key']
|
@@ -146,8 +154,14 @@ module Sidekiq
|
|
146
154
|
|
147
155
|
##
|
148
156
|
# Reset the tracking of job executions.
|
149
|
-
def
|
150
|
-
|
157
|
+
def reset!
|
158
|
+
executions.reset
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Get the storage backend.
|
163
|
+
def executions
|
164
|
+
@storage_class.instance
|
151
165
|
end
|
152
166
|
|
153
167
|
private
|
@@ -162,7 +176,7 @@ module Sidekiq
|
|
162
176
|
def self.count(limiter)
|
163
177
|
Thread.exclusive do
|
164
178
|
prune(limiter)
|
165
|
-
executions
|
179
|
+
limiter.executions.count(limiter.key)
|
166
180
|
end
|
167
181
|
end
|
168
182
|
|
@@ -175,28 +189,31 @@ module Sidekiq
|
|
175
189
|
# The current number of jobs executed.
|
176
190
|
def self.increment(limiter)
|
177
191
|
Thread.exclusive do
|
178
|
-
executions
|
192
|
+
limiter.executions.append(limiter.key, Time.now)
|
179
193
|
end
|
180
194
|
count(limiter)
|
181
195
|
end
|
182
196
|
|
183
|
-
##
|
184
|
-
# A hash storing job executions as timestamps for each throttled worker.
|
185
|
-
def self.executions
|
186
|
-
@executions || reset!
|
187
|
-
end
|
188
|
-
|
189
197
|
##
|
190
198
|
# Remove old entries for the provided `RateLimit`.
|
191
199
|
#
|
192
200
|
# @param [RateLimit] limiter
|
193
201
|
# The rate limit to prune.
|
194
202
|
def self.prune(limiter)
|
195
|
-
executions
|
196
|
-
(Time.now - execution) < limiter.period
|
197
|
-
end
|
203
|
+
limiter.executions.prune(limiter.key, Time.now - limiter.period)
|
198
204
|
end
|
199
205
|
|
206
|
+
##
|
207
|
+
# Lookup storage class for a given options key
|
208
|
+
#
|
209
|
+
# @param [Symbol] key
|
210
|
+
# The options key, :memory or :redis
|
211
|
+
#
|
212
|
+
# @return [Class]
|
213
|
+
# The storage backend class, or nil if the key is not found
|
214
|
+
def lookup_storage(key)
|
215
|
+
{ memory: Storage::Memory, redis: Storage::Redis }[key]
|
216
|
+
end
|
200
217
|
end # RateLimit
|
201
218
|
end # Throttler
|
202
|
-
end # Sidekiq
|
219
|
+
end # Sidekiq
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
class Throttler
|
3
|
+
module Storage
|
4
|
+
##
|
5
|
+
# Stores job executions in a Hash of Arrays.
|
6
|
+
class Memory
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@hash = Hash.new { |hash, key| hash[key] = [] }
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Number of executions for +key+.
|
15
|
+
#
|
16
|
+
# @param [String]
|
17
|
+
# Key to fetch count for
|
18
|
+
#
|
19
|
+
# @return [Fixnum]
|
20
|
+
# Execution count
|
21
|
+
def count(key)
|
22
|
+
@hash[key].length
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Remove entries older than +cutoff+.
|
27
|
+
#
|
28
|
+
# @param [String] key
|
29
|
+
# The key to prune
|
30
|
+
#
|
31
|
+
# @param [Time] cutoff
|
32
|
+
# Oldest allowable time
|
33
|
+
def prune(key, cutoff)
|
34
|
+
@hash[key].reject! { |time| time <= cutoff }
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Add a new entry to the hash.
|
39
|
+
#
|
40
|
+
# @param [String] key
|
41
|
+
# The key to append to
|
42
|
+
#
|
43
|
+
# @param [Time]
|
44
|
+
# The time to insert
|
45
|
+
def append(key, time)
|
46
|
+
@hash[key] << time
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset
|
50
|
+
@hash.clear
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end # Storage
|
54
|
+
end # Throttler
|
55
|
+
end # Sidekiq
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
class Throttler
|
3
|
+
module Storage
|
4
|
+
##
|
5
|
+
# Stores job executions in Redis lists.
|
6
|
+
#
|
7
|
+
# Timestamps in each list are ordered with the oldest on the right.
|
8
|
+
# Values are inserted on the left (LPUSH) & pruned from the right (RPOP)
|
9
|
+
class Redis
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
##
|
13
|
+
# Number of executions for +key+.
|
14
|
+
#
|
15
|
+
# @param [String]
|
16
|
+
# Key to fetch count for
|
17
|
+
#
|
18
|
+
# @return [Fixnum]
|
19
|
+
# Execution count
|
20
|
+
def count(key)
|
21
|
+
Sidekiq.redis do |conn|
|
22
|
+
conn.llen(namespace_key(key))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Remove entries older than +cutoff+.
|
28
|
+
#
|
29
|
+
# @param [String] key
|
30
|
+
# The key to prune
|
31
|
+
#
|
32
|
+
# @param [Time] cutoff
|
33
|
+
# Oldest allowable time
|
34
|
+
def prune(key, cutoff)
|
35
|
+
# Repeatedly pop from the right of the list until we encounter
|
36
|
+
# a value greater than the cutoff.
|
37
|
+
#
|
38
|
+
# We compare popped values to account for race conditions,
|
39
|
+
# pushing them back if they don't match.
|
40
|
+
Sidekiq.redis do |conn|
|
41
|
+
prune_one = ->(timestamp) {
|
42
|
+
if timestamp && timestamp.to_i <= cutoff.to_i
|
43
|
+
last = conn.rpop(namespace_key(key))
|
44
|
+
if last == timestamp
|
45
|
+
true
|
46
|
+
else
|
47
|
+
conn.rpush(namespace_key(key), last)
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
}
|
52
|
+
|
53
|
+
loop while prune_one.call(conn.lindex(namespace_key(key), -1))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Add a new entry to the hash.
|
59
|
+
#
|
60
|
+
# @param [String] key
|
61
|
+
# The key to append to
|
62
|
+
#
|
63
|
+
# @param [Time]
|
64
|
+
# The time to insert
|
65
|
+
def append(key, time)
|
66
|
+
Sidekiq.redis do |conn|
|
67
|
+
conn.lpush(namespace_key(key), time.to_i)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Clear all data from storage.
|
73
|
+
def reset
|
74
|
+
Sidekiq.redis do |conn|
|
75
|
+
conn.keys(namespace_key("*")).each do |key|
|
76
|
+
conn.del(key)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def namespace_key(key)
|
84
|
+
"throttled:#{key}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end # Storage
|
88
|
+
end # Throttler
|
89
|
+
end # Sidekiq
|
data/lib/sidekiq/throttler.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
require 'sidekiq'
|
2
|
-
require 'active_support'
|
3
|
-
require 'active_support/core_ext'
|
2
|
+
require 'active_support/core_ext/numeric/time'
|
4
3
|
|
5
4
|
require 'sidekiq/throttler/version'
|
6
5
|
require 'sidekiq/throttler/rate_limit'
|
7
6
|
|
7
|
+
require 'sidekiq/throttler/storage/memory'
|
8
|
+
require 'sidekiq/throttler/storage/redis'
|
9
|
+
|
8
10
|
module Sidekiq
|
9
11
|
##
|
10
12
|
# Sidekiq server middleware. Throttles jobs when they exceed limits specified
|
11
13
|
# on the worker. Jobs that exceed the limit are requeued with a delay.
|
12
14
|
class Throttler
|
15
|
+
def initialize(options = {})
|
16
|
+
@options = options.dup
|
17
|
+
end
|
13
18
|
|
14
19
|
##
|
15
20
|
# Passes the worker, arguments, and queue to {RateLimit} and either yields
|
@@ -24,7 +29,7 @@ module Sidekiq
|
|
24
29
|
# @param [String] queue
|
25
30
|
# The current queue.
|
26
31
|
def call(worker, msg, queue)
|
27
|
-
rate_limit = RateLimit.new(worker, msg['args'], queue)
|
32
|
+
rate_limit = RateLimit.new(worker, msg['args'], queue, @options)
|
28
33
|
|
29
34
|
rate_limit.within_bounds do
|
30
35
|
yield
|
@@ -38,4 +43,4 @@ module Sidekiq
|
|
38
43
|
end
|
39
44
|
|
40
45
|
end # Throttler
|
41
|
-
end # Sidekiq
|
46
|
+
end # Sidekiq
|
@@ -1,5 +1,29 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
shared_examples "incrementing" do
|
4
|
+
it 'increments #count by one' do
|
5
|
+
Timecop.freeze do
|
6
|
+
expect { rate_limit.increment }.to change{ rate_limit.count }.by(1)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when #period has passed' do
|
11
|
+
|
12
|
+
it 'removes old increments' do
|
13
|
+
rate_limit.options['period'] = 5
|
14
|
+
|
15
|
+
Timecop.freeze
|
16
|
+
|
17
|
+
20.times do
|
18
|
+
Timecop.travel(1.second.from_now)
|
19
|
+
rate_limit.increment
|
20
|
+
end
|
21
|
+
|
22
|
+
rate_limit.count.should eq(5)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
3
27
|
describe Sidekiq::Throttler::RateLimit do
|
4
28
|
|
5
29
|
let(:worker_class) do
|
@@ -22,6 +46,10 @@ describe Sidekiq::Throttler::RateLimit do
|
|
22
46
|
described_class.new(worker, payload, 'meow')
|
23
47
|
end
|
24
48
|
|
49
|
+
before(:each) do
|
50
|
+
rate_limit.reset!
|
51
|
+
end
|
52
|
+
|
25
53
|
describe '.new' do
|
26
54
|
|
27
55
|
it 'initializes with a provided worker' do
|
@@ -35,6 +63,14 @@ describe Sidekiq::Throttler::RateLimit do
|
|
35
63
|
it 'initializes with a provided queue' do
|
36
64
|
rate_limit.queue.should eq('meow')
|
37
65
|
end
|
66
|
+
|
67
|
+
context "with an invalid storage backend" do
|
68
|
+
it "raises an ArgumentError" do
|
69
|
+
expect {
|
70
|
+
described_class.new(worker, payload, 'meow', storage: :blarg)
|
71
|
+
}.to raise_error(ArgumentError)
|
72
|
+
end
|
73
|
+
end
|
38
74
|
end
|
39
75
|
|
40
76
|
describe '#options' do
|
@@ -69,6 +105,20 @@ describe Sidekiq::Throttler::RateLimit do
|
|
69
105
|
|
70
106
|
describe '#threshold' do
|
71
107
|
|
108
|
+
context 'when threshold is a Proc' do
|
109
|
+
let(:worker_class) do
|
110
|
+
ProcThresholdWorker
|
111
|
+
end
|
112
|
+
|
113
|
+
let(:payload) do
|
114
|
+
[1, 500]
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'returns the result of the called Proc' do
|
118
|
+
rate_limit.threshold.should eq(500)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
72
122
|
it 'retrieves the threshold from #options' do
|
73
123
|
rate_limit.options['threshold'] = 26
|
74
124
|
rate_limit.threshold.should eq(26)
|
@@ -275,27 +325,14 @@ describe Sidekiq::Throttler::RateLimit do
|
|
275
325
|
end
|
276
326
|
|
277
327
|
describe '#increment' do
|
328
|
+
include_examples "incrementing"
|
329
|
+
end
|
278
330
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
end
|
331
|
+
context "with a :redis storage backend" do
|
332
|
+
subject(:rate_limit) do
|
333
|
+
described_class.new(worker, payload, 'meow', storage: :redis)
|
283
334
|
end
|
284
335
|
|
285
|
-
|
286
|
-
|
287
|
-
it 'removes old increments' do
|
288
|
-
rate_limit.options['period'] = 5
|
289
|
-
|
290
|
-
Timecop.freeze
|
291
|
-
|
292
|
-
20.times do
|
293
|
-
Timecop.travel(1.second.from_now)
|
294
|
-
rate_limit.increment
|
295
|
-
end
|
296
|
-
|
297
|
-
rate_limit.count.should eq(5)
|
298
|
-
end
|
299
|
-
end
|
336
|
+
include_examples "incrementing"
|
300
337
|
end
|
301
|
-
end
|
338
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Sidekiq::Throttler::Storage::Redis do
|
4
|
+
let(:storage) { described_class.instance }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@sidekiq = double()
|
8
|
+
Sidekiq.stub(:redis).and_yield(@sidekiq)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#prune" do
|
12
|
+
it "pops the last item off the list if it's lower than the cutoff" do
|
13
|
+
@sidekiq.stub(:lindex).and_return(100, nil)
|
14
|
+
@sidekiq.should_receive(:rpop).with("throttled:fake").and_return(100)
|
15
|
+
storage.prune("fake", 200)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "leaves the last item on the list if it's higher than the cutoff" do
|
19
|
+
@sidekiq.stub(:lindex).and_return(200, nil)
|
20
|
+
@sidekiq.should_not_receive(:rpop)
|
21
|
+
storage.prune("fake", 100)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when another job has concurrently removed a timestamp" do
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@sidekiq.stub(:lindex) { 100 }
|
28
|
+
@sidekiq.stub(:rpop) { 200 }
|
29
|
+
end
|
30
|
+
|
31
|
+
it "pushes the value back onto the list" do
|
32
|
+
@sidekiq.should_receive(:rpush).with("throttled:fake", 200)
|
33
|
+
storage.prune("fake", 1000)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -3,13 +3,17 @@ require 'spec_helper'
|
|
3
3
|
describe Sidekiq::Throttler do
|
4
4
|
|
5
5
|
subject(:throttler) do
|
6
|
-
described_class.new
|
6
|
+
described_class.new(options)
|
7
7
|
end
|
8
8
|
|
9
9
|
let(:worker) do
|
10
10
|
LolzWorker.new
|
11
11
|
end
|
12
12
|
|
13
|
+
let(:options) do
|
14
|
+
{ storage: :memory }
|
15
|
+
end
|
16
|
+
|
13
17
|
let(:message) do
|
14
18
|
{
|
15
19
|
args: 'Clint Eastwood'
|
@@ -23,10 +27,9 @@ describe Sidekiq::Throttler do
|
|
23
27
|
describe '#call' do
|
24
28
|
|
25
29
|
it 'instantiates a rate limit with the worker, args, and queue' do
|
26
|
-
rate_limit = Sidekiq::Throttler::RateLimit.new(worker, message['args'], queue)
|
27
30
|
Sidekiq::Throttler::RateLimit.should_receive(:new).with(
|
28
|
-
worker, message['args'], queue
|
29
|
-
).
|
31
|
+
worker, message['args'], queue, options
|
32
|
+
).and_call_original
|
30
33
|
|
31
34
|
throttler.call(worker, message, queue) {}
|
32
35
|
end
|
@@ -49,4 +52,4 @@ describe Sidekiq::Throttler do
|
|
49
52
|
end
|
50
53
|
end
|
51
54
|
end
|
52
|
-
end
|
55
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -28,12 +28,8 @@ RSpec.configure do |config|
|
|
28
28
|
# the seed, which is printed after each run.
|
29
29
|
# --seed 1234
|
30
30
|
config.order = 'random'
|
31
|
-
|
32
|
-
config.before(:each) do
|
33
|
-
Sidekiq::Throttler::RateLimit.reset!
|
34
|
-
end
|
35
31
|
end
|
36
32
|
|
37
33
|
# Requires supporting files with custom matchers and macros, etc,
|
38
34
|
# in ./support/ and its subdirectories.
|
39
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
35
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-throttler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabe Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -274,13 +274,17 @@ files:
|
|
274
274
|
- lib/sidekiq-throttler.rb
|
275
275
|
- lib/sidekiq/throttler.rb
|
276
276
|
- lib/sidekiq/throttler/rate_limit.rb
|
277
|
+
- lib/sidekiq/throttler/storage/memory.rb
|
278
|
+
- lib/sidekiq/throttler/storage/redis.rb
|
277
279
|
- lib/sidekiq/throttler/version.rb
|
278
280
|
- sidekiq-throttler.gemspec
|
279
281
|
- spec/app/workers/custom_key_worker.rb
|
280
282
|
- spec/app/workers/lolz_worker.rb
|
283
|
+
- spec/app/workers/proc_threshold_worker.rb
|
281
284
|
- spec/app/workers/proc_worker.rb
|
282
285
|
- spec/app/workers/regular_worker.rb
|
283
286
|
- spec/sidekiq/throttler/rate_limit_spec.rb
|
287
|
+
- spec/sidekiq/throttler/storage/redis_spec.rb
|
284
288
|
- spec/sidekiq/throttler_spec.rb
|
285
289
|
- spec/spec.opts
|
286
290
|
- spec/spec_helper.rb
|
@@ -304,7 +308,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
304
308
|
version: '0'
|
305
309
|
requirements: []
|
306
310
|
rubyforge_project:
|
307
|
-
rubygems_version: 2.
|
311
|
+
rubygems_version: 2.1.5
|
308
312
|
signing_key:
|
309
313
|
specification_version: 4
|
310
314
|
summary: Sidekiq::Throttler is a middleware for Sidekiq that adds the ability to rate
|
@@ -312,9 +316,11 @@ summary: Sidekiq::Throttler is a middleware for Sidekiq that adds the ability to
|
|
312
316
|
test_files:
|
313
317
|
- spec/app/workers/custom_key_worker.rb
|
314
318
|
- spec/app/workers/lolz_worker.rb
|
319
|
+
- spec/app/workers/proc_threshold_worker.rb
|
315
320
|
- spec/app/workers/proc_worker.rb
|
316
321
|
- spec/app/workers/regular_worker.rb
|
317
322
|
- spec/sidekiq/throttler/rate_limit_spec.rb
|
323
|
+
- spec/sidekiq/throttler/storage/redis_spec.rb
|
318
324
|
- spec/sidekiq/throttler_spec.rb
|
319
325
|
- spec/spec.opts
|
320
326
|
- spec/spec_helper.rb
|