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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f93dfead3f604771c085987d5080ad96e4b89cf9
4
- data.tar.gz: 22bd5633ae333f60b33b47c4bd38e6a88a8f784f
3
+ metadata.gz: bdd9fb0afaa0e42a40abd457eba4dd1fc86519d3
4
+ data.tar.gz: 4738f36a9abf515bea030d2ca4650477738e588e
5
5
  SHA512:
6
- metadata.gz: be4ae6f091c52bb056129b7f7a9fa58c04d24533a0d48e49e3233e62359cee5a5e25233554517a522948517648011e099d249a3532de0bf9ee58a8b5bb2547a7
7
- data.tar.gz: 23113e249184a5ec4c50a0b67654d95eead593e6bcbb784767524e44665386299f7548aafd69276992e8c06efa9205f1f778ea54fe3689fe4491b382f89c30b8
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
@@ -1,2 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/testtask'
2
3
 
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.pattern = "test/*_test.rb"
7
+ end
@@ -6,12 +6,11 @@ require "resque/plugins/version"
6
6
  module Resque
7
7
  class Job
8
8
 
9
- # Given a queue name and a potential job (the one we are considering popping off the queue)
10
- # determine whether there is a worker currently working on a job with the same queue, class, and args
11
- # return true if we find an identical job, false if not
12
- def self.job_from_same_queue_is_currently_being_run(queue, job)
13
- return false unless job
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 the queue item has an identical job currently being worked on
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
- potential_job = Resque.peek(queue)
34
- return if job_from_same_queue_is_currently_being_run(queue, potential_job)
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 # :nodoc:
43
- module Plugins # :nodoc
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
@@ -1,7 +1,7 @@
1
1
  module Resque # :nodoc:
2
2
  module Plugins # :nodoc
3
3
  module RealSerialQueues
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
6
6
  end
7
7
  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 "resque", "~> 1.25"
21
+ spec.add_dependency 'resque', '~> 1.25'
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.6"
24
- spec.add_development_dependency "rake"
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
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'resque'
2
+ require 'resque_real_serial_queues'
3
+ require 'minitest'
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require 'minitest/pride'
7
+ require 'mocha/mini_test'
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.1
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-16 00:00:00.000000000 Z
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.6'
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.6'
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