@mark1russell7/kind 0.11.8 → 0.11.10
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/build/index.d.ts +77 -3
- package/build/index.js +223 -22
- package/build/index.js.map +1 -1
- package/build/{judge-Cs91dOGO.js → judge-BIXZEX__.js} +150 -17
- package/build/judge-BIXZEX__.js.map +1 -0
- package/build/{judge-DnB9wEwC.d.ts → judge-DLxpBamt.d.ts} +75 -6
- package/build/judge.d.ts +2 -2
- package/build/judge.js +1 -1
- package/image/agent.mjs +58 -1
- package/package.json +2 -2
- package/build/judge-Cs91dOGO.js.map +0 -1
|
@@ -121,6 +121,16 @@ const dropOf = (lines, node, backend, after, source = "rules") => rulesOf(lines,
|
|
|
121
121
|
const emptyOf = (lines, node, after) => rulesOf(lines).find((line) => line.node === node && line.t >= after && line.b.length === 0) ?? null;
|
|
122
122
|
/** This function gives when an EndpointSlice of the Service first had no ready endpoint, after a time. */
|
|
123
123
|
const sliceEmptyOf = (lines, svc, after) => slicesOf(lines, svc).find((slice) => slice.t >= after && !slice.eps.some((endpoint) => endpoint.r === true))?.t ?? null;
|
|
124
|
+
/** This function gives when an EndpointSlice of the Service first had a ready endpoint, after a time. */
|
|
125
|
+
const sliceReadyOf = (lines, svc, after) => slicesOf(lines, svc).find((slice) => slice.t >= after && slice.eps.some((endpoint) => endpoint.r === true))?.t ?? null;
|
|
126
|
+
/**
|
|
127
|
+
* This function tells if the latest EndpointSlice of the Service at a time had a ready endpoint. A
|
|
128
|
+
* slice line comes only at a change, thus with no line before the time, it gives null.
|
|
129
|
+
*/
|
|
130
|
+
const sliceReadyAt = (lines, svc, at) => {
|
|
131
|
+
const latest = slicesOf(lines, svc).filter((slice) => slice.t <= at).at(-1);
|
|
132
|
+
return latest === void 0 ? null : latest.eps.some((endpoint) => endpoint.r === true);
|
|
133
|
+
};
|
|
124
134
|
/** This function gives when the endpoint of an address was first not ready in the EndpointSlice of the Service, after a time. */
|
|
125
135
|
const sliceDropOf = (lines, svc, ip, after) => slicesOf(lines, svc).find((slice) => slice.t >= after && !slice.eps.some((endpoint) => endpoint.ip === ip && endpoint.r === true))?.t ?? null;
|
|
126
136
|
/** This function gives the latest state of each pod at a time, by its name. A deleted pod is not in it. */
|
|
@@ -264,6 +274,18 @@ const referenceOf = (run, from, pod = run.target?.pod) => {
|
|
|
264
274
|
return intakeOf(lines, pod, run.start);
|
|
265
275
|
};
|
|
266
276
|
/**
|
|
277
|
+
* This function gives the cycles of a run: each fault and its heal (`KindRun.acts.cycles`). A run
|
|
278
|
+
* without cycles gives its one fault and heal, or none when it does not have both stamps.
|
|
279
|
+
*/
|
|
280
|
+
const cyclesOf = (run) => {
|
|
281
|
+
if (run.acts.cycles !== void 0) return run.acts.cycles;
|
|
282
|
+
const { fault, heal } = run.acts;
|
|
283
|
+
return fault === null || heal === null ? [] : [{
|
|
284
|
+
fault,
|
|
285
|
+
heal
|
|
286
|
+
}];
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
267
289
|
* This function gives the source of the propagation of a cell. In a sidecar mesh, the client sidecar
|
|
268
290
|
* picks the backend of each call from its endpoints (EDS), thus the source is `eds`. Each other cell
|
|
269
291
|
* goes through the rules of kube-proxy (`rules`).
|
|
@@ -398,6 +420,74 @@ const factsOf = (cell, run) => {
|
|
|
398
420
|
} : {}
|
|
399
421
|
};
|
|
400
422
|
};
|
|
423
|
+
/**
|
|
424
|
+
* This function judges a removal with flaps. In each cycle, the Service has no ready endpoint, and the
|
|
425
|
+
* rules of each node have no backend, in the band after its fault. Each time comes before the fault of
|
|
426
|
+
* the next cycle. At the fault of each cycle after the first, the Service has a ready endpoint and the
|
|
427
|
+
* rules of each node a backend. After the last heal, the Service has a ready endpoint again. The main
|
|
428
|
+
* value is the empty Service of the first cycle.
|
|
429
|
+
*/
|
|
430
|
+
const removalOfCycles = (cell, run, prediction, done) => {
|
|
431
|
+
const lines = run.lines;
|
|
432
|
+
const cycles = cyclesOf(run);
|
|
433
|
+
if (cycles.length === 0) return done(false, "the run has no cycle of a fault and its heal", null);
|
|
434
|
+
const band = secondsOf(prediction.band);
|
|
435
|
+
const nodes = [...new Set(lines.filter((line) => line.ev === "rules").map((line) => String(line["node"])))].sort();
|
|
436
|
+
const problems = [];
|
|
437
|
+
const times = [];
|
|
438
|
+
let rules = {};
|
|
439
|
+
cycles.forEach((cycle, k) => {
|
|
440
|
+
const n = k + 1;
|
|
441
|
+
const next = cycles[k + 1]?.fault ?? run.end;
|
|
442
|
+
if (k > 0) {
|
|
443
|
+
if (sliceReadyAt(lines, "lab", cycle.fault) !== true) problems.push(`the Service had no ready endpoint at the fault of the cycle ${n}`);
|
|
444
|
+
const backends = backendsAt(lines, cycle.fault);
|
|
445
|
+
for (const node of nodes) if ((backends.get(node) ?? []).length === 0) problems.push(`the rules of ${node} had no backend at the fault of the cycle ${n}`);
|
|
446
|
+
}
|
|
447
|
+
const empty = sliceEmptyOf(lines, "lab", cycle.fault);
|
|
448
|
+
const value = empty === null || empty > next ? null : sec(empty - cycle.fault);
|
|
449
|
+
if (value === null) problems.push(`the Service kept a ready endpoint in the cycle ${n}`);
|
|
450
|
+
else if (!inBand(value, band)) problems.push(`the EndpointSlice had no ready endpoint at ${value} s in the cycle ${n}`);
|
|
451
|
+
const own = {};
|
|
452
|
+
for (const node of nodes) {
|
|
453
|
+
const drop = emptyOf(lines, node, cycle.fault);
|
|
454
|
+
const at = drop === null || drop.t > next ? null : sec(drop.t - cycle.fault);
|
|
455
|
+
own[node] = at === null ? null : seconds(at);
|
|
456
|
+
if (at === null) problems.push(`the rules of ${node} kept a backend in the cycle ${n}`);
|
|
457
|
+
else if (!inBand(at, {
|
|
458
|
+
lo: band.lo,
|
|
459
|
+
hi: band.hi + .05
|
|
460
|
+
})) problems.push(`the rules of ${node} had no backend at ${at} s in the cycle ${n}`);
|
|
461
|
+
}
|
|
462
|
+
if (k === 0) rules = own;
|
|
463
|
+
const ready = sliceReadyOf(lines, "lab", cycle.heal);
|
|
464
|
+
const back = ready === null || ready > next ? null : sec(ready - cycle.heal);
|
|
465
|
+
if (k === cycles.length - 1 && back === null) problems.push("the Service had no ready endpoint after the last heal");
|
|
466
|
+
times.push({
|
|
467
|
+
empty: value === null ? null : seconds(value),
|
|
468
|
+
ready: back === null ? null : seconds(back)
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
const first = times[0].empty === null ? null : valueIn(times[0].empty, "s");
|
|
472
|
+
const inner = prediction.window === void 0 ? null : checkRun({
|
|
473
|
+
...cell,
|
|
474
|
+
prediction: prediction.window
|
|
475
|
+
}, run);
|
|
476
|
+
if (inner !== null && !inner.ok) problems.push(inner.why);
|
|
477
|
+
const empties = times.map((each) => each.empty === null ? "none" : `${valueIn(each.empty, "s")} s`).join(", ");
|
|
478
|
+
const agrees = `the Service was empty in each of ${cycles.length} cycles, at ${empties} after its fault${inner === null ? "" : `; ${inner.why}`}`;
|
|
479
|
+
const more = {
|
|
480
|
+
...inner === null ? {} : inner.facts,
|
|
481
|
+
...first === null ? {} : { sliceEmpty: seconds(first) },
|
|
482
|
+
rules,
|
|
483
|
+
cycles: times
|
|
484
|
+
};
|
|
485
|
+
const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join("; "), first, more);
|
|
486
|
+
return inner?.tail === void 0 ? checked : {
|
|
487
|
+
...checked,
|
|
488
|
+
tail: inner.tail
|
|
489
|
+
};
|
|
490
|
+
};
|
|
401
491
|
/** This function judges one run against the prediction of its cell. */
|
|
402
492
|
const checkRun = (cell, run) => {
|
|
403
493
|
const lines = run.lines;
|
|
@@ -434,10 +524,23 @@ const checkRun = (cell, run) => {
|
|
|
434
524
|
};
|
|
435
525
|
const pods = each ? (facts.deletions ?? []).map((deleted) => deleted.pod) : [run.target?.pod];
|
|
436
526
|
if (pods.length === 0) return done(false, "no replica of the run got a deletion", null);
|
|
527
|
+
const flaps = prediction.flaps === true;
|
|
528
|
+
const cyclic = (from) => from === "fault" || from === "heal";
|
|
529
|
+
if (flaps && (each || !cyclic(prediction.start.from) || prediction.end !== null && !cyclic(prediction.end.from))) return done(false, "a window with flaps has no each, and its references are the fault and the heal", null);
|
|
530
|
+
const cycles = flaps ? cyclesOf(run) : [];
|
|
531
|
+
if (flaps && cycles.length === 0) return done(false, "the run has no cycle of a fault and its heal", null);
|
|
532
|
+
const sources = flaps ? cycles.map((cycle) => ({
|
|
533
|
+
pod: run.target?.pod,
|
|
534
|
+
cycle
|
|
535
|
+
})) : pods.map((pod) => ({
|
|
536
|
+
pod,
|
|
537
|
+
cycle: void 0
|
|
538
|
+
}));
|
|
437
539
|
const windows = [];
|
|
438
|
-
for (const pod of
|
|
439
|
-
const
|
|
440
|
-
const
|
|
540
|
+
for (const { pod, cycle } of sources) {
|
|
541
|
+
const at = (from) => cycle !== void 0 && cyclic(from) ? cycle[from] : referenceOf(run, from, pod);
|
|
542
|
+
const start = at(prediction.start.from);
|
|
543
|
+
const end = prediction.end === null ? null : at(prediction.end.from);
|
|
441
544
|
if (start === null || prediction.end !== null && end === null) return done(false, `the run has no ${start === null ? prediction.start.from : prediction.end.from} reference${each ? ` for ${pod}` : ""}`, null);
|
|
442
545
|
const origin = each ? referenceOf(run, "deletion", pod) : facts.deletion ?? (cell.trigger.kind === "crash" ? run.acts.fault : null);
|
|
443
546
|
const ip = run.replicas.find((replica) => replica.pod === pod)?.ip;
|
|
@@ -504,19 +607,27 @@ const checkRun = (cell, run) => {
|
|
|
504
607
|
const wrong = allowed === void 0 ? [] : relevant.filter((request) => !late.includes(request) && !allowed.includes(request.o));
|
|
505
608
|
const bounds = (window) => `[${sec(window.lo - window.start)}, ${sec(window.hi - window.start)}] s`;
|
|
506
609
|
const problems = [];
|
|
507
|
-
if (outside.length > 0) problems.push(each ? `${outside.length} failed requests outside the window of each deleted replica: ${windows.map((window) => `${window.pod} ${bounds(window)}`).join(", ")} after its ${prediction.start.from}` : `${outside.length} failed requests outside ${bounds(windows[0])} after ${prediction.start.from}`);
|
|
610
|
+
if (outside.length > 0) problems.push(each ? `${outside.length} failed requests outside the window of each deleted replica: ${windows.map((window) => `${window.pod} ${bounds(window)}`).join(", ")} after its ${prediction.start.from}` : flaps ? `${outside.length} failed requests outside the window of each cycle: ${windows.map((window, k) => `${k + 1} ${bounds(window)}`).join(", ")} after its ${prediction.start.from}` : `${outside.length} failed requests outside ${bounds(windows[0])} after ${prediction.start.from}`);
|
|
508
611
|
if (others.length > 0) problems.push(`${others.length} failed requests on nodes whose kube-proxy did not pause`);
|
|
509
612
|
if (wrong.length > 0) problems.push(`${wrong.length} failed requests in the window ended ${JSON.stringify(outcomesOf(wrong))}, not ${allowed.join(", ")}`);
|
|
510
613
|
if (prediction.certain && relevant.length === 0) problems.push("no request failed in a window that the law opens");
|
|
511
614
|
const final = windows.reduce((a, b) => (b.end ?? Number.NEGATIVE_INFINITY) > (a.end ?? Number.NEGATIVE_INFINITY) ? b : a);
|
|
512
|
-
if (
|
|
615
|
+
if (flaps && prediction.certain && relevant.length > 0) windows.forEach((window, k) => {
|
|
616
|
+
const own = relevant.filter((request) => request.t >= window.lo && request.t <= window.hi);
|
|
617
|
+
if (own.length === 0) problems.push(`no request failed in the window of the cycle ${k + 1}`);
|
|
618
|
+
else if (window.end !== null) {
|
|
619
|
+
const earliest = window.end + closes.lo * 1e3 - NOISE - SLACK;
|
|
620
|
+
if (own.at(-1).t < earliest) problems.push(`the last failed request of the cycle ${k + 1} started ${sec(earliest - own.at(-1).t)} s before its window can end`);
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
if (!flaps && prediction.certain && final.end !== null && relevant.length > 0) {
|
|
513
624
|
const last = relevant.at(-1).t;
|
|
514
625
|
const earliest = final.end + closes.lo * 1e3 - NOISE - SLACK;
|
|
515
626
|
if (last < earliest) problems.push(`the last failed request started ${sec(earliest - last)} s before the window can end`);
|
|
516
627
|
}
|
|
517
628
|
const inside = relevant.filter((request) => !late.includes(request));
|
|
518
629
|
const span = inside.length === 0 ? 0 : sec(inside.at(-1).t - inside[0].t);
|
|
519
|
-
const where = each ? `the windows of ${windows.length} deleted replicas` : "the window";
|
|
630
|
+
const where = each ? `the windows of ${windows.length} deleted replicas` : flaps ? `the windows of ${windows.length} cycles` : "the window";
|
|
520
631
|
const agrees = reused.length === 0 ? `${relevant.length} failed requests, all in ${where} (span ${span} s)` : `${inside.length} failed requests in ${where} (span ${span} s), and ${reused.length} on a port that a reset closed`;
|
|
521
632
|
const checked = done(problems.length === 0, problems.length === 0 ? agrees : problems.join("; "), relevant.length);
|
|
522
633
|
if (problems.length > 0) return checked;
|
|
@@ -546,6 +657,7 @@ const checkRun = (cell, run) => {
|
|
|
546
657
|
case "removal": {
|
|
547
658
|
const fault = run.acts.fault;
|
|
548
659
|
if (fault === null) return done(false, "the run has no fault stamp", null);
|
|
660
|
+
if (prediction.flaps === true) return removalOfCycles(cell, run, prediction, done);
|
|
549
661
|
const empty = sliceEmptyOf(lines, "lab", fault);
|
|
550
662
|
if (empty === null) return done(false, "the Service kept a ready endpoint", null);
|
|
551
663
|
const value = sec(empty - fault);
|
|
@@ -589,7 +701,9 @@ const checkRun = (cell, run) => {
|
|
|
589
701
|
const problems = [];
|
|
590
702
|
if (!inBand(value, band)) problems.push(`${run.target.pod} left the EndpointSlice at ${value} s`);
|
|
591
703
|
const propagation = propagationOf(run, fault, void 0, propagationSource(cell));
|
|
704
|
+
const lost = cell.trigger.kind === "zone-loss" ? run.paused : null;
|
|
592
705
|
for (const [node, drop] of Object.entries(propagation)) {
|
|
706
|
+
if (node === lost) continue;
|
|
593
707
|
const by = drop === null ? null : valueIn(drop.by, "s");
|
|
594
708
|
if (by === null) problems.push(`the rules of ${node} kept ${run.target.pod}`);
|
|
595
709
|
else if (!inBand(by, {
|
|
@@ -992,7 +1106,7 @@ const upgradeFacts = (facts) => {
|
|
|
992
1106
|
by: seconds(old.by)
|
|
993
1107
|
};
|
|
994
1108
|
const byKey = (record) => Object.fromEntries(Object.entries(record).map(([key, old]) => [key, propagated(old)]));
|
|
995
|
-
const { sliceEmpty, rules, left, signals, updates, healUpdates, closes, ...rest } = facts;
|
|
1109
|
+
const { sliceEmpty, rules, left, signals, updates, healUpdates, closes, cycles, ...rest } = facts;
|
|
996
1110
|
return {
|
|
997
1111
|
...rest,
|
|
998
1112
|
intakeAfterDeletion: time$1(facts.intakeAfterDeletion),
|
|
@@ -1004,7 +1118,11 @@ const upgradeFacts = (facts) => {
|
|
|
1004
1118
|
...rules === void 0 ? {} : { rules: Object.fromEntries(Object.entries(rules).map(([node, old]) => [node, time$1(old)])) },
|
|
1005
1119
|
...left === void 0 ? {} : { left: seconds(left) },
|
|
1006
1120
|
...signals === void 0 ? {} : { signals: signals.map((old) => time$1(old)) },
|
|
1007
|
-
...closes === void 0 ? {} : { closes: Object.fromEntries(Object.entries(closes).map(([client, old]) => [client, time$1(old)])) }
|
|
1121
|
+
...closes === void 0 ? {} : { closes: Object.fromEntries(Object.entries(closes).map(([client, old]) => [client, time$1(old)])) },
|
|
1122
|
+
...cycles === void 0 ? {} : { cycles: cycles.map((old) => ({
|
|
1123
|
+
empty: time$1(old.empty),
|
|
1124
|
+
ready: time$1(old.ready)
|
|
1125
|
+
})) }
|
|
1008
1126
|
};
|
|
1009
1127
|
};
|
|
1010
1128
|
/**
|
|
@@ -1074,8 +1192,8 @@ const atBand = (from, band) => {
|
|
|
1074
1192
|
const predictionText = (prediction) => {
|
|
1075
1193
|
switch (prediction.kind) {
|
|
1076
1194
|
case "none": return prediction.outcomes === void 0 ? "no failure" : `no ${prediction.outcomes.join(", ")}`;
|
|
1077
|
-
case "window": return `failures only from ${atBand(prediction.start.from, prediction.start.band)}${prediction.end === null ? "" : ` to ${atBand(prediction.end.from, prediction.end.band)}`}${prediction.each === true ? ", of each deleted replica" : ""}${prediction.nodes === "paused" ? ", on the paused node" : ""}${prediction.certain ? ", at least one" : ""}${prediction.outcomes === void 0 ? "" : `, each one ${prediction.outcomes.join(" or ")}`}${prediction.afterReset === void 0 ? "" : `, or a ${prediction.afterReset.outcome} up to ${format(prediction.afterReset.life)} after a reset on its port`}${prediction.propagation === void 0 ? "" : `, the rules drop the replica in ${showBand(prediction.propagation)}`}`;
|
|
1078
|
-
case "removal": return `Service empty in ${showBand(prediction.band)}${prediction.window === void 0 ? "" : `; ${predictionText(prediction.window)}`}`;
|
|
1195
|
+
case "window": return `failures only from ${atBand(prediction.start.from, prediction.start.band)}${prediction.end === null ? "" : ` to ${atBand(prediction.end.from, prediction.end.band)}`}${prediction.each === true ? ", of each deleted replica" : ""}${prediction.flaps === true ? ", in each cycle" : ""}${prediction.nodes === "paused" ? ", on the paused node" : ""}${prediction.certain ? ", at least one" : ""}${prediction.outcomes === void 0 ? "" : `, each one ${prediction.outcomes.join(" or ")}`}${prediction.afterReset === void 0 ? "" : `, or a ${prediction.afterReset.outcome} up to ${format(prediction.afterReset.life)} after a reset on its port`}${prediction.propagation === void 0 ? "" : `, the rules drop the replica in ${showBand(prediction.propagation)}`}`;
|
|
1196
|
+
case "removal": return `Service empty in ${showBand(prediction.band)}${prediction.flaps === true ? " after each fault, and ready again before the next" : ""}${prediction.window === void 0 ? "" : `; ${predictionText(prediction.window)}`}`;
|
|
1079
1197
|
case "leaves": return `the replica leaves in ${showBand(prediction.band)}${prediction.window === void 0 ? "" : `; ${predictionText(prediction.window)}`}`;
|
|
1080
1198
|
case "restarts": return prediction.band === null ? "no restart" : `each replica SIGTERM in ${showBand(prediction.band)}`;
|
|
1081
1199
|
case "stays": return "stays ready, no refusal";
|
|
@@ -1107,7 +1225,7 @@ const cellsTable = (judged) => [
|
|
|
1107
1225
|
...judged.map((each) => {
|
|
1108
1226
|
const { cell, verdict } = each;
|
|
1109
1227
|
const runs = verdict.voided === 0 ? `${verdict.counted}` : `${verdict.counted} (+${verdict.voided} void)`;
|
|
1110
|
-
return `| ${cell.name} | ${cell.id} | ${cell.mode} | ${cell.trigger.kind} | ${predictionText(cell.prediction)} | ${verdict.decision} | ${runs} | ${medianText(each)} |`;
|
|
1228
|
+
return `| ${cell.name} | ${cell.id} | ${cell.mode} | ${cell.trigger.kind}${cell.trigger.flaps === void 0 || cell.trigger.flaps.length === 0 ? "" : ` (${cell.trigger.flaps.length + 1} faults)`} | ${predictionText(cell.prediction)} | ${verdict.decision} | ${runs} | ${medianText(each)} |`;
|
|
1111
1229
|
})
|
|
1112
1230
|
].join("\n");
|
|
1113
1231
|
/**
|
|
@@ -1189,7 +1307,8 @@ const TRIGGERS = [
|
|
|
1189
1307
|
"idle",
|
|
1190
1308
|
"ztunnel-restart",
|
|
1191
1309
|
"certificate-expiry",
|
|
1192
|
-
"cannot-serve"
|
|
1310
|
+
"cannot-serve",
|
|
1311
|
+
"zone-loss"
|
|
1193
1312
|
];
|
|
1194
1313
|
const MODES = [
|
|
1195
1314
|
"iptables",
|
|
@@ -1286,7 +1405,11 @@ const run = z.object({
|
|
|
1286
1405
|
acts: z.object({
|
|
1287
1406
|
fault: z.number().nullable(),
|
|
1288
1407
|
heal: z.number().nullable(),
|
|
1289
|
-
resume: z.number().nullable()
|
|
1408
|
+
resume: z.number().nullable(),
|
|
1409
|
+
cycles: z.array(z.object({
|
|
1410
|
+
fault: z.number(),
|
|
1411
|
+
heal: z.number()
|
|
1412
|
+
})).optional()
|
|
1290
1413
|
}),
|
|
1291
1414
|
target: replica.nullable(),
|
|
1292
1415
|
paused: z.string().nullable(),
|
|
@@ -1360,6 +1483,7 @@ const recordOf = (a, main) => {
|
|
|
1360
1483
|
}).optional(),
|
|
1361
1484
|
each: z.boolean().optional(),
|
|
1362
1485
|
propagation: band.optional(),
|
|
1486
|
+
flaps: z.boolean().optional(),
|
|
1363
1487
|
outcomes: z.array(z.string()).optional(),
|
|
1364
1488
|
why: z.string()
|
|
1365
1489
|
});
|
|
@@ -1374,6 +1498,7 @@ const recordOf = (a, main) => {
|
|
|
1374
1498
|
kind: z.literal("removal"),
|
|
1375
1499
|
band,
|
|
1376
1500
|
window: window.optional(),
|
|
1501
|
+
flaps: z.boolean().optional(),
|
|
1377
1502
|
why: z.string()
|
|
1378
1503
|
}),
|
|
1379
1504
|
z.object({
|
|
@@ -1440,7 +1565,11 @@ const recordOf = (a, main) => {
|
|
|
1440
1565
|
quiet: z.boolean().optional(),
|
|
1441
1566
|
close: z.boolean().optional(),
|
|
1442
1567
|
partition: z.boolean().optional(),
|
|
1443
|
-
serves: z.boolean().optional()
|
|
1568
|
+
serves: z.boolean().optional(),
|
|
1569
|
+
flaps: z.array(z.object({
|
|
1570
|
+
rest: time,
|
|
1571
|
+
hold: time
|
|
1572
|
+
})).optional()
|
|
1444
1573
|
}),
|
|
1445
1574
|
pod: z.object({
|
|
1446
1575
|
replicas: count,
|
|
@@ -1494,7 +1623,11 @@ const recordOf = (a, main) => {
|
|
|
1494
1623
|
after: a.nullable(),
|
|
1495
1624
|
by: a
|
|
1496
1625
|
}).nullable()).optional(),
|
|
1497
|
-
closes: z.record(z.string(), a.nullable()).optional()
|
|
1626
|
+
closes: z.record(z.string(), a.nullable()).optional(),
|
|
1627
|
+
cycles: z.array(z.object({
|
|
1628
|
+
empty: a.nullable(),
|
|
1629
|
+
ready: a.nullable()
|
|
1630
|
+
})).optional()
|
|
1498
1631
|
});
|
|
1499
1632
|
return {
|
|
1500
1633
|
cell,
|
|
@@ -1556,6 +1689,6 @@ const readRecord = (data) => {
|
|
|
1556
1689
|
throw new Error(`a kind cell record has the format ${FORMAT} or ${FORMAT_V1}, not ${String(format)}`);
|
|
1557
1690
|
};
|
|
1558
1691
|
//#endregion
|
|
1559
|
-
export {
|
|
1692
|
+
export { rulesOf as $, RELATIVE as A, dropOf as B, observationEnd as C, reusesReset as D, referenceOf as E, TCP_STATE as F, kernelCounts as G, failuresOf as H, backendsAt as I, podsOf as J, outcomesOf as K, byClients as L, middle as M, quantileOf as N, unitOf as O, HBONE_PORT as P, restartsAt as Q, byNode as R, observationAfter as S, showBand as St, propagationSource as T, intakeOf as U, emptyOf as V, isTunnelState as W, requestsOf as X, recordsOf as Y, restartOf as Z, checkRun as _, REDIS as _t, calibrationOf as a, sliceReadyOf as at, factsOf as b, seconds as bt, predictionText as c, stoppingOf as ct, FORMAT_V1 as d, ztunnelPodsOf as dt, signalOf as et, judge as f, ztunnelReplaced as ft, LAST_SLACK as g, PORT as gt, KIND_NOISE as h, LOG_LABEL as ht, readRecord as i, sliceReadyAt as it, medianInterval as j, updatesOf as k, timeSpread as l, transitionOf as lt, upgradeCell as m, HEALTH_PORT as mt, kindCellRecordSchema as n, sliceDropOf as nt, cellsTable as o, slicesOf as ot, upgrade as p, CLIENT as pt, podsAt as q, kindCellRecordV1Schema as r, sliceEmptyOf as rt, medianText as s, socketsOf as st, STAGES as t, signalsOf as tt, FORMAT as u, tunnelsOf as ut, cyclesOf as v, SERVER as vt, propagationOf as w, judgeKind as x, secondsOf as xt, deletionsOf as y, bandOf as yt, deletionOf as z };
|
|
1560
1693
|
|
|
1561
|
-
//# sourceMappingURL=judge-
|
|
1694
|
+
//# sourceMappingURL=judge-BIXZEX__.js.map
|