@mark1russell7/machines 0.3.32 → 0.3.33

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { machineSchema } from "@mark1russell7/algebra/schema";
2
2
  import { z } from "zod";
3
- //#region src/call.ts
3
+ // src/call.ts
4
4
  /**
5
5
  * This document is one call of a program on a socket of Linux TCP: a deadline for each try, and a
6
6
  * retry after each deadline. It is a generic client that the program configures, as the
@@ -127,8 +127,7 @@ const DEADLINE_CALL = machineSchema.parse({
127
127
  }
128
128
  ]
129
129
  });
130
- //#endregion
131
- //#region src/grpc/grpc-go-server.ts
130
+ // src/grpc/grpc-go-server.ts
132
131
  const AT$18 = "grpc-go v1.84.0";
133
132
  const GO = "go1.27.2 src/net";
134
133
  const ETCD = "etcd v3.6.15";
@@ -828,8 +827,7 @@ const ETCD_SERVER = serverOf({
828
827
  setsUserTimeout: 0,
829
828
  note: "keepalive_listener.go:68: SetKeepAlivePeriod(30 s) on each accepted connection"
830
829
  });
831
- //#endregion
832
- //#region src/grpc/grpc-js.ts
830
+ // src/grpc/grpc-js.ts
833
831
  const AT$17 = "@grpc/grpc-js 1.14.6 src";
834
832
  /**
835
833
  * This document is grpc-js 1.14.6 on Node, for one channel to one server with no TLS, its transport
@@ -1364,8 +1362,7 @@ const GRPC_JS = machineSchema.parse({
1364
1362
  note: "The socket of the transport: a Linux TCP socket with TCP_NODELAY and no keepalive. Thus the kernel ends a send with no ACK only at the give-up of its retransmissions, and an idle socket to a peer that is gone stays open"
1365
1363
  }
1366
1364
  });
1367
- //#endregion
1368
- //#region src/http/timers.ts
1365
+ // src/http/timers.ts
1369
1366
  /**
1370
1367
  * This module gives the lateness of a timer in user space on Linux 6.6. A Node timer and a Go timer
1371
1368
  * both sleep in `epoll_wait` with a timeout in whole milliseconds. The kernel lets that sleep end
@@ -1415,15 +1412,19 @@ const COARSE_MS = "min(floor(hz / 1000), 1) * 1000 / hz";
1415
1412
  * arithmetic reads `ms` in milliseconds, and the knob `hz` in Hz.
1416
1413
  */
1417
1414
  const nodeTimerLateness = (ms) => ({
1418
- expr: `${slackMs(ms)} + 1 + ${COARSE_MS}`,
1415
+ expr: nodeLateMs(ms),
1419
1416
  unit: "ms"
1420
1417
  });
1418
+ /** This function gives the arithmetic of `nodeTimerLateness`, in ms, for a document that adds it to other terms. */
1419
+ const nodeLateMs = (ms) => `${slackMs(ms)} + 1 + ${COARSE_MS}`;
1420
+ /** This text is the arithmetic of `NODE_TIMER_EARLY`, in ms, for a document that adds it to other terms. */
1421
+ const NODE_EARLY_MS = `1 + ${COARSE_MS}`;
1421
1422
  /**
1422
1423
  * This expression is how early a Node timer can fire. It is 1 ms for the truncation of the loop
1423
1424
  * clock that stamps its start, and the step of the coarse clock.
1424
1425
  */
1425
1426
  const NODE_TIMER_EARLY = {
1426
- expr: `1 + ${COARSE_MS}`,
1427
+ expr: NODE_EARLY_MS,
1427
1428
  unit: "ms"
1428
1429
  };
1429
1430
  /** This function gives the lateness of a Go timer of `s` seconds: the slack of its sleep and 1 ms. The arithmetic reads `s` in seconds. */
@@ -1468,8 +1469,7 @@ const undiciFastLateness = (ms) => ({
1468
1469
  expr: `ceil((${ms}) / 499) * 499 - (${ms}) + ceil((${ms}) / 499) * (${slackMs(String(499))} + 1 + ${COARSE_MS})`,
1469
1470
  unit: "ms"
1470
1471
  });
1471
- //#endregion
1472
- //#region src/http/go-transport.ts
1472
+ // src/http/go-transport.ts
1473
1473
  /**
1474
1474
  * This document is one connection of the `http.Transport` of Go 1.27.2 at its defaults, over its
1475
1475
  * Linux TCP socket. Each fact comes from the source at the tag `go1.27.2`. The comments give the
@@ -1791,8 +1791,7 @@ const GO_TRANSPORT = machineSchema.parse({
1791
1791
  note: "Go sets SO_KEEPALIVE with its own idle, interval and count on each dialed socket, rounded up to whole seconds. Thus the keepalive sysctls of the namespace do not reach it. A negative KeepAlive turns it off: a reader gives keepidle no bound."
1792
1792
  }
1793
1793
  });
1794
- //#endregion
1795
- //#region src/http/node-agent.ts
1794
+ // src/http/node-agent.ts
1796
1795
  /**
1797
1796
  * This document is one socket of the `http.Agent` of Node v24.21.0, as its global agent sets it.
1798
1797
  * Its keep-alive is on, its free socket timeout is 5 s, and it is LIFO. It is over the Linux TCP socket. Each fact
@@ -2054,8 +2053,7 @@ const NODE_HTTP_AGENT = machineSchema.parse({
2054
2053
  note: "The agent turns keepalive on at the connect (lib/_http_agent.js:474-478, lib/net.js:1991-1994) and again on each free socket. Node passes the delay in whole seconds and libuv sets 1 s and 10 probes. Thus the keepalive sysctls of the namespace do not reach it."
2055
2054
  }
2056
2055
  });
2057
- //#endregion
2058
- //#region src/http/node-server.ts
2056
+ // src/http/node-server.ts
2059
2057
  /**
2060
2058
  * This document is one connection as the `http.Server` of Node v24.21.0 holds it, over the Linux
2061
2059
  * TCP socket of the connection. Each fact comes from the source at the tag `v24.21.0`. The comments
@@ -2387,8 +2385,7 @@ const NODE_HTTP_SERVER = machineSchema.parse({
2387
2385
  note: "http.Server passes keepAlive to net.Server, and its default is off (lib/_http_server.js:646-651, lib/net.js:2753-2756). Thus an accepted socket has no SO_KEEPALIVE, and a reader gives the keepalive of the kernel no bound."
2388
2386
  }
2389
2387
  });
2390
- //#endregion
2391
- //#region src/http/undici.ts
2388
+ // src/http/undici.ts
2392
2389
  /**
2393
2390
  * This document is the socket of an HTTP/1.1 `Client` of undici 8.12.2, over its Linux TCP socket.
2394
2391
  * Each fact comes from the published package at 8.12.2, with the file and the line.
@@ -2712,8 +2709,7 @@ const UNDICI_CLIENT = machineSchema.parse({
2712
2709
  note: "The connector turns keepalive on with a delay of 60 s, and Node and libuv add 1 s and 10 probes (src/tcp_wrap.cc:215-216). Thus the keepalive sysctls of the namespace do not reach it."
2713
2710
  }
2714
2711
  });
2715
- //#endregion
2716
- //#region src/http/undici-retry.ts
2712
+ // src/http/undici-retry.ts
2717
2713
  const AT$16 = "undici 8.12.2 lib/handler/retry-handler.js";
2718
2714
  /**
2719
2715
  * This document is one request through a `RetryAgent` of undici 8.12.2: the retries of a reply
@@ -2928,8 +2924,7 @@ const UNDICI_RETRY = machineSchema.parse({
2928
2924
  }
2929
2925
  ]
2930
2926
  });
2931
- //#endregion
2932
- //#region src/ioredis-sentinel.ts
2927
+ // src/ioredis-sentinel.ts
2933
2928
  const AT$15 = "ioredis 6.0.0 built";
2934
2929
  /**
2935
2930
  * This document is the Sentinel path of ioredis 6.0.0. It tells how ioredis finds the primary of a
@@ -3286,8 +3281,7 @@ const IOREDIS_SENTINEL = machineSchema.parse({
3286
3281
  note: "the socket of the primary is a Linux TCP socket with keepalive at keepAlive. A write in flight to a black hole waits for the retransmissions of the kernel"
3287
3282
  }
3288
3283
  });
3289
- //#endregion
3290
- //#region src/ioredis-status.json
3284
+ // src/ioredis-status.json
3291
3285
  var ioredis_status_default = {
3292
3286
  format: "mark1russell7.machine/1",
3293
3287
  id: "ioredis-status",
@@ -3550,8 +3544,7 @@ var ioredis_status_default = {
3550
3544
  "note": "ioredis's socket is a Linux TCP socket. Once it connects, ioredis calls setKeepAlive(true, keepAlive), and Node gives libuv the delay in whole seconds with its own interval and count, so the namespace's keepalive sysctls never reach it. A delay under a second is 0 s, which libuv refuses with EINVAL. When the socket ends, ioredis hears stream.close."
3551
3545
  }
3552
3546
  };
3553
- //#endregion
3554
- //#region src/linux-tcp.json
3547
+ // src/linux-tcp.json
3555
3548
  var linux_tcp_default = {
3556
3549
  format: "mark1russell7.machine/1",
3557
3550
  id: "linux-tcp",
@@ -4292,14 +4285,12 @@ var linux_tcp_default = {
4292
4285
  }
4293
4286
  }
4294
4287
  };
4295
- //#endregion
4296
- //#region src/manifestations.json
4288
+ // src/manifestations.json
4297
4289
  var manifestations_default = {
4298
4290
  blackhole: [],
4299
4291
  "freeze-process": ["rx.ack"]
4300
4292
  };
4301
- //#endregion
4302
- //#region src/nf-conntrack-tcp.json
4293
+ // src/nf-conntrack-tcp.json
4303
4294
  var nf_conntrack_tcp_default = {
4304
4295
  format: "mark1russell7.machine/1",
4305
4296
  id: "nf-conntrack-tcp",
@@ -4923,8 +4914,7 @@ var nf_conntrack_tcp_default = {
4923
4914
  "note": "events are cached per packet and delivered at confirm: a change caused by a packet dropped before POSTROUTING is never reported (observed: a1, a2); netlink overruns drop events (ENOBUFS); DESTROY lags expiry by the GC"
4924
4915
  } }
4925
4916
  };
4926
- //#endregion
4927
- //#region src/redis-client.json
4917
+ // src/redis-client.json
4928
4918
  var redis_client_default = {
4929
4919
  format: "mark1russell7.machine/1",
4930
4920
  id: "redis-client",
@@ -5172,8 +5162,7 @@ var redis_client_default = {
5172
5162
  "note": "Redis holds each client on a Linux TCP socket, and anetKeepAlive sets its keepalive from tcp-keepalive alone: the idle time, a third of it in whole seconds and at least 1, and 3 probes. So its detection of a dead client is the kernel's keepalive, or its retransmissions when a reply is unacknowledged, and either reaches Redis as a read error."
5173
5163
  }
5174
5164
  };
5175
- //#endregion
5176
- //#region src/json.ts
5165
+ // src/json.ts
5177
5166
  /** This document is TCP as Linux 6.6 implements it: one full socket, from the source of the kernel and the RFCs. */
