talentbox-delayed_job_sequel 4.2.1 → 4.2.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: 4302cd23662982c235f239ad688b7e625590bef5
4
- data.tar.gz: 216726ccad71885a93664e0478d2f2719d0ae4f0
3
+ metadata.gz: b1852e994414af80378eb9b6dc43f5d0896f5efc
4
+ data.tar.gz: 5dea3af8a408fdaae2999522b58c39b2be0d59a8
5
5
  SHA512:
6
- metadata.gz: f124eca09c6ed6276f61c89223cda8509fff8d39019b52b1faca646bd1469c4d649282e4de261f530c17f77e515dfbd37e1a48c70d425c30db2675d584f5490a
7
- data.tar.gz: 24862b85887f74e7235ae1675f284ea69343840e2634204222c84eba8d9b4d82d677226485cc0eff388ee5b3ec53c8fd67c19689fd642015edf89a10d5caee26
6
+ metadata.gz: 1d4ece1d72b8cd5325918caa63a71cb06e69ace258c8a1da3ac04a06ba93833fd6748ea156cbe7f944f600aa602afd19d00b1d527821950369ec004f3d010feb
7
+ data.tar.gz: 728f1b030ff5a21aece61a2da07edb9ca1502301381f5c03465680c33f5fdd30ffdd354ac5b18d902ff02658c5d7a34b4cd17606460de343923d9ad63acb2f9d
data/README.md CHANGED
@@ -51,6 +51,7 @@ Improvements has been made by those awesome contributors:
51
51
  * Phan Le
52
52
  * Tim Labeeuw
53
53
  * James Goodhouse (@jamesgoodhouse)
54
+ * Lyle Franklin (@ljfranklin)
54
55
 
55
56
  ## How to contribute
56
57
 
@@ -44,14 +44,28 @@ module Delayed
44
44
  filter(:locked_by => worker_name).update(:locked_by => nil, :locked_at => nil)
45
45
  end
46
46
 
47
+ # adapted from
48
+ # https://github.com/collectiveidea/delayed_job_active_record/blob/master/lib/delayed/backend/active_record.rb
47
49
  def self.reserve(worker, max_run_time = Worker.max_run_time)
48
50
  ds = ready_to_run(worker.name, max_run_time)
51
+
49
52
  ds = ds.filter(::Sequel.lit("priority >= ?", Worker.min_priority)) if Worker.min_priority
50
53
  ds = ds.filter(::Sequel.lit("priority <= ?", Worker.max_priority)) if Worker.max_priority
51
54
  ds = ds.filter(:queue => Worker.queues) if Worker.queues.any?
52
55
  ds = ds.by_priority
53
- ds = ds.for_update
54
56
 
57
+ case ::Sequel::Model.db.database_type
58
+ when :mysql
59
+ lock_with_read_ahead(ds, worker)
60
+ else
61
+ lock_with_for_update(ds, worker)
62
+ end
63
+ end
64
+
65
+ # Lock a single job using SELECT ... FOR UPDATE.
66
+ # More performant but may cause deadlocks in some databases.
67
+ def self.lock_with_for_update(ds, worker)
68
+ ds = ds.for_update
55
69
  db.transaction do
56
70
  if job = ds.first
57
71
  job.locked_at = self.db_time_now
@@ -62,6 +76,15 @@ module Delayed
62
76
  end
63
77
  end
64
78
 
79
+ # Fetch up-to `worker.read_ahead` jobs, try to lock one at a time.
80
+ # This query is more conservative as it does not acquire any DB read locks.
81
+ def self.lock_with_read_ahead(ds, worker)
82
+ ds.limit(worker.read_ahead).detect do |job|
83
+ count = ds.where(id: job.id).update(locked_at: self.db_time_now, locked_by: worker.name)
84
+ count == 1 && job.reload
85
+ end
86
+ end
87
+
65
88
  # Get the current time (GMT or local depending on DB)
66
89
  # Note: This does not ping the DB to get the time, so all your clients
67
90
  # must have syncronized clocks.
@@ -14,20 +14,33 @@ describe Delayed::Backend::Sequel::Job do
14
14
 
15
15
  it "does not allow more than 1 worker to grab the same job" do
16
16
  expect do
17
- 10.times do
17
+ jobs_to_run = 200
18
+ workers_to_run = 20
19
+ jobs_per_worker = jobs_to_run/workers_to_run
20
+
21
+ jobs_to_run.times do
18
22
  described_class.create(payload_object: SimpleJob.new)
19
23
  end
20
24
 
21
- 20.times.map do |i|
25
+ workers_to_run.times.map do |i|
22
26
  Thread.new do
23
27
  worker = Delayed::Worker.new
24
28
  worker.name = "worker_#{i}"
25
- worker.work_off(4)
29
+
30
+ # Ensure each worker performs the expected number of jobs as
31
+ # `work_off` will ocassionally perform less than the requested number
32
+ # if it is unable to lock a job within the `worker.read_ahead` limit
33
+ jobs_completed_by_this_worker = 0
34
+ while jobs_completed_by_this_worker < jobs_per_worker do
35
+ successes, failures = worker.work_off(jobs_per_worker - jobs_completed_by_this_worker)
36
+ expect(failures).to eq(0), "Expected zero failures, got #{failures}"
37
+ jobs_completed_by_this_worker += successes
38
+ end
26
39
  end
27
40
  end.map(&:join)
28
41
  end.not_to raise_error
29
42
 
30
- expect(Delayed::Job.count).to be < 10
43
+ expect(Delayed::Job.count).to eql 0
31
44
  end
32
45
 
33
46
  context ".count" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: talentbox-delayed_job_sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.1
4
+ version: 4.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Tron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-19 00:00:00.000000000 Z
11
+ date: 2017-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  version: '0'
128
128
  requirements: []
129
129
  rubyforge_project:
130
- rubygems_version: 2.5.1
130
+ rubygems_version: 2.5.2
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Sequel backend for DelayedJob