canvas-jobs 0.9.16 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57643efbeabb15ec7af78f3150afd1852462c4e0
4
- data.tar.gz: 70ada31da936583af18e042eee3e68080725703f
3
+ metadata.gz: f7bf248a7914d0c5dbf6c0aafd1ecae8cb320734
4
+ data.tar.gz: 96d5f165dbba5d4390876d9d2770de2c72e3fd0f
5
5
  SHA512:
6
- metadata.gz: c2b9ad3960cbd1b008e31b5e2c28375277a27366a2df2e5682f334eb85d2a179a3e68885e4cba7ed44ebc3366bb039c76f1e99105e625d877208d5f309ed7cbf
7
- data.tar.gz: 238773d9623aaeb6c567ffdd87033e5574cc5a39cb07a891c4721c70b85359b25b8844352aa48355678287b7d747d07d1efc9b007436cecde99f9902d3825da3
6
+ metadata.gz: 957b4893c64372f6930c9311c3ce0a4f94dd87339d09e680b995be6098fa73271b158db5871d4f6e57d9718d51f0dd81052be81ad08e6e220c86c509e18a0348
7
+ data.tar.gz: a819d0f1218927de1fd18569d7bce5ff5659d9a57666104bd66937fbfa2f556661c333a8d66d4179ff26b45c6259e32d50ac35a8c818cfb05051d976da3ed0b9
@@ -0,0 +1,70 @@
1
+ class AddMaxConcurrentToJobs < ActiveRecord::Migration
2
+ def connection
3
+ Delayed::Job.connection
4
+ end
5
+
6
+ def up
7
+ add_column :delayed_jobs, :max_concurrent, :integer, :default => 1, :null => false
8
+
9
+ if connection.adapter_name == 'PostgreSQL'
10
+ execute(<<-CODE)
11
+ CREATE OR REPLACE FUNCTION delayed_jobs_before_insert_row_tr_fn () RETURNS trigger AS $$
12
+ BEGIN
13
+ IF NEW.strand IS NOT NULL THEN
14
+ PERFORM pg_advisory_xact_lock(half_md5_as_bigint(NEW.strand));
15
+ IF (SELECT COUNT(*) FROM delayed_jobs WHERE strand = NEW.strand) >= NEW.max_concurrent THEN
16
+ NEW.next_in_strand := 'f';
17
+ END IF;
18
+ END IF;
19
+ RETURN NEW;
20
+ END;
21
+ $$ LANGUAGE plpgsql;
22
+ CODE
23
+
24
+ execute(<<-CODE)
25
+ CREATE OR REPLACE FUNCTION delayed_jobs_after_delete_row_tr_fn () RETURNS trigger AS $$
26
+ BEGIN
27
+ IF OLD.strand IS NOT NULL THEN
28
+ PERFORM pg_advisory_xact_lock(half_md5_as_bigint(OLD.strand));
29
+ IF (SELECT COUNT(*) FROM delayed_jobs WHERE strand = OLD.strand AND next_in_strand = 't') < OLD.max_concurrent THEN
30
+ UPDATE delayed_jobs SET next_in_strand = 't' WHERE id = (
31
+ SELECT id FROM delayed_jobs j2 WHERE next_in_strand = 'f' AND
32
+ j2.strand = OLD.strand ORDER BY j2.id ASC LIMIT 1 FOR UPDATE
33
+ );
34
+ END IF;
35
+ END IF;
36
+ RETURN OLD;
37
+ END;
38
+ $$ LANGUAGE plpgsql;
39
+ CODE
40
+ end
41
+ end
42
+
43
+ def down
44
+ remove_column :delayed_jobs, :max_concurrent
45
+
46
+ if connection.adapter_name == 'PostgreSQL'
47
+ execute(<<-CODE)
48
+ CREATE OR REPLACE FUNCTION delayed_jobs_before_insert_row_tr_fn () RETURNS trigger AS $$
49
+ BEGIN
50
+ PERFORM pg_advisory_xact_lock(half_md5_as_bigint(NEW.strand));
51
+ IF (SELECT 1 FROM delayed_jobs WHERE strand = NEW.strand LIMIT 1) = 1 THEN
52
+ NEW.next_in_strand := 'f';
53
+ END IF;
54
+ RETURN NEW;
55
+ END;
56
+ $$ LANGUAGE plpgsql;
57
+ CODE
58
+
59
+ execute(<<-CODE)
60
+ CREATE OR REPLACE FUNCTION delayed_jobs_after_delete_row_tr_fn () RETURNS trigger AS $$
61
+ BEGIN
62
+ PERFORM pg_advisory_xact_lock(half_md5_as_bigint(OLD.strand));
63
+ UPDATE delayed_jobs SET next_in_strand = 't' WHERE id = (SELECT id FROM delayed_jobs j2 WHERE j2.strand = OLD.strand ORDER BY j2.strand, j2.id ASC LIMIT 1 FOR UPDATE);
64
+ RETURN OLD;
65
+ END;
66
+ $$ LANGUAGE plpgsql;
67
+ CODE
68
+ end
69
+ end
70
+ end
@@ -43,6 +43,13 @@ module Delayed
43
43
  end
44
44
  end
45
45
 
46
+ # This overwrites the previous behavior
47
+ # so rather than changing the strand and balancing at queue time,
48
+ # this keeps the strand intact and uses triggers to limit the number running
49
+ def self.n_strand_options(strand_name, num_strands)
50
+ {:strand => strand_name, :max_concurrent => num_strands}
51
+ end
52
+
46
53
  def self.current
47
54
  where("run_at<=?", db_time_now)
48
55
  end
@@ -298,6 +305,7 @@ module Delayed
298
305
  attrs['original_job_id'] = attrs.delete('id')