5178
5167
  const LINUX_TCP = machineSchema.parse(linux_tcp_default);
5179
5168
  /** This document is the TCP state machine of conntrack on Linux 6.6.87.2: the state of a router or a NAT for one flow. */
@@ -5188,8 +5177,7 @@ const IOREDIS_STATUS = machineSchema.parse(ioredis_status_default);
5188
5177
  * process continues to send ACKs, thus `rx.ack` arrives.
5189
5178
  */
5190
5179
  const MANIFESTATIONS = z.record(z.string(), z.array(z.string())).parse(manifestations_default);
5191
- //#endregion
5192
- //#region src/k8s/kubelet-readiness.ts
5180
+ // src/k8s/kubelet-readiness.ts
5193
5181
  const AT$14 = "kubernetes v1.37.0";
5194
5182
  const WORKER = `${AT$14} pkg/kubelet/prober/worker.go`;
5195
5183
  /**
@@ -5341,8 +5329,7 @@ const KUBELET_READINESS = machineSchema.parse({
5341
5329
  source: "worker.go:366-379"
5342
5330
  }]
5343
5331
  });
5344
- //#endregion
5345
- //#region src/kafka/group.ts
5332
+ // src/kafka/group.ts
5346
5333
  const GROUP = "kafka 4.3.2 group-coordinator/src/main/java/org/apache/kafka/coordinator/group";
5347
5334
  const INTERNALS = "kafka 4.3.2 clients/src/main/java/org/apache/kafka/clients/consumer/internals";
5348
5335
  /**
@@ -5634,8 +5621,7 @@ const KAFKA_CONSUMER_GROUP = machineSchema.parse({
5634
5621
  }
5635
5622
  ]
5636
5623
  });
5637
- //#endregion
5638
- //#region src/kafka/partition.ts
5624
+ // src/kafka/partition.ts
5639
5625
  const CORE = "kafka 4.3.2 core/src/main/scala/kafka";
5640
5626
  const SERVER = "kafka 4.3.2 server/src/main/java/org/apache/kafka/server";
5641
5627
  const STORAGE = "kafka 4.3.2 storage/src/main/java/org/apache/kafka/storage/internals/log";
@@ -6055,8 +6041,7 @@ const KAFKA_PARTITION = machineSchema.parse({
6055
6041
  }
6056
6042
  ]
6057
6043
  });
6058
- //#endregion
6059
- //#region src/mongo/mongod-replication.ts
6044
+ // src/mongo/mongod-replication.ts
6060
6045
  const AT$13 = "mongodb r9.0.4 src/mongo/db/repl";
6061
6046
  /**
6062
6047
  * This document is the replication of mongod 9.0.4. It gives one member of a replica set, its view
@@ -6813,8 +6798,7 @@ const MONGOD_REPL = machineSchema.parse({
6813
6798
  }
6814
6799
  } }
6815
6800
  });
6816
- //#endregion
6817
- //#region src/mongo/mongod-session.ts
6801
+ // src/mongo/mongod-session.ts
6818
6802
  const AT$12 = "mongodb r9.0.4 src/mongo";
6819
6803
  /**
6820
6804
  * This document is the hold of mongod 9.0.4 on one client connection, over its socket. `mongod`
@@ -7022,8 +7006,7 @@ const MONGOD_SESSION = machineSchema.parse({
7022
7006
  note: "at the Linux defaults the window is 300 s + 9 × 1 s = 309 s, not 300 s + 9 × 75 s: the interval has a maximum too"
7023
7007
  }
7024
7008
  });
7025
- //#endregion
7026
- //#region src/mongo/mongodb-node.ts
7009
+ // src/mongo/mongodb-node.ts
7027
7010
  const AT$11 = "mongodb 7.7.0 src";
7028
7011
  /**
7029
7012
  * This document is the MongoDB Node driver 7.7.0, for one server of a replica set. It gives one
@@ -7662,8 +7645,7 @@ const MONGODB_NODE = machineSchema.parse({
7662
7645
  note: "each socket of the driver is a Linux TCP socket. makeSocket calls setKeepAlive(true, keepAliveInitialDelay), and Node gives libuv the delay in whole seconds with its own interval and count. Thus the keepalive sysctls of the namespace never reach these sockets"
7663
7646
  }
7664
7647
  });
7665
- //#endregion
7666
- //#region src/pg/hikaricp-pgjdbc.ts
7648
+ // src/pg/hikaricp-pgjdbc.ts
7667
7649
  const HK = "HikariCP-7.1.0 src/main/java/com/zaxxer/hikari";
7668
7650
  const PG = "pgjdbc REL42.7.13 pgjdbc/src/main/java/org/postgresql";
7669
7651
  /**
@@ -8797,8 +8779,7 @@ const HIKARICP_PGJDBC = machineSchema.parse({
8797
8779
  note: "Each socket of pgjdbc is a Linux TCP socket with TCP_NODELAY. At the defaults no socket has keepalive, thus keepidle has no bound. With tcpKeepAlive on, pgjdbc sets SO_KEEPALIVE only, thus the interval and the count of the namespace apply"
8798
8780
  }
8799
8781
  });
8800
- //#endregion
8801
- //#region src/pg/node-postgres.ts
8782
+ // src/pg/node-postgres.ts
8802
8783
  const AT$10 = "pg 8.23.1 lib";
8803
8784
  const POOL = "pg-pool 3.14.0";
8804
8785
  /**
@@ -9613,8 +9594,7 @@ const NODE_POSTGRES = machineSchema.parse({
9613
9594
  note: "Each socket of pg is a Linux TCP socket with TCP_NODELAY. At the defaults pg turns keepalive on for no socket, thus keepidle has no bound. With keepAlive on and a delay of 1 s or more, Node gives libuv the delay in whole seconds, with 1 s and 10 probes. With a delay below 1 s, libuv sets SO_KEEPALIVE and no other option, thus the three keepalive sysctls of the namespace apply"
9614
9595
  }
9615
9596
  });
9616
- //#endregion
9617
- //#region src/pg/pgbouncer.ts
9597
+ // src/pg/pgbouncer.ts
9618
9598
  const PB = "pgbouncer_1_26_1";
9619
9599
  /** These are the sources of both documents: the defaults, the janitor and its clock. */
