/
worker.rb
100 lines (81 loc) · 2.4 KB
/
worker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# frozen_string_literal: true
module ActiveSupport
module Testing
class Parallelization # :nodoc:
class Worker
def initialize(number, url)
@id = SecureRandom.uuid
@number = number
@url = url
@setup_exception = nil
end
def start
fork do
set_process_title("(starting)")
DRb.stop_service
@queue = DRbObject.new_with_uri(@url)
@queue.start_worker(@id)
begin
after_fork
rescue => @setup_exception; end
work_from_queue
ensure
set_process_title("(stopping)")
run_cleanup
@queue.stop_worker(@id)
end
end
def work_from_queue
while job = @queue.pop
perform_job(job)
end
end
def perform_job(job)
klass = job[0]
method = job[1]
reporter = job[2]
set_process_title("#{klass}##{method}")
result = klass.with_info_handler reporter do
Minitest.run_one_method(klass, method)
end
safe_record(reporter, result)
end
def safe_record(reporter, result)
add_setup_exception(result) if @setup_exception
begin
@queue.record(reporter, result)
rescue DRb::DRbConnError
result.failures.map! do |failure|
if failure.respond_to?(:error)
# minitest >5.14.0
error = DRb::DRbRemoteError.new(failure.error)
else
error = DRb::DRbRemoteError.new(failure.exception)
end
Minitest::UnexpectedError.new(error)
end
@queue.record(reporter, result)
end
set_process_title("(idle)")
end
def after_fork
Parallelization.after_fork_hooks.each do |cb|
cb.call(@number)
end
end
def run_cleanup
Parallelization.run_cleanup_hooks.each do |cb|
cb.call(@number)
end
end
private
def add_setup_exception(result)
result.failures.prepend Minitest::UnexpectedError.new(@setup_exception)
end
def set_process_title(status)
Process.setproctitle("Rails test worker #{@number} - #{status}")
end
end
end
end
end