A learned kind keeps one ready copy while its copies are leased
维护者通常 1 天内回复
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 20/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 停滞
- 技术栈
- react-native, typescript
- 领域
- backend
调研方向
Start with src/core/warm-pool/policy.ts and its tests in src/core/warm-pool/policy.test.ts; trace how learned target shortfalls use ready, leased and in-flight devices. Update the e2e coverage in e2e/warm-pool-learned.test.ts and the capacity and how-it-works pages. Done when the specified unit and e2e commands pass and haveOfKind has no remaining source matches.
由索引模型根据 Issue 内容生成。
描述
Part of #1374.
Scope
After this PR, a warm pool pass keeps max(peak − leased, 1) copies of each learned kind ready (ADR 0069), so the next lease of a learned kind finds a ready copy while its other copies are leased. Plain and baseline kinds alike. Leased counts every open lease of the kind that its peak counts, so a baseline kind counts the leased copies of all its versions, not only the newest (decided in delivery, pending the maintainer). Configured targets, the budget, displacement and the reaper's sparing are unchanged. The capacity and how-it-works pages say so.
In short
While a learned kind's copies are leased, the pool now boots a spare copy, so the next lease of that kind starts without a boot. It keeps at least 1 spare and at most the kind's peak (the most leases of that kind held at once in the last 24 hours).
flowchart LR
A[lease.granted] --> P[pool pass]
P --> W["wanted ready = max(peak − leased, 1) ← changed"]
W --> F[fill: boot or create the missing copies, within the budget]
| Peak | Leased | Ready kept today | After |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 3 | 3 | 0 | 1 |
| 3 | 1 | 2 | 2 |
| 3 | 0 | 3 | 3 |
If this goes wrong, a lease of a learned kind still waits tens of seconds for a boot while another copy of it is leased.
Technical spec
Facts
Commit ba6582dde.
| # | Fact | Source |
|---|---|---|
| F1 | A learned kind's shortfall is learnedCount − haveOfKind(...), beside the configured configuredCount − ready, less copies on their way (filling) |
src/core/warm-pool/policy.ts:671-675 |
| F2 | haveOfKind counts a kind's ready idle devices plus its leased, reclaiming and claimed non-provisioning devices; it is used only at F1's line |
src/core/warm-pool/policy.ts:441-461; git grep -n haveOfKind origin/main -- src → 2 hits, both policy.ts |
| F3 | Every virtual device is destroyed after one lease; a leased copy never comes back ready | docs/internal/adr/0061-every-virtual-device-is-a-copy-of-a-source-and-a-baseline-is-a-named-source.md:139-143 |
| F4 | A pass runs on lease.granted (and on lease.released, device.deleted and others) |
src/core/warm-pool/converger.ts:932-942 |
| F5 | pending(spec) counts a kind's in-flight boots and creations and the queue's proposals for it |
src/core/warm-pool/policy.ts:650-660 |
| F6 | targetedDevices spares up to max(configuredCount, learnedCount) of a kind's ready idle devices for the reaper |
src/core/warm-pool/policy.ts:527-530 |
| F7 | The existing test "fills configured targets … and counts a learned kind's leased, reclaiming and claimed devices as had" pins today's rule: 3 leased at peak 3 → [], 1 claimed ready at peak 1 → [], 2 leased + 1 reclaiming at peak 3 → [] |
src/core/warm-pool/policy.test.ts:1742-1796 |
| F8 | The reproduction "creates a ready copy of a learned baseline kind of count one while its only copy is leased, and while that copy is reclaiming" fails on main at its leased case | branch bug/1371-repro, src/core/warm-pool/policy.test.ts (+12 lines after 1796); pnpm exec vitest run --project unit src/core/warm-pool/policy.test.ts -t "baseline kind of count one" → AssertionError: expected [] to deeply equal [ { action: 'provision', … } ] (#1371 triage comment) |
| F9 | The report's count is max(configuredCount, learnedCount), the peak for a learned kind |
src/core/warm-pool/policy.ts:684 |
| F10 | The capacity page says the pool "keeps as many booted as were leased at the same time at the busiest moment of the last 24 hours, at least one" | website/src/content/docs/docs/worker/capacity.mdx:156 |
| F11 | The how-it-works page says it "keeps ready as many of each kind as were in use at the busiest moment" | website/src/content/docs/docs/introduction/how-it-works.mdx:71 |
| F13 | The fast-lane e2e test "creates nothing while the first lease is held, makes a new device of the kind in place of the deleted one, leaves it ready through a cleanup run, and grants the next lease of its kind warm" holds one lease with room for 2 devices, waits 1.5 s and expects 1 device; the warm pool is on in that environment | e2e/warm-pool-learned.test.ts:57-80; e2e/helpers/env.ts:459 (only the lane home sets enabled: false) |
| F12 | The warm-pool manual's Known gaps say "a burst larger than count pays the boot" |
src/core/warm-pool/AGENTS.md (Known gaps, "A warm target costs one create per lease") |
Modules touched
Searches: git grep -n 'haveOfKind\|learnedCount' origin/main -- src (11 hits, all src/core/warm-pool/policy.ts and its test); git grep -n -i 'while the first lease is held' origin/main -- e2e src (1 hit, F13); git grep -n -i 'busiest' origin/main -- website docs (2 hits, F10, F11).
flowchart LR
C[warm-pool/converger.ts] --> P["warm-pool/policy.ts: evaluate ✱"]
T["warm-pool/policy.test.ts ✱"] --> P
D["website capacity.mdx, how-it-works.mdx ✱"]
src/core/warm-pool/policy.ts: the learned shortfall in the targets step (F1) becomesmax(learnedCount − leasedOfKind, 1) − ready;haveOfKindis replaced by a count of the kind's devices under an open lease (view.leases), and deleted.src/core/warm-pool/policy.test.ts: the test of F7 and the reproduction of F8.e2e/warm-pool-learned.test.ts: the test of F13, rewritten to the new outcome.src/core/warm-pool/AGENTS.md: the Known gaps line of F12.website/src/content/docs/docs/worker/capacity.mdx,website/src/content/docs/docs/introduction/how-it-works.mdx: the lines of F10 and F11.
Contract and event changes
none. Searched src/contract/ for count, ready and short in the warm-pool target shape: the report's fields keep their meaning (F9).
Other code on the same state
Searches: git grep -n 'readyOfKind\|pending(\|targetedDevices' origin/main -- src/core/warm-pool (15 hits in policy.ts).
- Configured fill (
policy.ts:662-666): runs first and is unchanged; the learned shortfall still subtractsconfigured.added. - Reaper sparing (F6): spares up to the peak; the new wanted ready count is never above the peak, so every spare it plans is spared.
- Over-budget and displacement (
fillTarget,addDisplacing): unchanged; a spare that does not fit is reported short like any learned shortfall.
Failure modes
none. evaluate is pure and crosses no boundary; the converger acts on its proposals as it does today.
Rules in play
- ADR 0069 §1: "keeps
max(L − H, 1)devices ready" — the new shortfall, withHthe kind's devices under an open lease only. - ADR 0069 §2: "the larger of
Cless its ready devices andmax(L − H, 1)less its ready devices" — the merged entry. - ADR 0038 §3: "every configured count is filled before any learned count" — unchanged order.
- Warm-pool manual: "
policy.tsis pure" — the count readsview.leases, already in the view. - Documentation rule 9: the website pages of F10 and F11 change in the same PR.
Retired words
counts a learned kind's leased, reclaiming and claimed devices as had: a learned kind's leased copies lower its wanted ready count; reclaiming and claimed devices count as neither.creates nothing while the first lease is held: while a lease of a learned kind is held, the pool makes a spare of it.
Tests
Seam: evaluate in src/core/warm-pool/policy.ts, modelled on src/core/warm-pool/policy.test.ts ("learned kinds"). The test of F7 is rewritten to the new rule (testing rule 7), and the reproduction of F8 is folded into it. The user-seam line drives withDaemon with the fake iOS driver, modelled on and rewriting the test of F13 in e2e/warm-pool-learned.test.ts.
- A warm pool pass over a learned kind plans enough copies to keep
max(peak − leased, 1)ready, counting copies on their way, for a plain kind and a baseline kind alike: peak 1, 1 leased → 1 new; peak 1, 1 reclaiming → 1 new; peak 1, 1 ready under a claim → 1 new; peak 3, 3 leased → 1 new; peak 3, 2 leased + 1 reclaiming → 1 new; peak 3, 1 leased + 1 ready → 1 new; peak 3, 3 leased + 1 boot in flight (the view'sinFlight) → none; baseline kinddemopeak 1, 1 leased → 1 new; baseline kinddemopeak 2, 2 copies of version 1 leased while version 2 is newest → 1 new (decided in delivery, pending the maintainer). - A pass over a kind both configured and learned plans the larger of what each count lacks: configured 1 + learned peak 2, 1 leased, 0 ready → 1 new; configured 2 + learned peak 1, 1 leased, 0 ready → 2 new.
- A worker with no targets and room for a second device, holding a lease of a kind, grants the next lease of that kind warm, and after a release makes a new ready copy in place of the deleted one: first lease held → a second ready copy appears and a second lease is granted
warmwhile the first is held; first released → a new ready copy of the kind, not the released device.
Done when
pnpm exec vitest run --project unit src/core/warm-pool/passes, with the cases above.pnpm test:e2e e2e/warm-pool-learned.test.tspasses.git grep -n haveOfKind -- srcprints nothing.capacity.mdxandhow-it-works.mdxsay a learned kind keeps at least one spare ready while its copies are leased, and at most its peak.
Out of scope
- Configured targets, the budget, displacement, learning and forgetting.
configuration.mdx'swarmPool.enabledline (#1373).
Depends on
Written by an agent.
- 主要语言
- TypeScript
- 星标
- 535
- 派生
- 21
- 平均合并
- 9 小时 10 分钟
- 30 天内合并 PR
- 454
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
callstackincubator/simlock 的其他 Issue
-
os:windows request:new
难度 2/5 1-3 小时 新手友好度 70/100
callstackincubator/simlock#1071 ·
维护者通常 1 天内回复
-
feature:planned
难度 4/5 3-5 天 新手友好度 35/100
callstackincubator/simlock#1374 · 2 条评论 ·
维护者通常 1 天内回复
-
request:new
难度 3/5 1-2 天 新手友好度 55/100
callstackincubator/simlock#1372 ·
维护者通常 1 天内回复
-
bug:new
难度 4/5 1-2 天 新手友好度 55/100
callstackincubator/simlock#1371 · 2 条评论 ·
维护者通常 1 天内回复
-
task:ready
难度 3/5 1-2 天 新手友好度 74/100
callstackincubator/simlock#1365 ·
维护者通常 1 天内回复
查看 callstackincubator/simlock 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
pending close triaging
难度 2/5 1-3 小时 新手友好度 78/100
anomalyco/opencode#62582 · 1 条评论 ·
维护者通常 1 天内回复
-
feature request
难度 2/5 1-3 小时 新手友好度 72/100
callstack/react-native-paper#5189 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
live-codes/livecodes#1079 · 1 条评论 ·
维护者通常 1 天内回复
-
Add: ESP 2 RO未关闭approved check:passed streams:add
难度 2/5 1-3 小时 新手友好度 66/100
维护者通常 1 天内回复