Repository navigation
Add opt-in durable HTTP failure retries - #338
Conversation
Bernd Verst (berndverst)
left a comment
There was a problem hiding this comment.
Reviewed the HTTP-only changes against the stacked retry-timeout base. This accomplishes the opt-in durable HTTP retry goal without changing the existing no-policy path. Selected responses are closed before buffering; excluded responses and subsequent 202 polling retain their existing behavior. I found no actionable correctness, performance, or backward-compatibility regressions. The immutable request snapshot, replay coverage, and explicit idempotency/upgrade guidance are appropriate. Validated 554 unit/retry-timeout tests, 199 focused strict-typing tests, and the registered activity against real local HTTP responses. The documented corrected-core release coordination remains required before publishing.
f0a5a38 to
3e534a2
Compare
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues block the opt-in durable HTTP retry change.
No open issues 🎉
What changed in this PR
Adds opt-in durable HTTP failure retries to the Azure Functions provider, reusing the core activity retry engine. Existing behavior remains unchanged when no policy is supplied, and subsequent 202 Location polls remain separate from failure retries.
Changes:
- Exposes
HttpRetryOptionsthroughcall_http(), with configurable timing and retryable statuses captured in the request. - Converts selected HTTP responses into activity failures and applies durable retries to the initial request.
- Adds regression coverage and documents retry semantics, replay safety, and release coordination with the core timeout fix in #326.
| File | Description |
|---|---|
tests/azure-functions-durable/test_http_retry.py |
Tests serialization, status selection, retries, exhaustion, replay, timeouts, and polling. |
azure-functions-durable/README.md |
Documents usage, compatibility, side-effect risks, and rollout requirements. |
azure-functions-durable/CHANGELOG.md |
Records the new capability and release dependency. |
azure-functions-durable/azure/durable_functions/internal/compat/orchestration_context.py |
Adds optional retry configuration to call_http(). |
azure-functions-durable/azure/durable_functions/http/models.py |
Defines HttpRetryOptions and snapshots policies in HTTP requests. |
azure-functions-durable/azure/durable_functions/http/builtin.py |
Classifies selected responses as failures and retries the initial activity. |
azure-functions-durable/azure/durable_functions/__init__.py |
Exports the public HttpRetryOptions class. |
Review effort: Balanced
Expose HttpRetryOptions for the initial call_http activity and reuse core durable retries without changing Location polling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
3e534a2 to
5ac55ff
Compare
Bernd Verst (berndverst)
left a comment
There was a problem hiding this comment.
Re-reviewed after #326 landed and #338 was restacked onto main. The HTTP-only patch is equivalent to the previously reviewed change, and the final head preserves the merged retry-timeout/undefined-offset fixes, invocation metadata propagation, modernization/warning guardrails, and changelog upgrade warnings. No actionable correctness, performance, API-compatibility, or replay regressions found. Validated 631 unit/retry-timeout tests and 219 focused strict-typing tests, plus provider lint and documentation checks. Release coordination still requires publishing the corrected core before the provider feature.
Fixes #268.
Depends on #326. This PR targets its replay-safe retry-timeout branch and adds only the Azure Functions HTTP layer.
Behavior
Adds public
HttpRetryOptionsand optionalretry_optionson compatibilitycontext.call_http(). The policy uses nativetimedeltadurations, snapshots timing and status selection into the request, and reuses the core durable activity retry engine for the initial HTTP request. No second retry engine or additional core changes are introduced.The attempt limit includes the initial attempt. Defaults are constant backoff, a six-day maximum retry interval, and an unbounded retry timeout. An omitted,
None, or empty status list selects every non-2xx response, including unfollowed redirects. A nonempty list is exact, including 202 when explicitly selected. Selected responses are closed before reading their bodies and become activity failures; exhausting retries failscall_httprather than returning the last selected response. Excluded statuses retain their complete response. Transport and other activity failures also use the policy.Compatibility and rollout
Omitting retry options preserves the existing scheduled input shape and behavior. Policies apply only to the initial request, not subsequent 202 Location GET polls, matching the JavaScript SDK and extension behavior. Existing response wrapping, URL validation, redirects, credentials, token acquisition, registration, and polling behavior remain intact.
Retry timeout uses orchestration time and does not cancel in-flight HTTP requests. Python checks elapsed time when a failure is handled; unlike the JavaScript core engine, it can schedule a delay that crosses the timeout boundary. The README documents this difference, side-effect/idempotency risks, and versioning or draining affected in-flight orchestrations when changing policies.
Package versions and dependency minimums are unchanged. The corrected core from #326 must be released before publishing this provider feature, with provider version and dependency minimum updates coordinated in a dedicated release PR.