Repository navigation
fix(sandbox): worker/本机路由满池时 sandbox.get 同样返回 down(#649 补全) - #662
Merged
yifanxuaaa merged 2 commits intoNov 13, 2026
Merged
yifanxuaaa merged 2 commits into
yifanxuaaa merged 2 commits into
Conversation
…emeral-AI-Lab#649) A Sandbox whose Workspace list runs in a machine's worker, or in this process (`Executor::Local`), sends the same daemon the same call, and a daemon whose pool has no vacant control slot refuses it before any handshake. The forwarded route already keeps that notice as the partial `down` counts (Ephemeral-AI-Lab#649); on these routes the refusal is the answer the call returned - `Capacity` with `resource: daemon_control_slot` and the notice's counts, and no `code` - and `get` propagated it, so the whole read failed `Capacity` with no `down_reason` and no `down`. One event read two ways is a defect. `get` now reads that one refusal as the forwarded route's down Sandbox: `slot_refused` names it (`Capacity` on `daemon_control_slot`, and nothing else), and the record is answered with its derived `state`, `workspaces: []`, the refusal's own message as `down_reason`, and `down` from the same notice through `direct::down_detail` (now `pub(crate)`, so both routes use one tagging action instead of a second implementation). `daemon_capacity` is absent: a notice is never mapped into that model, and the get dials nothing twice. A `Capacity` on another resource, a refusal an admitted connection returned (`values::refusal`'s `{phase}`), and `Busy` still fail the get. No RPC, no retry, no new wait: the admission window is still the product's 60 s, and mount, commit and unmount keep their own `Capacity`. Docs: `docs/architecture/api/sdk/sandbox/get.md` (the `down_reason` and `down` rows, the route diagram and the errors table), `docs/architecture/api/sdk/sandbox/README.md` (`get`'s row and the capacity paragraph), and `docs/architecture/control/routing/daemon-channel.md` (`sandbox.get`'s cell). Tests: new `layerfs-api` --test sandbox_capacity_worker (3 passed, 0.03 s). A stand-in worker answers its secret, reads one request and returns the full pool's `Capacity`; the get answers `state: running`, `workspaces: []`, the refusal's words and `down { code: Capacity, resource: daemon_control_slot, pool_vacant: 0, reserved_vacant: 1, retained: 3 }` and no other field, with no `daemon_capacity`, asking the worker once. Its two other cases pin that `Capacity` on another resource and `Busy` still fail the get, and that a `Capacity` carrying only `{phase}` fails it too. The same file on the unmodified head 03883a6: 1 failed / 2 passed (exit 100; the positive case got the bare `Capacity`), and with this change 3 passed. Checks: layerfs-sandbox 27 passed; layerfs-api --test sandbox_capacity (6 fast passed, and the two 60 s cases once each: 60.30 s and 60.37 s) with --test sandbox_capacity_worker, --test sandbox_family, --test sandbox_records and --test sandbox_lost 13 passed / 2 filtered; clippy --workspace --exclude layerfs-node --all-targets -D warnings clean; `cargo fmt --all -- --check` clean; tools/check_product_boundary.py PASS (1352 files); tools unittest 182 OK. Production LOC: 158705 -> 158715 (delta +10) Scope and method: first-party production Rust/SQL/JavaScript in core, engine, control and api (tests, fixtures, tools and docs excluded), counted with tools/production_loc.py on a `git archive` of 03883a6 and of this commit's staged tree. Control 39012 -> 39022 (+10, all of it layerfs-sandbox 8238 -> 8248); core 39787, engine 74342 and api 5564 unchanged. The new test file is not counted. Reference absent (retired R9c; last counted 65,417 at tree 498dd19).
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
Collaborator
Author
|
@yhcedpn @mengmengmengqiang 这个 PR 补上 #655 没覆盖到的 worker 与本机路由:daemon 满池时 sandbox.get 同样返回 down,而不是整个报 Capacity。形状与 #655 一致(复用 down_detail),生产代码 +10 行。已合入最新 layerfs_v2_0_0,Linux 全量 CI 通过。有空麻烦看一下,谢谢! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
相关:#649、#655
背景
#655 让转发路由在 daemon 满池时把容量通知带进
sandbox.get的down。worker 与本机自己拨的路由收到的是同一个拒绝,却仍以Capacity错误结束整个 get,两条路由对同一故障的回答不一致。改动
get.rs:仅当拒绝为Capacity且detail.resource == daemon_control_slot时,返回state=running、workspaces=[]、down_reason(daemon 原话)、down{code,resource,pool_vacant,reserved_vacant,retained};不二次拨号,daemon_capacity缺席。direct.rs:down_detail改为pub(crate),与转发路由共用同一打标签动作。Busy、已准入连接折叠成{phase}的拒绝)行为不变。sandbox/get.md、sandbox/README.md、routing/daemon-channel.md。layerfs_v2_0_0(be317c045)。验证
api/crates/layerfs-api/tests/sandbox_capacity_worker.rs(3 条):改前失败(exit 100),改后 3 passed;断言down只有 5 个键、worker 只被问 1 次。-D warnings、fmt、product boundary 通过。未覆盖