299
306
  attrs['failed_at'] ||= self.class.db_time_now
300
307
  attrs.delete('next_in_strand')
308
+ attrs.delete('max_concurrent')
301
309
  self.class.transaction do
302
310
  failed_job = Failed.create(attrs)
303
311
  self.destroy
@@ -59,9 +59,7 @@ module Delayed
59
59
  num_strands ||= Delayed::Settings.num_strands.call(strand_name)
60
60
  num_strands = num_strands ? num_strands.to_i : 1
61
61
 
62
- strand_num = num_strands > 1 ? rand(num_strands) + 1 : 1
63
- full_strand_name += ":#{strand_num}" if strand_num > 1
64
- options[:strand] = full_strand_name
62
+ options.merge!(n_strand_options(full_strand_name, num_strands))
65
63
  end
66
64
 
67
65
  if options[:singleton]
@@ -80,6 +78,15 @@ module Delayed
80
78
  job
81
79
  end
82
80
 
81
+ # by default creates a new strand name randomly based on num_strands
82
+ # effectively balancing the load during queueing
83
+ # overwritten in ActiveRecord::Job to use triggers to balance at run time
84
+ def n_strand_options(strand_name, num_strands)
85
+ strand_num = num_strands > 1 ? rand(num_strands) + 1 : 1
86
+ strand_name += ":#{strand_num}" if strand_num > 1
87
+ {:strand => strand_name}
88
+ end
89
+
83
90
  def in_delayed_job?
84
91
  !!Thread.current[:in_delayed_job]
85
92
  end
@@ -201,7 +201,7 @@ class Pool
201
201
  def join
202
202
  loop do
203
203
  child = Process.wait
204
- if child
204
+ if workers.include?(child)
205
205
  worker = workers.delete(child)
206
206
  if worker.is_a?(Symbol)
207
207
  say "ran auditor: #{worker}"
@@ -1,3 +1,3 @@
1
1
  module Delayed
2
- VERSION = "0.9.16"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -68,7 +68,6 @@ describe 'Delayed::Backed::ActiveRecord::Job' do
68
68
  job.locked_at.should == nil
69
69
  end
70
70
 
71
-
72
71
  describe "bulk_update failed jobs" do
73
72
  before do
74
73
  @flavor = 'failed'
@@ -101,4 +100,107 @@ describe 'Delayed::Backed::ActiveRecord::Job' do
101
100
  end
102
101
  end
103
102
 
103
+ context 'n_strand' do
104
+ it "should default to 1" do
105
+ expect(Delayed::Job).to receive(:rand).never
106
+ job = Delayed::Job.enqueue(SimpleJob.new, :n_strand => 'njobs')
107
+ job.strand.should == "njobs"
108
+ end
109
+
110
+ it "should set max_concurrent based on num_strands" do
111
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) { expect(strand_name).to eql "njobs"; "3" }) do
112
+ job = Delayed::Job.enqueue(SimpleJob.new, :n_strand => 'njobs')
113
+ job.strand.should == "njobs"
114
+ job.max_concurrent.should == 3
115
+ end
116
+ end
117
+
118
+ context "with two parameters" do
119
+ it "should use the first param as the setting to read" do
120
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
121
+ job.strand.should == "njobs/123"
122
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
123
+ case strand_name
124
+ when "njobs"; 3
125
+ else nil
126
+ end
127
+ }) do
128
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
129
+ job.strand.should == "njobs/123"
130
+ job.max_concurrent.should == 3
131
+ end
132
+ end
133
+
134
+ it "should allow overridding the setting based on the second param" do
135
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
136
+ case strand_name
137
+ when "njobs/123"; 5
138
+ else nil
139
+ end
140
+ }) do
141
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
142
+ job.strand.should == "njobs/123"
143
+ job.max_concurrent.should == 5
144
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "456"])
145
+ job.strand.should == "njobs/456"
146
+ job.max_concurrent.should == 1
147
+ end
148
+
149
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
150
+ case strand_name
151
+ when "njobs/123"; 5
152
+ when "njobs"; 3
153
+ else nil
154
+ end
155
+ }) do
156
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
157
+ job.strand.should == "njobs/123"
158
+ job.max_concurrent.should == 5
159
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "456"])
160
+ job.strand.should == "njobs/456"
161
+ job.max_concurrent.should == 3
162
+ end
163
+ end
164
+ end
165
+
166
+ context "max_concurrent triggers" do
167
+ before do
168
+ skip("postgres specific") unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
169
+ end
170
+
171
+ it "should set one job as next_in_strand at a time with max_concurrent of 1" do
172
+ job1 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
173
+ job1.reload
174
+ job1.next_in_strand.should == true
175
+ job2 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
176
+ job2.reload
177
+ job2.next_in_strand.should == false
178
+ run_job(job1)
179
+ job2.reload
180
+ job2.next_in_strand.should == true
181
+ end
182
+
183
+ it "should run set multiple jobs as next_in_strand at a time based on max_concurrent" do
184
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
185
+ case strand_name
186
+ when "njobs"; 2
187
+ else nil
188
+ end
189
+ }) do
190
+ job1 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
191
+ job1.reload
192
+ job1.next_in_strand.should == true
193
+ job2 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
194
+ job2.reload
195
+ job2.next_in_strand.should == true
196
+ job3 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
197
+ job3.reload
198
+ job3.next_in_strand.should == false
199
+ run_job(job1)
200
+ job3.reload
201
+ job3.next_in_strand.should == true
202
+ end
203
+ end
204
+ end
205
+ end
104
206
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../../
3
3
  specs:
4
- canvas-jobs (0.9.15)
4
+ canvas-jobs (0.9.14)
5
5
  after_transaction_commit (= 1.0.1)
