@mark1russell7/harness 0.11.23 → 0.11.24
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 +2 -1
- package/build/{cell-Dn1TvJcA.d.ts → cell-wInJC-GH.d.ts} +6 -2
- package/build/index.d.ts +4 -3
- package/build/index.js +29 -4
- package/build/index.js.map +1 -1
- package/build/schema.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -250,7 +250,8 @@ ioredis sets the keepalive of its socket itself, after it connects. Thus a cell
|
|
|
250
250
|
- **A close of the server** (`server-close`) makes the server close the connection of each client, with `Target.close`: `CLIENT KILL` for Redis.
|
|
251
251
|
- **A stall of the application** (`app-stall`) injects nothing. The server process holds the reply, because the request asks for it (`HttpProbe.hold`), and its kernel stays up.
|
|
252
252
|
- **An event at a proxy** (`hop-event`, `Cell.event`) is a signal to the program of the proxy, or a query on its console. Examples are a reload of the configuration, a stop of a proxy and PAUSE on the console of PgBouncer.
|
|
253
|
-
- A signal goes to each process of `ProxyHop.program`: HUP, TERM or
|
|
253
|
+
- A signal goes to each process of `ProxyHop.program`: HUP, TERM, INT, STOP or CONT (`HopSignal`). A sidecar in the network and process namespaces of the proxy sends it (`inject signal NAME HUP`). The lab starts that sidecar at the first signal.
|
|
254
|
+
- STOP blocks the event loop of the proxy: its processes stop, and its kernel keeps each socket. With a hold (`Cell.hold`), CONT thaws it at that time after the stop, from inside the VM (`--at`). The lift thaws a proxy that its hold did not thaw.
|
|
254
255
|
- A query goes from the injector of the proxy to its console on 127.0.0.1, as a user that the console trusts (`inject query`). The injector speaks the simple query of the PostgreSQL protocol. Its stamps bracket the query and its ReadyForQuery. After the run, the harness sends the `undo` of the query, for example RESUME after PAUSE.
|
|
255
256
|
- Without `inFlight`, the event comes first, and the request meets it. With `inFlight`, the request goes first, and the event comes while it is in flight. A run whose order is not that order is void.
|
|
256
257
|
- **A fault on a group** acts on the part that `Cell.faultAt` names by its role:
|
|
@@ -130,8 +130,12 @@ interface ProxyHop {
|
|
|
130
130
|
/**
|
|
131
131
|
* A signal of a hop event. HUP reloads the configuration of a pooler. TERM stops a proxy, as a stop of
|
|
132
132
|
* its container does. INT stops docker-proxy, as Docker does when it removes a port binding.
|
|
133
|
+
*
|
|
134
|
+
* STOP blocks the event loop of a proxy: its processes stop, and its kernel keeps each socket. Thus
|
|
135
|
+
* ACKs go on, and the data of each peer waits in its receive queue. With the hold of the cell
|
|
136
|
+
* (`Cell.hold`), CONT thaws it at the end of the hold, from inside the VM.
|
|
133
137
|
*/
|
|
134
|
-
type HopSignal = "HUP" | "TERM" | "INT";
|
|
138
|
+
type HopSignal = "HUP" | "TERM" | "INT" | "STOP" | "CONT";
|
|
135
139
|
/**
|
|
136
140
|
* An event at a proxy hop (`hop-event`). A signal goes to each process of the program of the hop
|
|
137
141
|
* (`ProxyHop.program`). A query goes to the console of the hop from its own namespace, as a user
|
|
@@ -1128,4 +1132,4 @@ interface RunTopology {
|
|
|
1128
1132
|
}
|
|
1129
1133
|
//#endregion
|
|
1130
1134
|
export { Subject as $, Prediction as A, RequestPrediction as B, KernelRecord as C, MiddleboxForm as D, MiddleboxExpectation as E, Recovers as F, RunPart as G, RttRange as H, Reference as I, SentinelStage as J, RunTopology as K, ReplicaSet as L, ProxyHop as M, ProxyTime as N, Observer as O, Reconnects as P, StageBand as Q, ReplicaSetStage as R, ImageSource as S, MiddleboxEvent as T, Run as U, RouterHop as V, RunGroup as W, ShippedImage as X, Shipped as Y, Stage as Z, Hop as _, Cluster as a, latestEndOf as at, HopSignal as b, DriverBand as c, FaultPlace as d, Target as et, Group as f, HarnessImage as g, GroupRole as h, ClientImage as i, isHopPlace as it, ProbeEvent as j, PinnedImage as k, DriverStep as l, GroupPrediction as m, Cell as n, Toxic as nt, ClusterClientAt as o, GroupPlace as p, SentinelEvent as q, Client as r, WsProbe as rt, ClusterStage as s, BuildImage as t, Topology as tt, Fault as u, HopEvent as v, LineMatch as w, HttpProbe as x, HopPlace as y, Replies as z };
|
|
1131
|
-
//# sourceMappingURL=cell-
|
|
1135
|
+
//# sourceMappingURL=cell-wInJC-GH.d.ts.map
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Subject, A as Prediction, B as RequestPrediction, C as KernelRecord, D as MiddleboxForm, E as MiddleboxExpectation, F as Recovers, G as RunPart, H as RttRange, I as Reference, J as SentinelStage, K as RunTopology, L as ReplicaSet, M as ProxyHop, N as ProxyTime, O as Observer, P as Reconnects, Q as StageBand, R as ReplicaSetStage, S as ImageSource, T as MiddleboxEvent, U as Run, V as RouterHop, W as RunGroup, X as ShippedImage, Y as Shipped, Z as Stage, _ as Hop, a as Cluster, at as latestEndOf, b as HopSignal, c as DriverBand, d as FaultPlace, et as Target, f as Group, g as HarnessImage, h as GroupRole, i as ClientImage, it as isHopPlace, j as ProbeEvent, k as PinnedImage, l as DriverStep, m as GroupPrediction, n as Cell, nt as Toxic, o as ClusterClientAt, p as GroupPlace, q as SentinelEvent, r as Client, rt as WsProbe, s as ClusterStage, t as BuildImage, tt as Topology, u as Fault, v as HopEvent, w as LineMatch, x as HttpProbe, y as HopPlace, z as Replies } from "./cell-
|
|
1
|
+
import { $ as Subject, A as Prediction, B as RequestPrediction, C as KernelRecord, D as MiddleboxForm, E as MiddleboxExpectation, F as Recovers, G as RunPart, H as RttRange, I as Reference, J as SentinelStage, K as RunTopology, L as ReplicaSet, M as ProxyHop, N as ProxyTime, O as Observer, P as Reconnects, Q as StageBand, R as ReplicaSetStage, S as ImageSource, T as MiddleboxEvent, U as Run, V as RouterHop, W as RunGroup, X as ShippedImage, Y as Shipped, Z as Stage, _ as Hop, a as Cluster, at as latestEndOf, b as HopSignal, c as DriverBand, d as FaultPlace, et as Target, f as Group, g as HarnessImage, h as GroupRole, i as ClientImage, it as isHopPlace, j as ProbeEvent, k as PinnedImage, l as DriverStep, m as GroupPrediction, n as Cell, nt as Toxic, o as ClusterClientAt, p as GroupPlace, q as SentinelEvent, r as Client, rt as WsProbe, s as ClusterStage, t as BuildImage, tt as Topology, u as Fault, v as HopEvent, w as LineMatch, x as HttpProbe, y as HopPlace, z as Replies } from "./cell-wInJC-GH.js";
|
|
2
2
|
import { Quantity } from "@mark1russell7/quantity";
|
|
3
3
|
import "testcontainers";
|
|
4
4
|
//#region src/application.d.ts
|
|
@@ -941,9 +941,10 @@ interface Lab {
|
|
|
941
941
|
* This method applies an event at a proxy hop (`HopEvent`), or its undo. A signal goes from a
|
|
942
942
|
* sidecar in the network and process namespaces of the hop. The lab starts that sidecar at the
|
|
943
943
|
* first signal of the hop. A query goes from the injector of the hop to its console on 127.0.0.1. The
|
|
944
|
-
* injector stamps each one. An event with no undo gives null for its undo.
|
|
944
|
+
* injector stamps each one. An event with no undo gives null for its undo. A signal can wait for an
|
|
945
|
+
* instant on CLOCK_MONOTONIC (`at`), as the thaw at the end of a hold does.
|
|
945
946
|
*/
|
|
946
|
-
event(event: HopEvent, undo?: boolean): Promise<{
|
|
947
|
+
event(event: HopEvent, undo?: boolean, at?: number): Promise<{
|
|
947
948
|
t0: number;
|
|
948
949
|
t1: number;
|
|
949
950
|
} | null>;
|
package/build/index.js
CHANGED
|
@@ -2803,7 +2803,7 @@ const openLab = async (target, kind = "tcp", topology) => {
|
|
|
2803
2803
|
...when
|
|
2804
2804
|
]);
|
|
2805
2805
|
},
|
|
2806
|
-
async event(event, undo = false) {
|
|
2806
|
+
async event(event, undo = false, at) {
|
|
2807
2807
|
const hop = hopNamed(event.hop);
|
|
2808
2808
|
if (hop.hop.kind !== "proxy") throw new Error(`the hop ${event.hop} is a router: an event goes to a proxy`);
|
|
2809
2809
|
if ("signal" in event) {
|
|
@@ -2816,11 +2816,13 @@ const openLab = async (target, kind = "tcp", topology) => {
|
|
|
2816
2816
|
hopSignallers.set(event.hop, sidecar);
|
|
2817
2817
|
opened.push(sidecar);
|
|
2818
2818
|
}
|
|
2819
|
+
const when = at === void 0 ? [] : ["--at", String(Math.round(at))];
|
|
2819
2820
|
return stamped(sidecar, [
|
|
2820
2821
|
"/opt/harness/inject",
|
|
2821
2822
|
"signal",
|
|
2822
2823
|
program,
|
|
2823
|
-
event.signal
|
|
2824
|
+
event.signal,
|
|
2825
|
+
...when
|
|
2824
2826
|
]);
|
|
2825
2827
|
}
|
|
2826
2828
|
const query = undo ? event.console.undo : event.console.query;
|
|
@@ -5324,9 +5326,23 @@ const once = async (lab, cell, environment, index, dry = false) => {
|
|
|
5324
5326
|
case "server-close":
|
|
5325
5327
|
await lab.serverClose();
|
|
5326
5328
|
return null;
|
|
5327
|
-
case "hop-event":
|
|
5329
|
+
case "hop-event": {
|
|
5328
5330
|
if (cell.event === void 0) throw new Error(`${cell.name} names no event`);
|
|
5329
|
-
|
|
5331
|
+
const stamp = await lab.event(cell.event);
|
|
5332
|
+
if ("signal" in cell.event && cell.event.signal === "STOP" && cell.hold !== void 0 && stamp !== null) {
|
|
5333
|
+
const thaw = {
|
|
5334
|
+
hop: cell.event.hop,
|
|
5335
|
+
signal: "CONT"
|
|
5336
|
+
};
|
|
5337
|
+
thawing = lab.event(thaw, false, stamp.t0 + valueIn(cell.hold, "s") * 1e9).then((thawed) => {
|
|
5338
|
+
if (thawed === null) throw new Error(`the hop ${thaw.hop} gave no stamp for CONT`);
|
|
5339
|
+
heal = thawed;
|
|
5340
|
+
return thawed;
|
|
5341
|
+
});
|
|
5342
|
+
thawing.catch(() => void 0);
|
|
5343
|
+
}
|
|
5344
|
+
return stamp;
|
|
5345
|
+
}
|
|
5330
5346
|
default: return lab.fault("blackhole", faultAt);
|
|
5331
5347
|
}
|
|
5332
5348
|
};
|
|
@@ -5346,6 +5362,15 @@ const once = async (lab, cell, environment, index, dry = false) => {
|
|
|
5346
5362
|
case "app-stall":
|
|
5347
5363
|
case "none": return;
|
|
5348
5364
|
case "hop-event":
|
|
5365
|
+
if (cell.event !== void 0 && "signal" in cell.event && cell.event.signal === "STOP") {
|
|
5366
|
+
const thaw = {
|
|
5367
|
+
hop: cell.event.hop,
|
|
5368
|
+
signal: "CONT"
|
|
5369
|
+
};
|
|
5370
|
+
if (thawing !== null) await thawing.catch(() => lab.event(thaw));
|
|
5371
|
+
else await lab.event(thaw);
|
|
5372
|
+
return;
|
|
5373
|
+
}
|
|
5349
5374
|
if (cell.event !== void 0) await lab.event(cell.event, true);
|
|
5350
5375
|
return;
|
|
5351
5376
|
case "unreachable": return lab.lift("reject", faultAt, { code: cell.icmp ?? "host" });
|