Module: Scheduler

Defined in:
lib/scheduler.rb

Defined Under Namespace

Classes: Event

Class Method Summary collapse

Class Method Details

.__message__(*args) ⇒ Object

:nodoc:



96
97
98
99
100
101
102
103
# File 'lib/scheduler.rb', line 96

def __message__( *args ) #:nodoc:
  @lock.synchronize do
    __scheduler__ unless @thread and @thread.status
    @write_status.write "x" if @messages.empty?
    @messages << args
  end
  self
end

.__scheduler__Object

:nodoc:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/scheduler.rb', line 105

def __scheduler__ #:nodoc:
  @read_status.close if @read_status
  @write_status.close if @write_status
  @read_status, @write_status = IO.pipe
  @messages = []
  @events = []
  @thread = Thread.new do
    timeout = nil
    loop do
      IO.select( [@read_status], nil, nil, timeout )
      current_time = Time.now.to_f
      while !@events.empty? and current_time >= @events.first.time
        @events.shift.run
      end
      @lock.synchronize do
        unless @messages.empty?
          @messages.each do |message, event|
            case message
            when :submit
              @events.push event
            when :cancel
              @events.delete event
            end
          end
          @messages.clear
          @read_status.read 1
          @events.sort!
        end
      end
      if @events.empty?
        timeout = nil
      else
        timeout = [ 0, @events.first.time - current_time ].max
      end
    end
  end
  self
end

.after_delay(delay, &proc) ⇒ Object

Just like Scheduler.at_time except that the time is given as a delay relative to the current time.



85
86
87
# File 'lib/scheduler.rb', line 85

def after_delay( delay, &proc )
  after_delay!( delay ) { Thread.new &proc }
end

.after_delay!(delay, &proc) ⇒ Object

Just like Scheduler.at_time! except that the time is given as a delay relative to the current time. Use Scheduler.after_delay unless you really know what you’re doing.



79
80
81
# File 'lib/scheduler.rb', line 79

def after_delay!( delay, &proc )
  at_time!( Time.now + delay, &proc )
end

.at_time(time, &proc) ⇒ Object

Executes the given block in a new thread no earlier than the given time (in seconds); returns an event object which can be used to cancel the event (see Event#cancel). Recommended over Scheduler.at_time! since blocking or long-running operations in the thread won’t mess up other tasks.



71
72
73
# File 'lib/scheduler.rb', line 71

def at_time( time, &proc )
  at_time!( time ) { Thread.new &proc }
end

.at_time!(time, &proc) ⇒ Object

Executes the given block in the context of the scheduler thread no earlier than the given time (in seconds); the block should be very short and should not call any blocking operations. Because of that, use Scheduler.at_time instead unless you really know what you’re doing. Returns an event object which can be used to cancel the event (see Event#cancel).



60
61
62
63
64
# File 'lib/scheduler.rb', line 60

def at_time!( time, &proc )
  event = Event.new time.to_f, &proc
  __message__ :submit, event
  event
end

.cancel(event) ⇒ Object

Cancels the given event if it has not already been; executed; see also Event#cancel.



91
92
93
94
# File 'lib/scheduler.rb', line 91

def cancel( event )
  __message__ :cancel, event
  self
end