disquo 0.3.0 → 0.3.1
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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/disquo.gemspec +1 -1
- data/lib/disquo/worker.rb +62 -43
- data/spec/disquo/worker_spec.rb +4 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4a5a02702349eb8b6c55ccda7678d0ec5374f9d
|
4
|
+
data.tar.gz: 2793c75864c561a6d96833c7a171c687b0bda854
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd458037bec4658dd490234ca46ab75f82f3f74e40deb1e6a65d95eea6e3ddf49d3a7f0770885389830be92fed26124e3a66422fad584382fc21ec33ee9f0618
|
7
|
+
data.tar.gz: e0575ada72338c810ee9186104f75b1478d8518f7a91bd5e5ed2218282c1d5c52ea99988b69c8c0550197cbf04d5e2d89919d1a6a7175d21e261f5733572b707
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/
|
data/Gemfile.lock
CHANGED
data/disquo.gemspec
CHANGED
data/lib/disquo/worker.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'disquo'
|
2
|
-
require 'concurrent'
|
3
2
|
require 'concurrent/executor/fixed_thread_pool'
|
3
|
+
require 'concurrent/atomic/atomic_fixnum'
|
4
4
|
|
5
5
|
class Disquo::Worker
|
6
6
|
attr_reader :disque, :queues, :wait_time, :wait_count
|
@@ -10,19 +10,18 @@ class Disquo::Worker
|
|
10
10
|
# @param [Hash] options
|
11
11
|
# @option [Array<String>] :queues queues to watch. Default: ["default"]
|
12
12
|
# @option [Integer] :concurrency the number of concurrent threads. Default: 10
|
13
|
-
# @option [Numeric] :wait_time maximum time (in seconds) to
|
14
|
-
|
15
|
-
def initialize(disque, queues: [Disquo::DEFAULT_QUEUE], concurrency: 10, wait_time: 1, wait_count: 100)
|
13
|
+
# @option [Numeric] :wait_time maximum time (in seconds) to wait for jobs when retrieving next batch. Default: 1s
|
14
|
+
def initialize(disque, queues: [Disquo::DEFAULT_QUEUE], concurrency: 10, wait_time: 1)
|
16
15
|
@disque = disque
|
17
16
|
@queues = Array(queues)
|
18
17
|
@threads = Concurrent::FixedThreadPool.new(concurrency)
|
18
|
+
@busy = Concurrent::AtomicFixnum.new
|
19
19
|
@wait_time = wait_time
|
20
|
-
@wait_count = wait_count
|
21
20
|
end
|
22
21
|
|
23
22
|
# Run starts the worker
|
24
23
|
def run
|
25
|
-
Disquo.logger.info "
|
24
|
+
Disquo.logger.info "Worker starting - queues: #{queues.inspect}, concurrency: #{@threads.max_length}"
|
26
25
|
|
27
26
|
begin
|
28
27
|
run_cycle
|
@@ -30,14 +29,14 @@ class Disquo::Worker
|
|
30
29
|
handle_exception(e)
|
31
30
|
end until @stopped
|
32
31
|
|
32
|
+
Disquo.logger.info "Worker shutting down"
|
33
33
|
@threads.shutdown
|
34
34
|
end
|
35
35
|
|
36
36
|
# Blocks until worker is stopped
|
37
37
|
def wait(timeout = nil)
|
38
|
-
Disquo.logger.info "Waiting for worker shutdown"
|
39
38
|
@threads.wait_for_termination(timeout)
|
40
|
-
Disquo.logger.info "
|
39
|
+
Disquo.logger.info "Worker shutdown complete"
|
41
40
|
end
|
42
41
|
|
43
42
|
# Stops the worker
|
@@ -50,57 +49,69 @@ class Disquo::Worker
|
|
50
49
|
private
|
51
50
|
|
52
51
|
def run_cycle
|
53
|
-
jobs = next_batch
|
54
|
-
|
52
|
+
jobs = Array(next_batch)
|
55
53
|
until @stopped || jobs.empty?
|
56
54
|
job = jobs.shift
|
57
|
-
|
55
|
+
schedule(*job)
|
58
56
|
end
|
59
57
|
ensure
|
60
58
|
requeue(jobs) unless jobs.nil? || jobs.empty?
|
61
59
|
end
|
62
60
|
|
63
61
|
def next_batch
|
62
|
+
count = @threads.max_length - @busy.value
|
63
|
+
if count < 1
|
64
|
+
sleep(wait_time.fdiv(2))
|
65
|
+
return
|
66
|
+
end
|
67
|
+
|
64
68
|
jobs = disque.with do |cn|
|
65
|
-
cn.fetch from: queues, timeout: (wait_time*1000).to_i, count:
|
69
|
+
cn.fetch from: queues, timeout: (wait_time*1000).to_i, count: count
|
66
70
|
end
|
71
|
+
|
67
72
|
@is_down = nil
|
68
|
-
|
69
|
-
rescue => e
|
70
|
-
|
71
|
-
|
72
|
-
handle_exception(e, message: 'Error retrieving jobs:')
|
73
|
-
end
|
74
|
-
sleep(1)
|
75
|
-
[]
|
73
|
+
jobs
|
74
|
+
rescue Errno::ECONNREFUSED => e
|
75
|
+
handle_disque_exception e, message: "Failed to retrieve jobs:", notrace: true
|
76
|
+
nil
|
76
77
|
end
|
77
78
|
|
78
|
-
def
|
79
|
+
def schedule(queue, job_id, payload)
|
80
|
+
@busy.increment
|
79
81
|
@threads.post do
|
80
|
-
thread_id = Thread.current.object_id.to_s(36)
|
81
|
-
Disquo.logger.info { "Process #{payload} - thread: #{thread_id}, job: #{job_id}" }
|
82
|
-
|
83
82
|
begin
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
job.disque = disque
|
88
|
-
job.queue = queue
|
89
|
-
job.job_id = job_id
|
90
|
-
job.perform(*args)
|
91
|
-
rescue => e
|
92
|
-
handle_exception e, message: "Error processing #{payload} - thread: #{thread_id}, job: #{job_id}:"
|
93
|
-
|
94
|
-
disque.with {|cn| cn.call :nack, job_id }
|
95
|
-
return
|
83
|
+
perform(queue, job_id, payload)
|
84
|
+
ensure
|
85
|
+
@busy.decrement
|
96
86
|
end
|
87
|
+
end
|
88
|
+
end
|
97
89
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
90
|
+
def perform(queue, job_id, payload)
|
91
|
+
thread_id = Thread.current.object_id.to_s(36)
|
92
|
+
Disquo.logger.info { "Process #{payload} - thread: #{thread_id}, job: #{job_id}" }
|
93
|
+
|
94
|
+
begin
|
95
|
+
class_name, args = Disquo.load_job(payload)
|
96
|
+
|
97
|
+
job = Object.const_get(class_name).new
|
98
|
+
job.disque = disque
|
99
|
+
job.queue = queue
|
100
|
+
job.job_id = job_id
|
101
|
+
job.perform(*args)
|
102
|
+
rescue => e
|
103
|
+
handle_exception e, message: "Error processing #{payload} - thread: #{thread_id}, job: #{job_id}:"
|
104
|
+
|
105
|
+
disque.with {|cn| cn.call :nack, job_id }
|
106
|
+
return
|
107
|
+
end
|
108
|
+
|
109
|
+
begin
|
110
|
+
disque.with {|cn| cn.call :ackjob, job_id }
|
111
|
+
@is_down = nil
|
112
|
+
rescue Errno::ECONNREFUSED => e
|
113
|
+
handle_disque_exception e, message: "Failed to ACK job #{job_id}:", notrace: true
|
114
|
+
retry unless @stopped
|
104
115
|
end
|
105
116
|
end
|
106
117
|
|
@@ -109,11 +120,19 @@ class Disquo::Worker
|
|
109
120
|
disque.with {|cn| cn.call :enqueue, *ids }
|
110
121
|
end
|
111
122
|
|
123
|
+
def handle_disque_exception(e, opts = {})
|
124
|
+
if !@is_down
|
125
|
+
@is_down = true
|
126
|
+
handle_exception(e, opts)
|
127
|
+
end
|
128
|
+
sleep(1)
|
129
|
+
end
|
130
|
+
|
112
131
|
def handle_exception(e, opts = {})
|
113
132
|
lines = [
|
114
133
|
opts[:message],
|
115
134
|
"#{e.class.name}: #{e.message}",
|
116
|
-
e.backtrace
|
135
|
+
(opts[:notrace] ? nil : e.backtrace),
|
117
136
|
].compact.flatten
|
118
137
|
|
119
138
|
Disquo.logger.error lines.join("\n")
|
data/spec/disquo/worker_spec.rb
CHANGED
@@ -3,11 +3,12 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Disquo::Worker do
|
4
4
|
|
5
5
|
subject do
|
6
|
-
described_class.new Disquo.connect, wait_time: 0.1,
|
6
|
+
described_class.new Disquo.connect, wait_time: 0.1, queues: Disquo::TEST::QUEUE
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should run/process/shutdown" do
|
10
10
|
runner = Thread.new { subject.run }
|
11
|
+
runner.abort_on_exception = true
|
11
12
|
|
12
13
|
# seed 200 jobs
|
13
14
|
200.times {|n| TestJob.enqueue(n) }
|
@@ -33,12 +34,13 @@ RSpec.describe Disquo::Worker do
|
|
33
34
|
queue: "__disquo_test__",
|
34
35
|
)
|
35
36
|
expect(Disquo::TEST::PERFORMED.last[:job_id]).to match(/^D\w+/)
|
37
|
+
expect(Disquo::TEST::PERFORMED.map {|e| e[:args].first }).to match_array(0..199)
|
36
38
|
end
|
37
39
|
|
38
40
|
def wait_for
|
39
41
|
20.times do
|
40
42
|
break if yield
|
41
|
-
sleep(0.
|
43
|
+
sleep(0.1)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: disquo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitrij Denissenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: disque
|
@@ -87,6 +87,7 @@ executables:
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
+
- ".gitignore"
|
90
91
|
- ".travis.yml"
|
91
92
|
- Gemfile
|
92
93
|
- Gemfile.lock
|