Skip to content

Commit 5053d35

Browse files
mraszykclaudelwshang
authored
chore: release 0.49.2 — retry SERVICE_UNAVAILABLE (bounded) (#688)
* chore: retry StatusCode::SERVICE_UNAVAILABLE * changelog * chore: nudge PR sync Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: clarify SERVICE_UNAVAILABLE retry in changelog Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * . * fix: bound SERVICE_UNAVAILABLE retries like TOO_MANY_REQUESTS The 503 retry branch looped forever (no cap, no deadline), unlike the 429 branch which gives up after 6 retries. A persistent 503 hung the caller indefinitely. This also broke the wasm browser test job, whose mock service worker uses 503 as its "handler threw" sentinel. Merge the two branches so 503 shares the same 6-retry cap as 429. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: release 0.49.2 — retry SERVICE_UNAVAILABLE (bounded) Bump all workspace crates 0.49.1 -> 0.49.2. Patch release: the HTTP retry logic now also retries 503 SERVICE_UNAVAILABLE, sharing the same 6-retry bound as 429 TOO_MANY_REQUESTS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Linwei Shang <linwei.shang@dfinity.org>
1 parent e3d9394 commit 5053d35

4 files changed

Lines changed: 22 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## Unreleased
1010

11+
## [0.49.2] - 2026-07-23
12+
13+
* `ic-agent`: The HTTP retry logic now also retries requests that fail with `StatusCode::SERVICE_UNAVAILABLE` (503), in addition to `TOO_MANY_REQUESTS` (429). This prevents non-idempotent calls from spuriously failing while polling for their status against a replica that is temporarily unhealthy (e.g. has no recent certified state, or a full ingress pool). Both status codes share the same retry bound (up to 6 retries).
14+
1115
## [0.49.1] - 2026-07-20
1216

1317
* `ic-agent`: Replaced the unmaintained `backoff` dependency with `backon` for the `request_status` polling backoff, using `backon`'s `ExponentialBackoff` iterator directly. The schedule is unchanged (500ms initial delay, growing by 1.4x up to 1s, jittered). `max_polling_time` now bounds the cumulative backoff sleep (via `backon`'s `with_total_delay`) rather than wall-clock elapsed time; in practice they differ only by per-poll request latency.

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ members = [
1313
]
1414

1515
[workspace.package]
16-
version = "0.49.1"
16+
version = "0.49.2"
1717
authors = ["DFINITY Stiftung <sdk@dfinity.org>"]
1818
edition = "2021"
1919
repository = "https://github.com/dfinity/agent-rs"
@@ -30,10 +30,10 @@ license = "Apache-2.0"
3030
# a comment listing those crates). Otherwise, features are declared in the individual crate Cargo.toml.
3131
#
3232
# The path dependencies below ensure all workspace members use the same version of internal crates.
33-
ic-agent = { path = "ic-agent", version = "0.49.1", default-features = false }
34-
ic-identity-hsm = { path = "ic-identity-hsm", version = "0.49.1" }
35-
ic-transport-types = { path = "ic-transport-types", version = "0.49.1" }
36-
ic-utils = { path = "ic-utils", version = "0.49.1" }
33+
ic-agent = { path = "ic-agent", version = "0.49.2", default-features = false }
34+
ic-identity-hsm = { path = "ic-identity-hsm", version = "0.49.2" }
35+
ic-transport-types = { path = "ic-transport-types", version = "0.49.2" }
36+
ic-utils = { path = "ic-utils", version = "0.49.2" }
3737
ic-utils-bindgen = { path = "ic-utils-bindgen" }
3838
ref-tests = { path = "ref-tests" }
3939

ic-agent/src/agent/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ impl Agent {
220220
/// Create an instance of an [`Agent`].
221221
pub fn new(config: agent_config::AgentConfig) -> Result<Agent, AgentError> {
222222
let client = config.http_service.unwrap_or_else(|| {
223-
Arc::new(Retry429Logic {
223+
Arc::new(RetryLogic {
224224
client: config.client.unwrap_or_else(|| {
225225
#[cfg(not(target_family = "wasm"))]
226226
{
@@ -2406,13 +2406,13 @@ where
24062406
}
24072407

24082408
#[derive(Debug)]
2409-
struct Retry429Logic {
2409+
struct RetryLogic {
24102410
client: Client,
24112411
}
24122412

24132413
#[cfg_attr(target_family = "wasm", async_trait(?Send))]
24142414
#[cfg_attr(not(target_family = "wasm"), async_trait)]
2415-
impl HttpService for Retry429Logic {
2415+
impl HttpService for RetryLogic {
24162416
async fn call<'a>(
24172417
&'a self,
24182418
req: &'a (dyn Fn() -> Result<http::Request<Bytes>, AgentError> + Send + Sync),
@@ -2436,7 +2436,9 @@ impl HttpService for Retry429Logic {
24362436
to_http_response(resp, _size_limit).await?
24372437
};
24382438

2439-
if resp.status() == StatusCode::TOO_MANY_REQUESTS {
2439+
if resp.status() == StatusCode::TOO_MANY_REQUESTS
2440+
|| resp.status() == StatusCode::SERVICE_UNAVAILABLE
2441+
{
24402442
if retries == 6 {
24412443
break Ok(resp);
24422444
} else {

0 commit comments

Comments
 (0)