Module: Dynflow::Action::Polling
- Defined in:
- lib/dynflow/action/polling.rb
Constant Summary collapse
- Poll =
Algebrick.atom
Instance Method Summary collapse
- #attempts_before_next_interval ⇒ Object
- #done? ⇒ Boolean
-
#external_task ⇒ Object
External task data.
- #external_task=(external_task_data) ⇒ Object
- #initiate_external_action ⇒ Object
- #invoke_external_task ⇒ Object
- #poll_attempts ⇒ Object
- #poll_external_task ⇒ Object
- #poll_external_task_with_rescue ⇒ Object
-
#poll_interval ⇒ Object
Returns the time to wait between two polling intervals.
-
#poll_intervals ⇒ Object
What is the trend in waiting for next polling event.
-
#poll_max_retries ⇒ Object
How man times in row should we retry the polling before giving up.
- #rescue_poll_external_task(error) ⇒ Object
- #resume_external_action ⇒ Object
- #run(event = nil) ⇒ Object
- #suspend_and_ping ⇒ Object
Instance Method Details
#attempts_before_next_interval ⇒ Object
54 55 56 |
# File 'lib/dynflow/action/polling.rb', line 54 def attempts_before_next_interval 5 end |
#done? ⇒ Boolean
21 22 23 |
# File 'lib/dynflow/action/polling.rb', line 21 def done? raise NotImplementedError end |
#external_task ⇒ Object
External task data. It should return nil when the task has not been triggered yet.
35 36 37 |
# File 'lib/dynflow/action/polling.rb', line 35 def external_task output[:task] end |
#external_task=(external_task_data) ⇒ Object
39 40 41 |
# File 'lib/dynflow/action/polling.rb', line 39 def external_task=(external_task_data) output[:task] = external_task_data end |
#initiate_external_action ⇒ Object
69 70 71 72 |
# File 'lib/dynflow/action/polling.rb', line 69 def initiate_external_action self.external_task = invoke_external_task suspend_and_ping unless done? end |
#invoke_external_task ⇒ Object
25 26 27 |
# File 'lib/dynflow/action/polling.rb', line 25 def invoke_external_task raise NotImplementedError end |
#poll_attempts ⇒ Object
94 95 96 |
# File 'lib/dynflow/action/polling.rb', line 94 def poll_attempts output[:poll_attempts] ||= { total: 0, failed: 0 } end |
#poll_external_task ⇒ Object
29 30 31 |
# File 'lib/dynflow/action/polling.rb', line 29 def poll_external_task raise NotImplementedError end |
#poll_external_task_with_rescue ⇒ Object
84 85 86 87 88 89 90 91 92 |
# File 'lib/dynflow/action/polling.rb', line 84 def poll_external_task_with_rescue poll_attempts[:total] += 1 self.external_task = poll_external_task poll_attempts[:failed] = 0 suspend_and_ping unless done? rescue => error poll_attempts[:failed] += 1 rescue_poll_external_task(error) end |
#poll_interval ⇒ Object
Returns the time to wait between two polling intervals.
59 60 61 62 |
# File 'lib/dynflow/action/polling.rb', line 59 def poll_interval interval_level = poll_attempts[:total]/attempts_before_next_interval poll_intervals[interval_level] || poll_intervals.last end |
#poll_intervals ⇒ Object
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
50 51 52 |
# File 'lib/dynflow/action/polling.rb', line 50 def poll_intervals [0.5, 1, 2, 4, 8, 16] end |
#poll_max_retries ⇒ Object
How man times in row should we retry the polling before giving up
65 66 67 |
# File 'lib/dynflow/action/polling.rb', line 65 def poll_max_retries 3 end |
#rescue_poll_external_task(error) ⇒ Object
98 99 100 101 102 103 104 105 106 |
# File 'lib/dynflow/action/polling.rb', line 98 def rescue_poll_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) suspend_and_ping else raise error end end |
#resume_external_action ⇒ Object
74 75 76 77 78 |
# File 'lib/dynflow/action/polling.rb', line 74 def resume_external_action poll_external_task_with_rescue rescue initiate_external_action end |
#run(event = nil) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/dynflow/action/polling.rb', line 6 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 else raise "unrecognized event #{event}" end end |
#suspend_and_ping ⇒ Object
80 81 82 |
# File 'lib/dynflow/action/polling.rb', line 80 def suspend_and_ping suspend { |suspended_action| world.clock.ping suspended_action, poll_interval, Poll } end |