Module: Specwrk::CLI::WorkerProcesses

Included in:
Watch, Workable
Defined in:
lib/specwrk/cli.rb

Constant Summary collapse

WORKER_INIT_SCRIPT =
<<~RUBY
  writer = IO.for_fd(Integer(ENV.fetch("SPECWRK_FINAL_FD")))
  $final_output = writer # standard:disable Style/GlobalVars
  $final_output.sync = true # standard:disable Style/GlobalVars
  $stdout.sync = true
  $stderr.sync = true

  require "specwrk/worker"

  trap("INT") do
    RSpec.world.wants_to_quit = true if defined?(RSpec)
    exit(1) if Specwrk.force_quit
    Specwrk.force_quit = true
  end

  status = Specwrk::Worker.run!
  $final_output.close # standard:disable Style/GlobalVars
  exit(status)
RUBY

Instance Method Summary collapse

Instance Method Details

#drain_outputsObject



57
58
59
60
61
62
# File 'lib/specwrk/cli.rb', line 57

def drain_outputs
  @final_outputs.each do |reader|
    reader.each_line { |line| $stdout.print line }
    reader.close
  end
end

#start_workersObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/specwrk/cli.rb', line 38

def start_workers
  @final_outputs = []
  @worker_pids = worker_count.times.map do |i|
    reader, writer = IO.pipe
    @final_outputs << reader

    env = worker_env_for(i + 1).merge(
      "SPECWRK_FINAL_FD" => writer.fileno.to_s
    )

    Process.spawn(
      env, RbConfig.ruby, "-e", WORKER_INIT_SCRIPT,
      writer.fileno => writer,
      :in => :close,
      :close_others => false
    ).tap { writer.close }
  end
end

#worker_countObject



64
65
66
# File 'lib/specwrk/cli.rb', line 64

def worker_count
  @worker_count ||= [1, ENV["SPECWRK_COUNT"].to_i].max
end

#worker_env_for(idx) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/specwrk/cli.rb', line 68

def worker_env_for(idx)
  {
    "TEST_ENV_NUMBER" => idx.to_s,
    "SPECWRK_FORKED" => idx.to_s,
    "SPECWRK_ID" => "#{ENV.fetch("SPECWRK_ID", "specwrk-worker")}-#{idx}"
  }
end