@mark1russell7/harness 0.11.4 → 0.11.5

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 CHANGED
@@ -229,6 +229,7 @@ Each run starts from kernels that keep nothing from the run before it (`lab.forg
229
229
  - **A topology.** A run in a topology also gives the bytes that the client read after its request, and when a router forgot its flow (`forgot`).
230
230
  - **Recovery.** After a stall (`prediction.recovers`), it times the send to the first segment back after the stall stopped. That segment is the answer of the server to the retransmission that got through. A run whose stall stopped outside the window of its prediction is void. A run where nothing came back is a finding.
231
231
  - **An end of file.** A FIN counts from the change of state of the socket of the peer when it closes (`peer-closed`). It ends at the change of the socket of the observer to CLOSE_WAIT. The kernel stamps the two changes.
232
+ - **A check of a pool.** A check on an idle connection counts from the first segment with data that the socket sends after the fault (`first-sent`). The keepalive of HikariCP comes at a phase from the creation of its connection. Thus no line of the client gives its time, and the kernel stamps it. The prediction gives the latest time of that send after the reply (`startsBy`), and the run waits that much longer.
232
233
  - **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.
233
234
  - The program writes `ping` before each ping of its heartbeat. The kernel stamps the write of the ping (`tx`).
234
235
  - 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.
@@ -222,8 +222,12 @@ interface Toxic {
222
222
  * A heartbeat of a program counts from its first ping that got no answer (`ping-sent`). The
223
223
  * program writes a `ping` line before each ping, and the kernel stamps the write (`tx`). No
224
224
  * segment with data reaches the socket after that write, up to the detection.
225
+ *
226
+ * A check of a pool on an idle connection counts from the first segment with data that the socket
227
+ * sends after the fault (`first-sent`). The keepalive of HikariCP comes at a phase from the
228
+ * creation of its connection, thus no line of the client gives its time. The kernel stamps it.
225
229
  */
226
- type Reference = "last-received" | "first-retransmission" | "request-sent" | "peer-closed" | "fault" | "client-start" | "ping-sent";
230
+ type Reference = "last-received" | "first-retransmission" | "request-sent" | "peer-closed" | "fault" | "client-start" | "ping-sent" | "first-sent";
227
231
  /**
228
232
  * This prediction tells when a connection moves again after a stall. That occurs at the first
229
233
  * firing of its retransmission timer after the stall stops, and its reply comes back one round
@@ -996,4 +1000,4 @@ interface RunTopology {
996
1000
  }
997
1001
  //#endregion
998
1002
  export { isHopPlace as $, Recovers as A, RunPart as B, Observer as C, ProxyHop as D, ProbeEvent as E, RequestPrediction as F, ShippedImage as G, SentinelEvent as H, RouterHop as I, Subject as J, Stage as K, RttRange as L, ReplicaSet as M, ReplicaSetStage as N, ProxyTime as O, Replies as P, WsProbe as Q, Run as R, MiddleboxForm as S, Prediction as T, SentinelStage as U, RunTopology as V, Shipped as W, Topology as X, Target as Y, Toxic as Z, ImageSource as _, DriverBand as a, MiddleboxEvent as b, FaultPlace as c, GroupPrediction as d, latestEndOf as et, GroupRole as f, HttpProbe as g, HopPlace as h, ClientImage as i, Reference as j, Reconnects as k, Group as l, Hop as m, Cell as n, DriverStep as o, HarnessImage as p, StageBand as q, Client as r, Fault as s, BuildImage as t, GroupPlace as u, KernelRecord as v, PinnedImage as w, MiddleboxExpectation as x, LineMatch as y, RunGroup as z };
999
- //# sourceMappingURL=cell-Di_YHiuB.d.ts.map
1003
+ //# sourceMappingURL=cell-lSCgFB54.d.ts.map
package/build/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as isHopPlace, A as Recovers, B as RunPart, C as Observer, D as ProxyHop, E as ProbeEvent, F as RequestPrediction, G as ShippedImage, H as SentinelEvent, I as RouterHop, J as Subject, K as Stage, L as RttRange, M as ReplicaSet, N as ReplicaSetStage, O as ProxyTime, P as Replies, Q as WsProbe, R as Run, S as MiddleboxForm, T as Prediction, U as SentinelStage, V as RunTopology, W as Shipped, X as Topology, Y as Target, Z as Toxic, _ as ImageSource, a as DriverBand, b as MiddleboxEvent, c as FaultPlace, d as GroupPrediction, et as latestEndOf, f as GroupRole, g as HttpProbe, h as HopPlace, i as ClientImage, j as Reference, k as Reconnects, l as Group, m as Hop, n as Cell, o as DriverStep, p as HarnessImage, q as StageBand, r as Client, s as Fault, t as BuildImage, u as GroupPlace, v as KernelRecord, w as PinnedImage, x as MiddleboxExpectation, y as LineMatch, z as RunGroup } from "./cell-Di_YHiuB.js";
1
+ import { $ as isHopPlace, A as Recovers, B as RunPart, C as Observer, D as ProxyHop, E as ProbeEvent, F as RequestPrediction, G as ShippedImage, H as SentinelEvent, I as RouterHop, J as Subject, K as Stage, L as RttRange, M as ReplicaSet, N as ReplicaSetStage, O as ProxyTime, P as Replies, Q as WsProbe, R as Run, S as MiddleboxForm, T as Prediction, U as SentinelStage, V as RunTopology, W as Shipped, X as Topology, Y as Target, Z as Toxic, _ as ImageSource, a as DriverBand, b as MiddleboxEvent, c as FaultPlace, d as GroupPrediction, et as latestEndOf, f as GroupRole, g as HttpProbe, h as HopPlace, i as ClientImage, j as Reference, k as Reconnects, l as Group, m as Hop, n as Cell, o as DriverStep, p as HarnessImage, q as StageBand, r as Client, s as Fault, t as BuildImage, u as GroupPlace, v as KernelRecord, w as PinnedImage, x as MiddleboxExpectation, y as LineMatch, z as RunGroup } from "./cell-lSCgFB54.js";
2
2
  import { Quantity } from "@mark1russell7/quantity";
3
3
  import "testcontainers";
4
4
  //#region src/application.d.ts
@@ -132,6 +132,7 @@ export declare const socketAt: (events: readonly ProbeEvent[], role: string, at:
132
132
  * - `first-retransmission`: the first retransmission of the RTO timer on the socket.
133
133
  * - `peer-closed`: the change of state of the socket of the target, when its process dies.
134
134
  * - `fault`: the start of the commit of the fault. `client-start`: the `connecting` line.
135
+ * - `first-sent`: the first segment with data that the socket sends after the fault.
135
136
  */
136
137
  export declare const referenceOf: (run: Run, from: Reference, role: string, data: boolean) => number | undefined;
137
138
  /**
package/build/index.js CHANGED
@@ -713,6 +713,7 @@ const outsetOf = (run) => {
713
713
  * - `first-retransmission`: the first retransmission of the RTO timer on the socket.
714
714
  * - `peer-closed`: the change of state of the socket of the target, when its process dies.
715
715
  * - `fault`: the start of the commit of the fault. `client-start`: the `connecting` line.
716
+ * - `first-sent`: the first segment with data that the socket sends after the fault.
716
717
  */
717
718
  const referenceOf = (run, from, role, data) => {
718
719
  const ready = run.events.find((event) => event.ev === "ready");
@@ -726,6 +727,7 @@ const referenceOf = (run, from, role, data) => {
726
727
  const counts = (record) => data ? (record.ev === "rx" || record.ev === "tx") && (record.seg?.len.value ?? 0) > 0 : record.ev === "rx";
727
728
  return place.records.filter((record) => record.mono <= before && counts(record)).at(-1)?.mono;
728
729
  }
730
+ if (from === "first-sent") return place.records.find((record) => record.ev === "tx" && record.mono > before && (record.seg?.len.value ?? 0) > 0)?.mono;
729
731
  if (from === "first-retransmission") {
730
732
  const request = run.events.filter((event) => event.ev === "sent")[1]?.t ?? before;
731
733
  return place.records.find((record) => record.ev === "retrans" && record.why === "rto" && record.mono > request)?.mono;
@@ -1352,7 +1354,7 @@ const count = (event, field) => event === void 0 ? 0 : Number(event[field] ?? 0)
1352
1354
  /** This function gives the view of the client on the same interval: TCP_INFO, with a sample each 2 ms. */
1353
1355
  const socketVantage = (cell, events, ready, request) => {
1354
1356
  const { from } = cell.prediction.detects === true ? cell.prediction : { from: void 0 };
1355
- if (from === void 0 || from === "peer-closed" || from === "fault" || from === "ping-sent") return null;
1357
+ if (from === void 0 || from === "peer-closed" || from === "fault" || from === "ping-sent" || from === "first-sent") return null;
1356
1358
  const ended = events.find((event) => event.ev === "error" || event.ev === "eof");
1357
1359
  const reference = from === "last-received" ? ready : from === "request-sent" ? request : events.find((event) => event.ev === "kernel" && event.t >= request.t && count(event, "retransmits") > 0);
1358
1360
  return ended === void 0 || reference === void 0 ? null : between(reference.t, ended.t);
@@ -1675,7 +1677,7 @@ const measureSocket = (cell, run) => {
1675
1677
  if (from === "fault") return run.fault?.t0;
1676
1678
  if (from === "client-start") return (events.find((event) => event.ev === "connecting") ?? events[0])?.t;
1677
1679
  if (from === "ping-sent") return firstUnanswered(pings, socket, ended)?.at;
1678
- return (from === "last-received" ? socket.filter((each) => each.ev === "rx" && each.mono <= before).at(-1) : from === "first-retransmission" ? retransmitted.find((each) => each.why === "rto") : kernel.find((each) => each.netns === peerNetns && each.cookie === peerCookie && each.ev === "state" && oldState(each) === 1))?.mono;
1680
+ return (from === "last-received" ? socket.filter((each) => each.ev === "rx" && each.mono <= before).at(-1) : from === "first-retransmission" ? retransmitted.find((each) => each.why === "rto") : from === "first-sent" ? socket.find((each) => each.ev === "tx" && each.mono > before && (each.seg?.len.value ?? 0) > 0) : kernel.find((each) => each.netns === peerNetns && each.cookie === peerCookie && each.ev === "state" && oldState(each) === 1))?.mono;
1679
1681
  };
1680
1682
  const lastRx = kernel.filter((each) => each.netns === run.netns && each.src === local && each.ev === "rx" && each.mono <= before).at(-1)?.mono ?? ready.t;
1681
1683
  const chain = run.topology === void 0 ? {} : {