@mark1russell7/kind 0.13.4 → 0.14.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/build/index.d.ts +157 -8
- package/build/index.js +716 -42
- package/build/index.js.map +1 -1
- package/build/{judge-DKrgfhAt.js → judge-C6XgY2Pk.js} +335 -5
- package/build/judge-C6XgY2Pk.js.map +1 -0
- package/build/{judge-BZFTT0RL.d.ts → judge-Cp3MzMk1.d.ts} +181 -3
- package/build/judge.d.ts +2 -2
- package/build/judge.js +1 -1
- package/package.json +2 -2
- package/build/judge-DKrgfhAt.js.map +0 -1
|
@@ -356,6 +356,236 @@ const restartsAt = (lines, at) => {
|
|
|
356
356
|
return out;
|
|
357
357
|
};
|
|
358
358
|
//#endregion
|
|
359
|
+
//#region src/reconnects.ts
|
|
360
|
+
const delaysOf = (backoff) => ({
|
|
361
|
+
initial: valueIn(backoff.initial, "ms"),
|
|
362
|
+
max: valueIn(backoff.max, "ms"),
|
|
363
|
+
stop: valueIn(backoff.mandatoryStop, "ms"),
|
|
364
|
+
jitter: backoff.jitter
|
|
365
|
+
});
|
|
366
|
+
/**
|
|
367
|
+
* This function gives the times of the tries of one path: each delay times `share`, and `latency`
|
|
368
|
+
* from each try to the next call. The tries end with the first one after `until`.
|
|
369
|
+
*/
|
|
370
|
+
const pathOf = (delays, share, latency, until) => {
|
|
371
|
+
const tries = [];
|
|
372
|
+
let next = delays.initial;
|
|
373
|
+
let call = 0;
|
|
374
|
+
let made = false;
|
|
375
|
+
for (let count = 0; count < 1e3; count += 1) {
|
|
376
|
+
let current = next;
|
|
377
|
+
next = Math.min(2 * next, delays.max);
|
|
378
|
+
if (!made && call + current > delays.stop) {
|
|
379
|
+
current = Math.max(delays.initial, delays.stop - call);
|
|
380
|
+
made = true;
|
|
381
|
+
}
|
|
382
|
+
const at = call + Math.max(delays.initial, current * share);
|
|
383
|
+
tries.push(at);
|
|
384
|
+
if (at > until) break;
|
|
385
|
+
call = at + latency;
|
|
386
|
+
}
|
|
387
|
+
return tries;
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* This function gives the band of each try after the first delay starts, up to the first try whose
|
|
391
|
+
* earliest time is after `until`. The earliest path has the most jitter and no time for a try. The
|
|
392
|
+
* latest path has no jitter and `attempt` for each failed try. A later call gets a delay that ends no
|
|
393
|
+
* earlier, thus each try of a path between them is in the band.
|
|
394
|
+
*/
|
|
395
|
+
const triesOf = (backoff, until) => {
|
|
396
|
+
const delays = delaysOf(backoff);
|
|
397
|
+
const late = pathOf(delays, 1, valueIn(backoff.attempt, "ms"), Number.POSITIVE_INFINITY);
|
|
398
|
+
return pathOf(delays, 1 - delays.jitter, 0, until).map((lo, index) => ({
|
|
399
|
+
lo,
|
|
400
|
+
hi: late[index] ?? Number.POSITIVE_INFINITY
|
|
401
|
+
}));
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* This function gives the latest return of a producer after the fault, from the bands of the
|
|
405
|
+
* prediction. It adds three terms. The first is the first delay at its latest. The second is the
|
|
406
|
+
* latest time of the first try that cannot come before the latest change of the owner. The third
|
|
407
|
+
* is the latest setup.
|
|
408
|
+
*/
|
|
409
|
+
const latestReturn = (prediction) => {
|
|
410
|
+
const disconnect = {
|
|
411
|
+
lo: valueIn(prediction.disconnect.lo, "ms"),
|
|
412
|
+
hi: valueIn(prediction.disconnect.hi, "ms")
|
|
413
|
+
};
|
|
414
|
+
const flip = valueIn(prediction.flip.hi, "ms");
|
|
415
|
+
const tries = triesOf(prediction.backoff, flip - disconnect.lo);
|
|
416
|
+
const after = tries.find((each) => each.lo >= flip - disconnect.lo) ?? tries.at(-1);
|
|
417
|
+
return disconnect.hi + after.hi + valueIn(prediction.setup.hi, "ms");
|
|
418
|
+
};
|
|
419
|
+
/** This function gives the delay of each call of a backoff, as an interval, with `elapsed` from the first call to this one. */
|
|
420
|
+
const delayBand = (delays, index, elapsed, made, noise) => {
|
|
421
|
+
const nominal = Math.min(delays.initial * 2 ** index, delays.max);
|
|
422
|
+
const band = (current) => ({
|
|
423
|
+
lo: Math.max(delays.initial, current * (1 - delays.jitter)),
|
|
424
|
+
hi: Math.max(delays.initial, current)
|
|
425
|
+
});
|
|
426
|
+
if (made) return {
|
|
427
|
+
...band(nominal),
|
|
428
|
+
made,
|
|
429
|
+
either: false
|
|
430
|
+
};
|
|
431
|
+
const clamped = band(Math.max(delays.initial, delays.stop - elapsed));
|
|
432
|
+
const plain = band(nominal);
|
|
433
|
+
if (Math.abs(elapsed + nominal - delays.stop) <= noise) return {
|
|
434
|
+
lo: Math.min(clamped.lo, plain.lo),
|
|
435
|
+
hi: Math.max(clamped.hi, plain.hi),
|
|
436
|
+
made: false,
|
|
437
|
+
either: true
|
|
438
|
+
};
|
|
439
|
+
return elapsed + nominal > delays.stop ? {
|
|
440
|
+
...clamped,
|
|
441
|
+
made: true,
|
|
442
|
+
either: false
|
|
443
|
+
} : {
|
|
444
|
+
...plain,
|
|
445
|
+
made: false,
|
|
446
|
+
either: false
|
|
447
|
+
};
|
|
448
|
+
};
|
|
449
|
+
/** This text is the start of the line of the C++ client that schedules a try: "Schedule reconnection in 0.1 s". */
|
|
450
|
+
const SCHEDULE = /Schedule reconnection in ([0-9.]+) s/;
|
|
451
|
+
const text = (line, field) => typeof line[field] === "string" ? line[field] : null;
|
|
452
|
+
/**
|
|
453
|
+
* This function judges one run: the fault at `fault`, the broker `broker` that owned the topic, and
|
|
454
|
+
* the lines of the run. A lookup line is `{ev: "lookup", t, o, owner}`, a line of the client is
|
|
455
|
+
* `{ev: "pulsar", t, p, m}`, and a send is `{ev: "send", t, d, o, p}`. `timeout` and `every` are the
|
|
456
|
+
* timeout and the interval of the sends. Each check has a margin of `noise`.
|
|
457
|
+
*
|
|
458
|
+
* For each producer, the delays of its backoff follow the law, from the observed time of each call.
|
|
459
|
+
* Its last try comes after the last lookup that named the old owner. The try before it comes no
|
|
460
|
+
* later than the first lookup that named another. Then the setup is in its band. Each failed send
|
|
461
|
+
* starts between the fault and the return, with an outcome of the prediction. At least one fails.
|
|
462
|
+
*
|
|
463
|
+
* With `owner: "either"`, the lookups can name the old owner for the whole run, because it started
|
|
464
|
+
* again and took the topic back. Then the last try comes after the start of the band `flip`. The
|
|
465
|
+
* try before it comes no later than the end of that band.
|
|
466
|
+
*/
|
|
467
|
+
const judgeReconnects = (prediction, run, sends, noise) => {
|
|
468
|
+
const { fault, broker, lines } = run;
|
|
469
|
+
const ms = (band) => ({
|
|
470
|
+
lo: valueIn(band.lo, "ms"),
|
|
471
|
+
hi: valueIn(band.hi, "ms")
|
|
472
|
+
});
|
|
473
|
+
const inBand = (value, band) => value >= band.lo - noise && value <= band.hi + noise;
|
|
474
|
+
const lookups = lines.filter((line) => line.ev === "lookup" && line.t >= fault).sort((a, b) => a.t - b.t);
|
|
475
|
+
const changed = lookups.findIndex((line) => line["o"] === "ok" && text(line, "owner") !== null && text(line, "owner") !== broker);
|
|
476
|
+
const fail = (why, more = {}) => ({
|
|
477
|
+
ok: false,
|
|
478
|
+
why,
|
|
479
|
+
flip: null,
|
|
480
|
+
gap: null,
|
|
481
|
+
returns: [],
|
|
482
|
+
failures: {},
|
|
483
|
+
value: null,
|
|
484
|
+
...more
|
|
485
|
+
});
|
|
486
|
+
if (changed === -1 && prediction.owner !== "either") return fail(`no lookup after the fault names an owner other than ${broker}`);
|
|
487
|
+
const band = ms(prediction.flip);
|
|
488
|
+
const same = changed === -1;
|
|
489
|
+
const flipAt = same ? fault + band.hi : lookups[changed].t;
|
|
490
|
+
const before = same ? fault + band.lo : changed === 0 ? fault : lookups[changed - 1].t;
|
|
491
|
+
const flip = same ? null : flipAt - fault;
|
|
492
|
+
const gap = same ? null : flipAt - before;
|
|
493
|
+
if (flip !== null && !inBand(flip, band)) return fail(`the first lookup with another owner is ${flip.toFixed(0)} ms after the fault, outside the band`, {
|
|
494
|
+
flip,
|
|
495
|
+
gap
|
|
496
|
+
});
|
|
497
|
+
if (gap !== null && gap > valueIn(prediction.probe, "ms") + noise) return fail(`the lookups have a gap of ${gap.toFixed(0)} ms before the change of the owner`, {
|
|
498
|
+
flip,
|
|
499
|
+
gap
|
|
500
|
+
});
|
|
501
|
+
const delays = delaysOf(prediction.backoff);
|
|
502
|
+
const setup = ms(prediction.setup);
|
|
503
|
+
const disconnect = ms(prediction.disconnect);
|
|
504
|
+
const pods = [...new Set(lines.filter((line) => line.ev === "send").map((line) => String(line["p"])))].sort();
|
|
505
|
+
if (pods.length === 0) return fail("the run has no sends", {
|
|
506
|
+
flip,
|
|
507
|
+
gap
|
|
508
|
+
});
|
|
509
|
+
const returns = pods.map((pod) => {
|
|
510
|
+
const own = lines.filter((line) => line.ev === "pulsar" && line["p"] === pod && line.t >= fault - noise).sort((a, b) => a.t - b.t);
|
|
511
|
+
const created = own.find((line) => (text(line, "m") ?? "").includes("Created producer on broker"));
|
|
512
|
+
const back = created === void 0 ? null : created.t - fault;
|
|
513
|
+
const schedules = own.filter((line) => created === void 0 || line.t <= created.t).flatMap((line) => {
|
|
514
|
+
const found = SCHEDULE.exec(text(line, "m") ?? "");
|
|
515
|
+
return found === null ? [] : [{
|
|
516
|
+
t: line.t,
|
|
517
|
+
delay: Number(found[1]) * 1e3
|
|
518
|
+
}];
|
|
519
|
+
});
|
|
520
|
+
const first = schedules[0];
|
|
521
|
+
const facts = {
|
|
522
|
+
pod,
|
|
523
|
+
disconnect: first === void 0 ? null : first.t - fault,
|
|
524
|
+
schedules,
|
|
525
|
+
back,
|
|
526
|
+
tries: schedules.length
|
|
527
|
+
};
|
|
528
|
+
const no = (why, more = {}) => ({
|
|
529
|
+
...facts,
|
|
530
|
+
setup: null,
|
|
531
|
+
...more,
|
|
532
|
+
ok: false,
|
|
533
|
+
why: `${pod}: ${why}`
|
|
534
|
+
});
|
|
535
|
+
if (created === void 0) return no("the producer is not back on a broker after the fault");
|
|
536
|
+
if (first === void 0) return no("the producer schedules no try after the fault");
|
|
537
|
+
if (!inBand(first.t - fault, disconnect)) return no(`its first try is scheduled ${(first.t - fault).toFixed(0)} ms after the fault, outside the band`);
|
|
538
|
+
let made = false;
|
|
539
|
+
for (const [index, schedule] of schedules.entries()) {
|
|
540
|
+
const band = delayBand(delays, index, schedule.t - first.t, made, noise);
|
|
541
|
+
if (schedule.delay < band.lo - 1 || schedule.delay > band.hi + 1) return no(`the delay ${index + 1} is ${schedule.delay} ms, not in ${band.lo.toFixed(0)}–${band.hi.toFixed(0)} ms of the backoff`);
|
|
542
|
+
made = band.either ? schedule.delay < Math.min(delays.initial * 2 ** index, delays.max) * (1 - delays.jitter) - 1 : band.made;
|
|
543
|
+
}
|
|
544
|
+
const tries = schedules.map((schedule) => schedule.t + schedule.delay);
|
|
545
|
+
const last = tries.at(-1);
|
|
546
|
+
const earlier = tries.at(-2);
|
|
547
|
+
if (last < before - noise) return no(`its last try at ${(last - fault).toFixed(0)} ms comes before the last lookup of the old owner`);
|
|
548
|
+
if (earlier !== void 0 && earlier > flipAt + noise) return no(`its try at ${(earlier - fault).toFixed(0)} ms comes after the change of the owner, and it did not succeed`);
|
|
549
|
+
const took = created.t - last;
|
|
550
|
+
if (!inBand(took, setup)) return no(`its setup takes ${took.toFixed(0)} ms, outside the band`, { setup: took });
|
|
551
|
+
return {
|
|
552
|
+
...facts,
|
|
553
|
+
setup: took,
|
|
554
|
+
ok: true,
|
|
555
|
+
why: `${pod}: back ${(created.t - fault).toFixed(0)} ms after the fault, at try ${tries.length}`
|
|
556
|
+
};
|
|
557
|
+
});
|
|
558
|
+
const failed = lines.filter((line) => line.ev === "send" && line["o"] !== "ok").sort((a, b) => a.t - b.t);
|
|
559
|
+
const failures = {};
|
|
560
|
+
for (const line of failed) failures[String(line["o"])] = (failures[String(line["o"])] ?? 0) + 1;
|
|
561
|
+
const backs = returns.flatMap((each) => each.back === null ? [] : [each.back]).sort((a, b) => a - b);
|
|
562
|
+
const value = backs.length === 0 ? null : backs.length % 2 === 1 ? backs[(backs.length - 1) / 2] : (backs[backs.length / 2 - 1] + backs[backs.length / 2]) / 2;
|
|
563
|
+
const done = (ok, why) => ({
|
|
564
|
+
ok,
|
|
565
|
+
why,
|
|
566
|
+
flip,
|
|
567
|
+
gap,
|
|
568
|
+
returns,
|
|
569
|
+
failures,
|
|
570
|
+
value
|
|
571
|
+
});
|
|
572
|
+
const wrong = returns.find((each) => !each.ok);
|
|
573
|
+
if (wrong !== void 0) return done(false, wrong.why);
|
|
574
|
+
const other = failed.find((line) => !prediction.outcomes.includes(String(line["o"])));
|
|
575
|
+
if (other !== void 0) return done(false, `a send of ${String(other["p"])} ended ${String(other["o"])}, not ${prediction.outcomes.join(" or ")}`);
|
|
576
|
+
if (failed.length === 0) return done(false, "no send failed");
|
|
577
|
+
for (const each of returns) {
|
|
578
|
+
const own = failed.filter((line) => line["p"] === each.pod);
|
|
579
|
+
const back = fault + each.back;
|
|
580
|
+
const outside = own.find((line) => line.t < fault - sends.timeout - noise || line.t > back + noise);
|
|
581
|
+
if (outside !== void 0) return done(false, `a send of ${each.pod} at ${(outside.t - fault).toFixed(0)} ms failed outside the time to its return`);
|
|
582
|
+
const latest = own.at(-1);
|
|
583
|
+
if (latest === void 0) return done(false, `no send of ${each.pod} failed`);
|
|
584
|
+
if (latest.t < back - sends.timeout - sends.every - noise) return done(false, `the last failed send of ${each.pod} is ${(back - latest.t).toFixed(0)} ms before its return`);
|
|
585
|
+
}
|
|
586
|
+
return done(true, `${flip === null ? "the stopped broker owns the topic again" : `another owner ${flip.toFixed(0)} ms after the fault`}; ${returns.map((each) => `${each.pod} back at try ${each.tries}`).join(", ")}`);
|
|
587
|
+
};
|
|
588
|
+
//#endregion
|
|
359
589
|
//#region src/verdict.ts
|
|
360
590
|
/**
|
|
361
591
|
* This time is δ for kind: each time of a run lands in its band ± δ. Its parts are the interval of
|
|
@@ -390,7 +620,8 @@ const unitOf = (prediction) => {
|
|
|
390
620
|
switch (prediction.kind) {
|
|
391
621
|
case "removal":
|
|
392
622
|
case "leaves":
|
|
393
|
-
case "stalls":
|
|
623
|
+
case "stalls":
|
|
624
|
+
case "reconnects": return "s";
|
|
394
625
|
case "restarts": return prediction.band === null ? "{replica}" : "s";
|
|
395
626
|
case "ends": return prediction.band === null ? "{socket}" : "s";
|
|
396
627
|
default: return "{request}";
|
|
@@ -534,6 +765,7 @@ const observationEnd = (cell, run) => {
|
|
|
534
765
|
if (at !== null) ends.push(at + valueIn(prediction.band.hi, "ms") + NOISE);
|
|
535
766
|
}
|
|
536
767
|
const after = observationAfter(cell);
|
|
768
|
+
if (prediction.kind === "reconnects" && run.acts.fault !== null) ends.push(run.acts.fault + latestReturn(prediction) + valueIn(cell.workload.timeout, "ms") + NOISE);
|
|
537
769
|
const window = windowOf(prediction);
|
|
538
770
|
if (after !== null && window !== null && window.end !== null) {
|
|
539
771
|
const from = window.end.from;
|
|
@@ -1012,6 +1244,37 @@ const checkRun = (cell, run) => {
|
|
|
1012
1244
|
return done(false, problems.join("; "), null);
|
|
1013
1245
|
}
|
|
1014
1246
|
case "ends": return checkEnds(cell, run, prediction, done);
|
|
1247
|
+
case "reconnects": {
|
|
1248
|
+
const fault = run.acts.fault;
|
|
1249
|
+
if (fault === null) return done(false, "the run has no stamp of the fault", null);
|
|
1250
|
+
if (run.broker === void 0) return done(false, "the run has no broker that owned the topic at the fault", null);
|
|
1251
|
+
const judged = judgeReconnects(prediction, {
|
|
1252
|
+
fault,
|
|
1253
|
+
broker: run.broker,
|
|
1254
|
+
lines
|
|
1255
|
+
}, {
|
|
1256
|
+
timeout: valueIn(cell.workload.timeout, "ms"),
|
|
1257
|
+
every: valueIn(cell.workload.every, "ms")
|
|
1258
|
+
}, NOISE);
|
|
1259
|
+
const time = (value) => value === null ? null : {
|
|
1260
|
+
value: sec(value),
|
|
1261
|
+
unit: "s"
|
|
1262
|
+
};
|
|
1263
|
+
const reconnects = {
|
|
1264
|
+
flip: time(judged.flip),
|
|
1265
|
+
gap: time(judged.gap),
|
|
1266
|
+
returns: judged.returns.map((each) => ({
|
|
1267
|
+
pod: each.pod,
|
|
1268
|
+
disconnect: time(each.disconnect),
|
|
1269
|
+
back: time(each.back),
|
|
1270
|
+
setup: time(each.setup),
|
|
1271
|
+
tries: each.tries
|
|
1272
|
+
})),
|
|
1273
|
+
failures: judged.failures
|
|
1274
|
+
};
|
|
1275
|
+
if (failures.length > 0) return done(false, `${failures.length} requests of the control failed: ${JSON.stringify(facts.outcomes)}`, null, { reconnects });
|
|
1276
|
+
return done(judged.ok, judged.why, judged.value === null ? null : sec(judged.value), { reconnects });
|
|
1277
|
+
}
|
|
1015
1278
|
case "measured": return done(true, "measured", facts.failures);
|
|
1016
1279
|
}
|
|
1017
1280
|
};
|
|
@@ -1349,6 +1612,23 @@ const upgradePrediction = (prediction) => {
|
|
|
1349
1612
|
...failures === void 0 ? {} : { failures: failures.kind === "window" ? upgradeWindow(failures) : failures }
|
|
1350
1613
|
};
|
|
1351
1614
|
}
|
|
1615
|
+
case "reconnects": {
|
|
1616
|
+
const { backoff } = prediction;
|
|
1617
|
+
return {
|
|
1618
|
+
...prediction,
|
|
1619
|
+
flip: band(prediction.flip),
|
|
1620
|
+
probe: seconds(prediction.probe),
|
|
1621
|
+
disconnect: band(prediction.disconnect),
|
|
1622
|
+
backoff: {
|
|
1623
|
+
...backoff,
|
|
1624
|
+
initial: seconds(backoff.initial),
|
|
1625
|
+
max: seconds(backoff.max),
|
|
1626
|
+
mandatoryStop: seconds(backoff.mandatoryStop),
|
|
1627
|
+
attempt: seconds(backoff.attempt)
|
|
1628
|
+
},
|
|
1629
|
+
setup: band(prediction.setup)
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1352
1632
|
default: return prediction;
|
|
1353
1633
|
}
|
|
1354
1634
|
};
|
|
@@ -1364,7 +1644,7 @@ const upgradeFacts = (facts) => {
|
|
|
1364
1644
|
by: seconds(old.by)
|
|
1365
1645
|
};
|
|
1366
1646
|
const byKey = (record) => Object.fromEntries(Object.entries(record).map(([key, old]) => [key, propagated(old)]));
|
|
1367
|
-
const { sliceEmpty, rules, left, signals, updates, healUpdates, closes, cycles, stall, period, ...rest } = facts;
|
|
1647
|
+
const { sliceEmpty, rules, left, signals, updates, healUpdates, closes, cycles, stall, period, reconnects, ...rest } = facts;
|
|
1368
1648
|
return {
|
|
1369
1649
|
...rest,
|
|
1370
1650
|
intakeAfterDeletion: time$1(facts.intakeAfterDeletion),
|
|
@@ -1385,6 +1665,17 @@ const upgradeFacts = (facts) => {
|
|
|
1385
1665
|
start: time$1(stall.start),
|
|
1386
1666
|
held: time$1(stall.held)
|
|
1387
1667
|
} },
|
|
1668
|
+
...reconnects === void 0 ? {} : { reconnects: {
|
|
1669
|
+
...reconnects,
|
|
1670
|
+
flip: time$1(reconnects.flip),
|
|
1671
|
+
gap: time$1(reconnects.gap),
|
|
1672
|
+
returns: reconnects.returns.map((each) => ({
|
|
1673
|
+
...each,
|
|
1674
|
+
disconnect: time$1(each.disconnect),
|
|
1675
|
+
back: time$1(each.back),
|
|
1676
|
+
setup: time$1(each.setup)
|
|
1677
|
+
}))
|
|
1678
|
+
} },
|
|
1388
1679
|
...period === void 0 ? {} : { period: {
|
|
1389
1680
|
...period,
|
|
1390
1681
|
median: seconds(period.median),
|
|
@@ -1471,6 +1762,7 @@ const predictionText = (prediction) => {
|
|
|
1471
1762
|
const closes = prediction.band === null ? "no socket of a client ends, and each one calls again on its socket" : prediction.of === "tunnel" ? `the side of the client ends the tunnel of each client in ${atBand(prediction.from, prediction.band)}${prediction.answer === void 0 ? "" : `, or the peer answers in ${atBand(prediction.from, prediction.answer)}`}, and each one calls again` : `the socket of each client ends in ${atBand(prediction.from, prediction.band)}`;
|
|
1472
1763
|
return prediction.window === void 0 ? closes : `${closes}; ${predictionText(prediction.window)}`;
|
|
1473
1764
|
}
|
|
1765
|
+
case "reconnects": return `another owner in ${showBand(prediction.flip)}, each producer back at the first try of its backoff after it, failures only before it, each one ${prediction.outcomes.join(" or ")}`;
|
|
1474
1766
|
case "measured": return "measured";
|
|
1475
1767
|
}
|
|
1476
1768
|
};
|
|
@@ -1686,6 +1978,7 @@ const run = z.object({
|
|
|
1686
1978
|
}),
|
|
1687
1979
|
target: replica.nullable(),
|
|
1688
1980
|
paused: z.string().nullable(),
|
|
1981
|
+
broker: z.string().optional(),
|
|
1689
1982
|
replicas: z.array(replica),
|
|
1690
1983
|
void: z.string().nullable(),
|
|
1691
1984
|
lines: z.array(line),
|
|
@@ -1826,6 +2119,22 @@ const recordOf = (a, main) => {
|
|
|
1826
2119
|
answer: band.optional(),
|
|
1827
2120
|
why: z.string()
|
|
1828
2121
|
}),
|
|
2122
|
+
z.object({
|
|
2123
|
+
kind: z.literal("reconnects"),
|
|
2124
|
+
flip: band,
|
|
2125
|
+
probe: a,
|
|
2126
|
+
disconnect: band,
|
|
2127
|
+
backoff: z.object({
|
|
2128
|
+
initial: a,
|
|
2129
|
+
max: a,
|
|
2130
|
+
mandatoryStop: a,
|
|
2131
|
+
jitter: z.number(),
|
|
2132
|
+
attempt: a
|
|
2133
|
+
}),
|
|
2134
|
+
setup: band,
|
|
2135
|
+
outcomes: z.array(z.string()),
|
|
2136
|
+
why: z.string()
|
|
2137
|
+
}),
|
|
1829
2138
|
z.object({
|
|
1830
2139
|
kind: z.literal("measured"),
|
|
1831
2140
|
why: z.string()
|
|
@@ -1894,7 +2203,16 @@ const recordOf = (a, main) => {
|
|
|
1894
2203
|
runs: count,
|
|
1895
2204
|
vip: z.object({
|
|
1896
2205
|
clients: count,
|
|
1897
|
-
announcer: z.enum(["kube-vip", "metallb"]).optional()
|
|
2206
|
+
announcer: z.enum(["kube-vip", "metallb"]).optional(),
|
|
2207
|
+
memberlist: z.object({
|
|
2208
|
+
probeInterval: time,
|
|
2209
|
+
probeTimeout: time,
|
|
2210
|
+
suspicionMult: count
|
|
2211
|
+
}).optional()
|
|
2212
|
+
}).optional(),
|
|
2213
|
+
pulsar: z.object({
|
|
2214
|
+
clients: count,
|
|
2215
|
+
probe: time
|
|
1898
2216
|
}).optional()
|
|
1899
2217
|
});
|
|
1900
2218
|
const facts = z.object({
|
|
@@ -1948,6 +2266,18 @@ const recordOf = (a, main) => {
|
|
|
1948
2266
|
high: a,
|
|
1949
2267
|
intervals: count,
|
|
1950
2268
|
byClient: z.record(z.string(), a)
|
|
2269
|
+
}).optional(),
|
|
2270
|
+
reconnects: z.object({
|
|
2271
|
+
flip: a.nullable(),
|
|
2272
|
+
gap: a.nullable(),
|
|
2273
|
+
returns: z.array(z.object({
|
|
2274
|
+
pod: z.string(),
|
|
2275
|
+
disconnect: a.nullable(),
|
|
2276
|
+
back: a.nullable(),
|
|
2277
|
+
setup: a.nullable(),
|
|
2278
|
+
tries: count
|
|
2279
|
+
})),
|
|
2280
|
+
failures: z.record(z.string(), count)
|
|
1951
2281
|
}).optional()
|
|
1952
2282
|
});
|
|
1953
2283
|
return {
|
|
@@ -2010,6 +2340,6 @@ const readRecord = (data) => {
|
|
|
2010
2340
|
throw new Error(`a kind cell record has the format ${FORMAT} or ${FORMAT_V1}, not ${String(format)}`);
|
|
2011
2341
|
};
|
|
2012
2342
|
//#endregion
|
|
2013
|
-
export {
|
|
2343
|
+
export { rulesOf as $, judgeReconnects as A, overshootBand as At, emptyOf as B, observationEnd as C, PORT as Ct, reusesReset as D, backlogEnd as Dt, referenceOf as E, VIP_ANNOTATION as Et, backendsAt as F, outcomesOf as G, intakeOf as H, byClients as I, podsOf as J, periodOf as K, byNode as L, triesOf as M, seconds as Mt, HBONE_PORT as N, secondsOf as Nt, unitOf as O, bandOf as Ot, TCP_STATE as P, showBand as Pt, restartsAt as Q, deletionOf as R, observationAfter as S, OUTSIDE as St, propagationSource as T, SERVER as Tt, isTunnelState as U, failuresOf as V, kernelCounts as W, requestsOf as X, recordsOf as Y, restartOf as Z, checkRun as _, quantileOf as _t, calibrationOf as a, sliceReadyAt as at, factsOf as b, LB_CLASS as bt, predictionText as c, socketsOf as ct, FORMAT_V1 as d, tunnelsOf as dt, sessionsAt as et, judge as f, ztunnelPodsOf as ft, LAST_SLACK as g, middle as gt, KIND_NOISE as h, medianInterval$1 as ht, readRecord as i, sliceEmptyOf as it, latestReturn as j, requestBand as jt, updatesOf as k, drainBand as kt, timeSpread as l, stoppingOf as lt, upgradeCell as m, RELATIVE as mt, kindCellRecordSchema as n, signalsOf as nt, cellsTable as o, sliceReadyOf as ot, upgrade as p, ztunnelReplaced as pt, podsAt as q, kindCellRecordV1Schema as r, sliceDropOf as rt, medianText as s, slicesOf as st, STAGES as t, signalOf as tt, FORMAT as u, transitionOf as ut, cyclesOf as v, CLIENT as vt, propagationOf as w, REDIS as wt, judgeKind as x, LOG_LABEL as xt, deletionsOf as y, HEALTH_PORT as yt, dropOf as z };
|
|
2014
2344
|
|
|
2015
|
-
//# sourceMappingURL=judge-
|
|
2345
|
+
//# sourceMappingURL=judge-C6XgY2Pk.js.map
|