text: module Lowkiq
    class Server
      def self.build(options)
        require options[:require]
        Lowkiq.on_server_init.call
  
        splitter = Lowkiq.build_splitter.call
        shard_handlers_by_thread = splitter.call Lowkiq.shard_handlers
        scheduler = Lowkiq.build_scheduler.call
        new shard_handlers_by_thread, scheduler
      end
  
      def initialize(shard_handlers_by_thread, scheduler)
        @shard_handlers_by_thread = shard_handlers_by_thread
        @scheduler = scheduler
        @threads = []
      end
  
      def start
        Lowkiq.server_redis_pool.with do |redis|
          Script.load! redis
        end
  
        @shard_handlers_by_thread.each do |handlers|
          handlers.each(&:restore)
        end
  
        @threads = @shard_handlers_by_thread.map do |handlers|
          job = @scheduler.build_job handlers
          Thread.new do
            job.call until exit_from_thread?
          end
        end
      end
  
      def stop
        @stopped = true
      end
  
      def join
        @threads.each(&:join)
      end
  
      def exit_from_thread?
        stopped? || failed?
      end
  
      def stopped?
        @stopped
      end
  
      def failed?
        @threads.map(&:status).any? do |status|
          status != "run" && status != "sleep"
        end
      end
    end
  end
  