canvas-jobs 0.9.16 → 0.10.0

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: 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)