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