resque-rate_limited 1.1.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 +7 -0
- data/.gitignore +16 -0
- data/.hound.yml +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +46 -0
- data/Gemfile +4 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +22 -0
- data/README.md +215 -0
- data/Rakefile +1 -0
- data/lib/resque-rate_limited/version.rb +3 -0
- data/lib/resque/plugins/rate_limited/apis/angellist_queue.rb +19 -0
- data/lib/resque/plugins/rate_limited/apis/base_api_queue.rb +17 -0
- data/lib/resque/plugins/rate_limited/apis/evernote_queue.rb +19 -0
- data/lib/resque/plugins/rate_limited/apis/twitter_queue.rb +19 -0
- data/lib/resque/plugins/rate_limited/rate_limited.rb +92 -0
- data/lib/resque/plugins/rate_limited/rate_limited_un_pause.rb +39 -0
- data/lib/resque/rate_limited.rb +9 -0
- data/resque-rate_limited.gemspec +43 -0
- data/spec/apis/angellist_queue_spec.rb +51 -0
- data/spec/apis/evernote_queue_spec.rb +77 -0
- data/spec/apis/twitter_queue_spec.rb +52 -0
- data/spec/rate_limited_spec.rb +243 -0
- data/spec/rate_limited_un_pause_spec.rb +49 -0
- data/spec/spec_helper.rb +18 -0
- metadata +326 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
module Resque
|
2
|
+
module Plugins
|
3
|
+
module RateLimited
|
4
|
+
class UnPause
|
5
|
+
@queue = nil
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_writer(:queue)
|
9
|
+
|
10
|
+
def use?
|
11
|
+
Resque.respond_to?(:enqueue_at_with_queue) && @queue
|
12
|
+
end
|
13
|
+
|
14
|
+
def enqueue(timestamp, klass)
|
15
|
+
# If Resque scheduler is installed and queue is set - use it to queue a wake up job
|
16
|
+
return unless use?
|
17
|
+
Resque.enqueue_at_with_queue(
|
18
|
+
@queue,
|
19
|
+
timestamp,
|
20
|
+
Resque::Plugins::RateLimited::UnPause,
|
21
|
+
klass
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def perform(klass)
|
26
|
+
class_from_string(klass.to_s).un_pause
|
27
|
+
end
|
28
|
+
|
29
|
+
def class_from_string(str)
|
30
|
+
return Object.const_get(str) unless str.include?('::')
|
31
|
+
str.split('::').reduce(Object) do |mod, class_name|
|
32
|
+
mod.const_get(class_name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'resque'
|
2
|
+
require 'redis-mutex'
|
3
|
+
require 'resque/version'
|
4
|
+
require 'resque/plugins/rate_limited/rate_limited'
|
5
|
+
require 'resque/plugins/rate_limited/rate_limited_un_pause'
|
6
|
+
require 'resque/plugins/rate_limited/apis/base_api_queue'
|
7
|
+
require 'resque/plugins/rate_limited/apis/angellist_queue'
|
8
|
+
require 'resque/plugins/rate_limited/apis/evernote_queue'
|
9
|
+
require 'resque/plugins/rate_limited/apis/twitter_queue'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'resque-rate_limited/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'resque-rate_limited'
|
8
|
+
spec.version = RateLimited::VERSION
|
9
|
+
spec.authors = ['Greg Dowling']
|
10
|
+
spec.email = ['mail@greddowling.com']
|
11
|
+
spec.summary = 'A Resque plugin to help manage jobs that use rate limited apis, pausing when you hit the limits and restarting later.'
|
12
|
+
spec.description = 'A Resque plugin which allows you to create dedicated queues for jobs that use rate limited apis.
|
13
|
+
These queues will pause when one of the jobs hits a rate limit, and unpause after a suitable time period.
|
14
|
+
The rate_limited can be used directly, and just requires catching the rate limit exception and pausing the
|
15
|
+
queue. There are also additional queues provided that already include the pause/rety logic for twitter, angelist
|
16
|
+
and evernote; these allow you to support rate limited apis with minimal changes.'
|
17
|
+
|
18
|
+
spec.homepage = 'http://github.com/Xenapto/resque-rate_limited'
|
19
|
+
spec.license = 'MIT'
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0")
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_dependency 'resque', '~> 1.9', '>= 1.9.10'
|
27
|
+
spec.add_dependency 'redis-mutex', '~> 4.0', '>= 4.0.0'
|
28
|
+
|
29
|
+
spec.add_dependency 'angellist_api', '~> 1.0', '>= 1.0.7'
|
30
|
+
spec.add_dependency 'evernote-thrift', '~> 1.25', '>= 1.25.1'
|
31
|
+
spec.add_dependency 'twitter', '~> 5.11', '>= 5.11.0'
|
32
|
+
|
33
|
+
spec.add_development_dependency 'rake', '~> 10'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 2'
|
35
|
+
spec.add_development_dependency 'simplecov', '~> 0'
|
36
|
+
spec.add_development_dependency 'rubocop', '~> 0'
|
37
|
+
spec.add_development_dependency 'reek', '~> 4'
|
38
|
+
spec.add_development_dependency 'listen', '~> 3.0', '< 3.1' # Dependency of guard, 3.1 requires Ruby 2.2+
|
39
|
+
spec.add_development_dependency 'guard', '~> 2'
|
40
|
+
spec.add_development_dependency 'guard-rspec', '~> 4'
|
41
|
+
spec.add_development_dependency 'guard-rubocop', '~> 1'
|
42
|
+
spec.add_development_dependency 'gem-release', '~> 0'
|
43
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resque/rate_limited'
|
3
|
+
|
4
|
+
class RateLimitedTestQueueAL
|
5
|
+
def self.perform(succeed)
|
6
|
+
raise(AngellistApi::Error::TooManyRequests, 'error') unless succeed
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Resque::Plugins::RateLimited::AngellistQueue do
|
11
|
+
before do
|
12
|
+
Resque::Plugins::RateLimited::AngellistQueue.stub(:paused?).and_return(false)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'enqueue' do
|
16
|
+
it 'enqueues to the correct queue with the correct parameters' do
|
17
|
+
Resque.should_receive(:enqueue_to).with(
|
18
|
+
:angellist_api,
|
19
|
+
Resque::Plugins::RateLimited::AngellistQueue,
|
20
|
+
RateLimitedTestQueueAL.to_s,
|
21
|
+
true
|
22
|
+
)
|
23
|
+
Resque::Plugins::RateLimited::AngellistQueue
|
24
|
+
.enqueue(RateLimitedTestQueueAL, true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'perform' do
|
29
|
+
before do
|
30
|
+
Resque.inline = true
|
31
|
+
end
|
32
|
+
context 'with everything' do
|
33
|
+
it 'calls the class with the right parameters' do
|
34
|
+
RateLimitedTestQueueAL.should_receive(:perform).with('test_param')
|
35
|
+
Resque::Plugins::RateLimited::AngellistQueue
|
36
|
+
.enqueue(RateLimitedTestQueueAL, 'test_param')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with rate limit exception' do
|
41
|
+
before do
|
42
|
+
Resque::Plugins::RateLimited::AngellistQueue.stub(:rate_limited_requeue)
|
43
|
+
end
|
44
|
+
it 'pauses queue when request fails' do
|
45
|
+
Resque::Plugins::RateLimited::AngellistQueue.should_receive(:pause_until)
|
46
|
+
Resque::Plugins::RateLimited::AngellistQueue
|
47
|
+
.enqueue(RateLimitedTestQueueAL, false)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resque/rate_limited'
|
3
|
+
|
4
|
+
class RateLimitDuration
|
5
|
+
def self.seconds
|
6
|
+
60
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class RateLimitedTestQueueEn
|
11
|
+
def self.perform(succeed)
|
12
|
+
raise(
|
13
|
+
Evernote::EDAM::Error::EDAMSystemException,
|
14
|
+
errorCode: Evernote::EDAM::Error::EDAMErrorCode::RATE_LIMIT_REACHED,
|
15
|
+
rateLimitDuration: RateLimitDuration
|
16
|
+
) unless succeed
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class RateLimitedTestQueueOther
|
21
|
+
def self.perform
|
22
|
+
raise(Evernote::EDAM::Error::EDAMSystemException)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Resque::Plugins::RateLimited::EvernoteQueue do
|
27
|
+
before do
|
28
|
+
Resque::Plugins::RateLimited::EvernoteQueue.stub(:paused?).and_return(false)
|
29
|
+
end
|
30
|
+
describe 'enqueue' do
|
31
|
+
it 'enqueues to the correct queue with the correct parameters' do
|
32
|
+
Resque.should_receive(:enqueue_to).with(
|
33
|
+
:evernote_api,
|
34
|
+
Resque::Plugins::RateLimited::EvernoteQueue,
|
35
|
+
RateLimitedTestQueueEn.to_s,
|
36
|
+
true
|
37
|
+
)
|
38
|
+
Resque::Plugins::RateLimited::EvernoteQueue
|
39
|
+
.enqueue(RateLimitedTestQueueEn, true)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'perform' do
|
44
|
+
before do
|
45
|
+
Resque.inline = true
|
46
|
+
end
|
47
|
+
context 'with everything' do
|
48
|
+
it 'calls the class with the right parameters' do
|
49
|
+
RateLimitedTestQueueEn.should_receive(:perform).with('test_param')
|
50
|
+
Resque::Plugins::RateLimited::EvernoteQueue
|
51
|
+
.enqueue(RateLimitedTestQueueEn, 'test_param')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with rate limit exception' do
|
56
|
+
before do
|
57
|
+
Resque::Plugins::RateLimited::EvernoteQueue.stub(:rate_limited_requeue)
|
58
|
+
end
|
59
|
+
it 'pauses queue when request fails' do
|
60
|
+
Resque::Plugins::RateLimited::EvernoteQueue.should_receive(:pause_until)
|
61
|
+
Resque::Plugins::RateLimited::EvernoteQueue
|
62
|
+
.enqueue(RateLimitedTestQueueEn, false)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'with exception that is not rate limit' do
|
67
|
+
before do
|
68
|
+
Resque::Plugins::RateLimited::EvernoteQueue.stub(:rate_limited_requeue)
|
69
|
+
end
|
70
|
+
it 'raises the exception when request fails' do
|
71
|
+
expect do
|
72
|
+
Resque::Plugins::RateLimited::EvernoteQueue.enqueue(RateLimitedTestQueueOther)
|
73
|
+
end.to raise_error Evernote::EDAM::Error::EDAMSystemException
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resque/rate_limited'
|
3
|
+
|
4
|
+
class RateLimitedTestQueueTw
|
5
|
+
def self.perform(succeed)
|
6
|
+
raise(Twitter::Error::TooManyRequests
|
7
|
+
.new('', 'x-rate-limit-reset' => (Time.now + 60).to_i)) unless succeed
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Resque::Plugins::RateLimited::TwitterQueue do
|
12
|
+
before do
|
13
|
+
Resque::Plugins::RateLimited::TwitterQueue.stub(:paused?).and_return(false)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'enqueue' do
|
17
|
+
it 'enqueues to the correct queue with the correct parameters' do
|
18
|
+
Resque.should_receive(:enqueue_to).with(
|
19
|
+
:twitter_api,
|
20
|
+
Resque::Plugins::RateLimited::TwitterQueue,
|
21
|
+
RateLimitedTestQueueTw.to_s,
|
22
|
+
true
|
23
|
+
)
|
24
|
+
Resque::Plugins::RateLimited::TwitterQueue
|
25
|
+
.enqueue(RateLimitedTestQueueTw, true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'perform' do
|
30
|
+
before do
|
31
|
+
Resque.inline = true
|
32
|
+
end
|
33
|
+
context 'with everything' do
|
34
|
+
it 'calls the class with the right parameters' do
|
35
|
+
RateLimitedTestQueueTw.should_receive(:perform).with('test_param')
|
36
|
+
Resque::Plugins::RateLimited::TwitterQueue
|
37
|
+
.enqueue(RateLimitedTestQueueTw, 'test_param')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with rate limit exception' do
|
42
|
+
before do
|
43
|
+
Resque::Plugins::RateLimited::TwitterQueue.stub(:rate_limited_requeue)
|
44
|
+
end
|
45
|
+
it 'pauses queue when request fails' do
|
46
|
+
Resque::Plugins::RateLimited::TwitterQueue.should_receive(:pause_until)
|
47
|
+
Resque::Plugins::RateLimited::TwitterQueue
|
48
|
+
.enqueue(RateLimitedTestQueueTw, false)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resque/rate_limited'
|
3
|
+
|
4
|
+
class RateLimitedTestQueue
|
5
|
+
extend Resque::Plugins::RateLimited
|
6
|
+
|
7
|
+
@queue = :test
|
8
|
+
|
9
|
+
def self.perform(succeed)
|
10
|
+
rate_limited_requeue(self, succeed) unless succeed
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.queue_name_private
|
14
|
+
@queue.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.queue_private
|
18
|
+
@queue
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Resque::Plugins::RateLimited do
|
23
|
+
it 'should be compliance with Resque::Plugin document' do
|
24
|
+
expect { Resque::Plugin.lint(Resque::Plugins::RateLimited) }.to_not raise_error
|
25
|
+
end
|
26
|
+
|
27
|
+
shared_examples_for 'queue' do |queue_suffix|
|
28
|
+
it 'should queue to the correct queue' do
|
29
|
+
queue_param = queue_suffix.empty? ? RateLimitedTestQueue.queue_private : "#{RateLimitedTestQueue.queue_name_private}#{queue_suffix}"
|
30
|
+
Resque.should_receive(:enqueue_to).with(queue_param, nil, nil)
|
31
|
+
RateLimitedTestQueue.rate_limited_enqueue(nil, nil)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when queue is not paused' do
|
36
|
+
before do
|
37
|
+
RateLimitedTestQueue.stub(:paused?).and_return(false)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'enqueue' do
|
41
|
+
include_examples 'queue', ''
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'paused?' do
|
45
|
+
it { RateLimitedTestQueue.paused?.should be false }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'perform' do
|
49
|
+
it 'should requeue the job on failure' do
|
50
|
+
Resque.should_receive(:enqueue_to)
|
51
|
+
RateLimitedTestQueue.perform(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should not requeue the job on success' do
|
55
|
+
Resque.should_not_receive(:enqueue_to)
|
56
|
+
RateLimitedTestQueue.perform(true)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'pause' do
|
61
|
+
it 'should rename the queue to paused' do
|
62
|
+
Resque.redis.should_receive(:renamenx).with("queue:#{RateLimitedTestQueue.queue_name_private}", "queue:#{RateLimitedTestQueue.queue_name_private}_paused")
|
63
|
+
RateLimitedTestQueue.pause
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'un_pause' do
|
68
|
+
it 'should not unpause the queue' do
|
69
|
+
Resque.redis.should_not_receive(:renamenx).with("queue:#{RateLimitedTestQueue.queue_name_private}", "queue:#{RateLimitedTestQueue.queue_name_private}_paused")
|
70
|
+
RateLimitedTestQueue.un_pause
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'pause_until' do
|
75
|
+
before do
|
76
|
+
Resque.redis.stub(:renamenx).and_return(true)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should pause the queue' do
|
80
|
+
RateLimitedTestQueue.should_receive(:pause)
|
81
|
+
RateLimitedTestQueue.pause_until(Time.now + (5 * 60 * 60))
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should schedule an unpause job' do
|
85
|
+
Resque::Plugins::RateLimited::UnPause.should_receive(:enqueue)
|
86
|
+
.with(nil, 'RateLimitedTestQueue')
|
87
|
+
RateLimitedTestQueue.pause_until(nil)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when queue is paused' do
|
93
|
+
before do
|
94
|
+
RateLimitedTestQueue.stub(:paused?).and_return(true)
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'enqueue' do
|
98
|
+
include_examples 'queue', '_paused'
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'paused?' do
|
102
|
+
it { RateLimitedTestQueue.paused?.should be true }
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'perform' do
|
106
|
+
it 'should not execute the block' do
|
107
|
+
Resque.should_receive(:enqueue_to).with("#{RateLimitedTestQueue.queue_name_private}_paused", RateLimitedTestQueue, true)
|
108
|
+
RateLimitedTestQueue.should_not_receive(:perform)
|
109
|
+
RateLimitedTestQueue.around_perform_with_check_and_requeue(true)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'un_pause' do
|
114
|
+
it 'should rename the queue to live' do
|
115
|
+
Resque.redis.should_receive(:renamenx).with("queue:#{RateLimitedTestQueue.queue_name_private}_paused", "queue:#{RateLimitedTestQueue.queue_name_private}")
|
116
|
+
RateLimitedTestQueue.un_pause
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'when queue is paused and Resque is in inline mode' do
|
122
|
+
let(:resque_prefix) { Resque::Plugins::RateLimited::RESQUE_PREFIX }
|
123
|
+
let(:queue) { resque_prefix + RateLimitedTestQueue.queue_name_private }
|
124
|
+
let(:paused_queue) { resque_prefix + RateLimitedTestQueue.paused_queue_name }
|
125
|
+
|
126
|
+
before do
|
127
|
+
Resque.redis.stub(:exists).with(queue).and_return(false)
|
128
|
+
Resque.redis.stub(:exists).with(paused_queue).and_return(true)
|
129
|
+
Resque.inline = true
|
130
|
+
end
|
131
|
+
|
132
|
+
after do
|
133
|
+
Resque.inline = false
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'would be paused' do
|
137
|
+
expect(Resque.redis.exists(queue)).to eq false
|
138
|
+
expect(Resque.redis.exists(paused_queue)).to eq true
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'says it is not paused' do
|
142
|
+
expect(RateLimitedTestQueue.paused?).to eq false
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'performs the job' do
|
146
|
+
expect do
|
147
|
+
# Stack overflow unless handled
|
148
|
+
RateLimitedTestQueue.rate_limited_enqueue(RateLimitedTestQueue, true)
|
149
|
+
end.not_to raise_error
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'find_class' do
|
154
|
+
it 'works with symbol' do
|
155
|
+
RateLimitedTestQueue.find_class(RateLimitedTestQueue).should eq RateLimitedTestQueue
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'works with simple string' do
|
159
|
+
RateLimitedTestQueue.find_class('RateLimitedTestQueue').should eq RateLimitedTestQueue
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'works with complex string' do
|
163
|
+
RateLimitedTestQueue.find_class('Resque::Plugins::RateLimited').should eq Resque::Plugins::RateLimited
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'with redis errors' do
|
168
|
+
before do
|
169
|
+
RateLimitedTestQueue.stub(:paused?).and_return(true)
|
170
|
+
end
|
171
|
+
context 'with not found error' do
|
172
|
+
before do
|
173
|
+
Resque.redis.stub(:renamenx).and_raise(Redis::CommandError.new('ERR no such key'))
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'pause' do
|
177
|
+
it 'should not throw exception' do
|
178
|
+
expect { RateLimitedTestQueue.pause }.to_not raise_error
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'un_pause' do
|
183
|
+
it 'should not throw exception' do
|
184
|
+
expect { RateLimitedTestQueue.un_pause }.to_not raise_error
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'with other errror' do
|
190
|
+
before do
|
191
|
+
Resque.redis.stub(:renamenx).and_raise(Redis::CommandError.new('ERR something else'))
|
192
|
+
end
|
193
|
+
|
194
|
+
describe 'pause' do
|
195
|
+
it 'should throw exception' do
|
196
|
+
expect { RateLimitedTestQueue.pause }.to raise_error(Redis::CommandError)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe 'un_pause' do
|
201
|
+
it 'should throw exception' do
|
202
|
+
expect { RateLimitedTestQueue.un_pause }.to raise_error(Redis::CommandError)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe 'paused?' do
|
209
|
+
context 'with paused queue' do
|
210
|
+
before do
|
211
|
+
Resque.redis.stub(:exists).with("queue:#{RateLimitedTestQueue.queue_name_private}_paused").and_return(true)
|
212
|
+
Resque.redis.stub(:exists).with("queue:#{RateLimitedTestQueue.queue_name_private}").and_return(false)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should return the true if the paused queue exists' do
|
216
|
+
expect(RateLimitedTestQueue.paused?).to eq(true)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'with un paused queue' do
|
221
|
+
before do
|
222
|
+
Resque.redis.stub(:exists).with("queue:#{RateLimitedTestQueue.queue_name_private}_paused").and_return(false)
|
223
|
+
Resque.redis.stub(:exists).with("queue:#{RateLimitedTestQueue.queue_name_private}").and_return(true)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'should return the false if the main queue exists exist' do
|
227
|
+
expect(RateLimitedTestQueue.paused?).to eq(false)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'with unknown queue state' do
|
232
|
+
before do
|
233
|
+
Resque.redis.stub(:exists).with("queue:#{RateLimitedTestQueue.queue_name_private}_paused").and_return(false)
|
234
|
+
Resque.redis.stub(:exists).with("queue:#{RateLimitedTestQueue.queue_name_private}").and_return(false)
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should return the default' do
|
238
|
+
expect(RateLimitedTestQueue.paused?(true)).to eq(true)
|
239
|
+
expect(RateLimitedTestQueue.paused?(false)).to eq(false)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|