class Bootsnap::CLI::WorkerPool

def create(size:, jobs:)

def create(size:, jobs:)
  if size > 0 && Process.respond_to?(:fork)
    new(size: size, jobs: jobs)
  else
    Inline.new(jobs: jobs)
  end
end

def dispatch_loop

def dispatch_loop
  loop do
    case job = @queue.pop
    when nil
      @workers.each do |worker|
        worker.write([:exit])
        worker.close
      end
      return true
    else
      unless @workers.sample.write(job, block: false)
        free_worker.write(job)
      end
    end
  end
end

def free_worker

def free_worker
  IO.select(nil, @workers)[1].sample
end

def initialize(size:, jobs: {})

def initialize(size:, jobs: {})
  @size = size
  @jobs = jobs
  @queue = Queue.new
  @pids = []
end

def push(*args)

def push(*args)
  @queue.push(args)
  nil
end

def shutdown

def shutdown
  @queue.close
  @dispatcher_thread.join
  @workers.each do |worker|
    _pid, status = Process.wait2(worker.pid)
    return status.exitstatus unless status.success?
  end
  nil
end

def spawn

def spawn
  @workers = @size.times.map { Worker.new(@jobs) }
  @workers.each(&:spawn)
  @dispatcher_thread = Thread.new { dispatch_loop }
  @dispatcher_thread.abort_on_exception = true
  true
end