@coreplane/switchboard 1.239.0 → 1.240.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/config/config.example.yaml +6 -0
- package/dist/assets/deploy/cloudflare-memory/worker.ts +115 -1
- package/dist/assets/deploy/cloudflare-memory/wrangler.template.jsonc +7 -1
- package/dist/assets/deploy/cloudflare-resident/worker.ts +223 -70
- package/dist/assets/deploy/secrets.manifest.json +1 -1
- package/dist/assets/package-lock.json +207 -3
- package/dist/assets/package.json +2 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/authz/actor.ts +33 -2
- package/dist/assets/src/core/authz/policy.ts +6 -0
- package/dist/assets/src/core/coordinator/contract.ts +12 -1
- package/dist/assets/src/core/coordinator/driver.ts +13 -0
- package/dist/assets/src/core/costs.ts +1114 -0
- package/dist/assets/src/core/costsSnapshotStore.ts +209 -0
- package/dist/assets/src/core/delivery.ts +4 -11
- package/dist/assets/src/core/deliverySnapshotStore.ts +12 -28
- package/dist/assets/src/core/ingressTokens.ts +27 -13
- package/dist/assets/src/core/runLedger/types.ts +3 -0
- package/dist/assets/src/core/runRecord.ts +10 -3
- package/dist/assets/src/core/schedules.ts +2 -1
- package/dist/assets/src/core/ship/coordinator.ts +70 -0
- package/dist/assets/src/core/snapshotAge.ts +30 -0
- package/dist/assets/src/core/stateWorkerRef.ts +41 -0
- package/dist/assets/src/execution/residentAutoRebuild.ts +73 -0
- package/dist/assets/src/execution/residentRefresh.ts +25 -3
- package/dist/assets/src/execution/restoreWaiters.ts +61 -0
- package/dist/assets/src/mcp/registry.ts +7 -0
- package/dist/assets/web/dist/.vite/manifest.json +507 -427
- package/dist/assets/web/dist/assets/AppShell-CM_fh-WW.js +1 -0
- package/dist/assets/web/dist/assets/CostsPage-BD3w5j_S.js +2 -0
- package/dist/assets/web/dist/assets/DeliveryPage-BtvzKA1m.js +1 -0
- package/dist/assets/web/dist/assets/HomePage-BU6aRCSe.js +2 -0
- package/dist/assets/web/dist/assets/NotFoundPage-DwOX1HaZ.js +1 -0
- package/dist/assets/web/dist/assets/{ResidentDetailPage-CrfCd8fx.js → ResidentDetailPage-CUAOh5d9.js} +1 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-B3KUlYy2.js +1 -0
- package/dist/assets/web/dist/assets/RunFoldRow-Dulcbg25.js +1 -0
- package/dist/assets/web/dist/assets/RunRoutePage-DGoGrQZq.js +6 -0
- package/dist/assets/web/dist/assets/RunsIndexPage-37W7OZbC.js +1 -0
- package/dist/assets/web/dist/assets/{RunsTabs-XpCqeWu4.js → RunsTabs-BnkvCBrM.js} +1 -1
- package/dist/assets/web/dist/assets/ScheduledPage-C1y9jgAk.js +1 -0
- package/dist/assets/web/dist/assets/SettingsPage-ggfB-Rqr.js +1 -0
- package/dist/assets/web/dist/assets/SlackMark-VDNs7Vjh.js +1 -0
- package/dist/assets/web/dist/assets/Slideover-CX-LEklF.js +1 -0
- package/dist/assets/web/dist/assets/{StatusDot-DkXALvKf.js → StatusDot-CiByEtoR.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-DtLIyi5P.js → Tooltip-DyRxk8A8.js} +1 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-CnWyOizV.js +1 -0
- package/dist/assets/web/dist/assets/{angular-html-DYtV9uIN.js → angular-html-DAQ_1T1v.js} +1 -1
- package/dist/assets/web/dist/assets/{angular-ts-DF2P25Zp.js → angular-ts-D4kxRVp1.js} +1 -1
- package/dist/assets/web/dist/assets/{apl-Ff96wxko.js → apl-Dy07l64y.js} +1 -1
- package/dist/assets/web/dist/assets/{astro-LbBnZna-.js → astro-DZIbTlc7.js} +1 -1
- package/dist/assets/web/dist/assets/{blade-DltuxeBW.js → blade-CmSXWX3l.js} +1 -1
- package/dist/assets/web/dist/assets/{c-DBg7yuPx.js → c-ggzVdJLK.js} +1 -1
- package/dist/assets/web/dist/assets/{chapel-C83hUAds.js → chapel-Bo1wktsG.js} +1 -1
- package/dist/assets/web/dist/assets/{cobol-DB0yV_2D.js → cobol-DJUmtKM2.js} +1 -1
- package/dist/assets/web/dist/assets/{coffee-Bpih6Kzl.js → coffee-BZWOVz4C.js} +1 -1
- package/dist/assets/web/dist/assets/{cpp-CU00ZeRn.js → cpp-Dtk39yMw.js} +1 -1
- package/dist/assets/web/dist/assets/{crystal-f8ImJkux.js → crystal-CGf_-Zoj.js} +1 -1
- package/dist/assets/web/dist/assets/{css-4VrC4ISo.js → css-CX2fcL4u.js} +1 -1
- package/dist/assets/web/dist/assets/delivery-CTdOqpVK.js +1 -0
- package/dist/assets/web/dist/assets/{dist-DtA7JiH5.js → dist-D8TaC961.js} +2 -2
- package/dist/assets/web/dist/assets/durationTone-DXG-3R7_.js +1 -0
- package/dist/assets/web/dist/assets/{edge-BwFDzfS_.js → edge-BYS8FtgQ.js} +1 -1
- package/dist/assets/web/dist/assets/{elixir-wwIYIpJm.js → elixir-fhUpi3nO.js} +1 -1
- package/dist/assets/web/dist/assets/{elm-DyDuM3v3.js → elm-DAQNiwsN.js} +1 -1
- package/dist/assets/web/dist/assets/{erb-DFJBEVrh.js → erb-CWzEys6U.js} +1 -1
- package/dist/assets/web/dist/assets/eventSource-tRprhqm7.js +1 -0
- package/dist/assets/web/dist/assets/favicon-D1hkyC5j.js +1 -0
- package/dist/assets/web/dist/assets/{git-rebase-CuDv-44X.js → git-rebase-9rY3p-Rw.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-js-ZFnrm4J3.js → glimmer-js-tY7hy0nE.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-ts-XY4Yqshp.js → glimmer-ts-CTrLv5JF.js} +1 -1
- package/dist/assets/web/dist/assets/{glsl-xnR8efx0.js → glsl-BRJbiDfq.js} +1 -1
- package/dist/assets/web/dist/assets/{graphql-D-gO5tnP.js → graphql-B-MtVLh2.js} +1 -1
- package/dist/assets/web/dist/assets/{hack-CSxbW4ax.js → hack-BtIkOypQ.js} +1 -1
- package/dist/assets/web/dist/assets/{haml-D4ar42QT.js → haml-CoOH6gfa.js} +1 -1
- package/dist/assets/web/dist/assets/{handlebars-CMLbDE7o.js → handlebars-DgrRu-GP.js} +1 -1
- package/dist/assets/web/dist/assets/{html-CVekU4Fs.js → html-DZaaI7ca.js} +1 -1
- package/dist/assets/web/dist/assets/{html-derivative-St3HHw_N.js → html-derivative-DgHvT-qZ.js} +1 -1
- package/dist/assets/web/dist/assets/{http-Mon0DWHS.js → http-CvAd51yz.js} +1 -1
- package/dist/assets/web/dist/assets/{hurl-Cbl5IvBs.js → hurl-CXGqAfzx.js} +1 -1
- package/dist/assets/web/dist/assets/{localIso-CNA-bhS-.js → indexFormat-B-pd4r7Y.js} +1 -1
- package/dist/assets/web/dist/assets/{indexRow-FLJu5mR9.js → indexRow-Cse3JGb0.js} +1 -1
- package/dist/assets/web/dist/assets/{java-Bprck1l-.js → java-CIQStIXF.js} +1 -1
- package/dist/assets/web/dist/assets/{javascript-C73G1-UR.js → javascript-WbH8s7E3.js} +1 -1
- package/dist/assets/web/dist/assets/{jinja-C4DuRxYJ.js → jinja-DzyWEVKC.js} +1 -1
- package/dist/assets/web/dist/assets/{jison-B2U03GEC.js → jison-CrT-zCa-.js} +1 -1
- package/dist/assets/web/dist/assets/{json-CvTZUDzx.js → json-lHjpjXMQ.js} +1 -1
- package/dist/assets/web/dist/assets/{jsx-DMWKCzwo.js → jsx-WTwYCHW6.js} +1 -1
- package/dist/assets/web/dist/assets/{julia-Czn7bV_3.js → julia-Bqpk9H7E.js} +1 -1
- package/dist/assets/web/dist/assets/{just-BBxpNfvC.js → just-LdXk1r3m.js} +1 -1
- package/dist/assets/web/dist/assets/{latex-Bw9yg5mr.js → latex-h_y2A5KD.js} +1 -1
- package/dist/assets/web/dist/assets/{liquid-BRCjaydE.js → liquid-CY7bF2_p.js} +1 -1
- package/dist/assets/web/dist/assets/localIso-L06jV29p.js +1 -0
- package/dist/assets/web/dist/assets/{lua-DUu2KIC0.js → lua-oQ7XVZOY.js} +1 -1
- package/dist/assets/web/dist/assets/main-CGO6fQ8k.js +28 -0
- package/dist/assets/web/dist/assets/main-O8UXRuEv.css +1 -0
- package/dist/assets/web/dist/assets/{marko-CZJZIlSQ.js → marko-zv_qZ4QV.js} +1 -1
- package/dist/assets/web/dist/assets/{mdc-BmClq6fd.js → mdc-Dl4kL_YK.js} +1 -1
- package/dist/assets/web/dist/assets/{nginx-Bmt3xSEm.js → nginx-CAHCZj4F.js} +1 -1
- package/dist/assets/web/dist/assets/{nim-Da-i0utK.js → nim-BOtmwCJH.js} +1 -1
- package/dist/assets/web/dist/assets/{org-BvAre2qP.js → org-DspQk3HQ.js} +1 -1
- package/dist/assets/web/dist/assets/{perl-v9WwFFtB.js → perl-CAXmvVl0.js} +1 -1
- package/dist/assets/web/dist/assets/{php-DTU4Zyze.js → php-CMUx4VyM.js} +1 -1
- package/dist/assets/web/dist/assets/{pug-DhTwEqTO.js → pug-B55xVJTv.js} +1 -1
- package/dist/assets/web/dist/assets/{qml-BUD9AC_c.js → qml-DsNKCCRk.js} +1 -1
- package/dist/assets/web/dist/assets/{r-CAnu56n7.js → r-DbhP0VvO.js} +1 -1
- package/dist/assets/web/dist/assets/{razor-Dn0P4gAq.js → razor-BCpE6P-p.js} +1 -1
- package/dist/assets/web/dist/assets/{regexp-CZyBRaVW.js → regexp-BllsjiN4.js} +1 -1
- package/dist/assets/web/dist/assets/{rst-Ckyd5UsY.js → rst-CO5Rpq9V.js} +1 -1
- package/dist/assets/web/dist/assets/{ruby-BBQ62fsx.js → ruby-C2A4OgQq.js} +1 -1
- package/dist/assets/web/dist/assets/{sas-CW35hMxG.js → sas-Butzoyql.js} +1 -1
- package/dist/assets/web/dist/assets/{scss-CpV8pF4J.js → scss-PEUwJBpf.js} +1 -1
- package/dist/assets/web/dist/assets/settingsApi-priOPiwu.js +1 -0
- package/dist/assets/web/dist/assets/{shellscript-CRJvsmE1.js → shellscript-3Yhq0khE.js} +1 -1
- package/dist/assets/web/dist/assets/{shellsession-CyriUZxf.js → shellsession-04Hkb7m3.js} +1 -1
- package/dist/assets/web/dist/assets/{soy-D5QzYUeg.js → soy-BnId73cP.js} +1 -1
- package/dist/assets/web/dist/assets/{sql-CUBf_Mse.js → sql-BKwdc0ch.js} +1 -1
- package/dist/assets/web/dist/assets/sseReplay-DutHNghE.js +9 -0
- package/dist/assets/web/dist/assets/{stata-B-4n4ITz.js → stata-BPPtNkay.js} +1 -1
- package/dist/assets/web/dist/assets/{surrealql-RuWZBLtr.js → surrealql-CDPChcYP.js} +1 -1
- package/dist/assets/web/dist/assets/{svelte-CO5YzCsK.js → svelte-B15DIQ-z.js} +1 -1
- package/dist/assets/web/dist/assets/{templ-DbkWVaBF.js → templ-D-rp_AiB.js} +1 -1
- package/dist/assets/web/dist/assets/{tex-IuxoEcId.js → tex-BnVDCD7p.js} +1 -1
- package/dist/assets/web/dist/assets/{ts-tags-g6dGQPjd.js → ts-tags-cpujdyAR.js} +1 -1
- package/dist/assets/web/dist/assets/{tsx-WnXwiyH2.js → tsx-D1vO4L72.js} +1 -1
- package/dist/assets/web/dist/assets/{twig-Lx1G7PnY.js → twig-oQGnQGRc.js} +1 -1
- package/dist/assets/web/dist/assets/{typescript-BQd7biLF.js → typescript-CKSFpXiH.js} +1 -1
- package/dist/assets/web/dist/assets/{typst-D2lXPHK7.js → typst-DKHFo8BF.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-4wVQD9y9.js → vue-BstokpiS.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-html-DZPaRte4.js → vue-html-DpCp0_Sz.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-vine-DbmZCmu-.js → vue-vine-y5d5wUb1.js} +1 -1
- package/dist/assets/web/dist/assets/{xml-DV16szyo.js → xml-Br2hx5Ax.js} +1 -1
- package/dist/assets/web/dist/assets/{xsl-eo5-1sk0.js → xsl-Bc8Cobap.js} +1 -1
- package/dist/assets/web/dist/assets/{yaml-BXdX8HZf.js → yaml-LOITy_I1.js} +1 -1
- package/dist/cli.js +2314 -1571
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/AppShell-MYHNxJks.js +0 -1
- package/dist/assets/web/dist/assets/CostsPage-DKk9OjB0.js +0 -2
- package/dist/assets/web/dist/assets/DeliveryPage-Kz6js49i.js +0 -1
- package/dist/assets/web/dist/assets/NotFoundPage-BXLrQQzy.js +0 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-BdW0k2h3.js +0 -1
- package/dist/assets/web/dist/assets/RunFoldRow-CbTd9SiS.js +0 -9
- package/dist/assets/web/dist/assets/RunRoutePage-br0H-8Pz.js +0 -6
- package/dist/assets/web/dist/assets/RunsIndexPage-Bnzb15zH.js +0 -1
- package/dist/assets/web/dist/assets/ScheduledPage-NLhjzHAz.js +0 -1
- package/dist/assets/web/dist/assets/SettingsPage-D-i0uVw-.js +0 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-DGXukEAH.js +0 -1
- package/dist/assets/web/dist/assets/durationTone-CYMux25J.js +0 -1
- package/dist/assets/web/dist/assets/favicon-CSt-qDvc.js +0 -1
- package/dist/assets/web/dist/assets/main-CFHF2RvQ.css +0 -1
- package/dist/assets/web/dist/assets/main-Dht0in4v.js +0 -28
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// A resident `down` on a reason only a rebuild can escape is rebuilt on that
|
|
2
|
+
// transition, under a budget (docs/reference/specs/resident-repos.md item 36).
|
|
3
|
+
// Pure: the Worker's `goDown` and the watchdog's backstop both call
|
|
4
|
+
// `autoRebuildDecision` over the history row they persist
|
|
5
|
+
// (`resident:autoRebuilds`, ISO instants of the auto-rebuilds this resident
|
|
6
|
+
// has had), so the transition and the backstop cannot disagree.
|
|
7
|
+
|
|
8
|
+
/** The `down` reasons a rebuild is the only exit from: a down resident runs no
|
|
9
|
+
* cycle, and these say the snapshot (or the container that would restore it)
|
|
10
|
+
* cannot be used — never a provision failure, which would loop against the
|
|
11
|
+
* same broken build. `runtime-unreachable` is item 64's last rung: a recreated
|
|
12
|
+
* container that did not answer either. */
|
|
13
|
+
export const REHYDRATION_FAILURE_RE = /^(r2-restore-failed|snapshot-stamp-mismatch|no-snapshot|runtime-unreachable)/;
|
|
14
|
+
|
|
15
|
+
/** How many auto-rebuilds one resident gets inside one window. A rebuild is a
|
|
16
|
+
* clone, an install and a build (minutes to half an hour) that holds the cap
|
|
17
|
+
* slot and writes a fresh snapshot; a resident that comes back `warm` and
|
|
18
|
+
* goes `down` again on the same class of reason is flapping on something a
|
|
19
|
+
* rebuild does not fix, and the third time it stays down where a person can
|
|
20
|
+
* see it. */
|
|
21
|
+
export const AUTO_REBUILD_BUDGET = 2;
|
|
22
|
+
export const AUTO_REBUILD_WINDOW_MS = 24 * 60 * 60_000;
|
|
23
|
+
|
|
24
|
+
/** The stamp a spent budget leaves on the reason — the one mark the decision
|
|
25
|
+
* reads back so the watchdog's passes never judge the same down twice. */
|
|
26
|
+
const SPENT_MARK = " — auto-rebuild budget spent (";
|
|
27
|
+
|
|
28
|
+
export type AutoRebuildDecision =
|
|
29
|
+
/** Rebuild now; `history` is what to persist (pruned, this instant appended); `reason` is the rebuild's. */
|
|
30
|
+
| { action: "rebuild"; history: string[]; reason: string }
|
|
31
|
+
/** Stay down; `reason` is the down reason stamped with the budget; `history` is pruned. */
|
|
32
|
+
| { action: "budget-spent"; history: string[]; reason: string }
|
|
33
|
+
| { action: "not-eligible"; why: "reason" | "already-spent" };
|
|
34
|
+
|
|
35
|
+
/** A `down` reason the transition (or the watchdog) may rebuild from: a
|
|
36
|
+
* rehydration failure that no spent budget has stamped yet. */
|
|
37
|
+
export function isAutoRebuildEligible(reason: string): boolean {
|
|
38
|
+
return REHYDRATION_FAILURE_RE.test(reason) && !reason.includes(SPENT_MARK);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Judge one `down`. `history` are the ISO instants of this resident's past
|
|
42
|
+
* auto-rebuilds; entries outside the window (or unparseable) are dropped
|
|
43
|
+
* before counting and before writing back. */
|
|
44
|
+
export function autoRebuildDecision(input: {
|
|
45
|
+
reason: string;
|
|
46
|
+
history: readonly string[];
|
|
47
|
+
now: number;
|
|
48
|
+
}): AutoRebuildDecision {
|
|
49
|
+
if (!REHYDRATION_FAILURE_RE.test(input.reason)) return { action: "not-eligible", why: "reason" };
|
|
50
|
+
if (input.reason.includes(SPENT_MARK)) return { action: "not-eligible", why: "already-spent" };
|
|
51
|
+
const windowStart = input.now - AUTO_REBUILD_WINDOW_MS;
|
|
52
|
+
const kept = input.history
|
|
53
|
+
.map((iso) => ({ iso, at: Date.parse(iso) }))
|
|
54
|
+
.filter((e) => Number.isFinite(e.at) && e.at > windowStart)
|
|
55
|
+
.sort((a, b) => a.at - b.at);
|
|
56
|
+
const hours = Math.round(AUTO_REBUILD_WINDOW_MS / 3_600_000);
|
|
57
|
+
if (kept.length >= AUTO_REBUILD_BUDGET) {
|
|
58
|
+
// No reopen instant on the stamp: a stamped row is never judged again and
|
|
59
|
+
// a down resident runs no cycle, so nothing resumes when the window
|
|
60
|
+
// passes — only a person's rebuild recovers it, and the stamp says so.
|
|
61
|
+
return {
|
|
62
|
+
action: "budget-spent",
|
|
63
|
+
history: kept.map((e) => e.iso),
|
|
64
|
+
reason: `${input.reason}${SPENT_MARK}${AUTO_REBUILD_BUDGET} in ${hours} h) — repo rebuild resets it`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const history = [...kept.map((e) => e.iso), new Date(input.now).toISOString()];
|
|
68
|
+
return {
|
|
69
|
+
action: "rebuild",
|
|
70
|
+
history,
|
|
71
|
+
reason: `auto-rebuild (${history.length} of ${AUTO_REBUILD_BUDGET} in ${hours} h): ${input.reason}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -180,7 +180,7 @@ export function killStaleBuildProcessesCommand(user: string, dir: string): strin
|
|
|
180
180
|
* a tool naming the signal. A bare "killed" is NOT enough — compilers and
|
|
181
181
|
* OOM messages say it too — and a step the cycle itself timed out is a real
|
|
182
182
|
* failure however it died. */
|
|
183
|
-
const INTERRUPTION_SIGNATURE = /\bexit 143\b|Session terminated|SIGTERM
|
|
183
|
+
const INTERRUPTION_SIGNATURE = /\bexit 143\b|Session terminated|SIGTERM|^restore-interrupted:/;
|
|
184
184
|
|
|
185
185
|
/** Message wording of the Sandbox SDK's runtime-replacement error family — the
|
|
186
186
|
* container went away UNDER a live SDK call, so the failure never reaches the
|
|
@@ -396,12 +396,34 @@ export function isRuntimeUnreachableReason(reason: string): boolean {
|
|
|
396
396
|
* means the stream ran on before the replacement. */
|
|
397
397
|
export function restoreFailureDisposition(
|
|
398
398
|
message: string,
|
|
399
|
-
facts: { runtimeReplaced?: boolean } = {},
|
|
399
|
+
facts: { runtimeReplaced?: boolean; runtimeActive?: boolean } = {},
|
|
400
400
|
): { action: "interrupted"; reason: string } | { action: "down"; reason: string } {
|
|
401
401
|
const timedOut = /\(timed out\)/.test(message);
|
|
402
|
-
if (
|
|
402
|
+
if (timedOut) {
|
|
403
|
+
return {
|
|
404
|
+
action: "down",
|
|
405
|
+
reason: `r2-restore-failed: ${message} — container stopped so the transfer cannot land on a rebuild`,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
// The kill signature the instance step's classifier reads
|
|
409
|
+
// (INTERRUPTION_SIGNATURE): a container roll SIGTERMs the extract, whose
|
|
410
|
+
// exec comes back a normal `exit 143` result — the SDK's replacement
|
|
411
|
+
// wording only reaches the execs that follow. Same event, same reading.
|
|
412
|
+
if (
|
|
413
|
+
facts.runtimeReplaced === true ||
|
|
414
|
+
RUNTIME_REPLACEMENT_WORDING.test(message) ||
|
|
415
|
+
INTERRUPTION_SIGNATURE.test(message)
|
|
416
|
+
) {
|
|
403
417
|
return { action: "interrupted", reason: `restore-interrupted: ${message}` };
|
|
404
418
|
}
|
|
419
|
+
// The Worker's probe after the failure: a runtime that is no longer active
|
|
420
|
+
// took the disk the extract wrote to with it, whatever the exit code said.
|
|
421
|
+
if (facts.runtimeActive === false) {
|
|
422
|
+
return {
|
|
423
|
+
action: "interrupted",
|
|
424
|
+
reason: `restore-interrupted: ${message} — the container stopped under the restore`,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
405
427
|
return {
|
|
406
428
|
action: "down",
|
|
407
429
|
reason: `r2-restore-failed: ${message} — container stopped so the transfer cannot land on a rebuild`,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** The ledger of held `/await-restore` requests (docs/reference/specs/execution.md
|
|
2
|
+
* item 27): each waiter is one resolver held in memory until the resident's
|
|
3
|
+
* lifecycle state leaves `restoring`, when `publish` answers every held
|
|
4
|
+
* request at once with the state it landed on. Event-driven by construction —
|
|
5
|
+
* no polling and no retry timer anywhere: the one publish is the state
|
|
6
|
+
* transition itself (`setResidentState`). In-DO memory only: a Durable Object
|
|
7
|
+
* restart drops the held RPCs with the waiters, and the bot's own request
|
|
8
|
+
* deadline turns that into a named cold fallback, never a hang. */
|
|
9
|
+
export interface RestoreOutcome {
|
|
10
|
+
/** The lifecycle state the resident landed on when the restore span ended. */
|
|
11
|
+
state: string;
|
|
12
|
+
reason: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** One registered waiter: the outcome it will be answered with, and the way
|
|
16
|
+
* to withdraw it when the caller learns it need not wait after all. */
|
|
17
|
+
export interface RestoreHold {
|
|
18
|
+
outcome: Promise<RestoreOutcome>;
|
|
19
|
+
/** Take the waiter off the ledger; a no-op once a publish answered it. */
|
|
20
|
+
withdraw(): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class RestoreWaiters {
|
|
24
|
+
private waiters: Array<(outcome: RestoreOutcome) => void> = [];
|
|
25
|
+
|
|
26
|
+
/** How many requests are held right now (the ledger's size, for tests and logs). */
|
|
27
|
+
get size(): number {
|
|
28
|
+
return this.waiters.length;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Register a waiter for the next publish. Register BEFORE reading the
|
|
32
|
+
* state you are waiting to leave: a transition that lands between the read
|
|
33
|
+
* and the registration would otherwise publish to a ledger this request is
|
|
34
|
+
* not on yet, and hold it for a transition that may never come. A caller
|
|
35
|
+
* whose read then says the wait is over withdraws. */
|
|
36
|
+
hold(): RestoreHold {
|
|
37
|
+
let resolve!: (outcome: RestoreOutcome) => void;
|
|
38
|
+
const outcome = new Promise<RestoreOutcome>((r) => (resolve = r));
|
|
39
|
+
this.waiters.push(resolve);
|
|
40
|
+
return {
|
|
41
|
+
outcome,
|
|
42
|
+
withdraw: () => {
|
|
43
|
+
const at = this.waiters.indexOf(resolve);
|
|
44
|
+
if (at !== -1) this.waiters.splice(at, 1);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Hold one request until the next publish. */
|
|
50
|
+
wait(): Promise<RestoreOutcome> {
|
|
51
|
+
return this.hold().outcome;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Answer every held request with the state the resident landed on and
|
|
55
|
+
* empty the ledger; a publish with nothing held is a no-op. */
|
|
56
|
+
publish(outcome: RestoreOutcome): void {
|
|
57
|
+
const held = this.waiters;
|
|
58
|
+
this.waiters = [];
|
|
59
|
+
for (const resolve of held) resolve(outcome);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -234,6 +234,13 @@ export interface McpServerView {
|
|
|
234
234
|
addedByName?: string;
|
|
235
235
|
addedAt?: number;
|
|
236
236
|
promotedFrom?: string;
|
|
237
|
+
/** `promotedFrom` as a display name, when the lookup answered. */
|
|
238
|
+
promotedFromName?: string;
|
|
239
|
+
/** A user row's owner (the id after `user:` in `scopeKey`) as a display name, when the lookup answered. */
|
|
240
|
+
ownerName?: string;
|
|
241
|
+
/** A higher tier holds this name, so runs use that entry and this one is idle (`mcpServersFor`'s
|
|
242
|
+
* `shadowedBy`, the winning scope key — `org`, or `channel:<id>`); absent when this entry serves. */
|
|
243
|
+
shadowedBy?: string;
|
|
237
244
|
}
|
|
238
245
|
|
|
239
246
|
export function serverView(
|