6
6
  rails (>= 3.2)
7
7
  redis (> 3.0)
@@ -11,12 +11,12 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- actionmailer (3.2.19)
15
- actionpack (= 3.2.19)
14
+ actionmailer (3.2.22)
15
+ actionpack (= 3.2.22)
16
16
  mail (~> 2.5.4)
17
- actionpack (3.2.19)
18
- activemodel (= 3.2.19)
19
- activesupport (= 3.2.19)
17
+ actionpack (3.2.22)
18
+ activemodel (= 3.2.22)
19
+ activesupport (= 3.2.22)
20
20
  builder (~> 3.0.0)
21
21
  erubis (~> 2.7.0)
22
22
  journey (~> 1.0.4)
@@ -24,72 +24,72 @@ GEM
24
24
  rack-cache (~> 1.2)
25
25
  rack-test (~> 0.6.1)
26
26
  sprockets (~> 2.2.1)
27
- activemodel (3.2.19)
28
- activesupport (= 3.2.19)
27
+ activemodel (3.2.22)
28
+ activesupport (= 3.2.22)
29
29
  builder (~> 3.0.0)
30
- activerecord (3.2.19)
31
- activemodel (= 3.2.19)
32
- activesupport (= 3.2.19)
30
+ activerecord (3.2.22)
31
+ activemodel (= 3.2.22)
32
+ activesupport (= 3.2.22)
33
33
  arel (~> 3.0.2)
34
34
  tzinfo (~> 0.3.29)
35
- activeresource (3.2.19)
36
- activemodel (= 3.2.19)
37
- activesupport (= 3.2.19)
38
- activesupport (3.2.19)
35
+ activeresource (3.2.22)
36
+ activemodel (= 3.2.22)
37
+ activesupport (= 3.2.22)
38
+ activesupport (3.2.22)
39
39
  i18n (~> 0.6, >= 0.6.4)
40
40
  multi_json (~> 1.0)
41
41
  after_transaction_commit (1.0.1)
42
42
  activerecord (>= 3.2)
43
43
  arel (3.0.3)
44
44
  backports (3.6.6)
45
- builder (3.0.0)
46
- bump (0.5.0)
45
+ builder (3.0.4)
46
+ bump (0.5.2)
47
47
  coderay (1.1.0)
48
48
  database_cleaner (1.3.0)
49
49
  diff-lcs (1.2.5)
50
50
  erubis (2.7.0)
51
51
  hike (1.2.3)
52
- i18n (0.6.11)
52
+ i18n (0.7.0)
53
53
  journey (1.0.4)
54
- json (1.8.1)
54
+ json (1.8.3)
55
55
  mail (2.5.4)
56
56
  mime-types (~> 1.16)
57
57
  treetop (~> 1.4.8)
58
58
  method_source (0.8.2)
59
59
  mime-types (1.25.1)
60
- multi_json (1.10.1)
61
- pg (0.17.1)
60
+ multi_json (1.11.2)
61
+ pg (0.18.2)
62
62
  polyglot (0.3.5)
63
63
  pry (0.10.1)
64
64
  coderay (~> 1.1.0)
65
65
  method_source (~> 0.8.1)
66
66
  slop (~> 3.4)
67
- rack (1.4.5)
67
+ rack (1.4.7)
68
68
  rack-cache (1.2)
69
69
  rack (>= 0.4)
70
70
  rack-protection (1.5.3)
71
71
  rack
72
72
  rack-ssl (1.3.4)
73
73
  rack
74
- rack-test (0.6.2)
74
+ rack-test (0.6.3)
75
75
  rack (>= 1.0)
76
- rails (3.2.19)
77
- actionmailer (= 3.2.19)
78
- actionpack (= 3.2.19)
79
- activerecord (= 3.2.19)
80
- activeresource (= 3.2.19)
81
- activesupport (= 3.2.19)
76
+ rails (3.2.22)
77
+ actionmailer (= 3.2.22)
78
+ actionpack (= 3.2.22)
79
+ activerecord (= 3.2.22)
80
+ activeresource (= 3.2.22)
81
+ activesupport (= 3.2.22)
82
82
  bundler (~> 1.0)
83
- railties (= 3.2.19)
84
- railties (3.2.19)
85
- actionpack (= 3.2.19)
86
- activesupport (= 3.2.19)
83
+ railties (= 3.2.22)
84
+ railties (3.2.22)
85
+ actionpack (= 3.2.22)
86
+ activesupport (= 3.2.22)
87
87
  rack-ssl (~> 1.3.2)
88
88
  rake (>= 0.8.7)
89
89
  rdoc (~> 3.4)
90
90
  thor (>= 0.14.6, < 2.0)
91
- rake (10.3.2)
92
- rdoc (3.12)
91
+ rake (10.4.2)
92
+ rdoc (3.12.2)
93
93
  json (~> 1.4)
94
94
  redis (3.2.1)
95
95
  redis-scripting (1.0.1)
@@ -106,7 +106,7 @@ GEM
106
106
  rspec-mocks (3.1.3)
107
107
  rspec-support (~> 3.1.0)
108
108
  rspec-support (3.1.2)
109
- rufus-scheduler (3.1.7)
109
+ rufus-scheduler (3.1.3)
110
110
  sinatra (1.4.6)
111
111
  rack (~> 1.4)
112
112
  rack-protection (~> 1.4)
@@ -119,12 +119,11 @@ GEM
119
119
  sinatra (~> 1.4.0)
120
120
  tilt (>= 1.3, < 3)
121
121
  slop (3.6.0)
122
- sprockets (2.2.2)
122
+ sprockets (2.2.3)
123
123
  hike (~> 1.2)
124
124
  multi_json (~> 1.0)
