class Threasy::Schedule

Attributes

schedules[R]
watcher[R]

Public Class Methods

new(work = nil) click to toggle source

Creates new `Threasy::Schedule` instance

Parameters

  • `work` - Optional. Usually a `Threasy::Work` instance.

    Defaults to `Threasy.work`
    
# File lib/threasy/schedule.rb, line 33
def initialize(work = nil)
  @work = work
  @semaphore = Mutex.new
  @schedules = []
  @watcher = Thread.new{ watch }
end

Public Instance Methods

add(*args, &block) click to toggle source

Schedule a job

Examples

schedule = Threasy::Schedule.new(work: Threasy::Work.new)

# Schedule blocks
schedule.add(in: 5.min) { do_some_background_work }

# Schedule job objects compatible with the `work` queue
schedule.add(BackgroundJob.new(some: data), every: 1.hour)

# Enqueue strings that can be evals to a job object
schedule.add("BackgroundJob.new", every: 1.day)

Parameters

  • `job` - Job object which responds to `perform` or `call`

  • `options`

    • `every: n` - If present, job is repeated every `n` seconds

    • `in: n` - `n` seconds until job is executed

    • `at: Time` - Time to execute job at

  • `&block` - Job block

Must have either a `job` object or job `&block` present.

Returns

  • `Threasy::Schedule::Entry` if job was successfully added to schedule

  • `nil` if job was for the past

# File lib/threasy/schedule.rb, line 70
def add(*args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  job = block_given? ? block : args.first
  entry = Entry.new job, {schedule: self}.merge(options)
  add_entry entry if entry.future?
end
add_entry(entry) click to toggle source

Add a `Threasy::Schedule::Entry` object to `schedules`

# File lib/threasy/schedule.rb, line 78
def add_entry(entry)
  sync do
    schedules << entry
    schedules.sort_by!(&:at)
  end
  tickle_watcher
  entry
end
clear() click to toggle source
# File lib/threasy/schedule.rb, line 109
def clear
  log.debug "Clearing schedules"
  sync { schedules.clear }
end
count() click to toggle source
# File lib/threasy/schedule.rb, line 145
def count
  schedules.count
end
each() { |entry| ... } click to toggle source
# File lib/threasy/schedule.rb, line 105
def each
  schedules.each { |entry| yield entry }
end
entries_due() click to toggle source

Pop entries off the schedule that are due

# File lib/threasy/schedule.rb, line 135
def entries_due
  [].tap do |entries|
    sync do
      while schedules.first && schedules.first.due?
        entries << schedules.shift
      end
    end
  end
end
log() click to toggle source
# File lib/threasy/schedule.rb, line 149
def log
  Threasy.logger
end
max_sleep() click to toggle source
# File lib/threasy/schedule.rb, line 153
def max_sleep
  Threasy.config.max_sleep
end
remove_entry(entry) click to toggle source
# File lib/threasy/schedule.rb, line 92
def remove_entry(entry)
  sync { schedules.delete entry }
end
sync() { || ... } click to toggle source
# File lib/threasy/schedule.rb, line 101
def sync
  @semaphore.synchronize { yield }
end
tickle_watcher() click to toggle source

Wakes up the watcher thread if its sleeping

# File lib/threasy/schedule.rb, line 97
def tickle_watcher
  watcher.wakeup if watcher.stop?
end
watch() click to toggle source

Used by the watcher thread to find jobs that are due, add them to the `work` queue, re-sort the schedule, and attempt to sleep until the next job is due.

# File lib/threasy/schedule.rb, line 117
def watch
  loop do
    Thread.stop if schedules.empty?
    entries_due.each do |entry|
      log.debug "Adding scheduled job to work queue"
      entry.work!
      add_entry entry if entry.repeat?
    end
    next_job = @schedules.first
    if next_job && next_job.future?
      seconds = [next_job.at - Time.now, max_sleep].min
      log.debug "Schedule watcher sleeping for #{seconds} seconds"
      sleep seconds
    end
  end
end
work() click to toggle source

Returns the current work queue

# File lib/threasy/schedule.rb, line 88
def work
  @work ||= Threasy.work
end