Module: WaitUtil

Extended by:
WaitUtil
Included in:
WaitUtil
Defined in:
lib/waitutil.rb,
lib/waitutil/version.rb

Defined Under Namespace

Classes: TimeoutError

Constant Summary

DEFAULT_TIMEOUT_SEC =
60
DEFAULT_DELAY_SEC =
1
VERSION =
IO.read(File.expand_path("../../../VERSION", __FILE__))
@@logger =
Logger.new(STDOUT)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Class Method Details

+ (Object) logger



17
18
19
# File 'lib/waitutil.rb', line 17

def self.logger
  @@logger
end

Instance Method Details

- (Object) wait_for_condition(description, options = {}, &block)

Wait until the condition computed by the given block is met. The supplied block may return a boolean or an array of two elements: whether the condition has been met and an additional message to display in case of timeout.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/waitutil.rb', line 24

def wait_for_condition(description, options = {}, &block)
  delay_sec = options.delete(:delay_sec) || DEFAULT_DELAY_SEC
  timeout_sec = options.delete(:timeout_sec) || DEFAULT_TIMEOUT_SEC
  verbose = options.delete(:verbose)
  unless options.empty?
    raise "Invalid options: #{options}"
  end

  if verbose
    @@logger.info("Waiting for #{description} for up to #{timeout_sec} seconds")
  end

  start_time = Time.now
  stop_time = start_time + timeout_sec
  iteration = 0

  # Time when we started to evaluate the condition.
  condition_eval_start_time = start_time

  until is_condition_met(condition_result = yield(iteration))
    current_time = Time.now
    if current_time - start_time >= timeout_sec
      raise TimeoutError.new(
        "Timed out waiting for #{description} (#{timeout_sec} seconds elapsed)" +
        get_additional_message(condition_result)
      )
    end

    # The condition evaluation function might have taken some time, so we subtract that time
    # from the time we have to wait.
    sleep_time_sec = condition_eval_start_time + delay_sec - current_time
    sleep(sleep_time_sec) if sleep_time_sec > 0

    iteration += 1
    condition_eval_start_time = Time.now  # we will evaluate the condition again immediately
  end

  if verbose
    @@logger.info("Success waiting for #{description} (#{Time.now - start_time} seconds)")
  end
  true
end

- (Object) wait_for_service(description, host, port, options = {})

Wait until a TCP service is available at the given host/port.



68
69
70
71
72
73
74
75
76
77
# File 'lib/waitutil.rb', line 68

def wait_for_service(description, host, port, options = {})
  wait_for_condition("#{description} to become available on #{host}, port #{port}",
                     options) do
    begin
      is_tcp_port_open(host, port, options[:delay_sec] || DEFAULT_DELAY_SEC)
    rescue SocketError
      false
    end
  end
end