module Dynflow::Action::Polling

Constants

Poll

Public Class Methods

included(base) click to toggle source
# File lib/dynflow/action/polling.rb, line 6
def self.included(base)
  base.send :include, Action::Timeouts
end

Public Instance Methods

attempts_before_next_interval() click to toggle source
# File lib/dynflow/action/polling.rb, line 67
def attempts_before_next_interval
  5
end
done?() click to toggle source
# File lib/dynflow/action/polling.rb, line 31
def done?
  raise NotImplementedError
end
external_task() click to toggle source

External task data. It should return nil when the task has not been triggered yet.

# File lib/dynflow/action/polling.rb, line 48
def external_task
  output[:task]
end
external_task=(external_task_data) click to toggle source
# File lib/dynflow/action/polling.rb, line 52
def external_task=(external_task_data)
  output[:task] = external_task_data
end
initiate_external_action() click to toggle source
# File lib/dynflow/action/polling.rb, line 82
def initiate_external_action
  self.external_task = invoke_external_task
end
invoke_external_task() click to toggle source
# File lib/dynflow/action/polling.rb, line 35
def invoke_external_task
  raise NotImplementedError
end
on_finish() click to toggle source
# File lib/dynflow/action/polling.rb, line 43
def on_finish
end
poll_attempts() click to toggle source
# File lib/dynflow/action/polling.rb, line 105
def poll_attempts
  output[:poll_attempts] ||= { total: 0, failed: 0 }
end
poll_external_task() click to toggle source
# File lib/dynflow/action/polling.rb, line 39
def poll_external_task
  raise NotImplementedError
end
poll_external_task_with_rescue() click to toggle source
# File lib/dynflow/action/polling.rb, line 96
def poll_external_task_with_rescue
  poll_attempts[:total] += 1
  self.external_task = poll_external_task
  poll_attempts[:failed] = 0
rescue => error
  poll_attempts[:failed] += 1
  rescue_external_task(error)
end
poll_interval() click to toggle source

Returns the time to wait between two polling intervals.

# File lib/dynflow/action/polling.rb, line 72
def poll_interval
  interval_level = poll_attempts[:total]/attempts_before_next_interval
  poll_intervals[interval_level] || poll_intervals.last
end
poll_intervals() click to toggle source

What is the trend in waiting for next polling event. It allows to strart with frequent polling, but slow down once it's clear this task will take some time: the idea is we don't care that much in finishing few seconds sooner, when the task takes orders of minutes/hours. It allows not overwhelming the backend-servers with useless requests. By default, it switches to next interval after attempts_before_next_interval number of attempts

# File lib/dynflow/action/polling.rb, line 63
def poll_intervals
  [0.5, 1, 2, 4, 8, 16]
end
poll_max_retries() click to toggle source

How man times in row should we retry the polling before giving up

# File lib/dynflow/action/polling.rb, line 78
def poll_max_retries
  3
end
rescue_external_task(error) click to toggle source
# File lib/dynflow/action/polling.rb, line 109
def rescue_external_task(error)
  if poll_attempts[:failed] < poll_max_retries
    action_logger.warn("Polling failed, attempt no. #{poll_attempts[:failed]}, retrying in #{poll_interval}")
    action_logger.warn(error)
  else
    raise error
  end
end
resume_external_action() click to toggle source
# File lib/dynflow/action/polling.rb, line 86
def resume_external_action
  poll_external_task_with_rescue
rescue
  initiate_external_action
end
run(event = nil) click to toggle source
# File lib/dynflow/action/polling.rb, line 12
def run(event = nil)
  case event
  when nil
    if external_task
      resume_external_action
    else
      initiate_external_action
    end
  when Poll
    poll_external_task_with_rescue
  when Action::Timeouts::Timeout
    process_timeout
    suspend
  else
    raise "unrecognized event #{event}"
  end
  done? ? on_finish : suspend_and_ping
end
suspend_and_ping() click to toggle source
# File lib/dynflow/action/polling.rb, line 92
def suspend_and_ping
  suspend { |suspended_action| world.clock.ping suspended_action, poll_interval, Poll }
end