125
125
  rack (~> 1.0)
126
126
  tilt (~> 1.1, != 1.3.0)
127
- syck (1.0.5)
128
127
  test_after_commit (0.4.1)
129
128
  activerecord (>= 3.2)
130
129
  thor (0.19.1)
@@ -133,8 +132,8 @@ GEM
133
132
  treetop (1.4.15)
134
133
  polyglot
135
134
  polyglot (>= 0.3.1)
136
- tzinfo (0.3.39)
137
- wwtd (1.1.1)
135
+ tzinfo (0.3.44)
136
+ wwtd (0.7.0)
138
137
 
139
138
  PLATFORMS
140
139
  ruby
@@ -151,7 +150,6 @@ DEPENDENCIES
151
150
  rspec (= 3.1.0)
152
151
  sinatra
153
152
  sinatra-contrib
154
- syck (>= 1.0.4)
155
153
  test_after_commit (= 0.4.1)
156
154
  timecop (= 0.7.1)
157
- wwtd (~> 1.1.1)
155
+ wwtd (= 0.7.0)
@@ -74,4 +74,67 @@ describe 'Delayed::Backend::Redis::Job' do
74
74
  Delayed::Job.jobs_count(:current) == before_count + 1
75
75
  end
76
76
  end
77
+
78
+ context 'n_strand' do
79
+ it "should default to 1" do
80
+ expect(Delayed::Job).to receive(:rand).never
81
+ job = Delayed::Job.enqueue(SimpleJob.new, :n_strand => 'njobs')
82
+ job.strand.should == "njobs"
83
+ end
84
+
85
+ it "should pick a strand randomly out of N" do
86
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) { expect(strand_name).to eql "njobs"; "3" }) do
87
+ expect(Delayed::Job).to receive(:rand).with(3).and_return(1)
88
+ job = Delayed::Job.enqueue(SimpleJob.new, :n_strand => 'njobs')
89
+ job.strand.should == "njobs:2"
90
+ end
91
+ end
92
+
93
+ context "with two parameters" do
94
+ it "should use the first param as the setting to read" do
95
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
96
+ job.strand.should == "njobs/123"
97
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
98
+ case strand_name
99
+ when "njobs"; 3
100
+ else nil
101
+ end
102
+ }) do
103
+ expect(Delayed::Job).to receive(:rand).with(3).and_return(1)
104
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
105
+ job.strand.should == "njobs/123:2"
106
+ end
107
+ end
108
+
109
+ it "should allow overridding the setting based on the second param" do
110
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
111
+ case strand_name
112
+ when "njobs/123"; 5
113
+ else nil
114
+ end
115
+ }) do
116
+ expect(Delayed::Job).to receive(:rand).with(5).and_return(3)
117
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
118
+ job.strand.should == "njobs/123:4"
119
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "456"])
120
+ job.strand.should == "njobs/456"
121
+ end
122
+
123
+ change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
124
+ case strand_name
125
+ when "njobs/123"; 5
126
+ when "njobs"; 3
127
+ else nil
128
+ end
129
+ }) do
130
+ expect(Delayed::Job).to receive(:rand).with(5).and_return(2)
131
+ expect(Delayed::Job).to receive(:rand).with(3).and_return(1)
132
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
133
+ job.strand.should == "njobs/123:3"
134
+ job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "456"])
135
+ job.strand.should == "njobs/456:2"
136
+ end
137
+ end
138
+ end
139
+ end
77
140
  end
@@ -76,14 +76,14 @@ shared_examples_for 'a backend' do
76
76
  job = Delayed::Job.new :handler => "--- !ruby/struct:Delayed::JobThatDoesNotExist {}"
77
77
  lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError)
78
78
  end
79
-
79
+
80
80
  describe "find_available" do
81
81
  it "should not find failed jobs" do
82
82
  @job = create_job :attempts => 50
83
83
  @job.fail!
84
84
  Delayed::Job.find_available(5).should_not include(@job)
85
85
  end
86
-
86
+
87
87
  it "should not find jobs scheduled for the future" do
88
88
  @job = create_job :run_at => (Delayed::Job.db_time_now + 1.minute)
89
89
  Delayed::Job.find_available(5).should_not include(@job)
@@ -94,13 +94,13 @@ shared_examples_for 'a backend' do
94
94
  Delayed::Job.get_and_lock_next_available('other_worker').should == @job
95
95
  Delayed::Job.find_available(5).should_not include(@job)
96
96
  end
97
-
97
+
98
98
  it "should find open jobs" do
99
99
  @job = create_job
100
100
  Delayed::Job.find_available(5).should include(@job)
101
101
  end
102
102
  end
103
-
103
+
104
104
  context "when another worker is already performing an task, it" do
105
105
 
106
106
  before :each do
@@ -132,13 +132,13 @@ shared_examples_for 'a backend' do
132
132
  @job.name.should == 'Story#save'
133
133
  end
134
134
  end
135
-
135
+
136
136
  context "worker prioritization" do
137
137
  it "should fetch jobs ordered by priority" do
138
138
  10.times { create_job :priority => rand(10) }
139
139
  jobs = Delayed::Job.find_available(10)
140
140
  jobs.size.should == 10
141
- jobs.each_cons(2) do |a, b|
141
+ jobs.each_cons(2) do |a, b|
142
142
  a.priority.should <= b.priority
143
143
  end
144
144
  end
@@ -167,23 +167,23 @@ shared_examples_for 'a backend' do
167
167
  found.should == job3
168
168
  end
169
169
  end
170
-
170
+
171
171
  context "clear_locks!" do
172
172
  before do
173
173
  @job = create_job(:locked_by => 'worker', :locked_at => Delayed::Job.db_time_now)
174
174
  end
