resque-real-serial-queues 0.0.1 → 0.0.2
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/README.md +27 -1
- data/Rakefile +5 -0
- data/lib/resque/plugins/real_serial_queues.rb +47 -11
- data/lib/resque/plugins/version.rb +1 -1
- data/resque-real-serial-queues.gemspec +5 -3
- data/test/resque_test.rb +148 -0
- data/test/test_helper.rb +7 -0
- metadata +37 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdd9fb0afaa0e42a40abd457eba4dd1fc86519d3
|
4
|
+
data.tar.gz: 4738f36a9abf515bea030d2ca4650477738e588e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bef8645d3a33619d53e68488a2f8834b57c41d5e9b42b226c188e29862c0268e6016b65b2c7688c0c47f3e4c5921c5729f19090b29b6212bea8c6ce53355f032
|
7
|
+
data.tar.gz: 56bc2bf9062532e4f3e3586ffdb426e6a88609fd57e26340e019aad16f7af44df14595f7b597e3c45c217222cb66ab992bbb0713dab901a9064331db8f88d4cb
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ from the same queue as the potential job currently being processed by one of you
|
|
5
5
|
|
6
6
|
It is primarily meant to be used to queue long running background jobs across multiple queues in conjunction with something like [resque-scheduler](https://github.com/resque/resque-scheduler)
|
7
7
|
|
8
|
-
A key difference between this and [resque-lonely_job](https://github.com/wallace/resque-lonely_job) is that the queue is not touched when we check to see if we can process the job. However, because we must check all the workers
|
8
|
+
A key difference between this and [resque-lonely_job](https://github.com/wallace/resque-lonely_job) is that the queue is not touched when we check to see if we can process the job (thus there is no danger of your queues getting processed in a different order). However, because we must check all the workers
|
9
9
|
currently working on the system this plugin may not scale well to large numbers of workers.
|
10
10
|
|
11
11
|
This gem is under active development - so please use caution if your jobs are responsible for controlling rocket ships or providing food and shelter to young children.
|
@@ -40,6 +40,32 @@ Or install it yourself as:
|
|
40
40
|
directory with the above line should do the trick.
|
41
41
|
|
42
42
|
Note that this will currently affect all queues
|
43
|
+
|
44
|
+
## Configuration and Adding Non-Serial Queues
|
45
|
+
By default all queues are considered serial if you just install the plugin. If you'd like to have some queues that do not get processed serially - you can add them via a configuration option after you require the plugin:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# you can pass it straight in as a hash
|
49
|
+
Resque::Plugins::RealSerialQueues.config = {
|
50
|
+
non_serial_queues: ['non_serial_queue_one', 'non_serial_queue_two']
|
51
|
+
}
|
52
|
+
|
53
|
+
# or you can place it in a config file
|
54
|
+
require 'yaml'
|
55
|
+
|
56
|
+
Resque::Plugins::RealSerialQueues.config = YAML.load_file('your_config_file.yml')
|
57
|
+
```
|
58
|
+
|
59
|
+
If you choose to use a YAML config file - the queue names must be specified as a list:
|
60
|
+
|
61
|
+
```yaml
|
62
|
+
non_serial_queues:
|
63
|
+
- non_serial_queue_one
|
64
|
+
- non_serial_queue_two
|
65
|
+
```
|
66
|
+
|
67
|
+
Not specifying any configuration will cause all queues to be processed serially.
|
68
|
+
|
43
69
|
## Contributing
|
44
70
|
|
45
71
|
1. Fork it ( https://github.com/[my-github-username]/resque-real-serial-queues/fork )
|
data/Rakefile
CHANGED
@@ -6,12 +6,11 @@ require "resque/plugins/version"
|
|
6
6
|
module Resque
|
7
7
|
class Job
|
8
8
|
|
9
|
-
# Given a queue name
|
10
|
-
# determine whether there is a worker currently working on a
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
# Given a queue name
|
10
|
+
# determine whether there is a worker currently working on a
|
11
|
+
# job from the same queue
|
12
|
+
# return true
|
13
|
+
def self.job_from_same_queue_is_currently_being_run?(queue)
|
15
14
|
Worker.working.each do |worker|
|
16
15
|
processing_job = worker.job
|
17
16
|
next unless processing_job
|
@@ -28,10 +27,16 @@ module Resque
|
|
28
27
|
# Given a string queue name, returns an instance of Resque::Job
|
29
28
|
# if any jobs are available. If not, returns nil.
|
30
29
|
# This is a resque method overridden to first check
|
31
|
-
# if
|
30
|
+
# if there is another job from the queue being checked currently
|
31
|
+
# being worked on. This check can be bypassed by setting
|
32
|
+
# non_serial_queues via Resque::Plugins::RealSerialQueues.config=
|
33
|
+
# in your Resque config
|
32
34
|
def self.reserve(queue)
|
33
|
-
|
34
|
-
|
35
|
+
non_serial_queues = Resque::Plugins::RealSerialQueues.non_serial_queues
|
36
|
+
|
37
|
+
unless non_serial_queues && non_serial_queues.include?(queue)
|
38
|
+
return if job_from_same_queue_is_currently_being_run?(queue)
|
39
|
+
end
|
35
40
|
return unless payload = Resque.pop(queue)
|
36
41
|
new(queue, payload)
|
37
42
|
end
|
@@ -39,9 +44,40 @@ module Resque
|
|
39
44
|
end
|
40
45
|
|
41
46
|
# if we add any actual method extensions add them here
|
42
|
-
module Resque
|
43
|
-
module Plugins
|
47
|
+
module Resque
|
48
|
+
module Plugins
|
44
49
|
module RealSerialQueues
|
50
|
+
class InvalidConfigurationError < StandardError; end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
attr_accessor :non_serial_queues
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.config=(config_hash)
|
57
|
+
if config_hash
|
58
|
+
self.check_if_config_is_valid(config_hash)
|
59
|
+
self.non_serial_queues = config_hash[:non_serial_queues]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def self.check_if_config_is_valid(config_hash)
|
66
|
+
if !config_hash.is_a?(Hash)
|
67
|
+
fail(
|
68
|
+
InvalidConfigurationError,
|
69
|
+
'Something is wrong with your config file. Sorry...'
|
70
|
+
)
|
71
|
+
elsif config_hash[:non_serial_queues] &&
|
72
|
+
!config_hash[:non_serial_queues].is_a?(Array)
|
73
|
+
fail(
|
74
|
+
InvalidConfigurationError,
|
75
|
+
'Please specify non-serial queue names in an array ' +
|
76
|
+
'(or collection if you are using YAML: http://yaml4r.' +
|
77
|
+
'sourceforge.net/doc/page/collections_in_yaml.htm)'
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
45
81
|
end
|
46
82
|
end
|
47
83
|
end
|
@@ -18,8 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency
|
21
|
+
spec.add_dependency 'resque', '~> 1.25'
|
22
22
|
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'minitest', '~> 5.3'
|
26
|
+
spec.add_development_dependency 'mocha', '~> 1.1'
|
25
27
|
end
|
data/test/resque_test.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Resque::Job do
|
4
|
+
before do
|
5
|
+
@fake_queue = 'fake_queue'
|
6
|
+
@worker = Resque::Worker.new(@fake_queue)
|
7
|
+
# Resque checks redis for the worker's value and
|
8
|
+
# returns a hash decoded by MultiJSON
|
9
|
+
@job = {
|
10
|
+
'queue' => @fake_queue,
|
11
|
+
'payload' => {
|
12
|
+
'class' => 'SomeJob',
|
13
|
+
'args' => []
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#job_from_same_queue_is_currently_being_run?' do
|
19
|
+
it 'returns false if no workers' do
|
20
|
+
Resque::Worker.expects(:working).returns([])
|
21
|
+
Resque::Job
|
22
|
+
.job_from_same_queue_is_currently_being_run?('some_queue')
|
23
|
+
.must_equal(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns true if the queue name of any processing ' +
|
27
|
+
'job matches the queue name passed in' do
|
28
|
+
|
29
|
+
Resque::Worker.expects(:working).returns([@worker])
|
30
|
+
@worker.expects(:job).returns(@job)
|
31
|
+
Resque::Job
|
32
|
+
.job_from_same_queue_is_currently_being_run?(@fake_queue)
|
33
|
+
.must_equal(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns false if there are jobs but none from the specified queue' do
|
37
|
+
Resque::Worker.expects(:working).returns([@worker])
|
38
|
+
@worker.expects(:job).returns(@job)
|
39
|
+
Resque::Job
|
40
|
+
.job_from_same_queue_is_currently_being_run?('a_different_queue')
|
41
|
+
.must_equal(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#reserve' do
|
46
|
+
describe 'when there are no non-serial queues specified' do
|
47
|
+
before do
|
48
|
+
Resque::Plugins::RealSerialQueues.config = {}
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should return nil if job from requested queue is being performed' do
|
52
|
+
Resque::Job
|
53
|
+
.expects(:job_from_same_queue_is_currently_being_run?)
|
54
|
+
.returns(true)
|
55
|
+
Resque::Job.reserve('queue_name').must_equal(nil)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should return at instance of Resque::Job if no ' +
|
59
|
+
'job from requested queue is being performed' do
|
60
|
+
Resque::Job
|
61
|
+
.expects(:job_from_same_queue_is_currently_being_run?)
|
62
|
+
.returns(false)
|
63
|
+
|
64
|
+
Resque.expects(:pop).returns(@job)
|
65
|
+
|
66
|
+
result = Resque::Job.reserve(@fake_queue)
|
67
|
+
|
68
|
+
result.must_be_instance_of(Resque::Job)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'when there are non-serial queues specified' do
|
73
|
+
before do
|
74
|
+
@serial_queue = 'so_serial'
|
75
|
+
@non_serial = 'not_so_serial'
|
76
|
+
Resque::Plugins::RealSerialQueues.config = {
|
77
|
+
non_serial_queues: [@non_serial]
|
78
|
+
}
|
79
|
+
|
80
|
+
Resque.stubs(:pop).returns(@job)
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'and there is a job from the same queue being performed' do
|
84
|
+
before do
|
85
|
+
Resque::Job.stubs(:job_from_same_queue_is_currently_being_run?)
|
86
|
+
.returns(true)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should return an Resque::Job instance if in the non-serial queue' do
|
90
|
+
result = Resque::Job.reserve(@non_serial)
|
91
|
+
result.must_be_instance_of(Resque::Job)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return nil if not in the non-serial queue' do
|
95
|
+
result = Resque::Job.reserve(@serial_queue)
|
96
|
+
result.must_be_nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'and there is no job from the same queue being performed' do
|
101
|
+
before do
|
102
|
+
Resque::Job.stubs(:job_from_same_queue_is_currently_being_run?)
|
103
|
+
.returns(false)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should return a Resque::Job instance if in non-serial queue' do
|
107
|
+
result = Resque::Job.reserve(@non_serial)
|
108
|
+
result.must_be_instance_of(Resque::Job)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should return a Resque::Job instance if in serial queue' do
|
112
|
+
result = Resque::Job.reserve(@serial_queue)
|
113
|
+
result.must_be_instance_of(Resque::Job)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe Resque::Plugins::RealSerialQueues do
|
121
|
+
describe '#config=' do
|
122
|
+
it 'should take in the config hash in a way that is accessible' do
|
123
|
+
Resque::Plugins::RealSerialQueues.config = {
|
124
|
+
non_serial_queues:[:camera, :bear]
|
125
|
+
}
|
126
|
+
|
127
|
+
Resque::Plugins::RealSerialQueues
|
128
|
+
.non_serial_queues
|
129
|
+
.must_equal([:camera, :bear])
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should throw an error if the config is not a Hash' do
|
133
|
+
-> {
|
134
|
+
Resque::Plugins::RealSerialQueues.config = 'good morning bear'
|
135
|
+
}.must_raise(
|
136
|
+
Resque::Plugins::RealSerialQueues::InvalidConfigurationError
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should throw an error if non serial queues not specified in an array' do
|
141
|
+
-> {
|
142
|
+
Resque::Plugins::RealSerialQueues.config = {
|
143
|
+
non_serial_queues: 'best_queue, better_queue'
|
144
|
+
}
|
145
|
+
}.must_raise(Resque::Plugins::RealSerialQueues::InvalidConfigurationError)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-real-serial-queues
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: resque
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.5'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.1'
|
55
83
|
description: The plugin is designed for sequential running of different jobs in the
|
56
84
|
same queue across multiple queues. Specifically meant for running a variety of
|
57
85
|
long-running background tasks scheduled ahead of time using something like reque-scheduler. May
|
@@ -74,6 +102,8 @@ files:
|
|
74
102
|
- lib/resque/plugins/version.rb
|
75
103
|
- lib/resque_real_serial_queues.rb
|
76
104
|
- resque-real-serial-queues.gemspec
|
105
|
+
- test/resque_test.rb
|
106
|
+
- test/test_helper.rb
|
77
107
|
homepage: https://github.com/4141done/resque-real-serial-queues
|
78
108
|
licenses:
|
79
109
|
- MIT
|
@@ -99,4 +129,6 @@ signing_key:
|
|
99
129
|
specification_version: 4
|
100
130
|
summary: Resque plugin to allow queues to be processed serially without modifying
|
101
131
|
the queue order
|
102
|
-
test_files:
|
132
|
+
test_files:
|
133
|
+
- test/resque_test.rb
|
134
|
+
- test/test_helper.rb
|