9620
9600
  const PB_COMMON = [
@@ -10271,8 +10251,7 @@ const PGBOUNCER_CLIENT = machineSchema.parse({
10271
10251
  note: "Each socket has TCP_NODELAY and SO_KEEPALIVE. At the defaults PgBouncer sets no time of the keepalive, thus the keepidle, the interval and the count of the namespace apply. A waiting client is not read: the kernel takes its FIN, and PgBouncer does not see it"
10272
10252
  }
10273
10253
  });
10274
- //#endregion
10275
- //#region src/pg/pgbouncer-server.ts
10254
+ // src/pg/pgbouncer-server.ts
10276
10255
  /**
10277
10256
  * This document is PgBouncer 1.26.1 in transaction pooling, for one server connection of a pool:
10278
10257
  * from its launch to its close. It also gives the wait of the pool before its next connection after
@@ -10896,8 +10875,7 @@ const PGBOUNCER_SERVER = machineSchema.parse({
10896
10875
  note: "As for the client: TCP_NODELAY and SO_KEEPALIVE, with the times of the keepalive of the namespace at the defaults. PgBouncer reads each server socket, thus the kernel's end of a socket reaches it at once"
10897
10876
  }
10898
10877
  });
10899
- //#endregion
10900
- //#region src/pg/pgpool.ts
10878
+ // src/pg/pgpool.ts
10901
10879
  const PP = "V4_7_3";
10902
10880
  /**
10903
10881
  * This document is Pgpool-II 4.7.3 with one backend, for one session of a client. It gives the states
@@ -11322,8 +11300,7 @@ const PGPOOL_SESSION = machineSchema.parse({
11322
11300
  note: "The socket of the client. It has TCP_NODELAY and no SO_KEEPALIVE. In a wait the child does not read it: the kernel takes its FIN, and Pgpool-II finds it at the next write"
11323
11301
  }
11324
11302
  });
11325
- //#endregion
11326
- //#region src/pg/postgres-session.ts
11303
+ // src/pg/postgres-session.ts
11327
11304
  const AT$9 = "postgresql REL_17_11 src";
11328
11305
  const DOC = "postgresql REL_17_11 doc/src/sgml";
11329
11306
  /**
@@ -12133,8 +12110,7 @@ const POSTGRES_SESSION = machineSchema.parse({
12133
12110
  note: "These sets hold at the GUC defaults: the backend turns on SO_KEEPALIVE and keeps each keepalive option of the namespace. A keepalive GUC above 0 replaces its sysctl here. In SENDING no timer of PostgreSQL acts. Thus the timers of the machine below end a send to a lost client, or SIGTERM does"
12134
12111
  }
12135
12112
  });
12136
- //#endregion
12137
- //#region src/pg/supavisor-client.ts
12113
+ // src/pg/supavisor-client.ts
12138
12114
  const SV = "v2.9.13";
12139
12115
  /**
12140
12116
  * This document is Supavisor 2.9.13 in transaction mode, for one client connection. It gives the
@@ -12557,8 +12533,7 @@ const SUPAVISOR_CLIENT = machineSchema.parse({
12557
12533
  note: "The socket of the client. ranch sets SO_KEEPALIVE and no other keepalive option, thus the three keepalive sysctls of the namespace apply. It also sets a send timeout of 30 s that closes the socket. That close has no timer here: the kernel sends the FIN only after the data before it, an assumption of this document"
12558
12534
  }
12559
12535
  });
12560
- //#endregion
12561
- //#region src/pg/supavisor-server.ts
12536
+ // src/pg/supavisor-server.ts
12562
12537
  /**
12563
12538
  * This document is Supavisor 2.9.13 in transaction mode, for one server connection of the pool of a
12564
12539
  * tenant. It is one DbHandler, a gen_statem, from its start by the pool to its end.
@@ -12915,8 +12890,7 @@ const SUPAVISOR_SERVER = machineSchema.parse({
12915
12890
  note: "The server socket, with TCP_NODELAY and no SO_KEEPALIVE. The DbHandler reads it in each state, thus the end of the socket reaches it at once"
12916
12891
  }
12917
12892
  });
12918
- //#endregion
12919
- //#region src/procedures-ws.ts
12893
+ // src/procedures-ws.ts
12920
12894
  /**
12921
12895
  * This module holds the machine documents of the WebSocket transport of `@procedures/client` at
12922
12896
  * commit 2408cea of the client repository: 0.22.0 and two PATCHes after it. The WS and WST cells
@@ -12936,17 +12910,8 @@ const CT = `${AT$8}/client/transport.ts`;
12936
12910
  const ST$1 = `${AT$8}/server/transport.ts`;
12937
12911
  /** This text is the source of the version of the service that the lock of the client gives (pnpm-lock.yaml:443-454). */
12938
12912
  const SERVICE = "@mark1russell7/service 0.5.8 (systems 571e9e5) packages/service/src";
12939
- /** This function gives the arithmetic of a duration in ms. */
12940
- const arithmetic = (duration) => {
12941
- if (!("expr" in duration) || duration.unit !== "ms") throw new Error("not arithmetic in ms");
12942
- return duration.expr;
12943
- };
12944
12913
  /** This text is the backoff of try n + 1 of the reconnect, in ms: `fired` is n. It reads the arithmetic of `backoffDelay`. */
