Created
May 15, 2009 22:50
-
-
Save kjwierenga/112478 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def schedule_event(event) | |
now = Time.now | |
# Determine the next occurrence starting at (Time.now - event.duration) to | |
# catch the current occurence where start_at <= Time.now but end_at > Time.now. | |
# | |
# When occurrence == nil, this means the event will never occur. | |
occurrence = event.occurrences(:starting => now - event.duration, :count => 1) | |
return if occurrence.nil? | |
# Determine trigger time and end time. | |
# Note that occurrence.dtend still has the original value of event.end_at | |
# which may be in the past. | |
# TODO: Is this a ri_cal bug? | |
trigger_at = occurrence.dtstart.to_time + event.trigger*60 | |
end_at = occurrence.dtstart.to_time + event.duration | |
# Trigger the event immediately when Time.now falls within the timerange of the event. | |
# Set trigger_at to now to ensure correct job.at value in #schedule_next_occurrence. | |
if trigger_immediately = (trigger_at <= now && now < end_at) | |
trigger_at = now | |
end | |
@scheduler.at(trigger_at, | |
:job_id => event.id, | |
:tags => 'event', | |
:discard_past => !trigger_immediately, | |
:event => event, | |
:sequence => 0) do |job| | |
sequence = job.params[:sequence] | |
schedule_next_occurrence(job) unless "SINGLE" == event.recurrence | |
# do the stuff (start remote recording) | |
# sleep event.duration | |
end | |
end | |
def schedule_next_occurrence(job) | |
event = job.params[:event] | |
# find next occurrence after the current occurrence | |
return unless occurrence = event.occurrences(:starting => Time.at(job.at), :count => 1) | |
job.params[:discard_past] = false # should not fire immediately (would cause a loop) | |
job.params[:sequence] += 1 | |
# reschedule the job by setting a new @at value and adding to the job queue again | |
job.instance_variable_set('@at', (occurrence.dtstart.to_time + event.trigger*60).to_f) | |
@scheduler.send(:add_job, job) | |
end | |
# | |
# Relevant details of the Event class | |
# | |
class Event | |
attr_accessor :start_at, :end_at, :rrule | |
def duration; end_at - start_at; end | |
# | |
# Use RiCal::OccurrenceEnumerator#occurrences to return the next :count occurrence | |
# for the event between :starting and :before | |
# | |
def occurrences(options = {}) | |
occurrences = [] | |
enum_event = RiCal.Event do |event| | |
event.dtstart = self.start_at.utc | |
event.dtend = self.end_at.utc | |
event.rrule = self.rrule | |
end | |
occurrences = [enum_event] | |
occurrences = [] if options[:starting] && self.start_at < options[:starting] | |
occurrences = [] if options[:before] && self.start_at >= options[:before] | |
(options[:count].nil? || options[:count] > 1 ? occurrences : occurrences.first) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment