Method: Async::Reactor#run

Defined in:
lib/async/reactor.rb

#run(*args, &block) ⇒ Object

Run the reactor until either all tasks complete or #stop is invoked. Proxies arguments to #async immediately before entering the loop.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/async/reactor.rb', line 120

def run(*args, &block)
  raise RuntimeError, 'Reactor has been closed' if @selector.nil?
  
  @stopped = false
  
  # Allow the user to kick of the initial async tasks.
  async(*args, &block) if block_given?
  
  @timers.wait do |interval|
    # - nil: no timers
    # - -ve: timers expired already
    # -   0: timers ready to fire
    # - +ve: timers waiting to fire
    interval = 0 if interval && interval < 0
    
    # Async.logger.debug{"[#{self} Pre] Updating #{@children.count} children..."}
    # As timeouts may have been updated, and caused fibers to complete, we should check this.
    
    # If there is nothing to do, then finish:
    # Async.logger.debug{"[#{self}] @children.empty? = #{@children.empty?} && interval #{interval.inspect}"}
    return if @children.empty? && interval.nil?
    
    # Async.logger.debug{"Selecting with #{@children.count} fibers interval = #{interval}..."}
    if monitors = @selector.select(interval)
      monitors.each do |monitor|
        if fiber = monitor.value
          fiber.resume # if fiber.alive?
        end
      end
    end
  end until @stopped
  
  return self
ensure
  Async.logger.debug{"[#{self} Ensure] Exiting run-loop (stopped: #{@stopped} exception: #{$!.inspect})..."}
  @stopped = true
end