12945
- const RECONNECT_WAIT = "min(reconnect_initial_delay * pow(reconnect_backoff_multiplier, fired), reconnect_max_delay)";
12946
- /** This text is the late bound of one Node timer, in ms, for a time in ms. */
12947
- const late = (ms) => arithmetic(nodeTimerLateness(ms));
12948
- /** This text is the early bound of one Node timer, in ms. */
12949
- const EARLY = arithmetic(NODE_TIMER_EARLY);
12914
+ const RECONNECT_WAIT$1 = "min(reconnect_initial_delay * pow(reconnect_backoff_multiplier, fired), reconnect_max_delay)";
12950
12915
  /**
12951
12916
  * This document is the connection of the WebSocket client of `@procedures/client` 0.22.0 at
12952
12917
  * commit 2408cea (`WebSocketTransport`), over its socket class and its Linux TCP socket. The
@@ -13174,11 +13139,11 @@ const PROCEDURES_WS_CLIENT = machineSchema.parse({
13174
13139
  unit: "ms"
13175
13140
  },
13176
13141
  lateness: {
13177
- expr: `(heartbeat_misses - 1) * (${late("heartbeat_interval")}) + ${late("heartbeat_timeout")}`,
13142
+ expr: `(heartbeat_misses - 1) * (${nodeLateMs("heartbeat_interval")}) + ${nodeLateMs("heartbeat_timeout")}`,
13178
13143
  unit: "ms"
13179
13144
  },
13180
13145
  early: {
13181
- expr: `heartbeat_misses * (${EARLY})`,
13146
+ expr: `heartbeat_misses * (${NODE_EARLY_MS})`,
13182
13147
  unit: "ms"
13183
13148
  },
13184
13149
  arms: ["enter:AWAITING_PONG"],
@@ -13192,12 +13157,12 @@ const PROCEDURES_WS_CLIENT = machineSchema.parse({
13192
13157
  },
13193
13158
  reconnect: {
13194
13159
  duration: {
13195
- expr: RECONNECT_WAIT,
13160
+ expr: RECONNECT_WAIT$1,
13196
13161
  unit: "ms"
13197
13162
  },
13198
- lateness: nodeTimerLateness(RECONNECT_WAIT),
13163
+ lateness: nodeTimerLateness(RECONNECT_WAIT$1),
13199
13164
  early: {
13200
- expr: `reconnect_jitter * ${RECONNECT_WAIT} + ${EARLY}`,
13165
+ expr: `reconnect_jitter * ${RECONNECT_WAIT$1} + ${NODE_EARLY_MS}`,
13201
13166
  unit: "ms"
13202
13167
  },
13203
13168
  arms: ["enter:RECONNECTING"],
@@ -13501,11 +13466,11 @@ const PROCEDURES_WS_SERVER = machineSchema.parse({
13501
13466
  unit: "ms"
13502
13467
  },
13503
13468
  lateness: {
13504
- expr: `heartbeat_misses * (${late("heartbeat_interval")})`,
13469
+ expr: `heartbeat_misses * (${nodeLateMs("heartbeat_interval")})`,
13505
13470
  unit: "ms"
13506
13471
  },
13507
13472
  early: {
13508
- expr: `heartbeat_misses * (${EARLY})`,
13473
+ expr: `heartbeat_misses * (${NODE_EARLY_MS})`,
13509
13474
  unit: "ms"
13510
13475
  },
13511
13476
  arms: ["enter:MISSING"],
@@ -13575,8 +13540,7 @@ const PROCEDURES_WS_SERVER = machineSchema.parse({
13575
13540
  ends: "socket.error"
13576
13541
  }
13577
13542
  });
13578
- //#endregion
13579
- //#region src/proxy/caddy.ts
13543
+ // src/proxy/caddy.ts
13580
13544
  const AT$7 = "caddy v2.11.7";
13581
13545
  const XNET = "x/net v0.59.0";
13582
13546
  /**
@@ -13936,8 +13900,7 @@ const CADDY_HTTP2 = machineSchema.parse({
13936
13900
  note: "The socket toward the client: a Linux TCP socket with the keepalive of Go. The socket toward the upstream has 15 s, 30 s and 9 probes"
13937
13901
  }
13938
13902
  });
13939
- //#endregion
13940
- //#region src/proxy/envoy.ts
13903
+ // src/proxy/envoy.ts
13941
13904
  const AT$6 = "envoy v1.39.4";
13942
13905
  /**
13943
13906
  * This document is Envoy 1.39.4 as an HTTP/2 proxy of gRPC, for one connection of a client. Its static
@@ -14382,11 +14345,10 @@ const ENVOY_HTTP2 = machineSchema.parse({
14382
14345
  note: "The socket toward the client: a Linux TCP socket with TCP_NODELAY and no keepalive. The socket toward the cluster is the same"
14383
14346
  }
14384
14347
  });
14385
- //#endregion
14386
- //#region src/proxy/haproxy.ts
14348
+ // src/proxy/haproxy.ts
14387
14349
  const AT$5 = "haproxy-3.2 v3.2.25";
14388
14350
  const ST = "src/stream.c";
14389
- const SC = "src/stconn.c";
14351
+ const SC$1 = "src/stconn.c";
14390
14352
  /**
14391
14353
  * This document is one connection of HAProxy 3.2.25 in TCP mode, with the configuration of T02:
14392
14354
  * `mode tcp`, `timeout client`, `timeout server`, `option clitcpka` and `option srvtcpka`. It sets
@@ -14423,7 +14385,7 @@ const HAPROXY_TCP = machineSchema.parse({
14423
14385
  rung: "implemented"
14424
14386
  },
14425
14387
  {
14426
- ref: `${AT$5} ${SC}:394-398 the attach of the stream starts the timer of the client, and ${ST}:980 the connect starts the timer of the server`,
14388
+ ref: `${AT$5} ${SC$1}:394-398 the attach of the stream starts the timer of the client, and ${ST}:980 the connect starts the timer of the server`,
14427
14389
  rung: "implemented"
14428
14390
  },
14429
14391
  {
@@ -14431,11 +14393,11 @@ const HAPROXY_TCP = machineSchema.parse({
14431
14393
  rung: "implemented"
14432
14394
  },
14433
14395
  {
14434
- ref: `${AT$5} include/haproxy/stconn.h:194-198 an activity is now_ms, and ${SC}:1538-1544 a read of bytes reports one`,
14396
+ ref: `${AT$5} include/haproxy/stconn.h:194-198 an activity is now_ms, and ${SC$1}:1538-1544 a read of bytes reports one`,
14435
14397
  rung: "implemented"
14436
14398
  },
14437
14399
  {
14438
- ref: `${AT$5} include/haproxy/stconn.h:206-223 and ${SC}:1801-1803, :1817 a send of bytes reports one, because no option independent-streams sets SC_FL_INDEP_STR (${ST}:485-489, src/proxy.c:2573-2575)`,
14400
+ ref: `${AT$5} include/haproxy/stconn.h:206-223 and ${SC$1}:1801-1803, :1817 a send of bytes reports one, because no option independent-streams sets SC_FL_INDEP_STR (${ST}:485-489, src/proxy.c:2573-2575)`,
14439
14401
  rung: "implemented"
14440
14402
  },
14441
14403
  {
@@ -14451,7 +14413,7 @@ const HAPROXY_TCP = machineSchema.parse({
14451
14413
  rung: "implemented"
14452
14414
  },
14453
14415
  {
14454
- ref: `${AT$5} ${SC}:750-772 an abort does no system call while the side is not shut, and ${SC}:782-837 a shut sends a FIN (:807-809), or closes the socket after an abort (:812)`,
14416
+ ref: `${AT$5} ${SC$1}:750-772 an abort does no system call while the side is not shut, and ${SC$1}:782-837 a shut sends a FIN (:807-809), or closes the socket after an abort (:812)`,
14455
14417
  rung: "implemented"
14456
14418
  },
14457
14419
  {
@@ -14716,8 +14678,7 @@ const HAPROXY_TCP = machineSchema.parse({
14716
14678
  note: "Each socket of HAProxy, toward the client and toward the server: a Linux TCP socket with SO_KEEPALIVE and the keepalive sysctls of its namespace"
14717
14679
  }
14718
14680
  });
14719
- //#endregion
14720
- //#region src/proxy/istio.ts
14681
+ // src/proxy/istio.ts
14721
14682
  const IS = "istio 1.31.3";
14722
14683
  const AT$4 = "envoy v1.39.4";
14723
14684
  /** These sources hold for both sides of a sidecar of Istio 1.31.3. */
@@ -15404,8 +15365,7 @@ const PILOT_AGENT = machineSchema.parse({
15404
15365
  }
15405
15366
  ]
15406
15367
  });
15407
- //#endregion
15408
- //#region src/proxy/nginx.ts
15368
+ // src/proxy/nginx.ts
15409
15369
  const AT$3 = "nginx release-1.29.6";
15410
15370
  const V2 = "src/http/v2/ngx_http_v2.c";
15411
15371
  const UP = "src/http/ngx_http_upstream.c";
@@ -15792,8 +15752,7 @@ const NGINX_GRPC = machineSchema.parse({
15792
15752
  note: "The socket toward the client: a Linux TCP socket with no keepalive (so_keepalive is off at the defaults). The lingering close sends a FIN with shutdown(SHUT_WR)"
15793
15753
  }
15794
15754
  });
15795
- //#endregion
15796
- //#region src/proxy/traefik.ts
15755
+ // src/proxy/traefik.ts
15797
15756
  const AT$2 = "traefik v3.7.15";
15798
15757
  const H2 = "go1.26.9 src/net/http/h2_bundle.go";
15799
15758
  /**
@@ -16146,8 +16105,7 @@ const TRAEFIK_HTTP2 = machineSchema.parse({
16146
16105
  note: "The socket toward the client: a Linux TCP socket. Its keepalive is the one of the listener of Go, which the source of this document does not name"
16147
16106
  }
16148
16107
  });
16149
- //#endregion
16150
- //#region src/proxy/tcp-proxies.ts
16108
+ // src/proxy/tcp-proxies.ts
16151
16109
  const TOXI = "toxiproxy v2.12.0";
16152
16110
  const MOBY = "moby docker-v29.1.5";
16153
16111
  /** These are the facts of Go that both proxies share: the TCP keepalive of a socket that the caller does not set. */
