class RSpec::Core::Bisect::ForkRunner

@private
a ‘before(:suite)` hook, or use the slower `ShellRunner`.
problems. The solution is for users to move the bootstrapping logic into
`RunDispatcher` boots the application environment. This might cause
but for `ForkRunner`, such logic will only get run once, when the
bootstrapping logic will happen for each run of any subset of the suite,
Redis bootstrapping to happen on every spec run. With `ShellRunner`, the
in `spec_helper` to boot a Redis server for the test suite, intending the
hook. For example, consider a project that relies on some top-level logic
level in a file loaded by `–require`, rather than in a `before(:suite)`
bootstrapping logic that should run on every spec run directly at the top
it can cause problems for some projects that put side-effectful spec
that do not support forking (e.g. Windows), it cannot be used. In addition,
However, not all projects can use `ForkRunner`. Obviously, on platforms
a subset. In contrast, `ForkRunner` pays that cost only once.
pays the cost of booting RSpec and the app environment on every run of
`ShellRunner` will finish significantly faster, because the `ShellRunner`
For most projects, bisections that use `ForkRunner` instead of
not loaded in the main process.
spec run happens in a forked process, ensuring that the spec files are
that the individual spec runs do not have to re-pay that cost. Each
environment (including preloading files specified via `–require`) so
sub-processes. The main process bootstraps RSpec and the application
A Bisect runner that runs requested subsets of the suite by forking

def self.name

def self.name
  :fork
end

def self.start(shell_command, spec_runner)

def self.start(shell_command, spec_runner)
  instance = new(shell_command, spec_runner)
  yield instance
ensure
  instance.shutdown
end

def dispatch_run(run_descriptor)

def dispatch_run(run_descriptor)
  @run_dispatcher.dispatch_specs(run_descriptor)
  @channel.receive.tap do |result|
    if result.is_a?(String)
      raise BisectFailedError.for_failed_spec_run(result)
    end
  end
end

def initialize(shell_command, spec_runner)

def initialize(shell_command, spec_runner)
  @shell_command = shell_command
  @channel = Channel.new
  @run_dispatcher = RunDispatcher.new(spec_runner, @channel)
end

def original_results

def original_results
  @original_results ||= dispatch_run(ExampleSetDescriptor.new(
    @shell_command.original_locations, []))
end

def run(locations)

def run(locations)
  run_descriptor = ExampleSetDescriptor.new(locations, original_results.failed_example_ids)
  dispatch_run(run_descriptor)
end

def shutdown

def shutdown
  @channel.close
end