resque-lonely_job 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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