class TurboTests::Runner

def start_subprocess(env, extra_args, tests, process_id, record_runtime:)

def start_subprocess(env, extra_args, tests, process_id, record_runtime:)
  if tests.empty?
    @messages << {
      type: "exit",
      process_id: process_id
    }
  else
    tmp_filename = "tmp/test-pipes/subprocess-#{process_id}"
    begin
      File.mkfifo(tmp_filename)
    rescue Errno::EEXIST
    end
    env["RUBYOPT"] = ["-I#{File.expand_path("..", __dir__)}", ENV["RUBYOPT"]].compact.join(" ")
    env["RSPEC_SILENCE_FILTER_ANNOUNCEMENTS"] = "1"
    record_runtime_options =
      if record_runtime
        [
          "--format", "ParallelTests::RSpec::RuntimeLogger",
          "--out", @runtime_log,
        ]
      else
        []
      end
    command = [
      ENV["BUNDLE_BIN_PATH"], "exec", "rspec",
      *extra_args,
      "--seed", rand(0xFFFF).to_s,
      "--format", "TurboTests::JsonRowsFormatter",
      "--out", tmp_filename,
      *record_runtime_options,
      *tests
    ]
    if @verbose
      command_str = [
        env.map { |k, v| "#{k}=#{v}" }.join(" "),
        command.join(" ")
      ].select { |x| x.size > 0 }.join(" ")
      STDERR.puts "Process #{process_id}: #{command_str}"
    end
    stdin, stdout, stderr, wait_thr = Open3.popen3(env, *command)
    stdin.close
    @threads <<
      Thread.new do
        File.open(tmp_filename) do |fd|
          fd.each_line do |line|
            message = JSON.parse(line, symbolize_names: true)
            message[:process_id] = process_id
            @messages << message
          end
        end
        @messages << {type: "exit", process_id: process_id}
      end
    @threads << start_copy_thread(stdout, STDOUT)
    @threads << start_copy_thread(stderr, STDERR)
    @threads << Thread.new {
      unless wait_thr.value.success?
        @messages << {type: "error"}
      end
    }
    wait_thr
  end
end