@@ -16512,8 +16470,7 @@ const DOCKER_PROXY_LINK = machineSchema.parse({
16512
16470
  ],
16513
16471
  over: overOf(["linked", "half-closed"])
16514
16472
  });
16515
- //#endregion
16516
- //#region src/proxy/ztunnel.ts
16473
+ // src/proxy/ztunnel.ts
16517
16474
  const Z = "ztunnel 1.31.3";
16518
16475
  const I = "istio 1.31.3";
16519
16476
  /**
@@ -17075,8 +17032,7 @@ const ZTUNNEL_HBONE = machineSchema.parse({
17075
17032
  note: "The HBONE socket in the network namespace of the client pod: a Linux TCP socket with the keepalive of ztunnel and no TCP_USER_TIMEOUT. A peer that is gone ends it at 180 + 9 × 180 = 1800 s, after the PING"
17076
17033
  }
17077
17034
  });
17078
- //#endregion
17079
- //#region src/rabbit/amqplib.ts
17035
+ // src/rabbit/amqplib.ts
17080
17036
  const AT$1 = "amqplib 2.2.0 lib";
17081
17037
  /**
17082
17038
  * This document is amqplib 2.2.0 on Node, for one connection to a broker of AMQP 0-9-1 and one channel
@@ -17526,8 +17482,7 @@ const AMQPLIB = machineSchema.parse({
17526
17482
  note: "The socket of the connection: a Linux TCP socket with Nagle on and no keepalive at the defaults. Thus the kernel ends a send with no ACK only at the give-up of its retransmissions"
17527
17483
  }
17528
17484
  });
17529
- //#endregion
17530
- //#region src/rabbit/aten.ts
17485
+ // src/rabbit/aten.ts
17531
17486
  const ATEN = "aten 0.6.0";
17532
17487
  /**
17533
17488
  * This document is aten 0.6.0, the failure detector between the nodes of RabbitMQ 4.3.6. It gives one
@@ -17744,8 +17699,7 @@ const ATEN_DETECTOR = machineSchema.parse({
17744
17699
  }
17745
17700
  ]
17746
17701
  });
17747
- //#endregion
17748
- //#region src/rabbit/ra-member.ts
17702
+ // src/rabbit/ra-member.ts
17749
17703
  const RA = "ra 3.1.10 src";
17750
17704
  const RMQ$1 = "rabbitmq v4.3.6 deps/rabbit/src";
17751
17705
  /**
@@ -18115,8 +18069,7 @@ const RA_MEMBER = machineSchema.parse({
18115
18069
  note: "at the default level the log has each change from or to leader (NOTICE), and the new leader that a follower detects (INFO). The elections are DEBUG"
18116
18070
  } }
18117
18071
  });
18118
- //#endregion
18119
- //#region src/rabbit/rabbitmq-connection.ts
18072
+ // src/rabbit/rabbitmq-connection.ts
18120
18073
  const RMQ = "v4.3.6";
18121
18074
  /**
18122
18075
  * This document is RabbitMQ 4.3.6, for one connection of AMQP 0-9-1 on the broker. It gives the reader of
@@ -18516,8 +18469,7 @@ const RABBITMQ_CONNECTION = machineSchema.parse({
18516
18469
  note: "The socket of the connection on the broker: TCP_NODELAY on, no keepalive, and SO_LINGER on with 0, thus each close of the broker is a reset"
18517
18470
  }
18518
18471
  });
18519
- //#endregion
18520
- //#region src/sentinel.ts
18472
+ // src/sentinel.ts
18521
18473
  const AT = "valkey 9.1.2 src/sentinel.c";
18522
18474
  /**
18523
18475
  * This document is the Sentinel of Valkey 9.1.2. It gives the view of one Sentinel on the primary
@@ -19099,8 +19051,545 @@ const SENTINEL = machineSchema.parse({
19099
19051
  }
19100
19052
  ]
19101
19053
  });
19102
- //#endregion
19103
- //#region src/index.ts
19054
+ // src/socketio.ts
19055
+ /**
19056
+ * This module holds the machine documents of Socket.IO 4.8.4 on Node, with the WebSocket transport
19057
+ * only. The client is socket.io-client 4.8.4 on engine.io-client 6.6.7. The server is socket.io
19058
+ * 4.8.4 on engine.io 6.6.11. Both use ws 8.21.3. The Socket.IO cells (SYS-87) operate
19059
+ * them from the lockfile of `packages/cells/targets/socketio`. Each fact comes from the published
19060
+ * tarball of each version, or from Node v24.21.0. The comments and the sources give the file and
19061
+ * the line. Node loads the build `build/esm-debug` of each client package (the condition `node` of
19062
+ * its exports), and the server packages are CommonJS (`build`).
19063
+ *
19064
+ * The protocol is engine.io 4. The server writes a ping each pingInterval, and the client answers
19065
+ * with a pong. Each side has its own timer. The server waits pingTimeout for the pong of its ping.
19066
+ * The client waits pingInterval + pingTimeout for the next ping. The handshake gives the client
19067
+ * both times, thus the client has no setting of its own for its heartbeat.
19068
+ */
19069
+ /** This text is the client package of the engine at its version. */
19070
+ const EC = "engine.io-client 6.6.7 build/esm-debug";
19071
+ /** This text is the client package of Socket.IO at its version. */
19072
+ const SC = "socket.io-client 4.8.4 build/esm-debug";
19073
+ /** This text is the server package of the engine at its version. */
19074
+ const ES = "engine.io 6.6.11 build";
19075
+ /** This text is the ws package at its version. */
19076
+ const WS = "ws 8.21.3 lib";
19077
+ /** This text is the wait of the client for the next ping, in ms: the sum that the handshake gives. */
19078
+ const PING_WAIT = "ping_interval + ping_timeout";
19079
+ /**
19080
+ * This text is the backoff of try n + 1 of the reconnect, in ms, before its jitter: `fired` is n.
19081
+ * The Backoff of socket.io-client has the factor 2.
19082
+ */
19083
+ const BACKOFF = "reconnection_delay * pow(2, fired)";
19084
+ /** This text is the wait of try n + 1 of the reconnect with no jitter, in ms. */
19085
+ const RECONNECT_WAIT = `min(${BACKOFF}, reconnection_delay_max)`;
19086
+ /**
19087
+ * This document is the connection of the Manager of socket.io-client 4.8.4 over engine.io-client
19088
+ * 6.6.7, with the Node WebSocket transport (the ws package), over its Linux TCP socket.
19089
+ *
19090
+ * - The client waits pingInterval + pingTimeout for each ping. The handshake arms the timer, and
19091
+ * each ping arms it again. No other packet and no write moves it. At its end the client closes
19092
+ * the connection with the reason "ping timeout".
19093
+ * - The close of the client is close() of ws: a close frame. The socket stays open below it until
19094
+ * the peer answers, or for the close timeout of ws (30 s).
19095
+ * - Each close starts the reconnect of the Manager, when it is on. The wait of try n + 1 is
19096
+ * min(reconnectionDelay × 2^n, reconnectionDelayMax), with a jitter of ± randomizationFactor of
19097
+ * the backoff before its cap. An open sets n to 0, and so does each close of an open connection.
19098
+ * - Each try has a time limit (`timeout` of the Manager).
19099
+ * - A call with an acknowledgement has its own time limit, and the connection stays.
19100
+ */
19101
+ const SOCKETIO_CLIENT = machineSchema.parse({
19102
+ format: "mark1russell7.machine/1",
19103
+ id: "socketio-client",
19104
+ title: "The connection of the Manager of socket.io-client 4.8.4 (engine.io-client 6.6.7, ws 8.21.3)",
19105
+ layer: "driver",
19106
+ version: "4.8.4",
19107
+ conditions: {
19108
+ "socket.io-client": "4.8.4",
19109
+ "engine.io-client": "6.6.7",
19110
+ ws: "8.21.3",
19111
+ node: "24.21.0",
19112
+ kernel: "Linux 6.6"
19113
+ },
19114
+ sources: [
19115
+ {
19116
+ ref: `${EC}/socket.js:401-414 onHandshake: pingInterval and pingTimeout come from the server (:406-407), and the timer starts (:413); :373-378 each ping writes a pong and starts the timer again (:377); :420-430 _resetPingTimeout: the delay is pingInterval + pingTimeout (:422), and at its end the reason "ping timeout" (:425)`,
19117
+ rung: "implemented"
19118
+ },
19119
+ {
19120
+ ref: `${EC}/socket.js:639-669 _onClose: transport.close() (:649); ${EC}/transport.js:55-61 close() of an open transport calls doClose(); ${EC}/transports/websocket.js:81-87 doClose calls close() of its WebSocket`,
19121
+ rung: "implemented"
19122
+ },
19123
+ {
19124
+ ref: `${WS}/websocket.js:302-340 close(): a handshake is aborted (:304-307); an open socket writes a close frame, then setCloseTimer (:1309-1314) destroys it after CLOSE_TIMEOUT, 30000 ms (lib/constants.js:10)`,
19125
+ rung: "implemented"
19126
+ },
19127
+ {
19128
+ ref: `${SC}/manager.js:23-33 the options: reconnectionAttempts || Infinity (:24), reconnectionDelay || 1000 (:25), reconnectionDelayMax || 5000 (:26), randomizationFactor ?? 0.5 (:27), timeout 20000 (:33)`,
19129
+ rung: "implemented"
19130
+ },
19131
+ {
19132
+ ref: `${SC}/manager.js:315-326 onclose: the backoff goes back to 0 (:320), then reconnect() (:324); :332-374 reconnect: backoff.duration() (:343), a timer, then open() (:354), and a failed try starts the next wait (:357-358); :380-385 an open sets the backoff to 0`,
19133
+ rung: "implemented"
19134
+ },
19135
+ {
19136
+ ref: `${SC}/contrib/backo2.js:26-34 duration: min × factor^attempts (:27), factor 2 (:16), the jitter adds or subtracts floor(rand × jitter × ms) (:28-32), then min(ms, max) | 0 (:33)`,
19137
+ rung: "implemented"
19138
+ },
19139
+ {
19140
+ ref: `${SC}/manager.js:140-156 the time limit of each try: an error "timeout", and close() of the engine`,
19141
+ rung: "implemented"
19142
+ },
19143
+ {
19144
+ ref: `${EC}/transports/websocket.node.js: createSocket gives new WebSocket of ws with the URL and the options of the engine. ws sets no keepalive on its socket, and the engine gives it none`,
19145
+ rung: "implemented"
19146
+ }
19147
+ ],
19148
+ states: {
19149
+ DISCONNECTED: {
19150
+ initial: true,
19151
+ note: "no socket"
19152
+ },
19153
+ CONNECTING: { note: "a try, with its time limit" },
19154
+ CONNECTED: { note: "the handshake ended: the ping timer runs" },
19155
+ RECONNECTING: { note: "the wait before the next try" }
19156
+ },
19157
+ events: {
19158
+ connect: {
19159
+ kind: "app",
19160
+ note: "the Manager opens"
19161
+ },
19162
+ open: {
19163
+ kind: "rx",
19164
+ note: "the handshake of the engine: the backoff goes back to 0"
19165
+ },
19166
+ "connect-timeout": { kind: "timer" },
19167
+ "rx.ping": {
19168
+ kind: "rx",
19169
+ note: "a ping of the server: the client writes a pong"
19170
+ },
19171
+ "ping-timeout": { kind: "timer" },
19172
+ drop: {
19173
+ kind: "local",
19174
+ note: "the close event of the socket: a FIN, a reset, a give-up of the kernel, or a failed try"
19175
+ },
19176
+ "reconnect-due": { kind: "timer" },
19177
+ "give-up": {
19178
+ kind: "local",
19179
+ note: "a close without reconnect, or without tries left"
19180
+ },
19181
+ "tx.request": {
19182
+ kind: "tx",
19183
+ note: "an event with an acknowledgement"
19184
+ },
19185
+ "rx.reply": {
19186
+ kind: "rx",
19187
+ note: "the acknowledgement"
19188
+ },
19189
+ "request-timeout": { kind: "timer" },
19190
+ close: {
19191
+ kind: "app",
19192
+ note: "close() of the application"
19193
+ }
19194
+ },
19195
+ knobs: {
19196
+ ping_interval: {
19197
+ key: "pingInterval (from the handshake)",
19198
+ scope: "server",
19199
+ unit: "ms",
19200
+ default: 25e3
19201
+ },
19202
+ ping_timeout: {
19203
+ key: "pingTimeout (from the handshake)",
19204
+ scope: "server",
19205
+ unit: "ms",
19206
+ default: 2e4
19207
+ },
19208
+ reconnection_delay: {
19209
+ key: "reconnectionDelay",
19210
+ scope: "client",
19211
+ unit: "ms",
19212
+ default: 1e3
19213
+ },
19214
+ reconnection_delay_max: {
19215
+ key: "reconnectionDelayMax",
19216
+ scope: "client",
19217
+ unit: "ms",
19218
+ default: 5e3
19219
+ },
19220
+ reconnection_attempts: {
19221
+ key: "reconnectionAttempts",
19222
+ scope: "client",
19223
+ unit: "count",
19224
+ default: null,
19225
+ note: "Infinity at the default"
19226
+ },
19227
+ randomization_factor: {
19228
+ key: "randomizationFactor",
19229
+ scope: "client",
19230
+ unit: "count",
19231
+ default: .5,
19232
+ note: "the random part of each wait, from 0 to 1: the backoff, plus or minus floor(r × factor × backoff)"
19233
+ },
19234
+ connect_timeout: {
19235
+ key: "timeout",
19236
+ scope: "client",
19237
+ unit: "ms",
19238
+ default: 2e4,
19239
+ note: "the time limit of each try"
19240
+ },
19241
+ request_timeout: {
19242
+ key: "socket.timeout()",
19243
+ scope: "client",
19244
+ unit: "ms",
19245
+ default: null,
19246
+ note: "no time limit at the default"
19247
+ },
19248
+ hz: {
19249
+ key: "CONFIG_HZ",
19250
+ scope: "global",
19251
+ unit: "Hz",
19252
+ default: null,
19253
+ note: "the HZ of the kernel, for the step of the coarse loop clock of libuv (http/timers.ts)"
19254
+ }
19255
+ },
19256
+ timers: {
19257
+ ping: {
19258
+ duration: {
19259
+ expr: PING_WAIT,
19260
+ unit: "ms"
19261
+ },
19262
+ lateness: nodeTimerLateness(PING_WAIT),
19263
+ early: NODE_TIMER_EARLY,
19264
+ arms: ["enter:CONNECTED", "rx.ping"],
19265
+ cancels: ["drop", "close"],
19266
+ fires: "ping-timeout",
19267
+ note: "from the last ping that reached the client, or from the handshake. Data of the connection does not move it"
19268
+ },
19269
+ reconnect: {
19270
+ duration: {
19271
+ expr: RECONNECT_WAIT,
19272
+ unit: "ms"
19273
+ },
19274
+ lateness: {
19275
+ expr: `randomization_factor * ${BACKOFF} + ${nodeLateMs(RECONNECT_WAIT)}`,
19276
+ unit: "ms"
19277
+ },
19278
+ early: {
19279
+ expr: `randomization_factor * ${BACKOFF} + ${NODE_EARLY_MS}`,
19280
+ unit: "ms"
19281
+ },
19282
+ arms: ["enter:RECONNECTING"],
19283
+ cancels: ["close"],
19284
+ fires: "reconnect-due",
19285
+ backoff: { resets: ["open", "drop"] },
19286
+ note: "the jitter adds or subtracts at most randomizationFactor × the backoff before its cap: both bounds"
19287
+ },
19288
+ connect: {
19289
+ duration: {
19290
+ knob: "connect_timeout",
19291
+ unit: "ms"
19292
+ },
19293
+ lateness: nodeTimerLateness("connect_timeout"),
19294
+ early: NODE_TIMER_EARLY,
19295
+ arms: ["enter:CONNECTING"],
19296
+ cancels: [
19297
+ "open",
19298
+ "drop",
19299
+ "close"
19300
+ ],
19301
+ fires: "connect-timeout"
19302
+ },
19303
+ request: {
19304
+ duration: {
19305
+ knob: "request_timeout",
19306
+ unit: "ms"
19307
+ },
19308
+ lateness: nodeTimerLateness("request_timeout"),
19309
+ early: NODE_TIMER_EARLY,
19310
+ arms: ["tx.request"],
19311
+ cancels: ["rx.reply", "close"],
19312
+ fires: "request-timeout",
19313
+ note: "one timer for each call: it fails the call, and the connection stays"
19314
+ }
19315
+ },
19316
+ transitions: [
19317
+ {
19318
+ id: "sc.connect",
19319
+ from: "DISCONNECTED",
19320
+ on: "connect",
19321
+ to: "CONNECTING"
19322
+ },
19323
+ {
19324
+ id: "sc.open",
19325
+ from: "CONNECTING",
19326
+ on: "open",
19327
+ to: "CONNECTED",
19328
+ source: `${EC}/socket.js:401-414`
19329
+ },
19330
+ {
19331
+ id: "sc.connect-timeout",
19332
+ from: "CONNECTING",
19333
+ on: "connect-timeout",
19334
+ to: "RECONNECTING",
19335
+ timer: "connect",
19336
+ source: `${SC}/manager.js:144-149`
19337
+ },
19338
+ {
19339
+ id: "sc.ping",
19340
+ from: "CONNECTED",
19341
+ on: "rx.ping",
19342
+ to: "CONNECTED",
19343
+ emits: ["tx.pong"],
19344
+ source: `${EC}/socket.js:373-378`
19345
+ },
19346
+ {
19347
+ id: "sc.ping-timeout",
19348
+ from: "CONNECTED",
19349
+ on: "ping-timeout",
19350
+ to: "RECONNECTING",
19351
+ timer: "ping",
19352
+ emits: ["tx.close-frame"],
19353
+ note: "close() of ws writes a close frame, and the socket stays open below it",
19354
+ source: `${EC}/socket.js:424-426, :649`
19355
+ },
19356
+ {
19357
+ id: "sc.drop",
19358
+ from: ["CONNECTING", "CONNECTED"],
19359
+ on: "drop",
19360
+ to: "RECONNECTING",
19361
+ guard: "the reconnect is on, and tries are left",
19362
+ source: `${SC}/manager.js:315-326, :354-359`
19363
+ },
19364
+ {
19365
+ id: "sc.give-up",
19366
+ from: ["CONNECTING", "CONNECTED"],
19367
+ on: "give-up",
19368
+ to: "DISCONNECTED",
19369
+ source: `${SC}/manager.js:336-341`
19370
+ },
19371
+ {
19372
+ id: "sc.reconnect",
19373
+ from: "RECONNECTING",
19374
+ on: "reconnect-due",
19375
+ to: "CONNECTING",
19376
+ timer: "reconnect",
19377
+ source: `${SC}/manager.js:346-366`
19378
+ },
19379
+ {
19380
+ id: "sc.request-timeout",
19381
+ from: "CONNECTED",
19382
+ on: "request-timeout",
19383
+ to: "CONNECTED",
19384
+ timer: "request",
19385
+ errno: "TIMEOUT"
19386
+ },
19387
+ {
19388
+ id: "sc.close",
19389
+ from: [
19390
+ "CONNECTING",
19391
+ "CONNECTED",
19392
+ "RECONNECTING"
19393
+ ],
19394
+ on: "close",
19395
+ to: "DISCONNECTED"
19396
+ }
19397
+ ],
19398
+ over: {
19399
+ machine: "systems.machine.linux-tcp",
19400
+ states: {
19401
+ CONNECTING: "SYN_SENT",
19402
+ CONNECTED: "ESTABLISHED"
19403
+ },
19404
+ sets: {},
19405
+ ends: "drop",
19406
+ note: "ws turns no keepalive on, thus the keepalive sysctls of the namespace do not reach the socket"
19407
+ }
19408
+ });
19409
+ /**
19410
+ * This document is one connection as the Server of socket.io 4.8.4 on engine.io 6.6.11 holds it.
19411
+ * The transport is WebSocket (ws 8.21.3), over its Linux TCP socket.
19412
+ *
19413
+ * - pingInterval after the handshake, or after the last pong, the server writes a ping. Then it
19414
+ * waits pingTimeout for the pong, and at its end it closes the connection: close() of ws, a close
19415
+ * frame. Thus the drop comes pingTimeout after the first ping without an answer.
19416
+ * - In that wait, the first packet that is not a pong starts the wait again, once for each ping.
19417
+ * - The http.Server of Node sets no SO_KEEPALIVE when keepAlive is off, its default.
19418
+ */
19419
+ const SOCKETIO_SERVER = machineSchema.parse({
19420
+ format: "mark1russell7.machine/1",
19421
+ id: "socketio-server",
19422
+ title: "One connection as the Server of socket.io 4.8.4 (engine.io 6.6.11, ws 8.21.3) holds it",
19423
+ layer: "server",
19424
+ version: "4.8.4",
19425
+ conditions: {
19426
+ "socket.io": "4.8.4",
19427
+ "engine.io": "6.6.11",
19428
+ ws: "8.21.3",
19429
+ node: "24.21.0",
19430
+ kernel: "Linux 6.6"
19431
+ },
19432
+ sources: [
19433
+ {
19434
+ ref: `${ES}/server.js:48-49 the defaults: pingTimeout 20000 and pingInterval 25000`,
19435
+ rung: "implemented"
19436
+ },
19437
+ {
19438
+ ref: `${ES}/socket.js:88-95 the handshake schedules the first ping (protocol 4); :166-173 schedulePing: after pingInterval, sendPacket("ping"), then resetPingTimeout; :179-188 resetPingTimeout: onClose("ping timeout") after pingTimeout`,
19439
+ rung: "implemented"
19440
+ },
19441
+ {
19442
+ ref: `${ES}/socket.js:130-140 a pong clears the wait (:136-137) and starts the interval again (:138); :111-118 in the wait, the first packet that is not a pong starts the wait again, once`,
19443
+ rung: "implemented"
19444
+ },
19445
+ {
19446
+ ref: `${ES}/socket.js:336-352 onClose clears the timers and calls clearTransport (:315-327), which calls close() of the transport (:327); ${ES}/transports/websocket.js:90-94 doClose calls close() of its WebSocket: a close frame (${WS}/websocket.js:302-340)`,
19447
+ rung: "implemented"
19448
+ },
19449
+ {
19450
+ ref: `${ES}/socket.js:386-409 sendPacket emits packetCreate (:402) before the write of the packet: the line of each ping`,
19451
+ rung: "implemented"
19452
+ },
19453
+ {
19454
+ ref: "node v24.21.0 lib/_http_server.js:646-651 and lib/net.js:2753-2756: keepAlive of http.Server is off at the default, thus an accepted socket has no SO_KEEPALIVE",
19455
+ rung: "implemented"
19456
+ }
19457
+ ],
19458
+ states: {
19459
+ ABSENT: {
19460
+ initial: true,
19461
+ pseudo: true
19462
+ },
19463
+ OPEN: { note: "the interval to the next ping runs" },
19464
+ AWAITING_PONG: { note: "a ping went out: its wait runs" },
19465
+ CLOSED: { final: true }
19466
+ },
19467
+ events: {
19468
+ accept: {
19469
+ kind: "local",
19470
+ note: "the handshake of the engine"
19471
+ },
19472
+ "ping-due": { kind: "timer" },
19473
+ "rx.pong": { kind: "rx" },
19474
+ "rx.packet": {
19475
+ kind: "rx",
19476
+ note: "a packet that is not a pong"
19477
+ },
19478
+ "pong-timeout": { kind: "timer" },
19479
+ close: {
19480
+ kind: "peer",
19481
+ note: "the close event of the socket of ws"
19482
+ },
19483
+ "socket.error": {
19484
+ kind: "local",
19485
+ note: "the kernel beneath gave up on the socket, or a reset arrived"
19486
+ }
19487
+ },
19488
+ knobs: {
19489
+ ping_interval: {
19490
+ key: "pingInterval",
19491
+ scope: "server",
19492
+ unit: "ms",
19493
+ default: 25e3
19494
+ },
19495
+ ping_timeout: {
19496
+ key: "pingTimeout",
19497
+ scope: "server",
19498
+ unit: "ms",
19499
+ default: 2e4
19500
+ },
19501
+ hz: {
19502
+ key: "CONFIG_HZ",
19503
+ scope: "global",
19504
+ unit: "Hz",
19505
+ default: null
19506
+ }
19507
+ },
19508
+ timers: {
19509
+ ping: {
19510
+ duration: {
19511
+ knob: "ping_interval",
19512
+ unit: "ms"
19513
+ },
19514
+ lateness: nodeTimerLateness("ping_interval"),
19515
+ early: NODE_TIMER_EARLY,
19516
+ arms: ["enter:OPEN"],
19517
+ cancels: ["close"],
19518
+ fires: "ping-due",
19519
+ backoff: { resets: ["rx.pong"] },
19520
+ note: "a timer that starts again at each pong: each firing writes a ping, and the pong timer gives up on it"
19521
+ },
19522
+ pong: {
19523
+ duration: {
19524
+ knob: "ping_timeout",
19525
+ unit: "ms"
19526
+ },
19527
+ lateness: nodeTimerLateness("ping_timeout"),
19528
+ early: NODE_TIMER_EARLY,
19529
+ arms: ["enter:AWAITING_PONG"],
19530
+ cancels: ["rx.pong", "close"],
19531
+ fires: "pong-timeout",
19532
+ note: "from the write of the ping. The first packet that is not a pong in the wait starts it again, once (rx.packet)"
19533
+ }
19534
+ },
19535
+ transitions: [
19536
+ {
19537
+ id: "ss.accept",
19538
+ from: "ABSENT",
19539
+ on: "accept",
19540
+ to: "OPEN"
19541
+ },
19542
+ {
19543
+ id: "ss.ping",
19544
+ from: "OPEN",
19545
+ on: "ping-due",
19546
+ to: "AWAITING_PONG",
19547
+ timer: "ping",
19548
+ emits: ["tx.ping"],
19549
+ source: `${ES}/socket.js:166-173`
19550
+ },
19551
+ {
19552
+ id: "ss.pong",
19553
+ from: "AWAITING_PONG",
19554
+ on: "rx.pong",
19555
+ to: "OPEN",
19556
+ source: `${ES}/socket.js:130-140`
19557
+ },
19558
+ {
19559
+ id: "ss.refresh",
19560
+ from: "AWAITING_PONG",
19561
+ on: "rx.packet",
19562
+ to: "AWAITING_PONG",
19563
+ note: "the wait starts again once for each ping: a later packet does not move it",
19564
+ source: `${ES}/socket.js:111-118`
19565
+ },
19566
+ {
19567
+ id: "ss.pong-timeout",
19568
+ from: "AWAITING_PONG",
19569
+ on: "pong-timeout",
19570
+ to: "CLOSED",
19571
+ timer: "pong",
19572
+ emits: ["tx.close-frame"],
19573
+ source: `${ES}/socket.js:179-188, :336-352`
19574
+ },
19575
+ {
19576
+ id: "ss.close",
19577
+ from: ["OPEN", "AWAITING_PONG"],
19578
+ on: ["close", "socket.error"],
19579
+ to: "CLOSED"
19580
+ }
19581
+ ],
19582
+ over: {
19583
+ machine: "systems.machine.linux-tcp",
19584
+ states: {
19585
+ OPEN: "ESTABLISHED",
19586
+ AWAITING_PONG: "ESTABLISHED"
19587
+ },
19588
+ sets: {},
19589
+ ends: "socket.error"
19590
+ }
19591
+ });
19592
+ // src/index.ts
19104
19593
  /** This function gives each document by its identifier. Two documents with one identifier stop the import. */
