@mark1russell7/harness 0.12.0 → 0.12.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/README.md +6 -3
- package/build/index.d.ts +43 -4
- package/build/index.js +35 -6
- package/build/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -293,13 +293,15 @@ Each run starts from kernels that keep nothing from the run before it (`lab.forg
|
|
|
293
293
|
- **A detection by the program** (`application.ts`). The kernel has no report of it. Thus the program of the observer writes a line before each of its own acts, and the kernel stamps each act on the socket.
|
|
294
294
|
- The program writes `ping` before each ping of its heartbeat. The kernel stamps the write of the ping (`tx`).
|
|
295
295
|
- The reference is the first ping that got no answer (`ping-sent`): no segment with data reached the socket after its write, up to the detection. Its write starts the timer of the heartbeat that the fault met. The fault can come at any time, and its stamps are not necessary.
|
|
296
|
-
- The program writes `drop` before it drops the connection itself. The detection is the kernel's stamp of that drop: the write of its close frame, or the change of its socket out of ESTABLISHED. Without such a record in
|
|
296
|
+
- The program writes `drop` before it drops the connection itself. The detection is the kernel's stamp of that drop: the write of its close frame, or the change of its socket out of ESTABLISHED. Without such a record in the handling time of the program (`DROP_HANDLING`, 1.5 ms), it is the stamp of the line. Where δ_abs is longer, the window is δ_abs.
|
|
297
|
+
- The handling time is not δ_abs. δ_abs is the noise of the pipeline, from a reset. The handling is the time of the code of the program, from the firing of its timer to its act.
|
|
298
|
+
- In 585 drops with a close frame in CI, the write came a median of 0.652 ms after the `drop` line, and 1.017 ms at the most. Two of them came more than the δ_abs of 1 ms after it. Each failed its cell, with its time in the band. These are the runs 39390222333 and 39903020657 of the client repository. The bound is that maximum and a margin of 0.48 ms.
|
|
297
299
|
- A drop counts when it comes before each report of the kernel. A report of the kernel that comes first is the detection, and the drop after it is not.
|
|
298
300
|
- The second view is the stamps of the program: from its `ping` line to its `drop` line. The steps are the later pings, each from the reference.
|
|
299
301
|
- The lines of a client name the socket by its local address (`local`), and the lines of a server by its peer (`peer`). For the server, the lines are the lines of the target. A line whose address is null is about a try that did not open.
|
|
300
302
|
- The harness reads the peer of a server from the records of its socket. Behind a router, that peer is the address of the router, not the address of the client.
|
|
301
303
|
- A first ping without an answer can come late, for example at a beat of a server whose phase no document gives. Then the prediction gives its latest time after the reply (`startsBy`), and the run waits that much longer.
|
|
302
|
-
- A prediction can say how the program drops (`drop`). A close frame (`frame`) is a write, and the socket stays ESTABLISHED after it. A close (`close`) closes the socket in
|
|
304
|
+
- A prediction can say how the program drops (`drop`). A close frame (`frame`) is a write, and the socket stays ESTABLISHED after it. A close (`close`) closes the socket at once, in the same window: a FIN or an abort. Another drop is a finding. A FIN of the peer that answers a close frame is no close by the program. The run gives the time from the `drop` line to the close by the program (`left`).
|
|
303
305
|
- The client process ends at the end of each run, and its kernel then closes each socket that is still open. A prediction can say that the program is that client process (`exits`). Then a close in δ_abs of that end is no close by the program: `left` stays null, and `exited` gives the time.
|
|
304
306
|
- The end of the process is the first change out of ESTABLISHED of another socket of the client after its last `dial` line (`exitOf`). The program dropped none of these sockets.
|
|
305
307
|
- A heartbeat is a timer of the program. The retransmit timer of its ping fires in the same interval. Thus a run whose retransmit timer was two jiffies or more behind its wheel slot is void: the VM stopped a vCPU.
|
|
@@ -351,8 +353,9 @@ Each run starts from kernels that keep nothing from the run before it (`lab.forg
|
|
|
351
353
|
`verdictOf(prediction, runs)` (`verdict.ts`) judges a cell:
|
|
352
354
|
|
|
353
355
|
- **Containment.** Each run lands in [T_lo − δ_abs, T_hi + δ_abs]. `NOISE` (δ_abs) is 4 ms, from the calibration of the first environment: the worst reset took 1.141 ms, and δ_abs is one jiffy at the minimum.
|
|
354
|
-
- **δ_abs of an environment.** A cell can give the δ_abs of its environment (`Cell.noise`). Stage 0 measures it in each environment. On a hosted runner of GitHub at HZ 1000, the worst reset took 0.147 ms, thus δ_abs is one jiffy, 1 ms. These read it (`noiseOf`): the bands, the pairing of a program line with its kernel record, and the drop of a program.
|
|
356
|
+
- **δ_abs of an environment.** A cell can give the δ_abs of its environment (`Cell.noise`). Stage 0 measures it in each environment. On a hosted runner of GitHub at HZ 1000, the worst reset took 0.147 ms, thus δ_abs is one jiffy, 1 ms. These read it (`noiseOf`): the bands, the pairing of a program line with its kernel record, and the drop of a program (with `DROP_HANDLING`).
|
|
355
357
|
- **The injector has its own bound.** A fault that the injector commits or lifts late makes a run void. That bound is `INJECT` (4 ms), not δ_abs. Stage 0 measures the commit apart. On a hosted runner it took up to 2.75 ms at 4 environments.
|
|
358
|
+
- **The drop of a program has its own bound.** The pairing of a `drop` line with its act uses `DROP_HANDLING` (1.5 ms), or δ_abs when δ_abs is longer. The band of a drop in the cells adds `DROP_HANDLING` to its high bound.
|
|
356
359
|
- **Median equivalence.** The order-statistic interval of the median must be in the band, made 5 % wider.
|
|
357
360
|
- **Extension.** A median across the edge of the band extends the cell from 11 runs to 22, then 44. Then the verdict is inconclusive.
|
|
358
361
|
- **Recovery.** The recovery after a stall gets the same test as a detection, by its band. A detection is then a finding.
|
package/build/index.d.ts
CHANGED
|
@@ -2,10 +2,47 @@ import { $ as Subject, A as Prediction, B as RequestPrediction, C as KernelRecor
|
|
|
2
2
|
import { Quantity } from "@mark1russell7/quantity";
|
|
3
3
|
import "testcontainers";
|
|
4
4
|
//#region src/application.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* This module reads the acts of the program of the observer: its heartbeat, its drop of the
|
|
7
|
+
* connection, its reconnect and its call in flight. The kernel has no report of a detection by
|
|
8
|
+
* a program. Thus the program writes a line before each of its own acts, on CLOCK_MONOTONIC:
|
|
9
|
+
* - `ping` before each ping of its heartbeat, and `drop` before it closes the connection by itself.
|
|
10
|
+
* - `reconnecting` when it starts its reconnect timer, and `dial` before each new connection.
|
|
11
|
+
*
|
|
12
|
+
* The kernel then stamps each write of the program on the socket (`tx`) and each change of the
|
|
13
|
+
* state of the socket. A line of the client names its socket by its local address (`local`), and
|
|
14
|
+
* a line of a server names it by its peer (`peer`).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* This time bounds the handling of a drop by the program of the observer. It starts when the timer
|
|
18
|
+
* of the program fires. It ends at the kernel's stamp of the act: the write of a close frame, or
|
|
19
|
+
* the close of the socket. The `drop` line comes in that time, before the act.
|
|
20
|
+
*
|
|
21
|
+
* This bound is not δ_abs. δ_abs is the noise of the pipeline, and stage 0 calibrates it from a
|
|
22
|
+
* reset. The handling is the time of the code of the program, and it is longer:
|
|
23
|
+
* - No source and no machine document bounds it (`http/timers.ts` of `@mark1russell7/machines`).
|
|
24
|
+
* - The handling time of the HTTP cells (`HANDLING` in `packages/cells/src/http/race.ts`) is
|
|
25
|
+
* another act. It is the first reply of a new process, up to 11.182 ms.
|
|
26
|
+
* - A drop comes from a timer, long after the start of the process.
|
|
27
|
+
*
|
|
28
|
+
* The bound comes from the CI records of the WS and WST cells, from the `drop` line to the act:
|
|
29
|
+
* - 585 drops with a close frame had a median of 0.652 ms, a 99th percentile of 0.87 ms and a
|
|
30
|
+
* maximum of 1.017 ms.
|
|
31
|
+
* - 559 drops with a close of the socket had a maximum of 0.914 ms.
|
|
32
|
+
* - Two drops took more than the δ_abs of 1 ms. Each failed its cell, and its time was in the band.
|
|
33
|
+
* These are the runs 39390222333 and 39903020657 of the client repository.
|
|
34
|
+
*
|
|
35
|
+
* The bound is 1.5 ms: the maximum and a margin of 0.48 ms. The pairing of a drop with its act
|
|
36
|
+
* uses it, or δ_abs when δ_abs is longer. The band of a drop adds it to its high bound (the WS
|
|
37
|
+
* catalog of the cells). Read the records again after a change to the subject, to Node or to
|
|
38
|
+
* the runners.
|
|
39
|
+
*/
|
|
40
|
+
export declare const DROP_HANDLING: Quantity;
|
|
5
41
|
/**
|
|
6
42
|
* A program event is a line of the program of the observer, with the kernel's stamp of its act.
|
|
7
|
-
* The act is a write, or a change of state of the socket. Without a record of the kernel in
|
|
8
|
-
* after the line, the instant is the stamp of the line.
|
|
43
|
+
* The act is a write, or a change of state of the socket. Without a record of the kernel in its
|
|
44
|
+
* window after the line, the instant is the stamp of the line. The window is δ_abs, and for a drop
|
|
45
|
+
* it is `DROP_HANDLING` when that is longer.
|
|
9
46
|
*/
|
|
10
47
|
interface ProgramEvent {
|
|
11
48
|
readonly line: ProbeEvent;
|
|
@@ -42,7 +79,8 @@ export declare const closeOrExit: (line: ProbeEvent, left: Quantity | null, exit
|
|
|
42
79
|
};
|
|
43
80
|
/**
|
|
44
81
|
* This function tells how a drop differs from the way that its prediction gives, or gives null.
|
|
45
|
-
* A close closes the socket
|
|
82
|
+
* A close closes the socket at once: in the handling time of the program (`DROP_HANDLING`), or in
|
|
83
|
+
* δ_abs (`delta`) when δ_abs is longer. A close frame is a write, and the program does not close
|
|
46
84
|
* the socket at the drop. A peer that answers the close frame can close it, and that is no finding.
|
|
47
85
|
*/
|
|
48
86
|
export declare const dropFinding: (expected: "frame" | "close", drop: ProgramEvent, left: Quantity | null, delta?: Quantity, exited?: Quantity) => string | null;
|
|
@@ -56,7 +94,8 @@ export declare const firstUnanswered: (pings: readonly ProgramEvent[], socket: r
|
|
|
56
94
|
/**
|
|
57
95
|
* This function gives the first drop of the connection by its program. The kernel stamps it as the
|
|
58
96
|
* write of a close frame. Or it stamps the change of the socket out of ESTABLISHED: a close or an
|
|
59
|
-
* abort.
|
|
97
|
+
* abort. That stamp comes in the handling time of the program after the drop line
|
|
98
|
+
* (`DROP_HANDLING`), or in δ_abs (`delta`) when δ_abs is longer.
|
|
60
99
|
*/
|
|
61
100
|
export declare const dropOf: (lines: readonly ProbeEvent[], socket: readonly KernelRecord[], local: unknown, delta?: Quantity) => ProgramEvent | undefined;
|
|
62
101
|
/** A reconnect reading is what the client did after the detection, from its lines and from the records of the kernel. */
|
package/build/index.js
CHANGED
|
@@ -463,6 +463,33 @@ const verdictOfBand = (prediction, runs, delta = NOISE) => {
|
|
|
463
463
|
* state of the socket. A line of the client names its socket by its local address (`local`), and
|
|
464
464
|
* a line of a server names it by its peer (`peer`).
|
|
465
465
|
*/
|
|
466
|
+
/**
|
|
467
|
+
* This time bounds the handling of a drop by the program of the observer. It starts when the timer
|
|
468
|
+
* of the program fires. It ends at the kernel's stamp of the act: the write of a close frame, or
|
|
469
|
+
* the close of the socket. The `drop` line comes in that time, before the act.
|
|
470
|
+
*
|
|
471
|
+
* This bound is not δ_abs. δ_abs is the noise of the pipeline, and stage 0 calibrates it from a
|
|
472
|
+
* reset. The handling is the time of the code of the program, and it is longer:
|
|
473
|
+
* - No source and no machine document bounds it (`http/timers.ts` of `@mark1russell7/machines`).
|
|
474
|
+
* - The handling time of the HTTP cells (`HANDLING` in `packages/cells/src/http/race.ts`) is
|
|
475
|
+
* another act. It is the first reply of a new process, up to 11.182 ms.
|
|
476
|
+
* - A drop comes from a timer, long after the start of the process.
|
|
477
|
+
*
|
|
478
|
+
* The bound comes from the CI records of the WS and WST cells, from the `drop` line to the act:
|
|
479
|
+
* - 585 drops with a close frame had a median of 0.652 ms, a 99th percentile of 0.87 ms and a
|
|
480
|
+
* maximum of 1.017 ms.
|
|
481
|
+
* - 559 drops with a close of the socket had a maximum of 0.914 ms.
|
|
482
|
+
* - Two drops took more than the δ_abs of 1 ms. Each failed its cell, and its time was in the band.
|
|
483
|
+
* These are the runs 39390222333 and 39903020657 of the client repository.
|
|
484
|
+
*
|
|
485
|
+
* The bound is 1.5 ms: the maximum and a margin of 0.48 ms. The pairing of a drop with its act
|
|
486
|
+
* uses it, or δ_abs when δ_abs is longer. The band of a drop adds it to its high bound (the WS
|
|
487
|
+
* catalog of the cells). Read the records again after a change to the subject, to Node or to
|
|
488
|
+
* the runners.
|
|
489
|
+
*/
|
|
490
|
+
const DROP_HANDLING = quantity(1.5, "ms");
|
|
491
|
+
/** This function gives the window of the act of a drop after its line, in seconds: `DROP_HANDLING`, or δ_abs when δ_abs is longer. */
|
|
492
|
+
const dropWindow = (delta) => Math.max(valueIn(DROP_HANDLING, "s"), valueIn(delta, "s"));
|
|
466
493
|
/** This function gives the interval between two instants on the one clock, in seconds to the microsecond. */
|
|
467
494
|
const between$3 = (from, to) => quantity(Math.round((to - from) / 1e3) / 1e6, "s");
|
|
468
495
|
/** This function gives the state of a state record after the change, and before it. TCP_ESTABLISHED is 1, TCP_SYN_SENT 2. */
|
|
@@ -485,7 +512,7 @@ const onConnection = (line, local) => {
|
|
|
485
512
|
if (!("local" in line) && !("peer" in line)) return true;
|
|
486
513
|
return (line["local"] ?? line["peer"]) === local;
|
|
487
514
|
};
|
|
488
|
-
/** This function gives the first record of a socket that matches, at the stamp of a line or in
|
|
515
|
+
/** This function gives the first record of a socket that matches, at the stamp of a line or in a window (`delta`) after it. */
|
|
489
516
|
const kernelAt = (socket, line, matches, delta) => {
|
|
490
517
|
const noise = valueIn(delta, "s") * 1e9;
|
|
491
518
|
return socket.find((record) => record.mono >= line.t && record.mono <= line.t + noise && matches(record));
|
|
@@ -536,11 +563,12 @@ const closeOrExit = (line, left, exit, delta = NOISE) => {
|
|
|
536
563
|
};
|
|
537
564
|
/**
|
|
538
565
|
* This function tells how a drop differs from the way that its prediction gives, or gives null.
|
|
539
|
-
* A close closes the socket
|
|
566
|
+
* A close closes the socket at once: in the handling time of the program (`DROP_HANDLING`), or in
|
|
567
|
+
* δ_abs (`delta`) when δ_abs is longer. A close frame is a write, and the program does not close
|
|
540
568
|
* the socket at the drop. A peer that answers the close frame can close it, and that is no finding.
|
|
541
569
|
*/
|
|
542
570
|
const dropFinding = (expected, drop, left, delta = NOISE, exited) => {
|
|
543
|
-
const noise =
|
|
571
|
+
const noise = dropWindow(delta);
|
|
544
572
|
const soon = left !== null && valueIn(left, "s") <= noise;
|
|
545
573
|
if (expected === "close") {
|
|
546
574
|
if (left === null) return `the program did not close its socket after the drop, where a close is at once${exited === void 0 ? "" : ": it stayed open until the client process ended"}`;
|
|
@@ -560,11 +588,12 @@ const firstUnanswered = (pings, socket, until = Number.POSITIVE_INFINITY) => pin
|
|
|
560
588
|
/**
|
|
561
589
|
* This function gives the first drop of the connection by its program. The kernel stamps it as the
|
|
562
590
|
* write of a close frame. Or it stamps the change of the socket out of ESTABLISHED: a close or an
|
|
563
|
-
* abort.
|
|
591
|
+
* abort. That stamp comes in the handling time of the program after the drop line
|
|
592
|
+
* (`DROP_HANDLING`), or in δ_abs (`delta`) when δ_abs is longer.
|
|
564
593
|
*/
|
|
565
594
|
const dropOf = (lines, socket, local, delta = NOISE) => {
|
|
566
595
|
const line = lines.find((each) => each.ev === "drop" && onConnection(each, local));
|
|
567
|
-
return line === void 0 ? void 0 : eventOf(socket, line, (record) => isWrite(record) || record.ev === "state" && oldState$2(record) === 1, delta);
|
|
596
|
+
return line === void 0 ? void 0 : eventOf(socket, line, (record) => isWrite(record) || record.ev === "state" && oldState$2(record) === 1, quantity(dropWindow(delta), "s"));
|
|
568
597
|
};
|
|
569
598
|
/**
|
|
570
599
|
* This function reads the reconnect of the client after the detection at `detected`. The socket of
|
|
@@ -5699,6 +5728,6 @@ const runCell = async (cell, say = () => {}) => {
|
|
|
5699
5728
|
}
|
|
5700
5729
|
};
|
|
5701
5730
|
//#endregion
|
|
5702
|
-
export { CLIENT_NAMES, CLUSTER_STAGES, CONVERGE_MS, GIVES_AWAY, INJECT, KEPT, LINGER_MS, LISTING, MEMBER_MARKS, MONITOR_DOWN, NODE_MARKS, NOISE, PINNED, PUMP, PUMP_SLACK, QUIET_MS, RELATIVE, REPLICA_SET_STAGES, REPOSITORY, SHIPPED_CLIENTS, SHIPPED_NAMES, STAGES, STATUS_SCRIPT, STEPS, STEP_DOWN, amqpClientImage, callOf, clockOffsetOf, closeOrExit, clusterArgs, clusterConf, clusterCutOf, clusterHostsOf, clusterOnce, clusterStagesOf, clusterViewOf, crossingsOf, cutOf, deadlineOf, delayVoids, deviceOf, dropFinding, dropOf, endpointAfter, errorsOf, exitOf, fieldOf, fieldsOf, firstUnanswered, goHttpImage, groupOnce, groupVerdictOf, grpcClientImage, harnessImage, hikariClientImage, hzOf, imageOf, imageProblems, inContext, infoOf, initiateScript, isHopPlace, judge, lagsOf, latestEndOf, leftAfter, logNameOf, matches, measure, measureDriver, measureGroup, medianInterval, memberCommand, memberConfig, memberLineOf, mongoClientImage, monotonicOf, nodeClientImage, nodeCommand, nodeHttpImage, nodeLineOf, nodeNameOf, nodesOnMonotonic, noiseOf, onMonotonic, openClusterLab, openGroupLab, openLab, openReplicaSetLab, peersOf, pgClientImage, pingsOf, plainOf, planOf, programLines, programOf, quantileOf, reconnectFinding, reconnectOf, referenceOf, reorderingOf, replicaSetArgs, replicaSetOnce, replicaSetStagesOf, requestOf, requestWords, restamped, routerImage, routesOf, runCell, sentinelConfig, socketAt, socketOf, socketsOf, spread, spreadOf, stagesOf, statusViewOf, subjectClient, subjectProblems, subscriptionsOf, targetImageOf, targetSourceOf, templated, toolJsonOf, toxicBody, unlockedManifests, unpinnedBases, verdictOf, viewOf, writesOf };
|
|
5731
|
+
export { CLIENT_NAMES, CLUSTER_STAGES, CONVERGE_MS, DROP_HANDLING, GIVES_AWAY, INJECT, KEPT, LINGER_MS, LISTING, MEMBER_MARKS, MONITOR_DOWN, NODE_MARKS, NOISE, PINNED, PUMP, PUMP_SLACK, QUIET_MS, RELATIVE, REPLICA_SET_STAGES, REPOSITORY, SHIPPED_CLIENTS, SHIPPED_NAMES, STAGES, STATUS_SCRIPT, STEPS, STEP_DOWN, amqpClientImage, callOf, clockOffsetOf, closeOrExit, clusterArgs, clusterConf, clusterCutOf, clusterHostsOf, clusterOnce, clusterStagesOf, clusterViewOf, crossingsOf, cutOf, deadlineOf, delayVoids, deviceOf, dropFinding, dropOf, endpointAfter, errorsOf, exitOf, fieldOf, fieldsOf, firstUnanswered, goHttpImage, groupOnce, groupVerdictOf, grpcClientImage, harnessImage, hikariClientImage, hzOf, imageOf, imageProblems, inContext, infoOf, initiateScript, isHopPlace, judge, lagsOf, latestEndOf, leftAfter, logNameOf, matches, measure, measureDriver, measureGroup, medianInterval, memberCommand, memberConfig, memberLineOf, mongoClientImage, monotonicOf, nodeClientImage, nodeCommand, nodeHttpImage, nodeLineOf, nodeNameOf, nodesOnMonotonic, noiseOf, onMonotonic, openClusterLab, openGroupLab, openLab, openReplicaSetLab, peersOf, pgClientImage, pingsOf, plainOf, planOf, programLines, programOf, quantileOf, reconnectFinding, reconnectOf, referenceOf, reorderingOf, replicaSetArgs, replicaSetOnce, replicaSetStagesOf, requestOf, requestWords, restamped, routerImage, routesOf, runCell, sentinelConfig, socketAt, socketOf, socketsOf, spread, spreadOf, stagesOf, statusViewOf, subjectClient, subjectProblems, subscriptionsOf, targetImageOf, targetSourceOf, templated, toolJsonOf, toxicBody, unlockedManifests, unpinnedBases, verdictOf, viewOf, writesOf };
|
|
5703
5732
|
|
|
5704
5733
|
//# sourceMappingURL=index.js.map
|