def start(host, port, threads: Concurrent.processor_count)
      raise 'Block is required for the farm to start' unless block_given?
      @log.info('Zero-threads farm won\'t score anything!') if threads.zero?
      if best.empty?
        @log.info("No scores found in the cache at #{@cache}")
      else
        @log.info("#{best.size} scores pre-loaded from #{@cache}, the best is: #{best[0]}")
      end
      (1..threads).map do |t|
        @threads.add do
          Thread.current.thread_variable_set(:tid, t.to_s)
          Endless.new("f#{t}", log: @log).run do
            cycle(host, port, threads)
          end
        end
      end
      unless threads.zero?
        ready = false
        @threads.add do
          Endless.new('cleanup', log: @log).run do
            cleanup(host, port, threads)
            ready = true
            sleep(1)
          end
        end
        loop { break if ready }
      end
      if threads.zero?
        cleanup(host, port, threads)
        @log.info("Farm started with no threads (there will be no score) at #{host}:#{port}")
      else
        @log.info("Farm started with #{@threads.count} threads (one for cleanup) \
at #{host}:#{port}, strength is #{@strength}")
      end
      begin
        yield(self)
      ensure
        @threads.kill
      end
    end
def start(host, port, threads: Concurrent.processor_count)
      raise 'Block is required for the farm to start' unless block_given?
      @log.info('Zero-threads farm won\'t score anything!') if threads.zero?
      if best.empty?
        @log.info("No scores found in the cache at #{@cache}")
      else
        @log.info("#{best.size} scores pre-loaded from #{@cache}, the best is: #{best[0]}")
      end
      (1..threads).map do |t|
        @threads.add do
          Thread.current.thread_variable_set(:tid, t.to_s)
          Endless.new("f#{t}", log: @log).run do
            cycle(host, port, threads)
          end
        end
      end
      unless threads.zero?
        ready = false
        @threads.add do
          Endless.new('cleanup', log: @log).run do
            cleanup(host, port, threads)
            ready = true
            sleep(1)
          end
        end
        loop { break if ready }
      end
      if threads.zero?
        cleanup(host, port, threads)
        @log.info("Farm started with no threads (there will be no score) at #{host}:#{port}")
      else
        @log.info("Farm started with #{@threads.count} threads (one for cleanup) \
at #{host}:#{port}, strength is #{@strength}")
      end
      begin
        yield(self)
      ensure
        @threads.kill
      end
    end
Starts a farm, all threads, and yields the block provided. You are
 supposed to use it only with the block:

  Farm.new.start('example.org', 4096) do |farm|
    score = farm.best[0]
    # Everything else...
  end

 The farm will stop all its threads and close all resources safely
 right after the block provided exists.