code: 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
docs: 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.