class EventMachine::TickLoop

A TickLoop is useful when one needs to distribute amounts of work throughout ticks in order to maintain response times. It is also useful for simple repeated checks and metrics. @example

# Here we run through an array one item per tick until it is empty,
# printing each element.
# When the array is empty, we return :stop from the callback, and the
# loop will terminate.
# When the loop terminates, the on_stop callbacks will be called.
EM.run do
  array = (1..100).to_a

  tickloop = EM.tick_loop do
    if array.empty?
      :stop
    else
      puts array.shift
    end
  end

  tickloop.on_stop { EM.stop }
end

Public Class Methods

new(*a, &b) click to toggle source

Arguments: A callback (EM::Callback) to call each tick. If the call returns :stop then the loop will be stopped. Any other value is ignored.

# File lib/em/tick_loop.rb, line 35
def initialize(*a, &b)
  @work = EM::Callback(*a, &b)
  @stops = []
  @stopped = true
end

Public Instance Methods

on_stop(*a, &b) click to toggle source

Arguments: A callback (EM::Callback) to call once on the next stop (or immediately if already stopped).

# File lib/em/tick_loop.rb, line 43
def on_stop(*a, &b)
  if @stopped
    EM::Callback(*a, &b).call
  else
    @stops << EM::Callback(*a, &b)
  end
end
start() click to toggle source

Start the tick loop, will raise argument error if the loop is already running.

# File lib/em/tick_loop.rb, line 66
def start
  raise ArgumentError, "double start" unless @stopped
  @stopped = false
  schedule
end
stop() click to toggle source

Stop the tick loop immediately, and call it's #on_stop callbacks.

# File lib/em/tick_loop.rb, line 52
def stop
  @stopped = true
  until @stops.empty?
    @stops.shift.call
  end
end
stopped?() click to toggle source

Query if the loop is stopped.

# File lib/em/tick_loop.rb, line 60
def stopped?
  @stopped
end

Private Instance Methods

schedule() click to toggle source
# File lib/em/tick_loop.rb, line 73
def schedule
  EM.next_tick do
    next if @stopped
    if @work.call == :stop
      stop
    else
      schedule
    end
  end
  self
end