175
-
175
+
176
176
  it "should clear locks for the given worker" do
177
177
  Delayed::Job.clear_locks!('worker')
178
178
  Delayed::Job.find_available(5).should include(@job)
179
179
  end
180
-
180
+
181
181
  it "should not clear locks for other workers" do
182
182
  Delayed::Job.clear_locks!('worker1')
183
183
  Delayed::Job.find_available(5).should_not include(@job)
184
184
  end
185
185
  end
186
-
186
+
187
187
  context "unlock" do
188
188
  before do
189
189
  @job = create_job(:locked_by => 'worker', :locked_at => Delayed::Job.db_time_now)
@@ -324,69 +324,6 @@ shared_examples_for 'a backend' do
324
324
  Delayed::Job.get_and_lock_next_available('w1').should == job1
325
325
  end
326
326
  end
327
-
328
- context 'n_strand' do
329
- it "should default to 1" do
330
- expect(Delayed::Job).to receive(:rand).never
331
- job = Delayed::Job.enqueue(SimpleJob.new, :n_strand => 'njobs')
332
- job.strand.should == "njobs"
333
- end
334
-
335
- it "should pick a strand randomly out of N" do
336
- change_setting(Delayed::Settings, :num_strands, ->(strand_name) { expect(strand_name).to eql "njobs"; "3" }) do
337
- expect(Delayed::Job).to receive(:rand).with(3).and_return(1)
338
- job = Delayed::Job.enqueue(SimpleJob.new, :n_strand => 'njobs')
339
- job.strand.should == "njobs:2"
340
- end
341
- end
342
-
343
- context "with two parameters" do
344
- it "should use the first param as the setting to read" do
345
- job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
346
- job.strand.should == "njobs/123"
347
- change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
348
- case strand_name
349
- when "njobs"; 3
350
- else nil
351
- end
352
- }) do
353
- expect(Delayed::Job).to receive(:rand).with(3).and_return(1)
354
- job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
355
- job.strand.should == "njobs/123:2"
356
- end
357
- end
358
-
359
- it "should allow overridding the setting based on the second param" do
360
- change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
361
- case strand_name
362
- when "njobs/123"; 5
363
- else nil
364
- end
365
- }) do
366
- expect(Delayed::Job).to receive(:rand).with(5).and_return(3)
367
- job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
368
- job.strand.should == "njobs/123:4"
369
- job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "456"])
370
- job.strand.should == "njobs/456"
371
- end
372
-
373
- change_setting(Delayed::Settings, :num_strands, ->(strand_name) {
374
- case strand_name
375
- when "njobs/123"; 5
376
- when "njobs"; 3
377
- else nil
378
- end
379
- }) do
380
- expect(Delayed::Job).to receive(:rand).with(5).and_return(2)
381
- expect(Delayed::Job).to receive(:rand).with(3).and_return(1)
382
- job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "123"])
383
- job.strand.should == "njobs/123:3"
384
- job = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs", "456"])
385
- job.strand.should == "njobs/456:2"
386
- end
387
- end
388
- end
389
- end
390
327
  end
391
328
 
392
329
  context "on hold" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.16
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-10-23 00:00:00.000000000 Z
12
+ date: 2015-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: after_transaction_commit
@@ -275,6 +275,7 @@ files:
275
275
  - db/migrate/20140505215510_copy_failed_jobs_original_id.rb
276
276
  - db/migrate/20140505223637_drop_failed_jobs_original_id.rb
277
277
  - db/migrate/20140512213941_add_source_to_jobs.rb
278
+ - db/migrate/20150807133223_add_max_concurrent_to_jobs.rb
278
279
  - lib/canvas-jobs.rb
279
280
  - lib/delayed/backend/active_record.rb
280
281
  - lib/delayed/backend/base.rb
@@ -317,11 +318,8 @@ files:
317
318
  - spec/gemfiles/32.gemfile
318
319
  - spec/gemfiles/32.gemfile.lock
319
320
  - spec/gemfiles/40.gemfile
320
- - spec/gemfiles/40.gemfile.lock
321
321
  - spec/gemfiles/41.gemfile
322
- - spec/gemfiles/41.gemfile.lock
323
322
  - spec/gemfiles/42.gemfile
324
- - spec/gemfiles/42.gemfile.lock
325
323
  - spec/migrate/20140924140513_add_story_table.rb
326
324
  - spec/redis_job_spec.rb
327
325
  - spec/sample_jobs.rb
@@ -352,7 +350,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
352
350
  version: '0'
353
351
  requirements: []
354
352
  rubyforge_project:
355
- rubygems_version: 2.4.5.1
353
+ rubygems_version: 2.4.7
356
354
  signing_key:
357
355
  specification_version: 4
358
356
  summary: Instructure-maintained fork of delayed_job
@@ -364,11 +362,8 @@ test_files:
364
362
  - spec/gemfiles/32.gemfile
365
363
  - spec/gemfiles/32.gemfile.lock
366
364
  - spec/gemfiles/40.gemfile
367
- - spec/gemfiles/40.gemfile.lock
368
365
  - spec/gemfiles/41.gemfile
369
- - spec/gemfiles/41.gemfile.lock
370
366
  - spec/gemfiles/42.gemfile
371
- - spec/gemfiles/42.gemfile.lock
372
367
  - spec/migrate/20140924140513_add_story_table.rb
373
368
  - spec/redis_job_spec.rb
374
369
  - spec/sample_jobs.rb
