Class: Waiter

Inherits:
Object
  • Object
show all
Defined in:
lib/vapir-common/waiter.rb

Class Method Summary collapse

Class Method Details

.try_for(time, options = {}) ⇒ Object

Tries for time seconds to get the desired result from the given block. Stops when either:

  1. The :condition option (which should be a proc) returns true (that is, not false or nil)

  2. The block returns true (that is, anything but false or nil) if no :condition option is given

  3. The specified amount of time has passed. By default a WaiterError is raised. If :exception option is given, then if it is nil, no exception is raised; otherwise it should be an exception class or an exception instance which will be raised instead of WaiterError

Returns the value of the block, which can be handy for things that return nil on failure and some other object on success, like Enumerable#detect for example: found_thing=Waiter.try_for(30) { all_things().detect {|thing| thing.name==“Bill” } }

Examples: Waiter.try_for(30) do

Time.now.year == 2015

end Raises a WaiterError unless it is called between the last 30 seconds of December 31, 2014 and the end of 2015

Waiter.try_for(365.242199*24*60*60, :interval => 0.1, :exception => nil, :condition => proc{ 2+2==5 }) do

STDERR.puts "any decisecond now ..."

end Complains to STDERR for one year, every tenth of a second, as long as 2+2 does not equal 5. Does not raise an exception if 2+2 does not become equal to 5.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/vapir-common/waiter.rb', line 120

def self.try_for(time, options={})
  unless time.is_a?(Numeric) && options.is_a?(Hash)
    raise TypeError, "expected arguments are time (a numeric) and, optionally, options (a Hash). received arguments #{time.inspect} (#{time.class}), #{options.inspect} (#{options.class})"
  end
  options=handle_options(options, {:interval => 0.5, :condition => proc{|_ret| _ret}, :exception => WaiterError})
  started=Time.now
  begin
    ret=yield
    break if options[:condition].call(ret)
    sleep options[:interval]
  end while Time.now < started+time && !options[:condition].call(ret)
  if options[:exception] && !options[:condition].call(ret)
    ex=if options[:exception].is_a?(Class)
      options[:exception].new("Waiter waited #{time} seconds and condition was not met")
    else
      options[:exception]
    end
    raise ex
  end
  ret
end