Box cancelled-turn settlement out of the resume_task future

Merged
VA
1d ago
+27-14

Class

API futures over budget. The future-size budget is 4,096 bytes (task_runtime/tests/future_sizes.rs). On main, resume_task is 9,296 bytes, so the existing future-size test fails.

Invariant

Cancelled-turn settlement is the cold path. Its state (host.cancel plus settle_task, a 6,480-byte future) lives in its own bounded allocation, never inline in the resume_task state machine. Every resume future therefore stays within the 4,096-byte API budget.

Root cause (bisect)

The growth came from #626 (d5b0f17d0, "Rewrite GraphCoder…"). It was not #875, #864 or #804. #626 added an inline async { cancel; settle_task } block to resume_task.

Future (windows-gnu, -Zprint-type-sizes)Merge base 3b62cd1c4Main
resume_task2,4409,296
settle_task6,4806,480
verify_owner4,7364,736
Error / WorkLease104 / 1,032104 / 1,032

#626's block is the only change to worker.rs in that range.

Fix

  • The block becomes settle_cancelled. It is awaited through BoundedContentFuture::new(io, …), the existing boxed-and-accounted future wrapper, so the allocation is charged like other cold-path content futures.
  • resume_task drops from 9,296 to 2,616 bytes.
  • The limit is unchanged.

Why it can't recur

The existing future_size test pins resume_task under the 4,096-byte budget. It fails on main at 9,296, which is the negative control, and passes here.

Settlement now has a single entry point (settle_cancelled), so it can't be reinlined into the resume future without the test catching it.

Validation (bb1)

CheckResult
Build1,354 s
future_size2 passed, 38 ms
filesystem::task_runtime::36 passed, 1.2 s
client::local_headless8 passed, 300 ms
local::tests::live_ui (tui)2 passed
Windows check (x86_64-pc-windows-gnu)passed, 259 s

canonical_chunks_render_before_completion_and_cancel_settles still fails with the render timeout it shows on main (main-health/latest.txt; it depends on #823/#839). The test times out before it reaches the cancel step.

Finding: future-size regression on main (resume_task at 9,296 bytes against a 4,096-byte limit).

Deletions: the 14-line inline settle block is removed.

🤖 Generated with Claude Code


Summary by cubic

Fixes the resume_task future exceeding the 4,096-byte API budget. The GraphCoder rewrite (#626) grew it from 2,440 to 9,296 bytes by inlining cancelled-turn settlement; that block now runs as settle_cancelled behind BoundedContentFuture::new, so settlement state is boxed instead of carried in every resume future. resume_task drops to 2,616 bytes.

  • Settlement now has a single entry point, settle_cancelled.
  • canonical_chunks_render_before_completion_and_cancel_settles still fails with a pre-existing render timeout on main (depends on #823/#839).