instar 1.3.337 → 1.3.339
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/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +37 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/core/LearningVelocityScorer.d.ts +40 -0
- package/dist/core/LearningVelocityScorer.d.ts.map +1 -0
- package/dist/core/LearningVelocityScorer.js +67 -0
- package/dist/core/LearningVelocityScorer.js.map +1 -0
- package/dist/core/OwnerSuspectBreaker.d.ts +79 -0
- package/dist/core/OwnerSuspectBreaker.d.ts.map +1 -0
- package/dist/core/OwnerSuspectBreaker.js +106 -0
- package/dist/core/OwnerSuspectBreaker.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +17 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionRouter.d.ts +7 -0
- package/dist/core/SessionRouter.d.ts.map +1 -1
- package/dist/core/SessionRouter.js +14 -2
- package/dist/core/SessionRouter.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +4 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +62 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +4 -0
- package/upgrades/{1.3.337.md → 1.3.338.md} +41 -0
- package/upgrades/1.3.339.md +48 -0
- package/upgrades/side-effects/exo3-g5-ci-greening.md +29 -0
- package/upgrades/side-effects/owner-suspect-breaker.md +52 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgxRtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -9654,10 +9654,39 @@ export async function startServer(options) {
|
|
|
9654
9654
|
// Shared-cluster writes stay blocked on a standby. (bug #9: the moved session's
|
|
9655
9655
|
// saveSession was blocked by the standby read-only guard.)
|
|
9656
9656
|
state.setSessionPoolActive(true);
|
|
9657
|
+
// Per-peer suspect breaker (P19) — the markOwnerSuspect hook's missing
|
|
9658
|
+
// half. A peer whose deliveries exhaust retries is short-circuited for
|
|
9659
|
+
// a half-open 30s window: every session it owns goes straight to the
|
|
9660
|
+
// EXISTING failover re-place path instead of re-paying the ~4.5s retry
|
|
9661
|
+
// tax per message. Any successful delivery closes the window; sustained
|
|
9662
|
+
// suspicion (10min of consecutive windows) raises ONE degradation
|
|
9663
|
+
// signal per episode.
|
|
9664
|
+
const ownerSuspectBreaker = new (await import('../core/OwnerSuspectBreaker.js')).OwnerSuspectBreaker({
|
|
9665
|
+
logger: (m) => console.log(pc.dim(m)),
|
|
9666
|
+
reportSustained: ({ machineId, suspectForMs, marks }) => {
|
|
9667
|
+
DegradationReporter.getInstance().report({
|
|
9668
|
+
feature: 'SessionPool.ownerDelivery',
|
|
9669
|
+
primary: 'Messages forward to the machine that owns their session',
|
|
9670
|
+
fallback: `Owner ${machineId} unresponsive to deliveries for ~${Math.round(suspectForMs / 60_000)}min (${marks} suspect windows); its sessions re-place on dispatch; half-open re-probes continue`,
|
|
9671
|
+
reason: 'deliverMessage retries to the owning machine keep exhausting',
|
|
9672
|
+
impact: 'Sessions owned by that machine fail over to other machines on their next message instead of being delivered in place.',
|
|
9673
|
+
});
|
|
9674
|
+
},
|
|
9675
|
+
});
|
|
9657
9676
|
_sessionRouter = new routerMod.SessionRouter({
|
|
9658
9677
|
selfMachineId: meshSelfId,
|
|
9659
9678
|
placement: new placeMod.PlacementExecutor(),
|
|
9660
|
-
|
|
9679
|
+
// Placement must consult the breaker too: a message re-placed OFF a
|
|
9680
|
+
// suspect owner must not be placed right back ONTO it. Suspect
|
|
9681
|
+
// machines are filtered from the candidate set UNLESS that would
|
|
9682
|
+
// empty it — with every machine suspect, placement proceeds on the
|
|
9683
|
+
// full set (mirrors the all-machines-quota-blocked precedent:
|
|
9684
|
+
// degraded placement beats no placement).
|
|
9685
|
+
machineRegistry: () => {
|
|
9686
|
+
const all = machinePoolRegistry?.getCapacities() ?? [];
|
|
9687
|
+
const ok = all.filter((c) => !ownerSuspectBreaker.isSuspect(c.machineId));
|
|
9688
|
+
return ok.length > 0 ? ok : all;
|
|
9689
|
+
},
|
|
9661
9690
|
resolveOwnership: (sk) => {
|
|
9662
9691
|
const r = ownReg.read(sk);
|
|
9663
9692
|
if (!r)
|
|
@@ -9665,7 +9694,13 @@ export async function startServer(options) {
|
|
|
9665
9694
|
const status = r.status === 'released' ? null : r.status;
|
|
9666
9695
|
return { owner: ownReg.ownerOf(sk), epoch: r.ownershipEpoch, status, target: ownReg.placementTargetOf(sk) ?? undefined };
|
|
9667
9696
|
},
|
|
9668
|
-
|
|
9697
|
+
// Capacity-online AND not currently suspect: a slow-but-heartbeating
|
|
9698
|
+
// peer that keeps failing deliveries reads as not-alive for routing,
|
|
9699
|
+
// sending its sessions down the existing failover re-place path
|
|
9700
|
+
// without each message re-paying the retry tax.
|
|
9701
|
+
isMachineAlive: (m) => m === meshSelfId || ((machinePoolRegistry?.getCapacity(m)?.online ?? false) && !ownerSuspectBreaker.isSuspect(m)),
|
|
9702
|
+
markOwnerSuspect: (m) => ownerSuspectBreaker.markSuspect(m),
|
|
9703
|
+
onOwnerResponsive: (m) => ownerSuspectBreaker.recordSuccess(m),
|
|
9669
9704
|
casClaimOwnership: (sk, machineId) => {
|
|
9670
9705
|
const r = ownReg.cas({ type: 'place', machineId }, { sessionKey: sk, sender: meshSelfId, nonce: `${meshSelfId}:c:${++routerNonce}` });
|
|
9671
9706
|
return { ok: r.ok, epoch: ownReg.read(sk)?.ownershipEpoch ?? 0 };
|