resque-lonely_job 0.0.2 → 0.0.3

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.
data/README.md CHANGED
@@ -8,8 +8,11 @@ time.
8
8
  This differs from [resque-lock](from https://github.com/defunkt/resque-lock) and
9
9
  [resque-loner](http://github.com/jayniz/resque-loner) in that the same job may
10
10
  be queued multiple times but you're guaranteed that first job queued will run to
11
- completion before subsequent jobs are run. In other words, job ordering is
12
- preserved.
11
+ completion before subsequent jobs are run.
12
+
13
+ However, it is possible that subsequent jobs are re-ordered depending upon
14
+ worker behavior. Therefore it is recommended that the payload for jobs be
15
+ stored in a separate redis list distinct from the Resque queue (see Example #3).
13
16
 
14
17
  ## Installation
15
18
 
@@ -27,7 +30,7 @@ Or install it yourself as:
27
30
 
28
31
  ## Usage
29
32
 
30
- #### Example #1
33
+ #### Example #1 -- One job running per queue
31
34
 
32
35
  require 'resque/plugins/lonely_job'
33
36
 
@@ -42,7 +45,7 @@ Or install it yourself as:
42
45
  end
43
46
  end
44
47
 
45
- #### Example #2
48
+ #### Example #2 -- One job running per user-defined attribute
46
49
 
47
50
  Let's say you want the serial constraint to apply at a more granular
48
51
  level. Instead of applying at the queue level, you can overwrite the .redis\_key
@@ -62,6 +65,12 @@ method.
62
65
  "lonely_job:strictly_serial_job:#{account_id}"
63
66
  end
64
67
 
68
+ # Overwrite reenqueue to lpush instead of default rpush. This attempts to
69
+ # preserve job ordering but job order is *NOT* guaranteed.
70
+ def self.reenqueue(*args)
71
+ Resque.redis.lpush("queue:#{Resque.queue_from_class(self)}", Resque.encode(class: self, args: args))
72
+ end
73
+
65
74
  def self.perform(account_id, *args)
66
75
  # only one at a time in this block, no parallelism allowed for this
67
76
  # particular redis_key
@@ -98,6 +107,10 @@ where you have three jobs in the queue with two resque workers:
98
107
  http://blog.kabisa.nl/2010/03/16/dynamic-queue-assignment-for-resque-jobs/,
99
108
  where the queue is a one to one mapping to the redis\_key.
100
109
 
110
+ #### Example #3 -- One job running per user-defined attribute with job ordering preserved
111
+
112
+ TODO
113
+
101
114
  ## Contributing
102
115
 
103
116
  1. Fork it
@@ -1,7 +1,7 @@
1
1
  module Resque
2
2
  module Plugins
3
3
  module LonelyJob
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
@@ -27,14 +27,14 @@ module Resque
27
27
  # role our own. This is based on Resque.push but we don't need to
28
28
  # call Resque.watch_queue as the queue should already exist if we're
29
29
  # unable to get the lock.
30
- def lpush(*args)
31
- Resque.redis.lpush("queue:#{Resque.queue_from_class(self)}", Resque.encode(class: self, args: args))
30
+ def reenqueue(*args)
31
+ Resque.enqueue(self, *args)
32
32
  end
33
33
 
34
34
  def before_perform(*args)
35
35
  unless can_lock_queue?(*args)
36
- # can't get the lock, so place at the front of the queue
37
- lpush(*args)
36
+ # can't get the lock, so re-enqueue the task
37
+ reenqueue(*args)
38
38
 
39
39
  # and don't perform
40
40
  raise Resque::Job::DontPerform
@@ -15,9 +15,10 @@ Gem::Specification.new do |gem|
15
15
  gem.version = Resque::Plugins::LonelyJob::VERSION
16
16
 
17
17
  gem.add_dependency 'resque', '~> 1.20.0'
18
- gem.add_dependency 'mock_redis', '~> 0.4.1'
18
+ gem.add_development_dependency 'mock_redis', '~> 0.4.1'
19
19
  gem.add_development_dependency 'rake'
20
20
  gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'debugger'
21
22
 
22
23
  gem.description = <<desc
23
24
  Ensures that for a given queue, only one worker is working on a job at any given time.
@@ -65,9 +65,11 @@ describe Resque::Plugins::LonelyJob do
65
65
  -> { job.perform }.should raise_error(Exception)
66
66
  end
67
67
 
68
- it 'should place self at the beginning of the queue if unable to acquire the lock' do
69
- job1 = Resque::Job.create(:serial_work, 'SerialJob', %w[account_one job_one])
70
- job2 = Resque::Job.create(:serial_work, 'SerialJob', %w[account_one job_two])
68
+ it 'should place self at the end of the queue if unable to acquire the lock' do
69
+ job1_payload = %w[account_one job_one]
70
+ job2_payload = %w[account_one job_two]
71
+ Resque::Job.create(:serial_work, 'SerialJob', job1_payload)
72
+ Resque::Job.create(:serial_work, 'SerialJob', job2_payload)
71
73
 
72
74
  SerialJob.should_receive(:can_lock_queue?).and_return(false)
73
75
 
@@ -77,7 +79,7 @@ describe Resque::Plugins::LonelyJob do
77
79
  job1.perform.should be_false
78
80
 
79
81
  first_queue_element = Resque.reserve(:serial_work)
80
- first_queue_element.should == job1
82
+ first_queue_element.payload["args"].should == [job2_payload]
81
83
  end
82
84
  end
83
85
 
@@ -111,9 +113,11 @@ describe Resque::Plugins::LonelyJob do
111
113
  -> { job.perform }.should raise_error(Exception)
112
114
  end
113
115
 
114
- it 'should place self at the beginning of the queue if unable to acquire the lock' do
115
- job1 = Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', %w[account_one job_one])
116
- job2 = Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', %w[account_one job_two])
116
+ it 'should place self at the end of the queue if unable to acquire the lock' do
117
+ job1_payload = %w[account_one job_one]
118
+ job2_payload = %w[account_one job_two]
119
+ Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', job1_payload)
120
+ Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', job2_payload)
117
121
 
118
122
  SerialJobWithCustomRedisKey.should_receive(:can_lock_queue?).and_return(false)
119
123
 
@@ -123,7 +127,7 @@ describe Resque::Plugins::LonelyJob do
123
127
  job1.perform.should be_false
124
128
 
125
129
  first_queue_element = Resque.reserve(:serial_work)
126
- first_queue_element.should == job1
130
+ first_queue_element.payload["args"].should == [job2_payload]
127
131
  end
128
132
  end
129
133
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-lonely_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-24 00:00:00.000000000 Z
12
+ date: 2012-06-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: resque
16
- requirement: &70163618247460 !ruby/object:Gem::Requirement
16
+ requirement: &70264194773380 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,21 +21,21 @@ dependencies:
21
21
  version: 1.20.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70163618247460
24
+ version_requirements: *70264194773380
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mock_redis
27
- requirement: &70163618260080 !ruby/object:Gem::Requirement
27
+ requirement: &70264194772640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.4.1
33
- type: :runtime
33
+ type: :development
34
34
  prerelease: false
35
- version_requirements: *70163618260080
35
+ version_requirements: *70264194772640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70163618269840 !ruby/object:Gem::Requirement
38
+ requirement: &70264194772020 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,21 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70163618269840
46
+ version_requirements: *70264194772020
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70163618268580 !ruby/object:Gem::Requirement
49
+ requirement: &70264194771040 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70264194771040
58
+ - !ruby/object:Gem::Dependency
59
+ name: debugger
60
+ requirement: &70264194768800 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,7 +65,7 @@ dependencies:
54
65
  version: '0'
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *70163618268580
68
+ version_requirements: *70264194768800
58
69
  description: ! "Ensures that for a given queue, only one worker is working on a job
59
70
  at any given time.\n\nExample:\n\n require 'resque/plugins/lonely_job'\n\n class
60
71
  StrictlySerialJob\n extend Resque::Plugins::LonelyJob\n\n @queue = :serial_work\n\n