in azure/durable_functions/models/Task.py [0:0]
def try_set_value(self, child: TaskBase):
"""Transition a Retryable Task to a terminal state and set its value.
Parameters
----------
child : TaskBase
A sub-task that just completed
"""
if self.is_waiting_on_timer:
# timer fired, re-scheduling original task
self.is_waiting_on_timer = False
# As per DTFx semantics: we need to check the number of retires only after the final
# timer has fired. This means we essentially have to wait for one "extra" timer after
# the maximum number of attempts has been reached. Removing this extra timer will cause
# stuck orchestrators as we need to be "in sync" with the replay logic of DTFx.
if self.num_attempts >= self.retry_options.max_number_of_attempts:
self.is_waiting_on_timer = True
# we have reached the maximum number of attempts, set error
self.set_value(is_error=True, value=self.error)
else:
rescheduled_task = self.context._generate_task(
action=NoOpAction("rescheduled task"), parent=self)
self.pending_tasks.add(rescheduled_task)
self.context._add_to_open_tasks(rescheduled_task)
self.num_attempts += 1
return
if child.state is TaskState.SUCCEEDED:
if len(self.pending_tasks) == 0:
# if all pending tasks have completed,
# and we have a successful child, then
# we can set the Task's event
self.set_value(is_error=False, value=child.result)
else: # child.state is TaskState.FAILED:
# increase size of pending tasks by adding a timer task
# when it completes, we'll retry the original task
timer_task = self.context._generate_task(
action=NoOpAction("-WithRetry timer"), parent=self)
self.pending_tasks.add(timer_task)
self.context._add_to_open_tasks(timer_task)
self.is_waiting_on_timer = True
self.error = child.result