Skip to content

docs(workflow): clarify RetryPolicy field docstrings - #1204

Open
magic-peach wants to merge 4 commits into
dapr:mainfrom
magic-peach:docs/retry-policy-field-clarification
Open

magic-peach wants to merge 4 commits into
dapr:mainfrom
magic-peach:docs/retry-policy-field-clarification

Conversation

@magic-peach

Copy link
Copy Markdown
Contributor

Description

RetryPolicy's docstrings did not explain three behaviors that are easy to get wrong: max_number_of_attempts counts the first attempt, not just retries after it; leaving max_retry_interval unset means the backoff interval keeps growing without a cap rather than disabling retries; and hitting retry_timeout ends retries with whatever the last attempt returned, it does not run one more attempt first. This spells all three out in the docstrings. Verified each claim directly against the attempt-counting and timeout-scheduling logic in dapr/ext/workflow/_durabletask/task.py before writing it.

Issue reference

No existing issue tracks this; found while reading the retry policy implementation.

Checklist

  • Code compiles correctly
  • Created/updated tests
  • Extended the documentation

This is a docstring-only change with no behavior change, so no test or separate documentation update is needed beyond the docstrings themselves.

Users kept tripping over the same three gotchas: max_number_of_attempts
counts the first attempt too, an unset max_retry_interval leaves the
backoff interval uncapped rather than disabling retries, and hitting
retry_timeout ends retries with whatever the last attempt returned
instead of running one more attempt. Spell all three out in the
docstrings instead of leaving them to be discovered the hard way.

Signed-off-by: Akanksha Trehun <akankshatrehun@gmail.com>
@magic-peach
magic-peach requested review from a team as code owners September 10, 2026 04:29
yaron2
yaron2 previously approved these changes Sep 11, 2026
@codecov

codecov Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.83%. Comparing base (0943287) to head (5cba633).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1204      +/-   ##
==========================================
- Coverage   85.86%   85.83%   -0.03%     
==========================================
  Files         163      163              
  Lines       12782    12782              
==========================================
- Hits        10975    10972       -3     
- Misses       1807     1810       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@magic-peach

Copy link
Copy Markdown
Contributor Author

@sicoyle could you please review this one as well?

@CasperGN CasperGN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, clearer docstrings here are worth having. I checked each claim against RetryableTask.compute_next_delay (task.py L522-L560). The max_number_of_attempts, backoff_coefficient and max_retry_interval wording is accurate. Two changes:

  1. retry_timeout isn't quite right. The code doesn't fail "once exceeded". Before each retry it computes when that retry would start: the time the first attempt was scheduled plus the sum of the backoff delays so far. It schedules the retry only if that point is before start + retry_timeout; otherwise the last attempt's failure is returned. The time the attempts themselves take is not counted, so the clock is the delays, not wall time. "So its own final attempt is not run" is also hard to parse. Something like: "No further retry is scheduled once the next retry would start (the time the first attempt was scheduled plus the accumulated retry intervals) after retry_timeout; the last failure is then returned. Time spent running the attempts is not counted."
  2. The property docstrings still say the old thing. RetryPolicy.max_number_of_attempts still reads "The maximum number of retry attempts." (retry_policy.py), which contradicts the new constructor doc. Please update the properties to match, at least max_number_of_attempts, max_retry_interval and retry_timeout.

@CasperGN CasperGN self-assigned this Oct 12, 2026
@sicoyle

sicoyle commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

@magic-peach do you think you can address the comment from casper above pls? :)

@CasperGN CasperGN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2 of 3: follow-up on the changes since 2e49d55.

Still blocking:

  • F1: retry_timeout docstring says the activity/workflow 'fails outright' once exceeded; the code only skips scheduling the next retry, uses scheduled time plus summed retry delays (not wall clock), and fails the task, not the workflow (dapr/ext/workflow/retry_policy.py)

Nits, not blocking:

  • F2: max_number_of_attempts property docstring (line 88, outside the diff) still says 'maximum number of retry attempts', contradicting the new constructor docs (dapr/ext/workflow/retry_policy.py)

Drafted with AI assistance and reviewed by me.

Comment thread dapr/ext/workflow/retry_policy.py Outdated

@CasperGN CasperGN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 3 of 3: follow-up on the changes since 5cba633.

Every earlier blocker is resolved and the new changes add none.

Resolved since the last round: 2.

Drafted with AI assistance and reviewed by me.

@magic-peach

Copy link
Copy Markdown
Contributor Author

@CasperGN must I make any other changes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants