def start_loop
      loop do
        begin
          # Loads up a job queue.
          queue = []
          
          # Counts jobs to schedule.
          running_jobs = @job_class.running.entries
          schedulable_jobs = @job_class.queued.order_by(scheduled_at: :asc).entries
          jobs_to_schedule = @max_concurrent_jobs - running_jobs.count
          jobs_to_schedule = 0 if jobs_to_schedule < 0
  
          # Finds out scheduled jobs waiting to be performed.
          scheduled_jobs = []
          schedulable_jobs.first(jobs_to_schedule).each do |job|
            job_pid = Process.fork do
              begin
                job.perform_now
              rescue StandardError => e
                @logger.error "[Scheduler:#{@pid}] Error #{e.class}: #{e.message} "\
                  "(#{e.backtrace.select { |l| l.include?('app') }.first}).".red
              end
            end
            Process.detach(job_pid)
            job.update_attribute(:pid, job_pid)
            scheduled_jobs << job
            queue << job.id.to_s
          end
  
          # Logs launched jobs
          if scheduled_jobs.any?
            @logger.info "[Scheduler:#{@pid}] Launched #{scheduled_jobs.count} "\
              "jobs: #{scheduled_jobs.map(&:id).map(&:to_s).join(', ')}.".cyan
          else
            if schedulable_jobs.count == 0
              @logger.info "[Scheduler:#{@pid}] No jobs in queue.".cyan
            else
              @logger.warn "[Scheduler:#{@pid}] No jobs launched, reached maximum "\
                "number of concurrent jobs. Jobs in queue: #{schedulable_jobs.count}.".yellow
            end
          end
  
          # Checks for completed jobs: clears up queue and kills any zombie pid
          queue.delete_if do |job_id|
            job = @job_class.find(job_id)
            if job.present? and job.status.in? [ :completed, :error ]
              begin
                @logger.info "[Scheduler:#{@pid}] Rimosso processo #{job.pid} per lavoro completato".cyan
                Process.kill :QUIT, job.pid
              rescue Errno::ENOENT, Errno::ESRCH
              end
              true
            else false end
          end
  
          # Waits the specified amount of time before next iteration
          sleep @polling_interval
        rescue StandardError => error
          @logger.error "[Scheduler:#{@pid}] Error #{error.message}".red
          @logger.error error.backtrace.select { |line| line.include?('app') }.join("\n").red
        rescue SignalException => signal
          if signal.message.in? [ 'SIGINT', 'SIGTERM', 'SIGQUIT' ]
            @logger.warn "[Scheduler:#{@pid}] Received interrupt, terminating scheduler..".yellow
            reschedule_running_jobs
            break
          end
        end
      end
    end
def start_loop
      loop do
        begin
          # Loads up a job queue.
          queue = []
          
          # Counts jobs to schedule.
          running_jobs = @job_class.running.entries
          schedulable_jobs = @job_class.queued.order_by(scheduled_at: :asc).entries
          jobs_to_schedule = @max_concurrent_jobs - running_jobs.count
          jobs_to_schedule = 0 if jobs_to_schedule < 0
  
          # Finds out scheduled jobs waiting to be performed.
          scheduled_jobs = []
          schedulable_jobs.first(jobs_to_schedule).each do |job|
            job_pid = Process.fork do
              begin
                job.perform_now
              rescue StandardError => e
                @logger.error "[Scheduler:#{@pid}] Error #{e.class}: #{e.message} "\
                  "(#{e.backtrace.select { |l| l.include?('app') }.first}).".red
              end
            end
            Process.detach(job_pid)
            job.update_attribute(:pid, job_pid)
            scheduled_jobs << job
            queue << job.id.to_s
          end
  
          # Logs launched jobs
          if scheduled_jobs.any?
            @logger.info "[Scheduler:#{@pid}] Launched #{scheduled_jobs.count} "\
              "jobs: #{scheduled_jobs.map(&:id).map(&:to_s).join(', ')}.".cyan
          else
            if schedulable_jobs.count == 0
              @logger.info "[Scheduler:#{@pid}] No jobs in queue.".cyan
            else
              @logger.warn "[Scheduler:#{@pid}] No jobs launched, reached maximum "\
                "number of concurrent jobs. Jobs in queue: #{schedulable_jobs.count}.".yellow
            end
          end
  
          # Checks for completed jobs: clears up queue and kills any zombie pid
          queue.delete_if do |job_id|
            job = @job_class.find(job_id)
            if job.present? and job.status.in? [ :completed, :error ]
              begin
                @logger.info "[Scheduler:#{@pid}] Rimosso processo #{job.pid} per lavoro completato".cyan
                Process.kill :QUIT, job.pid
              rescue Errno::ENOENT, Errno::ESRCH
              end
              true
            else false end
          end
  
          # Waits the specified amount of time before next iteration
          sleep @polling_interval
        rescue StandardError => error
          @logger.error "[Scheduler:#{@pid}] Error #{error.message}".red
          @logger.error error.backtrace.select { |line| line.include?('app') }.join("\n").red
        rescue SignalException => signal
          if signal.message.in? [ 'SIGINT', 'SIGTERM', 'SIGQUIT' ]
            @logger.warn "[Scheduler:#{@pid}] Received interrupt, terminating scheduler..".yellow
            reschedule_running_jobs
            break
          end
        end
      end
    end
Creates a MainProcess which keeps running
 and continuously checks if new jobs are queued.

 @return [Scheduler::MainProcess] the created MainProcess.

 Main loop.

 @return [nil]