<commit_before>require 'fugit'

module Que
  module Scheduler
    ScheduleParserResult = Struct.new(:missed_jobs, :schedule_dictionary, :seconds_until_next_job)

    class ScheduleParser
      SCHEDULER_FREQUENCY = 60

      class << self
        def parse(jobs_list, as_time, last_time, known_jobs)
          missed_jobs = {}
          schedule_dictionary = []

          # For each scheduled item, we need not schedule a job it if it has no history, as it is
          # new. Otherwise, check how many times we have missed the job since the last run time.
          # If it is "unmissable" then we schedule all of them, with the missed time as an arg,
          # otherwise just schedule it once.
          jobs_list.each do |desc|
            schedule_dictionary << desc[:name]

            next unless known_jobs.include?(desc[:name])
            # This has been seen before. We should check if we have missed any executions.
            missed = calculate_missed_runs(desc, last_time, as_time)
            missed_jobs[desc[:clazz]] = missed unless missed.empty?
          end

          seconds_until_next_job = SCHEDULER_FREQUENCY # TODO: make it 1 sec after next known run
          ScheduleParserResult.new(missed_jobs, schedule_dictionary, seconds_until_next_job)
        end

        private

        def calculate_missed_runs(desc, last_scheduler_run_time, as_time)
          jobs_for_class = []
          missed_times = []
          last_time = last_scheduler_run_time
          while (next_run = next_run_time(desc[:cron], last_time, as_time))
            missed_times << next_run
            last_time = next_run
          end

          unless missed_times.empty?
            if desc[:unmissable]
              missed_times.each do |time_missed|
                jobs_for_class << [time_missed] + desc[:args]
              end
            else
              jobs_for_class << desc[:args]
            end
          end
          jobs_for_class
        end

        def next_run_time(cron, from, to)
          fugit_cron = Fugit::Cron.parse(cron)
          next_time = fugit_cron.next_time(from)
          next_run = next_time.to_local_time
          next_run <= to ? next_run : nil
          if cron == '10 6 * * *'
            puts "cron: #{cron}"
            puts "from: #{from}"
            puts "to: #{to}"
            puts "fugit_cron: #{fugit_cron}"
            puts "next_time: #{next_time}"
            puts "next_run: #{next_run}"
          end
        end
      end
    end
  end
end
<commit_msg>Setting timezone handling in travis<commit_after>require 'fugit'

module Que
  module Scheduler
    ScheduleParserResult = Struct.new(:missed_jobs, :schedule_dictionary, :seconds_until_next_job)

    class ScheduleParser
      SCHEDULER_FREQUENCY = 60

      class << self
        def parse(jobs_list, as_time, last_time, known_jobs)
          missed_jobs = {}
          schedule_dictionary = []

          # For each scheduled item, we need not schedule a job it if it has no history, as it is
          # new. Otherwise, check how many times we have missed the job since the last run time.
          # If it is "unmissable" then we schedule all of them, with the missed time as an arg,
          # otherwise just schedule it once.
          jobs_list.each do |desc|
            schedule_dictionary << desc[:name]

            next unless known_jobs.include?(desc[:name])
            # This has been seen before. We should check if we have missed any executions.
            missed = calculate_missed_runs(desc, last_time, as_time)
            missed_jobs[desc[:clazz]] = missed unless missed.empty?
          end

          seconds_until_next_job = SCHEDULER_FREQUENCY # TODO: make it 1 sec after next known run
          ScheduleParserResult.new(missed_jobs, schedule_dictionary, seconds_until_next_job)
        end

        private

        def calculate_missed_runs(desc, last_scheduler_run_time, as_time)
          jobs_for_class = []
          missed_times = []
          last_time = last_scheduler_run_time
          while (next_run = next_run_time(desc[:cron], last_time, as_time))
            missed_times << next_run
            last_time = next_run
          end

          unless missed_times.empty?
            if desc[:unmissable]
              missed_times.each do |time_missed|
                jobs_for_class << [time_missed] + desc[:args]
              end
            else
              jobs_for_class << desc[:args]
            end
          end
          jobs_for_class
        end

        def next_run_time(cron, from, to)
          fugit_cron = Fugit::Cron.parse(cron)
          next_time = fugit_cron.next_time(from)
          next_run = next_time.to_local_time.in_time_zone(next_time.zone)
          if cron == '10 6 * * *'
            puts "cron: #{cron}"
            puts "from: #{from}"
            puts "to: #{to}"
            puts "fugit_cron: #{fugit_cron}"
            puts "next_time: #{next_time}"
            puts "next_run: #{next_run}"
          end
          next_run <= to ? next_run : nil
        end
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.0750638632344272, 'fraction_numerical': 0.002358027117311849, 'mean_word_length': 1.9888432178508515, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '913260', 'n_tokens_mistral': 1532, 'n_tokens_neox': 1501, 'n_words': 414}