Class: RSpec::MultiprocessRunner::Worker
- Inherits:
-
Object
- Object
- RSpec::MultiprocessRunner::Worker
- Defined in:
- lib/rspec/multiprocess_runner/worker.rb
Overview
This object has several roles:
-
It forks the worker process
-
In the coordinator process, it is used to send messages to the worker and track the worker’s status, completed specs, and example results.
-
In the worker process, it is used to send messages to the coordinator and actually run specs.
Constant Summary collapse
- COMMAND_QUIT =
"quit"
- COMMAND_RUN_FILE =
"run_file"
- STATUS_EXAMPLE_COMPLETE =
"example_complete"
- STATUS_RUN_COMPLETE =
"run_complete"
- ERROR_RUNNING =
"error_running"
Instance Attribute Summary collapse
-
#current_file ⇒ Object
readonly
Returns the value of attribute current_file.
-
#deactivation_reason ⇒ Object
Returns the value of attribute deactivation_reason.
-
#environment_number ⇒ Object
readonly
Returns the value of attribute environment_number.
-
#example_results ⇒ Object
readonly
Returns the value of attribute example_results.
-
#options ⇒ Object
Returns the value of attribute options.
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Workers can be found in the coordinator process by their coordinator socket.
-
#initialize(environment_number, options) ⇒ Worker
constructor
A new instance of Worker.
- #kill_now ⇒ Object
- #quit_when_idle_and_wait_for_quit ⇒ Object
- #reap ⇒ Object
- #receive_and_act_on_message_from_worker ⇒ Object
- #report_error(message) ⇒ Object
- #report_example_result(example_status, description, line_number, details) ⇒ Object
- #run_file(filename) ⇒ Object
- #shutdown_now ⇒ Object
- #socket ⇒ Object
- #stalled? ⇒ Boolean
-
#start ⇒ Object
Forks the worker process.
- #test_env_number ⇒ Object
- #to_json(options = nil) ⇒ Object
- #working? ⇒ Boolean
Constructor Details
#initialize(environment_number, options) ⇒ Worker
Returns a new instance of Worker.
34 35 36 37 38 39 40 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 34 def initialize(environment_number, ) @environment_number = environment_number @worker_socket, @coordinator_socket = Socket.pair(:UNIX, :STREAM) @rspec_arguments = (. || []) + ["--format", ReportingFormatter.to_s] self. = @example_results = [] end |
Instance Attribute Details
#current_file ⇒ Object (readonly)
Returns the value of attribute current_file.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def current_file @current_file end |
#deactivation_reason ⇒ Object
Returns the value of attribute deactivation_reason.
25 26 27 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 25 def deactivation_reason @deactivation_reason end |
#environment_number ⇒ Object (readonly)
Returns the value of attribute environment_number.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def environment_number @environment_number end |
#example_results ⇒ Object (readonly)
Returns the value of attribute example_results.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def example_results @example_results end |
#options ⇒ Object
Returns the value of attribute options.
25 26 27 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 25 def @options end |
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def pid @pid end |
Instance Method Details
#==(other) ⇒ Object
Workers can be found in the coordinator process by their coordinator socket.
44 45 46 47 48 49 50 51 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 44 def ==(other) case other when Socket other == @coordinator_socket else super end end |
#kill_now ⇒ Object
136 137 138 139 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 136 def kill_now Process.kill(:KILL, pid) Process.detach(pid) end |
#quit_when_idle_and_wait_for_quit ⇒ Object
105 106 107 108 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 105 def quit_when_idle_and_wait_for_quit (command: COMMAND_QUIT) Process.wait(self.pid) end |
#reap ⇒ Object
141 142 143 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 141 def reap terminate_then_kill(3, "Reaping troubled process #{environment_number} (#{pid}; #{@current_file})") end |
#receive_and_act_on_message_from_worker ⇒ Object
145 146 147 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 145 def () end |
#report_error(message) ⇒ Object
231 232 233 234 235 236 237 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 231 def report_error() ( status: ERROR_RUNNING, message: , filename: @current_file, ) end |
#report_example_result(example_status, description, line_number, details) ⇒ Object
220 221 222 223 224 225 226 227 228 229 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 220 def report_example_result(example_status, description, line_number, details) ( status: STATUS_EXAMPLE_COMPLETE, example_status: example_status, description: description, line_number: line_number, details: details, filename: @current_file, ) end |
#run_file(filename) ⇒ Object
110 111 112 113 114 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 110 def run_file(filename) (command: COMMAND_RUN_FILE, filename: filename) @current_file = filename @current_file_started_at = @current_example_started_at = Time.now end |
#shutdown_now ⇒ Object
132 133 134 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 132 def shutdown_now terminate_then_kill(5) end |
#socket ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 91 def socket if self.pid == Process.pid @worker_socket else @coordinator_socket end end |
#stalled? ⇒ Boolean
120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 120 def stalled? file_stalled = if .file_timeout_seconds working? && (Time.now - @current_file_started_at > .file_timeout_seconds) end example_stalled = if .example_timeout_seconds working? && (Time.now - @current_example_started_at > .example_timeout_seconds) end file_stalled || example_stalled end |
#start ⇒ Object
Forks the worker process. In the parent, returns the PID.
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 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 63 def start pid = fork if pid @worker_socket.close @pid = pid else @coordinator_socket.close @pid = Process.pid ENV["TEST_ENV_NUMBER"] = test_env_number # reset TERM handler so that # - the coordinator's version (if any) is not executed twice # - it actually terminates the process, instead of doing the ruby # default (throw an exception, which gets caught by RSpec) Kernel.trap("TERM", "SYSTEM_DEFAULT") # rely on the coordinator to handle INT Kernel.trap("INT", "IGNORE") # prevent RSpec from trapping INT, also ::RSpec::Core::Runner.instance_eval { def self.trap_interrupt; end } # Disable RSpec's at_exit hook that would try to run whatever is in ARGV ::RSpec::Core::Runner.disable_autorun! set_process_name run_loop end end |
#test_env_number ⇒ Object
53 54 55 56 57 58 59 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 53 def test_env_number if environment_number == 1 && !.first_is_1 "" else environment_number.to_s end end |
#to_json(options = nil) ⇒ Object
149 150 151 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 149 def to_json( = nil) { "pid" => @pid, "environment_number" => @environment_number, "current_file" => @current_file, "deactivation_reason" => @deactivation_reason }.to_json end |
#working? ⇒ Boolean
116 117 118 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 116 def working? @current_file end |