<commit_before>module Que
  class RecurringJob < Job
    def initialize(attrs)
      @t_i, @t_f = attrs[:args].shift[:recurring_interval]
      # Hang onto a deep copy of the args so that if the job mutates them, that won't be passed on to the next job.
      @args_copy = JSON_MODULE.load(JSON_MODULE.dump(attrs[:args]))
      super
    end

    def _run
      run(*attrs[:args])
      reenqueue unless @reenqueued || @destroyed
    end

    def start_time
      Time.at(@t_i)
    end

    def end_time
      Time.at(@t_f)
    end

    def time_range
      start_time...end_time
    end

    def next_run_float
      @t_f + self.class.interval
    end

    def next_run_time
      Time.at(next_run_float)
    end

    private

    def reenqueue(interval: nil, args: nil)
      args     ||= @args_copy
      interval ||= self.class.interval
      new_args = args.unshift(recurring_interval: [@t_f, @t_f + interval])
      next_run_time = Time.at(end_time + interval)
      Que.execute :reenqueue_job, attrs.values_at(:priority, :run_at, :job_id, :job_class) << next_run_time << new_args
      @reenqueued = true
    end

    class << self
      def interval
        @interval || raise(Error, "Can't enqueue a recurring job (#{to_s}) unless an interval is set!")
      end

      def enqueue(*args)
        super(*args_with_interval(*args))
      end

      def run(*args)
        super(*args_with_interval(*args))
      end

      private

      def args_with_interval(*args)
        time  = (args.last.is_a?(Hash) && args.last[:run_at]) || Time.now
        float = time.utc.to_f.round(6) # Keep same precision as Postgres
        args.unshift(recurring_interval: [float - interval, float])
      end
    end
  end
end<commit_msg>Prefix instance variables in RecurringJob that the user shouldn't be interacting with with underscores.<commit_after>module Que
  class RecurringJob < Job
    def initialize(attrs)
      @_start_time, @_end_time = attrs[:args].shift[:recurring_interval]
      # Hang onto a deep copy of the args so that if the job mutates them, that won't be passed on to the next job.
      @_args_copy = JSON_MODULE.load(JSON_MODULE.dump(attrs[:args]))
      super
    end

    def _run
      run(*attrs[:args])
      reenqueue unless @reenqueued || @destroyed
    end

    def start_time
      Time.at(@_start_time)
    end

    def end_time
      Time.at(@_end_time)
    end

    def time_range
      start_time...end_time
    end

    def next_run_float
      @_end_time + self.class.interval
    end

    def next_run_time
      Time.at(next_run_float)
    end

    private

    def reenqueue(interval: nil, args: nil)
      args     ||= @_args_copy
      interval ||= self.class.interval
      new_args = args.unshift(recurring_interval: [@_end_time, @_end_time + interval])
      next_run_time = Time.at(end_time + interval)
      Que.execute :reenqueue_job, attrs.values_at(:priority, :run_at, :job_id, :job_class) << next_run_time << new_args
      @reenqueued = true
    end

    class << self
      def interval
        @interval || raise(Error, "Can't enqueue a recurring job (#{to_s}) unless an interval is set!")
      end

      def enqueue(*args)
        super(*args_with_interval(*args))
      end

      def run(*args)
        super(*args_with_interval(*args))
      end

      private

      def args_with_interval(*args)
        time  = (args.last.is_a?(Hash) && args.last[:run_at]) || Time.now
        float = time.utc.to_f.round(6) # Keep same precision as Postgres
        args.unshift(recurring_interval: [float - interval, float])
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.1000555864369094, 'fraction_numerical': 0.0005558643690939411, 'mean_word_length': 2.581094527363184, 'pattern_counts': {'":': 0, '<': 17, '<?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': '2939178', 'n_tokens_mistral': 1201, 'n_tokens_neox': 1165, 'n_words': 300}