@mark1russell7/kind 0.12.5 → 0.13.1
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 +18 -4
- package/build/index.js +53 -5
- package/build/index.js.map +1 -1
- package/build/{judge-DiEmspMx.d.ts → judge-CSWVew2-.d.ts} +21 -10
- package/build/{judge-B6cyI41-.js → judge-DA754h1o.js} +40 -45
- package/build/judge-DA754h1o.js.map +1 -0
- package/build/judge.d.ts +1 -1
- package/build/judge.js +1 -1
- package/image/Dockerfile +2 -1
- package/image/npm-lock.json +20 -0
- package/image/package.json +2 -0
- package/package.json +5 -4
- package/build/judge-B6cyI41-.js.map +0 -1
|
@@ -180,8 +180,11 @@ type Stack = "service" | "grpc";
|
|
|
180
180
|
* - `latency` delays each packet that Redis sends by `delay`, for the hold (T07). Thus each command
|
|
181
181
|
* of each replica takes that much longer, but Redis answers it. The heal sets the delay to zero.
|
|
182
182
|
* - `none` injects nothing: a calibration measures the path itself.
|
|
183
|
+
* - `dns-blackhole` drops each answer of a DNS server in the network namespace of each client pod,
|
|
184
|
+
* for the hold (S2, CoreDNS). CoreDNS still answers, but no answer gets to a client. The heal
|
|
185
|
+
* removes the rules. A client that resolves the name of the Service (`byName`) sees it.
|
|
183
186
|
*/
|
|
184
|
-
type TriggerKind = "pod-deletion" | "rolling-update" | "node-drain" | "scale-in" | "crash" | "liveness-restart" | "freeze-process" | "rst" | "blackhole" | "peer-gone-without-close" | "app-stall" | "rollout" | "cpu-throttle" | "authorization-policy" | "idle" | "ztunnel-restart" | "certificate-expiry" | "cannot-serve" | "zone-loss" | "latency";
|
|
187
|
+
type TriggerKind = "pod-deletion" | "rolling-update" | "node-drain" | "scale-in" | "crash" | "liveness-restart" | "freeze-process" | "rst" | "blackhole" | "peer-gone-without-close" | "app-stall" | "rollout" | "cpu-throttle" | "authorization-policy" | "idle" | "ztunnel-restart" | "certificate-expiry" | "cannot-serve" | "zone-loss" | "latency" | "dns-blackhole";
|
|
185
188
|
/**
|
|
186
189
|
* A trigger is its kind and the settings of its fault. The parameter `A` is the form of an amount:
|
|
187
190
|
* a quantity in the format `/2`, a number in the format `/1`.
|
|
@@ -366,6 +369,12 @@ interface Workload {
|
|
|
366
369
|
* until its first answer comes from its backend. With no value, the rules pick the backend of each session.
|
|
367
370
|
*/
|
|
368
371
|
readonly onTarget?: number | undefined;
|
|
372
|
+
/**
|
|
373
|
+
* This flag gives each client the name of the Service as its target, not the ClusterIP. Thus each
|
|
374
|
+
* new connection of a client starts with a lookup of the name in the cluster DNS (S2, CoreDNS).
|
|
375
|
+
* With no value, the target is the ClusterIP, and a client does no lookup.
|
|
376
|
+
*/
|
|
377
|
+
readonly byName?: boolean | undefined;
|
|
369
378
|
}
|
|
370
379
|
/**
|
|
371
380
|
* A band is a range of times after a reference event of the run. The format `/1` gives each end
|
|
@@ -710,11 +719,6 @@ declare const CLIENT = "client";
|
|
|
710
719
|
declare const REDIS = "redis";
|
|
711
720
|
//#endregion
|
|
712
721
|
//#region src/observe.d.ts
|
|
713
|
-
/**
|
|
714
|
-
* This module reads a run from its lines. Each time is in milliseconds on CLOCK_MONOTONIC. All the
|
|
715
|
-
* containers of the VM share that clock: the clients, the service, the agents, the injector, the
|
|
716
|
-
* watcher and the prober.
|
|
717
|
-
*/
|
|
718
722
|
/**
|
|
719
723
|
* A line is one JSON line of a source of a run, with its stamp `t` in milliseconds on
|
|
720
724
|
* CLOCK_MONOTONIC. It is a request of a client, a record of the service, a line of grpc-go or a probe answer. It is
|
|
@@ -1320,16 +1324,23 @@ declare const readRecord: (data: unknown) => KindCellRecord;
|
|
|
1320
1324
|
//#region src/stats.d.ts
|
|
1321
1325
|
/** This fraction, δ_rel, is how far the median of a cell can be outside its band and stay equivalent. */
|
|
1322
1326
|
declare const RELATIVE = .05;
|
|
1323
|
-
/**
|
|
1327
|
+
/**
|
|
1328
|
+
* This function gives the median of sorted values: the middle value, or the mean of the two middle values.
|
|
1329
|
+
* It is `median` of @mark1russell7/rigor-statistics, which throws a RangeError for an empty list.
|
|
1330
|
+
*/
|
|
1324
1331
|
declare const middle: (sorted: readonly number[]) => number;
|
|
1325
|
-
/**
|
|
1332
|
+
/**
|
|
1333
|
+
* This function gives the value at quantile p of sorted values, by nearest rank: x_(⌈p·n⌉). It is
|
|
1334
|
+
* `quantileSorted` of @mark1russell7/rigor-statistics with the method `"nearest-rank"`.
|
|
1335
|
+
*/
|
|
1326
1336
|
declare const quantileOf: (sorted: readonly number[], p: number) => number;
|
|
1327
1337
|
/**
|
|
1328
1338
|
* This function gives the distribution-free interval of a median: [x_(k), x_(n+1−k)], for the
|
|
1329
1339
|
* largest k whose two tails each hold 2.5 % or less. For eleven runs, it gives [x_(2), x_(10)],
|
|
1330
|
-
* at 98.8 %.
|
|
1340
|
+
* at 98.8 %. It is `medianInterval` of @mark1russell7/rigor-statistics at the level 0.95. An
|
|
1341
|
+
* empty list throws a RangeError.
|
|
1331
1342
|
*/
|
|
1332
1343
|
declare const medianInterval: (sorted: readonly number[]) => [number, number];
|
|
1333
1344
|
//#endregion
|
|
1334
1345
|
export { unitOf as $, scenario as $n, REDIS as $t, TriggerV1 as A, Template as An, recordsOf as At, RunCheck as B, KubeProxyMode as Bn, sliceReadyAt as Bt, KindCellResult as C, PodSettings as Cn, intakeOf as Ct, PredictionV1 as D, Replica as Dn, periodOf as Dt, LoadSample as E, Reference as En, outcomesOf as Et, KIND_NOISE as F, DATAPLANES as Fn, sessionsAt as Ft, factsOf as G, ZONE_LOST as Gn, transitionOf as Gt, checkRun as H, NodeImage as Hn, slicesOf as Ht, KindDecision as I, Dataplane as In, signalOf as It, observationEnd as J, goDuration as Jn, ztunnelReplaced as Jt, judgeKind as K, cidrOverlap as Kn, tunnelsOf as Kt, KindVerdict as L, KUBE_PROXY_MODES as Ln, signalsOf as Lt, upgrade as M, TriggerKind as Mn, restartOf as Mt, upgradeCell as N, WindowPrediction as Nn, restartsAt as Nt, RunCheckV1 as O, ResetReuse as On, podsAt as Ot, Deleted as P, Workload as Pn, rulesOf as Pt, reusesReset as Q, nodeNames as Qn, PORT as Qt, LAST_SLACK as R, KindConfig as Rn, sliceDropOf as Rt, KindCellRecordV1 as S, NonePrediction as Sn, failuresOf as St, KindVerdictV1 as T, RedisDeclaration as Tn, kernelCounts as Tt, cyclesOf as U, ZONE_KEPT as Un, socketsOf as Ut, RunFacts as V, NODE_IMAGES as Vn, sliceReadyOf as Vt, deletionsOf as W, ZONE_LABEL as Wn, stoppingOf as Wt, propagationSource as X, kindConfig as Xn, HEALTH_PORT as Xt, propagationOf as Y, isKubeProxyMode as Yn, CLIENT as Yt, referenceOf as Z, kubeProxyPatch as Zn, LOG_LABEL as Zt, ClusterManifest as _, KindRun as _n, byClients as _t, STAGES as a, overshootBand as an, PodLine as at, FORMAT_V1 as b, MeshFlavor as bn, dropOf as bt, readRecord as c, secondsOf as cn, Request as ct, calibrationOf as d, Band as dn, SliceLine as dt, SERVER as en, scenarioProblems as er, updatesOf as et, cellsTable as f, Cycle as fn, SocketLine as ft, BandV1 as g, KindCell as gn, backendsAt as gt, timeSpread as h, Flap as hn, ZtunnelPodLine as ht, quantileOf as i, drainBand as in, Period as it, judge as j, Trigger as jn, requestsOf as jt, RunFactsV1 as k, Stack as kn, podsOf as kt, Judged as l, showBand as ln, RulesLine as lt, predictionText as m, EdgeProtocol as mn, TunnelLine as mt, medianInterval as n, backlogEnd as nn, HBONE_PORT as nt, kindCellRecordSchema as o, requestBand as on, PropagationSource as ot, medianText as p, Declaration as pn, TCP_STATE as pt, observationAfter as q, cidrRange as qn, ztunnelPodsOf as qt, middle as r, bandOf as rn, Line as rt, kindCellRecordV1Schema as s, seconds as sn, RecordLine as st, RELATIVE as t, CountBand as tn, zoneOf as tr, Endpoint as tt, TimeSpread as u, BacklogTerm as un, Sessions as ut, EnvironmentManifest as v, KubeletProbe as vn, byNode as vt, KindCellV1 as w, Prediction as wn, isTunnelState as wt, KindCellRecord as x, MeshMode as xn, emptyOf as xt, FORMAT as y, Mesh as yn, deletionOf as yt, Propagated as z, KindScenario as zn, sliceEmptyOf as zt };
|
|
1335
|
-
//# sourceMappingURL=judge-
|
|
1346
|
+
//# sourceMappingURL=judge-CSWVew2-.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { format, valueIn } from "@mark1russell7/quantity";
|
|
2
|
+
import { median, medianInterval, quantileSorted } from "@mark1russell7/rigor-statistics";
|
|
2
3
|
import { extentSchema, quantitySchema } from "@mark1russell7/quantity/schema";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
//#region src/bands.ts
|
|
@@ -119,7 +120,36 @@ const SERVER = "lab";
|
|
|
119
120
|
const CLIENT = "client";
|
|
120
121
|
const REDIS = "redis";
|
|
121
122
|
//#endregion
|
|
123
|
+
//#region src/stats.ts
|
|
124
|
+
/** This fraction, δ_rel, is how far the median of a cell can be outside its band and stay equivalent. */
|
|
125
|
+
const RELATIVE = .05;
|
|
126
|
+
/**
|
|
127
|
+
* This function gives the median of sorted values: the middle value, or the mean of the two middle values.
|
|
128
|
+
* It is `median` of @mark1russell7/rigor-statistics, which throws a RangeError for an empty list.
|
|
129
|
+
*/
|
|
130
|
+
const middle = (sorted) => median(sorted);
|
|
131
|
+
/**
|
|
132
|
+
* This function gives the value at quantile p of sorted values, by nearest rank: x_(⌈p·n⌉). It is
|
|
133
|
+
* `quantileSorted` of @mark1russell7/rigor-statistics with the method `"nearest-rank"`.
|
|
134
|
+
*/
|
|
135
|
+
const quantileOf = (sorted, p) => quantileSorted(sorted, p, "nearest-rank");
|
|
136
|
+
/**
|
|
137
|
+
* This function gives the distribution-free interval of a median: [x_(k), x_(n+1−k)], for the
|
|
138
|
+
* largest k whose two tails each hold 2.5 % or less. For eleven runs, it gives [x_(2), x_(10)],
|
|
139
|
+
* at 98.8 %. It is `medianInterval` of @mark1russell7/rigor-statistics at the level 0.95. An
|
|
140
|
+
* empty list throws a RangeError.
|
|
141
|
+
*/
|
|
142
|
+
const medianInterval$1 = (sorted) => {
|
|
143
|
+
const interval = medianInterval(sorted, .95);
|
|
144
|
+
return [interval.low, interval.high];
|
|
145
|
+
};
|
|
146
|
+
//#endregion
|
|
122
147
|
//#region src/observe.ts
|
|
148
|
+
/**
|
|
149
|
+
* This module reads a run from its lines. Each time is in milliseconds on CLOCK_MONOTONIC. All the
|
|
150
|
+
* containers of the VM share that clock: the clients, the service, the agents, the injector, the
|
|
151
|
+
* watcher and the prober.
|
|
152
|
+
*/
|
|
123
153
|
/** This port is the HBONE port of ztunnel in each pod of the ambient mesh of Istio 1.31.3: the mesh leg ends there. */
|
|
124
154
|
const HBONE_PORT = 15008;
|
|
125
155
|
/** These are the states of a TCP socket of Linux that a tunnel line names (include/net/tcp_states.h of Linux v6.17, lines 12–28). */
|
|
@@ -181,10 +211,6 @@ const sessionsAt = (lines, at, target, connections) => {
|
|
|
181
211
|
byClient
|
|
182
212
|
};
|
|
183
213
|
};
|
|
184
|
-
const medianOf = (sorted) => {
|
|
185
|
-
const middle = Math.floor(sorted.length / 2);
|
|
186
|
-
return sorted.length % 2 === 1 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
|
|
187
|
-
};
|
|
188
214
|
/**
|
|
189
215
|
* This function gives the measured period of the clients from their request lines that start from
|
|
190
216
|
* `from` to `to`. The timer of a client is late by a different amount at each tick. Thus the median
|
|
@@ -210,12 +236,12 @@ const periodOf = (lines, from, to) => {
|
|
|
210
236
|
const intervals = mine.slice(1).map((t, at) => t - mine[at]);
|
|
211
237
|
span += mine.at(-1) - mine[0];
|
|
212
238
|
all.push(...intervals);
|
|
213
|
-
byClient[client] =
|
|
239
|
+
byClient[client] = middle(intervals.sort((a, b) => a - b));
|
|
214
240
|
}
|
|
215
241
|
if (all.length === 0) return null;
|
|
216
242
|
all.sort((a, b) => a - b);
|
|
217
243
|
return {
|
|
218
|
-
median:
|
|
244
|
+
median: middle(all),
|
|
219
245
|
mean: span / all.length,
|
|
220
246
|
low: all[0],
|
|
221
247
|
high: all.at(-1),
|
|
@@ -324,38 +350,6 @@ const restartsAt = (lines, at) => {
|
|
|
324
350
|
return out;
|
|
325
351
|
};
|
|
326
352
|
//#endregion
|
|
327
|
-
//#region src/stats.ts
|
|
328
|
-
/** This fraction, δ_rel, is how far the median of a cell can be outside its band and stay equivalent. */
|
|
329
|
-
const RELATIVE = .05;
|
|
330
|
-
/** This function gives the median of sorted values: the middle value, or the mean of the two middle values. */
|
|
331
|
-
const middle = (sorted) => {
|
|
332
|
-
const half = Math.floor(sorted.length / 2);
|
|
333
|
-
return sorted.length % 2 === 1 ? sorted[half] : (sorted[half - 1] + sorted[half]) / 2;
|
|
334
|
-
};
|
|
335
|
-
/** This function gives the value at quantile p of sorted values, by nearest rank: x_(⌈p·n⌉). */
|
|
336
|
-
const quantileOf = (sorted, p) => sorted[Math.min(sorted.length, Math.max(1, Math.ceil(p * sorted.length))) - 1];
|
|
337
|
-
/** This function gives P(X ≤ j) for X ~ Binomial(n, 1/2), exactly. */
|
|
338
|
-
const below = (n, j) => {
|
|
339
|
-
let term = 1;
|
|
340
|
-
let sum = 0;
|
|
341
|
-
for (let i = 0; i <= j; i += 1) {
|
|
342
|
-
sum += term;
|
|
343
|
-
term = term * (n - i) / (i + 1);
|
|
344
|
-
}
|
|
345
|
-
return sum / 2 ** n;
|
|
346
|
-
};
|
|
347
|
-
/**
|
|
348
|
-
* This function gives the distribution-free interval of a median: [x_(k), x_(n+1−k)], for the
|
|
349
|
-
* largest k whose two tails each hold 2.5 % or less. For eleven runs, it gives [x_(2), x_(10)],
|
|
350
|
-
* at 98.8 %.
|
|
351
|
-
*/
|
|
352
|
-
const medianInterval = (sorted) => {
|
|
353
|
-
const n = sorted.length;
|
|
354
|
-
let k = 0;
|
|
355
|
-
while (k + 1 <= n / 2 && below(n, k) <= .025) k += 1;
|
|
356
|
-
return k === 0 ? [sorted[0], sorted[n - 1]] : [sorted[k - 1], sorted[n - k]];
|
|
357
|
-
};
|
|
358
|
-
//#endregion
|
|
359
353
|
//#region src/verdict.ts
|
|
360
354
|
/**
|
|
361
355
|
* This time is δ for kind: each time of a run lands in its band ± δ. Its parts are the interval of
|
|
@@ -1201,7 +1195,7 @@ const judgeKind = (cell, runs) => {
|
|
|
1201
1195
|
};
|
|
1202
1196
|
if (band !== null && values.length > 0) {
|
|
1203
1197
|
const ends = secondsOf(band);
|
|
1204
|
-
const [from, to] = medianInterval(values);
|
|
1198
|
+
const [from, to] = medianInterval$1(values);
|
|
1205
1199
|
const wide = {
|
|
1206
1200
|
lo: ends.lo * .95,
|
|
1207
1201
|
hi: ends.hi * 1.05
|
|
@@ -1421,8 +1415,7 @@ const judge = (record) => {
|
|
|
1421
1415
|
const timeSpread = (times) => {
|
|
1422
1416
|
if (times.length === 0) return null;
|
|
1423
1417
|
const sorted = times.map((each) => valueIn(each, "s")).sort((a, b) => a - b);
|
|
1424
|
-
const
|
|
1425
|
-
const median = sorted.length % 2 === 1 ? sorted[half] : (sorted[half - 1] + sorted[half]) / 2;
|
|
1418
|
+
const median = middle(sorted);
|
|
1426
1419
|
return {
|
|
1427
1420
|
count: sorted.length,
|
|
1428
1421
|
min: seconds(sorted[0]),
|
|
@@ -1557,7 +1550,8 @@ const TRIGGERS = [
|
|
|
1557
1550
|
"certificate-expiry",
|
|
1558
1551
|
"cannot-serve",
|
|
1559
1552
|
"zone-loss",
|
|
1560
|
-
"latency"
|
|
1553
|
+
"latency",
|
|
1554
|
+
"dns-blackhole"
|
|
1561
1555
|
];
|
|
1562
1556
|
const KUBE_PROXY = [
|
|
1563
1557
|
"iptables",
|
|
@@ -1857,7 +1851,8 @@ const recordOf = (a, main) => {
|
|
|
1857
1851
|
keepalive_time: extent,
|
|
1858
1852
|
keepalive_timeout: time
|
|
1859
1853
|
}).optional(),
|
|
1860
|
-
onTarget: count.optional()
|
|
1854
|
+
onTarget: count.optional(),
|
|
1855
|
+
byName: z.boolean().optional()
|
|
1861
1856
|
}),
|
|
1862
1857
|
prediction,
|
|
1863
1858
|
calibrates: z.boolean(),
|
|
@@ -1976,6 +1971,6 @@ const readRecord = (data) => {
|
|
|
1976
1971
|
throw new Error(`a kind cell record has the format ${FORMAT} or ${FORMAT_V1}, not ${String(format)}`);
|
|
1977
1972
|
};
|
|
1978
1973
|
//#endregion
|
|
1979
|
-
export {
|
|
1974
|
+
export { signalsOf as $, HBONE_PORT as A, isTunnelState as B, observationEnd as C, drainBand as Ct, reusesReset as D, secondsOf as Dt, referenceOf as E, seconds as Et, deletionOf as F, podsOf as G, outcomesOf as H, dropOf as I, restartOf as J, recordsOf as K, emptyOf as L, backendsAt as M, byClients as N, unitOf as O, showBand as Ot, byNode as P, signalOf as Q, failuresOf as R, observationAfter as S, bandOf as St, propagationSource as T, requestBand as Tt, periodOf as U, kernelCounts as V, podsAt as W, rulesOf as X, restartsAt as Y, sessionsAt as Z, checkRun as _, LOG_LABEL as _t, calibrationOf as a, socketsOf as at, factsOf as b, SERVER as bt, predictionText as c, tunnelsOf as ct, FORMAT_V1 as d, RELATIVE as dt, sliceDropOf as et, judge as f, medianInterval$1 as ft, LAST_SLACK as g, HEALTH_PORT as gt, KIND_NOISE as h, CLIENT as ht, readRecord as i, slicesOf as it, TCP_STATE as j, updatesOf as k, timeSpread as l, ztunnelPodsOf as lt, upgradeCell as m, quantileOf as mt, kindCellRecordSchema as n, sliceReadyAt as nt, cellsTable as o, stoppingOf as ot, upgrade as p, middle as pt, requestsOf as q, kindCellRecordV1Schema as r, sliceReadyOf as rt, medianText as s, transitionOf as st, STAGES as t, sliceEmptyOf as tt, FORMAT as u, ztunnelReplaced as ut, cyclesOf as v, PORT as vt, propagationOf as w, overshootBand as wt, judgeKind as x, backlogEnd as xt, deletionsOf as y, REDIS as yt, intakeOf as z };
|
|
1980
1975
|
|
|
1981
|
-
//# sourceMappingURL=judge-
|
|
1976
|
+
//# sourceMappingURL=judge-DA754h1o.js.map
|