@@ -1,141 +0,0 @@
1
- PATH
2
- remote: ../../
3
- specs:
4
- canvas-jobs (0.9.15)
5
- after_transaction_commit (= 1.0.1)
6
- rails (>= 3.2)
7
- redis (> 3.0)
8
- redis-scripting (~> 1.0.1)
9
- rufus-scheduler (~> 3.1.2)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actionmailer (4.0.13)
15
- actionpack (= 4.0.13)
16
- mail (~> 2.5, >= 2.5.4)
17
- actionpack (4.0.13)
18
- activesupport (= 4.0.13)
19
- builder (~> 3.1.0)
20
- erubis (~> 2.7.0)
21
- rack (~> 1.5.2)
22
- rack-test (~> 0.6.2)
23
- activemodel (4.0.13)
24
- activesupport (= 4.0.13)
25
- builder (~> 3.1.0)
26
- activerecord (4.0.13)
27
- activemodel (= 4.0.13)
28
- activerecord-deprecated_finders (~> 1.0.2)
29
- activesupport (= 4.0.13)
30
- arel (~> 4.0.0)
31
- activerecord-deprecated_finders (1.0.4)
32
- activesupport (4.0.13)
33
- i18n (~> 0.6, >= 0.6.9)
34
- minitest (~> 4.2)
35
- multi_json (~> 1.3)
36
- thread_safe (~> 0.1)
37
- tzinfo (~> 0.3.37)
38
- after_transaction_commit (1.0.1)
39
- activerecord (>= 3.2)
40
- arel (4.0.2)
41
- backports (3.6.6)
42
- builder (3.1.4)
43
- bump (0.5.2)
44
- coderay (1.1.0)
45
- database_cleaner (1.3.0)
46
- diff-lcs (1.2.5)
47
- erubis (2.7.0)
48
- i18n (0.7.0)
49
- mail (2.6.3)
50
- mime-types (>= 1.16, < 3)
51
- method_source (0.8.2)
52
- mime-types (2.6.2)
53
- minitest (4.7.5)
54
- multi_json (1.11.2)
55
- pg (0.18.3)
56
- pry (0.10.3)
57
- coderay (~> 1.1.0)
58
- method_source (~> 0.8.1)
59
- slop (~> 3.4)
60
- rack (1.5.5)
61
- rack-protection (1.5.3)
62
- rack
63
- rack-test (0.6.3)
64
- rack (>= 1.0)
65
- rails (4.0.13)
66
- actionmailer (= 4.0.13)
67
- actionpack (= 4.0.13)
68
- activerecord (= 4.0.13)
69
- activesupport (= 4.0.13)
70
- bundler (>= 1.3.0, < 2.0)
71
- railties (= 4.0.13)
72
- sprockets-rails (~> 2.0)
73
- railties (4.0.13)
74
- actionpack (= 4.0.13)
75
- activesupport (= 4.0.13)
76
- rake (>= 0.8.7)
77
- thor (>= 0.18.1, < 2.0)
78
- rake (10.4.2)
79
- redis (3.2.1)
80
- redis-scripting (1.0.1)
81
- redis (>= 3.0)
82
- rspec (3.1.0)
83
- rspec-core (~> 3.1.0)
84
- rspec-expectations (~> 3.1.0)
85
- rspec-mocks (~> 3.1.0)
86
- rspec-core (3.1.7)
87
- rspec-support (~> 3.1.0)
88
- rspec-expectations (3.1.2)
89
- diff-lcs (>= 1.2.0, < 2.0)
90
- rspec-support (~> 3.1.0)
91
- rspec-mocks (3.1.3)
92
- rspec-support (~> 3.1.0)
93
- rspec-support (3.1.2)
94
- rufus-scheduler (3.1.7)
95
- sinatra (1.4.6)
96
- rack (~> 1.4)
97
- rack-protection (~> 1.4)
98
- tilt (>= 1.3, < 3)
99
- sinatra-contrib (1.4.6)
100
- backports (>= 2.0)
101
- multi_json
102
- rack-protection
103
- rack-test
104
- sinatra (~> 1.4.0)
105
- tilt (>= 1.3, < 3)
106
- slop (3.6.0)
107
- sprockets (3.4.0)
108
- rack (> 1, < 3)
109
- sprockets-rails (2.3.3)
110
- actionpack (>= 3.0)
111
- activesupport (>= 3.0)
112
- sprockets (>= 2.8, < 4.0)
113
- syck (1.0.5)
114
- test_after_commit (0.4.1)
115
- activerecord (>= 3.2)
116
- thor (0.19.1)
117
- thread_safe (0.3.5)
118
- tilt (2.0.1)
119
- timecop (0.7.1)
120
- tzinfo (0.3.45)
121
- wwtd (1.1.1)
122
-
123
- PLATFORMS
124
- ruby
125
-
126
- DEPENDENCIES
127
- bump
128
- canvas-jobs!
129
- database_cleaner (= 1.3.0)
130
- pg
131
- pry
132
- rack-test
133
- rails (~> 4.0.10)
134
- rake
135
- rspec (= 3.1.0)
136
- sinatra
137
- sinatra-contrib
138
- syck (>= 1.0.4)
139
- test_after_commit (= 0.4.1)
140
- timecop (= 0.7.1)
141
- wwtd (~> 1.1.1)
@@ -1,147 +0,0 @@
1
- PATH
2
- remote: ../../
3
- specs:
4
- canvas-jobs (0.9.15)
5
- after_transaction_commit (= 1.0.1)
6
- rails (>= 3.2)
7
- redis (> 3.0)
8
- redis-scripting (~> 1.0.1)
9
- rufus-scheduler (~> 3.1.2)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actionmailer (4.1.13)
15
- actionpack (= 4.1.13)
16
- actionview (= 4.1.13)
17
- mail (~> 2.5, >= 2.5.4)
18
- actionpack (4.1.13)
19
- actionview (= 4.1.13)
20
- activesupport (= 4.1.13)
21
- rack (~> 1.5.2)
22
- rack-test (~> 0.6.2)
23
- actionview (4.1.13)
24
- activesupport (= 4.1.13)
25
- builder (~> 3.1)
26
- erubis (~> 2.7.0)
27
- activemodel (4.1.13)
28
- activesupport (= 4.1.13)
29
- builder (~> 3.1)
30
- activerecord (4.1.13)
31
- activemodel (= 4.1.13)
32
- activesupport (= 4.1.13)
33
- arel (~> 5.0.0)
34
- activesupport (4.1.13)
35
- i18n (~> 0.6, >= 0.6.9)
36
- json (~> 1.7, >= 1.7.7)
37
- minitest (~> 5.1)
38
- thread_safe (~> 0.1)
39
- tzinfo (~> 1.1)
40
- after_transaction_commit (1.0.1)
41
- activerecord (>= 3.2)
42
- arel (5.0.1.20140414130214)
43
- backports (3.6.6)
44
- builder (3.2.2)
45
- bump (0.5.2)
46
- coderay (1.1.0)
47
- database_cleaner (1.3.0)
48
- diff-lcs (1.2.5)
49
- erubis (2.7.0)
50
- i18n (0.7.0)
51
- json (1.8.3)
52
- mail (2.6.3)
53
- mime-types (>= 1.16, < 3)
54
- method_source (0.8.2)
55
- mime-types (2.6.2)
56
- minitest (5.8.1)
57
- multi_json (1.11.2)
58
- pg (0.18.3)
59
- pry (0.10.3)
60
- coderay (~> 1.1.0)
61
- method_source (~> 0.8.1)
62
- slop (~> 3.4)
63
- rack (1.5.5)
64
- rack-protection (1.5.3)
65
- rack
66
- rack-test (0.6.3)
67
- rack (>= 1.0)
68
- rails (4.1.13)
69
- actionmailer (= 4.1.13)
70
- actionpack (= 4.1.13)
71
- actionview (= 4.1.13)
72
- activemodel (= 4.1.13)
73
- activerecord (= 4.1.13)
74
- activesupport (= 4.1.13)
75
- bundler (>= 1.3.0, < 2.0)
76
- railties (= 4.1.13)
77
- sprockets-rails (~> 2.0)
78
- railties (4.1.13)
79
- actionpack (= 4.1.13)
80
- activesupport (= 4.1.13)
81
- rake (>= 0.8.7)
82
- thor (>= 0.18.1, < 2.0)
83
- rake (10.4.2)
84
- redis (3.2.1)
85
- redis-scripting (1.0.1)
86
- redis (>= 3.0)
87
- rspec (3.1.0)
88
- rspec-core (~> 3.1.0)
89
- rspec-expectations (~> 3.1.0)
90
- rspec-mocks (~> 3.1.0)
91
- rspec-core (3.1.7)
92
- rspec-support (~> 3.1.0)
93
- rspec-expectations (3.1.2)
94
- diff-lcs (>= 1.2.0, < 2.0)
95
- rspec-support (~> 3.1.0)
96
- rspec-mocks (3.1.3)
97
- rspec-support (~> 3.1.0)
98
- rspec-support (3.1.2)
99
- rufus-scheduler (3.1.7)
100
- sinatra (1.4.6)
101
- rack (~> 1.4)
102
- rack-protection (~> 1.4)
103
- tilt (>= 1.3, < 3)
104
- sinatra-contrib (1.4.6)
105
- backports (>= 2.0)
106
- multi_json
107
- rack-protection
108
- rack-test
109
- sinatra (~> 1.4.0)
110
- tilt (>= 1.3, < 3)
111
- slop (3.6.0)
112
- sprockets (3.4.0)
113
- rack (> 1, < 3)
114
- sprockets-rails (2.3.3)
115
- actionpack (>= 3.0)
116
- activesupport (>= 3.0)
117
- sprockets (>= 2.8, < 4.0)
118
- syck (1.0.5)
119
- test_after_commit (0.4.1)
120
- activerecord (>= 3.2)
121
- thor (0.19.1)
122
- thread_safe (0.3.5)
123
- tilt (2.0.1)
124
- timecop (0.7.1)
125
- tzinfo (1.2.2)
126
- thread_safe (~> 0.1)
127
- wwtd (1.1.1)
128
-
129
- PLATFORMS
130
- ruby
131
-
132
- DEPENDENCIES
133
- bump
134
- canvas-jobs!
135
- database_cleaner (= 1.3.0)
136
- pg
137
- pry
138
- rack-test
139
- rails (~> 4.1.6)
140
- rake
141
- rspec (= 3.1.0)
142
- sinatra
143
- sinatra-contrib
144
- syck (>= 1.0.4)
145
- test_after_commit (= 0.4.1)
146
- timecop (= 0.7.1)
147
- wwtd (~> 1.1.1)
@@ -1,172 +0,0 @@
1
- PATH
2
- remote: ../../
3
- specs:
4
- canvas-jobs (0.9.15)
5
- after_transaction_commit (= 1.0.1)
6
- rails (>= 3.2)
7
- redis (> 3.0)
8
- redis-scripting (~> 1.0.1)
9
- rufus-scheduler (~> 3.1.2)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actionmailer (4.2.4)
15
- actionpack (= 4.2.4)
16
- actionview (= 4.2.4)
17
- activejob (= 4.2.4)
18
- mail (~> 2.5, >= 2.5.4)
19
- rails-dom-testing (~> 1.0, >= 1.0.5)
20
- actionpack (4.2.4)
21
- actionview (= 4.2.4)
22
- activesupport (= 4.2.4)
23
- rack (~> 1.6)
24
- rack-test (~> 0.6.2)
25
- rails-dom-testing (~> 1.0, >= 1.0.5)
26
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
27
- actionview (4.2.4)
28
- activesupport (= 4.2.4)
29
- builder (~> 3.1)
30
- erubis (~> 2.7.0)
31
- rails-dom-testing (~> 1.0, >= 1.0.5)
32
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
33
- activejob (4.2.4)
34
- activesupport (= 4.2.4)
35
- globalid (>= 0.3.0)
36
- activemodel (4.2.4)
37
- activesupport (= 4.2.4)
38
- builder (~> 3.1)
39
- activerecord (4.2.4)
40
- activemodel (= 4.2.4)
41
- activesupport (= 4.2.4)
42
- arel (~> 6.0)
43
- activesupport (4.2.4)
44
- i18n (~> 0.7)
45
- json (~> 1.7, >= 1.7.7)
46
- minitest (~> 5.1)
47
- thread_safe (~> 0.3, >= 0.3.4)
48
- tzinfo (~> 1.1)
49
- after_transaction_commit (1.0.1)
50
- activerecord (>= 3.2)
51
- arel (6.0.3)
52
- backports (3.6.6)
53
- builder (3.2.2)
54
- bump (0.5.2)
55
- coderay (1.1.0)
56
- database_cleaner (1.3.0)
57
- diff-lcs (1.2.5)
58
- erubis (2.7.0)
59
- globalid (0.3.6)
60
- activesupport (>= 4.1.0)
61
- i18n (0.7.0)
62
- json (1.8.3)
63
- loofah (2.0.3)
64
- nokogiri (>= 1.5.9)
65
- mail (2.6.3)
66
- mime-types (>= 1.16, < 3)
67
- method_source (0.8.2)
68
- mime-types (2.6.2)
69
- mini_portile (0.6.2)
70
- minitest (5.8.1)
71
- multi_json (1.11.2)
72
- nokogiri (1.6.6.2)
73
- mini_portile (~> 0.6.0)
74
- pg (0.18.3)
75
- pry (0.10.3)
76
- coderay (~> 1.1.0)
77
- method_source (~> 0.8.1)
78
- slop (~> 3.4)
79
- rack (1.6.4)
80
- rack-protection (1.5.3)
81
- rack
82
- rack-test (0.6.3)
83
- rack (>= 1.0)
84
- rails (4.2.4)
85
- actionmailer (= 4.2.4)
86
- actionpack (= 4.2.4)
87
- actionview (= 4.2.4)
88
- activejob (= 4.2.4)
89
- activemodel (= 4.2.4)
90
- activerecord (= 4.2.4)
91
- activesupport (= 4.2.4)
92
- bundler (>= 1.3.0, < 2.0)
93
- railties (= 4.2.4)
94
- sprockets-rails
95
- rails-deprecated_sanitizer (1.0.3)
96
- activesupport (>= 4.2.0.alpha)
97
- rails-dom-testing (1.0.7)
98
- activesupport (>= 4.2.0.beta, < 5.0)
99
- nokogiri (~> 1.6.0)
100
- rails-deprecated_sanitizer (>= 1.0.1)
101
- rails-html-sanitizer (1.0.2)
102
- loofah (~> 2.0)
103
- railties (4.2.4)
104
- actionpack (= 4.2.4)
105
- activesupport (= 4.2.4)
106
- rake (>= 0.8.7)
107
- thor (>= 0.18.1, < 2.0)
108
- rake (10.4.2)
109
- redis (3.2.1)
110
- redis-scripting (1.0.1)
111
- redis (>= 3.0)
112
- rspec (3.1.0)
113
- rspec-core (~> 3.1.0)
114
- rspec-expectations (~> 3.1.0)
115
- rspec-mocks (~> 3.1.0)
116
- rspec-core (3.1.7)
117
- rspec-support (~> 3.1.0)
118
- rspec-expectations (3.1.2)
119
- diff-lcs (>= 1.2.0, < 2.0)
120
- rspec-support (~> 3.1.0)
121
- rspec-mocks (3.1.3)
122
- rspec-support (~> 3.1.0)
123
- rspec-support (3.1.2)
124
- rufus-scheduler (3.1.7)
125
- sinatra (1.4.6)
126
- rack (~> 1.4)
127
- rack-protection (~> 1.4)
128
- tilt (>= 1.3, < 3)
129
- sinatra-contrib (1.4.6)
130
- backports (>= 2.0)
131
- multi_json
132
- rack-protection
133
- rack-test
134
- sinatra (~> 1.4.0)
135
- tilt (>= 1.3, < 3)
136
- slop (3.6.0)
137
- sprockets (3.4.0)
138
- rack (> 1, < 3)
139
- sprockets-rails (2.3.3)
140
- actionpack (>= 3.0)
141
- activesupport (>= 3.0)
142
- sprockets (>= 2.8, < 4.0)
143
- syck (1.0.5)
144
- test_after_commit (0.4.1)
145
- activerecord (>= 3.2)
146
- thor (0.19.1)
147
- thread_safe (0.3.5)
148
- tilt (2.0.1)
149
- timecop (0.7.1)
150
- tzinfo (1.2.2)
151
- thread_safe (~> 0.1)
152
- wwtd (1.1.1)
153
-
154
- PLATFORMS
155
- ruby
156
-
157
- DEPENDENCIES
158
- bump
159
- canvas-jobs!
160
- database_cleaner (= 1.3.0)
161
- pg
162
- pry
163
- rack-test
164
- rails (~> 4.2.0.beta2)
165
- rake
166
- rspec (= 3.1.0)
167
- sinatra
168
- sinatra-contrib
169
- syck (>= 1.0.4)
170
- test_after_commit (= 0.4.1)
171
- timecop (= 0.7.1)
172
- wwtd (~> 1.1.1)