Skip to content

Commit 5644741

Browse files
author
Roy Lin
committed
chore(release): v2.5.2 — faster pipeline step-readiness (exponential backoff)
pipeline::wait_ready polls with exponential backoff (25ms -> ... -> 500ms cap, ~30s budget) instead of a fixed 500ms sleep, cutting per-step latency from ~500ms to ~100-200ms for multi-step pipelines. SDK-only; no API change. Bumps workspace to 2.5.2.
1 parent 84a7356 commit 5644741

4 files changed

Lines changed: 37 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to A3S Box will be documented in this file.
44

55
## [Unreleased]
66

7+
## [2.5.2] — 2026-06-22
8+
9+
### Changed
10+
11+
- **`a3s-box-sdk` pipeline: faster per-step readiness wait.** `pipeline::wait_ready`
12+
now polls with exponential backoff (25ms → … → 500ms cap, ~30s budget) instead of a
13+
fixed 500ms sleep, so a step's box is detected ready in ~100-200ms instead of ~500ms —
14+
cutting noticeable latency from multi-step pipelines. No API change.
15+
716
## [2.5.1] — 2026-06-22
817

918
SDK crate naming. No runtime behavior change.

src/Cargo.lock

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

src/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ resolver = "2"
2323
h2 = { path = "third_party/h2" }
2424

2525
[workspace.package]
26-
version = "2.5.1"
26+
version = "2.5.2"
2727
edition = "2021"
2828
authors = ["A3S Lab Team"]
2929
license = "MIT"

src/sdk/src/pipeline.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,18 @@ fn slug(s: &str) -> String {
149149

150150
/// Poll `exec <box> -- true` until the box is ready (box has no "wait-ready" verb).
151151
fn wait_ready(box_name: &str) -> Result<()> {
152-
wait_ready_inner(box_name, 60, 500)
152+
// ~30s total budget. A box is usually ready in ~100-300ms, so poll fast first
153+
// and back off — far lower per-step latency than a fixed long sleep.
154+
wait_ready_inner(box_name, std::time::Duration::from_secs(30))
153155
}
154156

155-
/// Polling core, parameterized so tests can drive the timeout path without waiting.
156-
fn wait_ready_inner(box_name: &str, tries: u32, delay_ms: u64) -> Result<()> {
157-
for _ in 0..tries {
157+
/// Polling core: exponential backoff (25ms → … → 500ms cap) bounded by `budget`.
158+
/// Parameterized so tests can drive the timeout path with a tiny budget.
159+
fn wait_ready_inner(box_name: &str, budget: std::time::Duration) -> Result<()> {
160+
let start = std::time::Instant::now();
161+
let mut delay = std::time::Duration::from_millis(25);
162+
let cap = std::time::Duration::from_millis(500);
163+
loop {
158164
let ready = Command::new(box_bin())
159165
.args(["exec", box_name, "--", "true"])
160166
.output()
@@ -163,9 +169,12 @@ fn wait_ready_inner(box_name: &str, tries: u32, delay_ms: u64) -> Result<()> {
163169
if ready {
164170
return Ok(());
165171
}
166-
std::thread::sleep(std::time::Duration::from_millis(delay_ms));
172+
if start.elapsed() >= budget {
173+
return Err(PipelineError::NotReady(box_name.to_string()));
174+
}
175+
std::thread::sleep(delay);
176+
delay = (delay * 2).min(cap);
167177
}
168-
Err(PipelineError::NotReady(box_name.to_string()))
169178
}
170179

171180
/// Content-addressed step cache: one marker file per successful step key.
@@ -574,9 +583,9 @@ esac
574583
box_cleanup(&["rm", "-f", "x"]); // best-effort: must not panic
575584
assert!(snapshot_id("any").is_err());
576585
assert!(warm_base(WarmBase::new("img", "echo hi")).is_err());
577-
// wait_ready returns NotReady when the box never becomes ready (fast: 2 tries, 0ms).
586+
// wait_ready times out (NotReady) when the box never readies (fast: 0 budget).
578587
assert!(matches!(
579-
wait_ready_inner("b", 2, 0),
588+
wait_ready_inner("b", std::time::Duration::from_millis(0)),
580589
Err(PipelineError::NotReady(_))
581590
));
582591

0 commit comments

Comments
 (0)