class Rufus::Scheduler::RepeatJob

def determine_id

def determine_id
  [
    self.class.name.split(':').last.downcase[0..-4],
    @scheduled_at.to_f,
    (self.object_id < 0 ? 'm' : '') + self.object_id.to_s
  ].map(&:to_s).join('_')
end

def first_at=(first)

def first_at=(first)
  return (@first_at = nil) if first == nil
  n0 = EoTime.now
  n1 = n0 + 0.003
  first = n0 if FIRSTS.include?(first)
  fdur = Rufus::Scheduler.parse_duration(first, no_error: true)
  @first_at = (fdur && (EoTime.now + fdur)) || EoTime.make(first)
  @first_at = n1 if @first_at >= n0 && @first_at < n1
  @first_at = n0 if @first_at < n0 && @first_at_no_error
  fail ArgumentError.new(
    "cannot set first[_at|_in] in the past: " +
    "#{first.inspect} -> #{@first_at.inspect}"
  ) if @first_at < n0
  @first_at
end

def initialize(scheduler, duration, opts, block)

def initialize(scheduler, duration, opts, block)
  super
  @paused_at = nil
  @times = opts[:times]
  @first_at_no_error = opts[:first_at_no_error] || false
  fail ArgumentError.new(
    "cannot accept :times => #{@times.inspect}, not nil or an int"
  ) unless @times == nil || @times.is_a?(Integer)
  self.first_at =
    opts[:first] || opts[:first_time] ||
    opts[:first_at] || opts[:first_in] ||
    nil
  self.last_at =
    opts[:last] || opts[:last_at] || opts[:last_in]
  @resume_discard_past = nil
end

def last_at=(last)

def last_at=(last)
  @last_at =
    if last
      ldur = Rufus::Scheduler.parse_duration(last, no_error: true)
      (ldur && (EoTime.now + ldur)) || EoTime.make(last)
    else
      nil
    end
  fail ArgumentError.new(
    "cannot set last[_at|_in] in the past: " +
    "#{last.inspect} -> #{@last_at.inspect}"
  ) if last && @last_at < EoTime.now
  @last_at
end

def next_times(count)


(not from one trigger to the next, as for "cron" and "every").
"interval" works from the end of a job to its next trigger
Warning, for IntervalJob, the @mean_work_time is used since

(EtOrbi::EoTime instances) for this job.
Starting from now, returns the {count} next occurences
def next_times(count)
  (count - 1).times.inject([ next_time ]) { |a|
    a << next_time_from(a.last)
    a }
end

def occurrences(time0, time1)

def occurrences(time0, time1)
  a = []
  nt = @next_time
  ts = @times
  loop do
    break if nt > time1
    break if ts && ts <= 0
    a << nt if nt >= time0
    nt = next_time_from(nt)
    ts = ts - 1 if ts
  end
  a
end

def pause

def pause
  @paused_at = EoTime.now
end

def paused?

def paused?
  !! @paused_at
end

def resume(opts={})

def resume(opts={})
  @resume_discard_past = opts[:discard_past]
  @paused_at = nil
end

def trigger(time)

def trigger(time)
  return if @paused_at
  #return set_next_time(time) if @paused_at
  return (@next_time = nil) if @times && @times < 1
  return (@next_time = nil) if @last_at && time >= @last_at
    #
    # It keeps jobs one step too much in @jobs, but it's OK
  super
  @times -= 1 if @times
end