19105
19594
  const byId = (documents) => {
19106
19595
  const out = {};
@@ -19128,6 +19617,8 @@ const MACHINES = byId([
19128
19617
  GO_TRANSPORT,
19129
19618
  PROCEDURES_WS_CLIENT,
19130
19619
  PROCEDURES_WS_SERVER,
19620
+ SOCKETIO_CLIENT,
19621
+ SOCKETIO_SERVER,
19131
19622
  MONGODB_NODE,
19132
19623
  MONGOD_REPL,
19133
19624
  MONGOD_SESSION,
@@ -19162,7 +19653,6 @@ const MACHINES = byId([
19162
19653
  DEADLINE_CALL,
19163
19654
  KUBELET_READINESS
19164
19655
  ]);
19165
- //#endregion
19166
- export { AMQPLIB, ATEN_DETECTOR, CADDY_HTTP2, DEADLINE_CALL, DOCKER_PROXY_LINK, ENVOY_HTTP2, ETCD_SERVER, GO_TRANSPORT, GRPC_GO_SERVER, GRPC_JS, HAPROXY_TCP, HIKARICP_PGJDBC, IOREDIS_SENTINEL, IOREDIS_STATUS, ISTIO_SIDECAR_INBOUND, ISTIO_SIDECAR_OUTBOUND, KAFKA_CONSUMER_GROUP, KAFKA_PARTITION, KUBELET_READINESS, LINUX_TCP, MACHINES, MANIFESTATIONS, MONGODB_NODE, MONGOD_REPL, MONGOD_SESSION, NF_CONNTRACK_TCP, NGINX_GRPC, NODE_HTTP_AGENT, NODE_HTTP_SERVER, NODE_POSTGRES, NODE_TIMER_EARLY, PGBOUNCER_CLIENT, PGBOUNCER_SERVER, PGPOOL_SESSION, PILOT_AGENT, POSTGRES_SESSION, PROCEDURES_WS_CLIENT, PROCEDURES_WS_SERVER, RABBITMQ_CONNECTION, RA_MEMBER, REDIS_CLIENT, SENTINEL, SUPAVISOR_CLIENT, SUPAVISOR_SERVER, TOXIPROXY_LINK, TRAEFIK_HTTP2, UNDICI_CLIENT, UNDICI_RETRY, UNDICI_TICK_MS, ZTUNNEL_HBONE, goLateSeconds, goTimerLateness, istioSidecar, nodeEarlySeconds, nodeLateSeconds, nodeTimerLateness, undiciFastEarly, undiciFastLateness };
19656
+ export { AMQPLIB, ATEN_DETECTOR, CADDY_HTTP2, DEADLINE_CALL, DOCKER_PROXY_LINK, ENVOY_HTTP2, ETCD_SERVER, GO_TRANSPORT, GRPC_GO_SERVER, GRPC_JS, HAPROXY_TCP, HIKARICP_PGJDBC, IOREDIS_SENTINEL, IOREDIS_STATUS, ISTIO_SIDECAR_INBOUND, ISTIO_SIDECAR_OUTBOUND, KAFKA_CONSUMER_GROUP, KAFKA_PARTITION, KUBELET_READINESS, LINUX_TCP, MACHINES, MANIFESTATIONS, MONGODB_NODE, MONGOD_REPL, MONGOD_SESSION, NF_CONNTRACK_TCP, NGINX_GRPC, NODE_HTTP_AGENT, NODE_HTTP_SERVER, NODE_POSTGRES, NODE_TIMER_EARLY, PGBOUNCER_CLIENT, PGBOUNCER_SERVER, PGPOOL_SESSION, PILOT_AGENT, POSTGRES_SESSION, PROCEDURES_WS_CLIENT, PROCEDURES_WS_SERVER, RABBITMQ_CONNECTION, RA_MEMBER, REDIS_CLIENT, SENTINEL, SOCKETIO_CLIENT, SOCKETIO_SERVER, SUPAVISOR_CLIENT, SUPAVISOR_SERVER, TOXIPROXY_LINK, TRAEFIK_HTTP2, UNDICI_CLIENT, UNDICI_RETRY, UNDICI_TICK_MS, ZTUNNEL_HBONE, goLateSeconds, goTimerLateness, istioSidecar, nodeEarlySeconds, nodeLateSeconds, nodeTimerLateness, undiciFastEarly, undiciFastLateness };
19167
19657
 
19168
19658
  //# sourceMappingURL=index.js.map