@mark1russell7/service 0.5.10 → 0.5.12
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 +18 -1
- package/build/{builder-DyDB7zM9.d.ts → builder-DawJhq4p.d.ts} +3 -3
- package/build/{clock-D-38uH_z.d.ts → clock-mVqhXD0b.d.ts} +2 -2
- package/build/clock.d.ts +1 -1
- package/build/clock.js +11 -3
- package/build/clock.js.map +1 -1
- package/build/core-C2wnF4mg.d.ts +183 -0
- package/build/heartbeat.d.ts +1 -1
- package/build/http.d.ts +2 -2
- package/build/index.d.ts +13 -8
- package/build/index.js +416 -250
- package/build/index.js.map +1 -1
- package/build/{lifecycle-Chu9Pri2.d.ts → lifecycle-fgYfxrHK.d.ts} +18 -3
- package/build/{limiter-DCDdzVwe.d.ts → limiter-B0849Vhp.d.ts} +2 -2
- package/build/limiter.d.ts +2 -2
- package/build/machine-Czfb6fV4.js +372 -0
- package/build/machine-Czfb6fV4.js.map +1 -0
- package/build/pg.d.ts +230 -0
- package/build/pg.js +534 -0
- package/build/pg.js.map +1 -0
- package/build/redis.d.ts +26 -139
- package/build/redis.js +72 -279
- package/build/redis.js.map +1 -1
- package/build/{store-DzTyosou.d.ts → store-D5HLgBnW.d.ts} +2 -2
- package/build/testing.d.ts +3 -3
- package/package.json +11 -3
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ This release has the declaration, its export, the law, the health runtime, the l
|
|
|
15
15
|
- **The law.** `evaluate` and `verdictOf` decide one rule of the timer-ordering law on one binding. A rule is data: linear inequalities over `symbol@hop`, with a margin. A verdict is `holds`, `violated`, `unbounded` (it holds only because a timer is absent) or `depends` (nothing is bound).
|
|
16
16
|
- **The linter.** `lint(description, scenario, rules)` applies the service rules (`SERVICE_RULES`) to a declaration. The declaration binds the symbols of the service: the polls of its checks, the windows of its policies, its drain. The scenario binds the symbols of the platform and of each dependency. A `depends` finding names the symbols that have no bound.
|
|
17
17
|
- **The scopes of a rule.** A rule about a client applies one time for each dependency. A rule about a consumer, for example O20, applies one time for each consumer and each worker.
|
|
18
|
+
- **The loops of a progress check.** A check of the step `progress` can name the loops that mark it, with its stall time: `marks: { loops, stall }`. Each loop is a check or a worker of the service.
|
|
19
|
+
- **The stall time.** `lint()` compares the stall time with the longest gap between two marks of the slowest loop (`PROGRESS_RULE`). A loop marks at the end of each turn, also a turn that fails. The gap of a check is `interval × (1 + jitter) + timeout`. The gap of a worker is its sleep or its longest backoff, the longer one, plus `unit_processing_time`. At 300 s ± 20 % and a timeout of 10 s, a poll gives 370 s.
|
|
20
|
+
- **A name that is not a loop.** A name that is not a check or a worker gets a `depends` finding. Without `marks`, a check gets no finding of this rule.
|
|
18
21
|
- **Keyed limiters.** `svc.limiter(name, spec)` declares a rate limit for each key, as data. `keyedLimiter` makes its runtime on a store ([The keyed limiter](#the-keyed-limiter)).
|
|
19
22
|
- **The hold.** The cap of the `fail readiness` phase binds `readiness_hold@process`, and a service without that phase holds for zero. The hold keeps the listener open after the signal, as a preStop sleep does. Thus O04 can compare the sum of the two with the propagation of the endpoints.
|
|
20
23
|
|
|
@@ -510,13 +513,27 @@ const life = await app.run(); // the process exits after SIGTERM, with 0 or 1
|
|
|
510
513
|
- **Redis Cluster.** The names of the keys put the limiter in braces, a hash tag. Thus the state and the index of a limiter are in one slot. The prefix has no braces.
|
|
511
514
|
- **The test clock.** With `{ clock }`, the script uses the time of that clock in place of `TIME`. The tests use it to compare each decision of Redis with `decide`.
|
|
512
515
|
|
|
516
|
+
## The PostgreSQL client
|
|
517
|
+
|
|
518
|
+
`@mark1russell7/service/pg` is the PostgreSQL client of the service, over a pool of node-postgres 8. This entry is a prototype of S6. pg is an optional peer dependency. The client loads it only when it connects.
|
|
519
|
+
|
|
520
|
+
- **The declaration.** `pgClient(name, spec)` declares `connect_bound`, `request_timeout`, `statement_timeout`, `pool_idle_expiry`, `keepalive_idle`, `max_connection_age`, `close_bound` and `retrans_giveup_time`. Each knob is necessary, and a bound that nobody gives is "infinite". `specProblems` refuses a knob that pg cannot use, for example a zero, which pg reads as no timer.
|
|
521
|
+
- **The starting knobs.** `PG_STARTING_KNOBS` and `PG_STARTING_POLL` are a declaration from the cells of S1. Each value has its measured reason in its doc comment.
|
|
522
|
+
- **Three outcomes.** `query(operation, text, values)` gives `ok`, `error` or `indeterminate`. An ERROR of the server is certain. A FATAL, a reset or a query timeout is not certain. The client then gives the connection back with an error, thus the pool ends the orphaned query.
|
|
523
|
+
- **Idempotency for each operation.** SQL text does not tell if a statement changes a state. Thus the client sends again only an idempotent operation that its table names, one time at most, in the bound of the request.
|
|
524
|
+
- **The join.** At each connect, the client records the process id of the backend and the socket (`joins`).
|
|
525
|
+
- **No unheard error.** The client listens to the errors of the pool and of each client that it holds. In Node, an error with no listener ends the process.
|
|
526
|
+
- **The checks.** `checks({ poll, steps })` gives `local-state`, `checkout`, `round-trip` (a `SELECT 1` through the pool) and `dial` (an SSLRequest on a new connection).
|
|
527
|
+
- **The close.** At the shutdown, the client ends the pool, and it destroys each socket that stays at its `close_bound`.
|
|
528
|
+
- **The manifestations and the machine.** `meets` lists the manifestations and their detectors. `PG_CLIENT_MACHINE` is the client as a `mark1russell7.machine/1` document, and the tests replay the client against it.
|
|
529
|
+
|
|
513
530
|
## Installation
|
|
514
531
|
|
|
515
532
|
```sh
|
|
516
533
|
pnpm add @mark1russell7/service
|
|
517
534
|
```
|
|
518
535
|
|
|
519
|
-
For the Redis client, the application also installs `ioredis@6`.
|
|
536
|
+
For the Redis client, the application also installs `ioredis@6`. For the PostgreSQL client, it installs `pg@8`.
|
|
520
537
|
|
|
521
538
|
The package uses [`@mark1russell7/quantity`](https://www.npmjs.com/package/@mark1russell7/quantity) for each amount. No entry of the service loads `zod` at run time, thus `zod` is an optional peer dependency. An application that validates amounts with the schemas of `quantity` installs `zod`.
|
|
522
539
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Clock } from "./clock-
|
|
1
|
+
import { n as Clock } from "./clock-mVqhXD0b.js";
|
|
2
2
|
import { c as LimiterSpec } from "./policy-G4QJ1ZZq.js";
|
|
3
|
-
import { B as Gate,
|
|
3
|
+
import { B as Gate, D as Outcome, E as CheckFn, F as CooperativeFloor, G as ServiceDescription, H as Phase, I as Coupling, L as Dependency, N as Check, R as ExitCodes, T as StartOptions, V as MessageTrigger, W as RepeatSignal, Y as Poll, Z as Timing, d as TransportImpl, ht as ProcessTrigger, k as Trace, lt as ExitTrigger, n as HealthServer, o as PhaseWork, r as Lifecycle, rt as OperationOf, s as RunOptions, t as DependencyHandle, wt as Operation, x as Health } from "./lifecycle-fgYfxrHK.js";
|
|
4
4
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
5
5
|
//#region src/profiles.d.ts
|
|
6
6
|
/**
|
|
@@ -208,4 +208,4 @@ interface ServiceBuilder {
|
|
|
208
208
|
declare const service: (name: string) => ServiceBuilder;
|
|
209
209
|
//#endregion
|
|
210
210
|
export { WatchdogSpec as a, Profile as c, kubernetes as d, localDev as f, Watchdog as i, daemon as l, ServiceBuilder as n, watchdog as o, service as r, PodTiming as s, ControllerBuilder as t, ephemeral as u };
|
|
211
|
-
//# sourceMappingURL=builder-
|
|
211
|
+
//# sourceMappingURL=builder-DawJhq4p.d.ts.map
|
|
@@ -24,7 +24,7 @@ interface PlatformClockOptions {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* This function makes a clock of the platform: `performance.now()` and `setTimeout`. Each cancel
|
|
27
|
-
* that it gives also has `unref`.
|
|
27
|
+
* that it gives also has `unref`. A delay longer than `setTimeout` takes waits in steps.
|
|
28
28
|
*/
|
|
29
29
|
declare const platformClock: (options?: PlatformClockOptions) => Clock;
|
|
30
30
|
/**
|
|
@@ -34,4 +34,4 @@ declare const platformClock: (options?: PlatformClockOptions) => Clock;
|
|
|
34
34
|
declare const realClock: Clock;
|
|
35
35
|
//#endregion
|
|
36
36
|
export { realClock as a, platformClock as i, Clock as n, PlatformClockOptions as r, Cancel as t };
|
|
37
|
-
//# sourceMappingURL=clock-
|
|
37
|
+
//# sourceMappingURL=clock-mVqhXD0b.d.ts.map
|
package/build/clock.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as realClock, i as platformClock, n as Clock, r as PlatformClockOptions, t as Cancel } from "./clock-
|
|
1
|
+
import { a as realClock, i as platformClock, n as Clock, r as PlatformClockOptions, t as Cancel } from "./clock-mVqhXD0b.js";
|
|
2
2
|
export { Cancel, Clock, PlatformClockOptions, platformClock, realClock };
|
package/build/clock.js
CHANGED
|
@@ -4,18 +4,26 @@ const monotonic = () => {
|
|
|
4
4
|
const performance = globalThis.performance;
|
|
5
5
|
return performance === void 0 ? Date.now() : performance.now();
|
|
6
6
|
};
|
|
7
|
+
/** This delay is the longest that `setTimeout` takes, in milliseconds. A longer delay starts the function after 1 ms. */
|
|
8
|
+
const LONGEST_DELAY = 2147483647;
|
|
7
9
|
/**
|
|
8
10
|
* This function makes a clock of the platform: `performance.now()` and `setTimeout`. Each cancel
|
|
9
|
-
* that it gives also has `unref`.
|
|
11
|
+
* that it gives also has `unref`. A delay longer than `setTimeout` takes waits in steps.
|
|
10
12
|
*/
|
|
11
13
|
const platformClock = (options = {}) => ({
|
|
12
14
|
now: monotonic,
|
|
13
15
|
after(ms, run) {
|
|
14
|
-
|
|
16
|
+
let unrefed = options.unref === true;
|
|
17
|
+
const arm = (left) => {
|
|
18
|
+
const step = left > LONGEST_DELAY ? setTimeout(() => timer = arm(left - LONGEST_DELAY), LONGEST_DELAY) : setTimeout(run, Math.max(0, left));
|
|
19
|
+
if (unrefed) step.unref?.();
|
|
20
|
+
return step;
|
|
21
|
+
};
|
|
22
|
+
let timer = arm(ms);
|
|
15
23
|
const unref = () => {
|
|
24
|
+
unrefed = true;
|
|
16
25
|
timer.unref?.();
|
|
17
26
|
};
|
|
18
|
-
if (options.unref === true) unref();
|
|
19
27
|
return Object.assign(() => clearTimeout(timer), { unref });
|
|
20
28
|
}
|
|
21
29
|
});
|
package/build/clock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clock.js","names":[],"sources":["../src/clock.ts"],"sourcesContent":["// @mark1russell7/service/clock: the clock of the runtime, with no other part of the package. It\n// imports no `node:` module and no zod. Thus a client in a browser can use it.\n\n/**\n * This function stops a timer that `Clock.after` started. A second use does nothing. A clock of\n * the platform also gives `unref`: after it, the timer does not keep a Node process alive.\n */\nexport type Cancel = (() => void) & { readonly unref?: (() => void) | undefined };\n\n/**\n * A clock gives the monotonic time in milliseconds, and it starts a function after a delay. The\n * runtime reads time only through a clock. Thus a test can give a fake clock, and the timing of\n * the runtime is then exact and repeatable.\n */\nexport interface Clock {\n /** This method gives the monotonic time, in milliseconds. A step of the wall clock does not move it. */\n now(): number;\n /** This method starts `run` after `ms` milliseconds, and gives the function that stops it. */\n after(ms: number, run: () => void): Cancel;\n}\n\n/** These options make a clock of the platform. */\nexport interface PlatformClockOptions {\n /** True makes each timer not keep a Node process alive. The default is false, as with `setTimeout`. */\n readonly unref?: boolean | undefined;\n}\n\n/** This function gives the monotonic time: `performance.now()`, or `Date.now()` on a platform without `performance`. */\nconst monotonic = (): number => {\n const performance = (globalThis as { performance?: { now(): number } }).performance;\n return performance === undefined ? Date.now() : performance.now();\n};\n\n/**\n * This function makes a clock of the platform: `performance.now()` and `setTimeout`. Each cancel\n * that it gives also has `unref
|
|
1
|
+
{"version":3,"file":"clock.js","names":[],"sources":["../src/clock.ts"],"sourcesContent":["// @mark1russell7/service/clock: the clock of the runtime, with no other part of the package. It\n// imports no `node:` module and no zod. Thus a client in a browser can use it.\n\n/**\n * This function stops a timer that `Clock.after` started. A second use does nothing. A clock of\n * the platform also gives `unref`: after it, the timer does not keep a Node process alive.\n */\nexport type Cancel = (() => void) & { readonly unref?: (() => void) | undefined };\n\n/**\n * A clock gives the monotonic time in milliseconds, and it starts a function after a delay. The\n * runtime reads time only through a clock. Thus a test can give a fake clock, and the timing of\n * the runtime is then exact and repeatable.\n */\nexport interface Clock {\n /** This method gives the monotonic time, in milliseconds. A step of the wall clock does not move it. */\n now(): number;\n /** This method starts `run` after `ms` milliseconds, and gives the function that stops it. */\n after(ms: number, run: () => void): Cancel;\n}\n\n/** These options make a clock of the platform. */\nexport interface PlatformClockOptions {\n /** True makes each timer not keep a Node process alive. The default is false, as with `setTimeout`. */\n readonly unref?: boolean | undefined;\n}\n\n/** This function gives the monotonic time: `performance.now()`, or `Date.now()` on a platform without `performance`. */\nconst monotonic = (): number => {\n const performance = (globalThis as { performance?: { now(): number } }).performance;\n return performance === undefined ? Date.now() : performance.now();\n};\n\n/** This delay is the longest that `setTimeout` takes, in milliseconds. A longer delay starts the function after 1 ms. */\nconst LONGEST_DELAY = 0x7fffffff;\n\n/**\n * This function makes a clock of the platform: `performance.now()` and `setTimeout`. Each cancel\n * that it gives also has `unref`. A delay longer than `setTimeout` takes waits in steps.\n */\nexport const platformClock = (options: PlatformClockOptions = {}): Clock => ({\n now: monotonic,\n after(ms, run) {\n let unrefed = options.unref === true;\n const arm = (left: number): ReturnType<typeof setTimeout> => {\n const step =\n left > LONGEST_DELAY ? setTimeout(() => (timer = arm(left - LONGEST_DELAY)), LONGEST_DELAY) : setTimeout(run, Math.max(0, left));\n if (unrefed) (step as { unref?: () => void }).unref?.();\n return step;\n };\n let timer = arm(ms);\n const unref = (): void => {\n unrefed = true;\n (timer as { unref?: () => void }).unref?.();\n };\n return Object.assign(() => clearTimeout(timer), { unref });\n },\n});\n\n/**\n * This clock reads `performance.now()` and uses `setTimeout`. Its timers do not keep a Node\n * process alive, thus a timer that is not stopped cannot stop the exit of the process.\n */\nexport const realClock: Clock = /* @__PURE__ */ platformClock({ unref: true });\n"],"mappings":";;AA4BA,MAAM,kBAA0B;CAC9B,MAAM,cAAe,WAAmD;CACxE,OAAO,gBAAgB,KAAA,IAAY,KAAK,IAAI,IAAI,YAAY,IAAI;AAClE;;AAGA,MAAM,gBAAgB;;;;;AAMtB,MAAa,iBAAiB,UAAgC,CAAC,OAAc;CAC3E,KAAK;CACL,MAAM,IAAI,KAAK;EACb,IAAI,UAAU,QAAQ,UAAU;EAChC,MAAM,OAAO,SAAgD;GAC3D,MAAM,OACJ,OAAO,gBAAgB,iBAAkB,QAAQ,IAAI,OAAO,aAAa,GAAI,aAAa,IAAI,WAAW,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;GACjI,IAAI,SAAS,KAAiC,QAAQ;GACtD,OAAO;EACT;EACA,IAAI,QAAQ,IAAI,EAAE;EAClB,MAAM,cAAoB;GACxB,UAAU;GACV,MAAkC,QAAQ;EAC5C;EACA,OAAO,OAAO,aAAa,aAAa,KAAK,GAAG,EAAE,MAAM,CAAC;CAC3D;AACF;;;;;AAMA,MAAa,YAAmC,8BAAc,EAAE,OAAO,KAAK,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { n as Clock } from "./clock-mVqhXD0b.js";
|
|
2
|
+
import { B as Gate, E as CheckFn, G as ServiceDescription, K as Step, L as Dependency, M as Recorder, N as Check, Y as Poll, t as DependencyHandle, wt as Operation } from "./lifecycle-fgYfxrHK.js";
|
|
3
|
+
import { n as ServiceBuilder } from "./builder-DawJhq4p.js";
|
|
4
|
+
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
5
|
+
//#region src/client/meets.d.ts
|
|
6
|
+
/** A situation is what the connection did when the failure started: a command in flight, or idle. */
|
|
7
|
+
type Situation = "in flight" | "idle";
|
|
8
|
+
/** A detector is a mechanism that finds a failure, and the most time that it takes. */
|
|
9
|
+
interface Detector {
|
|
10
|
+
/** This name identifies the mechanism: a knob of the declaration, or the kernel. */
|
|
11
|
+
readonly by: string;
|
|
12
|
+
/** This time is the most that the detector takes, after the failure starts. "infinite" tells that it does not find the failure. */
|
|
13
|
+
readonly within: Extent;
|
|
14
|
+
readonly situation: Situation;
|
|
15
|
+
/** This text tells what the detector does, for example that it fails a command without a change of state. */
|
|
16
|
+
readonly effect: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A meeting is a manifestation that the client can meet, and its detectors (E9). The names of the
|
|
20
|
+
* manifestations are the names of the vocabulary of the harness and the corpus. `app-stall` is a
|
|
21
|
+
* server whose process is alive and does not answer, a proposal of the vocabulary.
|
|
22
|
+
*/
|
|
23
|
+
interface Meeting {
|
|
24
|
+
readonly manifestation: string;
|
|
25
|
+
/** This text tells the failure in words. */
|
|
26
|
+
readonly what: string;
|
|
27
|
+
readonly detectors: readonly Detector[];
|
|
28
|
+
}
|
|
29
|
+
/** These are the manifestations that each client gives a meeting for, in this sequence. */
|
|
30
|
+
declare const MANIFESTATIONS: readonly ["rst", "fin", "blackhole", "freeze-host", "freeze-process", "app-stall"];
|
|
31
|
+
/** A manifestation is one name of `MANIFESTATIONS`. */
|
|
32
|
+
type Manifestation = (typeof MANIFESTATIONS)[number];
|
|
33
|
+
/** This function gives the first detector of a manifestation in a situation, or null when no detector has an end (C3). */
|
|
34
|
+
declare const firstDetector: (meeting: Meeting, situation: Situation) => Detector | null;
|
|
35
|
+
/** This function gives each manifestation and situation that no detector of the client finds: the standing rule, as a query (C3, E9). */
|
|
36
|
+
declare const unwatched: (meets: readonly Meeting[]) => Array<{
|
|
37
|
+
readonly manifestation: string;
|
|
38
|
+
readonly situation: Situation;
|
|
39
|
+
}>;
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/client/core.d.ts
|
|
42
|
+
/**
|
|
43
|
+
* A sent result is the outcome of a call, in three values (C8):
|
|
44
|
+
* - `ok`: the server answered.
|
|
45
|
+
* - `error`: the call did not apply. The server answered with an error (`reply`), or the call did
|
|
46
|
+
* not leave the client.
|
|
47
|
+
* - `indeterminate`: the call can have reached the server, and nothing tells if it applied.
|
|
48
|
+
*/
|
|
49
|
+
type Sent<T> = {
|
|
50
|
+
readonly outcome: "ok";
|
|
51
|
+
readonly value: T;
|
|
52
|
+
readonly attempts: number;
|
|
53
|
+
} | {
|
|
54
|
+
readonly outcome: "error";
|
|
55
|
+
readonly error: string;
|
|
56
|
+
readonly reply: boolean;
|
|
57
|
+
readonly attempts: number;
|
|
58
|
+
} | {
|
|
59
|
+
readonly outcome: "indeterminate";
|
|
60
|
+
readonly error: string;
|
|
61
|
+
readonly attempts: number;
|
|
62
|
+
};
|
|
63
|
+
/** This type is the outcome of one try of a call, before the core counts the tries. */
|
|
64
|
+
type Attempt<T = unknown> = {
|
|
65
|
+
readonly outcome: "ok";
|
|
66
|
+
readonly value: T;
|
|
67
|
+
} | {
|
|
68
|
+
readonly outcome: "error";
|
|
69
|
+
readonly error: string;
|
|
70
|
+
readonly reply: boolean;
|
|
71
|
+
} | {
|
|
72
|
+
readonly outcome: "indeterminate";
|
|
73
|
+
readonly error: string;
|
|
74
|
+
};
|
|
75
|
+
/** Send options tell how the client sends one call. */
|
|
76
|
+
interface SendOptions {
|
|
77
|
+
/** This signal abandons the call. A call that left the client is then indeterminate. */
|
|
78
|
+
readonly signal?: AbortSignal | undefined;
|
|
79
|
+
/** False stops the client: it does not send the call again. A check that must fail at once uses it. */
|
|
80
|
+
readonly reissue?: boolean | undefined;
|
|
81
|
+
}
|
|
82
|
+
/** A dial function opens a new connection to the server, and reads one reply of the protocol. The `dial` check uses it. */
|
|
83
|
+
type DialFn = (host: string, port: number, signal: AbortSignal) => Promise<void>;
|
|
84
|
+
/** The steps of a connection that each client gives a check for (B14). A client can add more steps. */
|
|
85
|
+
type ClientStep = Extract<Step, "dial" | "round-trip" | "local-state">;
|
|
86
|
+
/** Check options tell which checks the client gives the health runtime, and which policy each one controls. */
|
|
87
|
+
interface CheckOptions<S extends Step = ClientStep> {
|
|
88
|
+
readonly poll: Poll;
|
|
89
|
+
/** For each step, the policy that its check controls, or null for a check that only reports. A step that is absent has no check. */
|
|
90
|
+
readonly steps: Partial<Record<S, Gate | null>>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* These are the knobs that each client has, by the names of the ordering law. Each driver adds its
|
|
94
|
+
* own knobs. The comments of each driver tell which option of the driver a knob sets.
|
|
95
|
+
*/
|
|
96
|
+
interface ClientKnobs {
|
|
97
|
+
/** This time bounds a new connection. */
|
|
98
|
+
readonly connect_bound: Quantity;
|
|
99
|
+
/** This time bounds each call on the connection of the application. */
|
|
100
|
+
readonly request_timeout: Quantity;
|
|
101
|
+
/** This time is the idle time of TCP keepalive. Node then sends 10 probes 1 s apart. */
|
|
102
|
+
readonly keepalive_idle: Extent;
|
|
103
|
+
/** This time is the age at which the client replaces a connection. */
|
|
104
|
+
readonly max_connection_age: Extent;
|
|
105
|
+
/** This time bounds the close of the client at the shutdown. */
|
|
106
|
+
readonly close_bound: Quantity;
|
|
107
|
+
/**
|
|
108
|
+
* This time is when the kernel gives up a segment that it retransmits. Node cannot set it, thus
|
|
109
|
+
* the declaration states it for the ordering law (O17), from the platform.
|
|
110
|
+
*/
|
|
111
|
+
readonly retrans_giveup_time: Extent;
|
|
112
|
+
}
|
|
113
|
+
/** A client spec is the declaration of one client: where it connects, and its knobs. Each driver adds its own fields. */
|
|
114
|
+
interface ClientSpec<K extends ClientKnobs = ClientKnobs> {
|
|
115
|
+
readonly host: string;
|
|
116
|
+
readonly port: number;
|
|
117
|
+
readonly password?: string | undefined;
|
|
118
|
+
/** This identifier is the component in the corpus, for example `systems.component.redis`, or null. */
|
|
119
|
+
readonly system: string | null;
|
|
120
|
+
readonly knobs: K;
|
|
121
|
+
/** These operations add to the table of the client, or change it. */
|
|
122
|
+
readonly operations?: Readonly<Record<string, Operation>> | undefined;
|
|
123
|
+
}
|
|
124
|
+
/** A factory makes the connection or the pool of a client from the options of its driver. */
|
|
125
|
+
type Factory<O, C> = (options: O) => C | Promise<C>;
|
|
126
|
+
/** These options make a client. Without them, a client uses its driver, the real clock, and the dial of its protocol. */
|
|
127
|
+
interface ClientOptions<F> {
|
|
128
|
+
readonly create?: F | undefined;
|
|
129
|
+
readonly clock?: Clock | undefined;
|
|
130
|
+
/** This function receives each transition of the client, for the prober (D3). */
|
|
131
|
+
readonly record?: Recorder | undefined;
|
|
132
|
+
readonly dial?: DialFn | undefined;
|
|
133
|
+
}
|
|
134
|
+
/** A client socket is the part of the socket of a connection that the join of the prober and the bounded close read. */
|
|
135
|
+
interface ClientSocket {
|
|
136
|
+
readonly localAddress?: string | undefined;
|
|
137
|
+
readonly localPort?: number | undefined;
|
|
138
|
+
readonly remoteAddress?: string | undefined;
|
|
139
|
+
readonly remotePort?: number | undefined;
|
|
140
|
+
/** This method closes the socket at once. A close of the driver only half-closes it, and a silent peer does not answer that. */
|
|
141
|
+
destroy?(): void;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A client join is one connection, at the time when it can serve (D1, D2). The prober joins its
|
|
145
|
+
* kernel records to the server's view of the connection through it. Each driver adds the server's id of the connection.
|
|
146
|
+
*/
|
|
147
|
+
interface ClientJoin {
|
|
148
|
+
readonly generation: number;
|
|
149
|
+
/** This time is when the connection became ready, in milliseconds on the monotonic clock. */
|
|
150
|
+
readonly at: number;
|
|
151
|
+
readonly localAddress: string | null;
|
|
152
|
+
readonly localPort: number | null;
|
|
153
|
+
readonly remoteAddress: string | null;
|
|
154
|
+
readonly remotePort: number | null;
|
|
155
|
+
}
|
|
156
|
+
/** A client is a dependency of a service: its declaration, its handle and its checks. Each driver adds the method that sends a call. */
|
|
157
|
+
interface Client<S extends Step = ClientStep, J extends ClientJoin = ClientJoin> {
|
|
158
|
+
readonly name: string;
|
|
159
|
+
/** This declaration goes to `svc.dependency(name, declaration, handle)`. */
|
|
160
|
+
readonly declaration: Omit<Dependency, "name">;
|
|
161
|
+
readonly handle: DependencyHandle;
|
|
162
|
+
/** These are the manifestations that the client can meet, and the detectors of each (E9). */
|
|
163
|
+
readonly meets: readonly Meeting[];
|
|
164
|
+
/** This text is the state of the client, as the machine document of the client names it. */
|
|
165
|
+
readonly status: string;
|
|
166
|
+
/** These are the connections of the client, the latest last. */
|
|
167
|
+
readonly joins: readonly J[];
|
|
168
|
+
/** This method gives the checks of the client and their functions, for `svc.check(check, run)`. */
|
|
169
|
+
checks(options: CheckOptions<S>): ReadonlyArray<readonly [Check, CheckFn]>;
|
|
170
|
+
/** This method declares the client in a service: its dependency, its handle and its checks. */
|
|
171
|
+
attach(svc: ServiceBuilder, options: CheckOptions<S>): ServiceBuilder;
|
|
172
|
+
/** This method gives the problems of the client in a description: a close that does not fit in its phase, for example. */
|
|
173
|
+
problems(description: ServiceDescription): string[];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* This poll is a poll of the checks to start from: each 5 s with a jitter of 20 %, and a timeout of
|
|
177
|
+
* 4 s (B6, O12). Its slowest poll is 4 s + 5 s × 1.2 = 10 s, the slowest poll of the cells of O13.
|
|
178
|
+
* It does not depend on a driver. The starting knobs of each driver fit it.
|
|
179
|
+
*/
|
|
180
|
+
declare const STARTING_POLL: Poll;
|
|
181
|
+
//#endregion
|
|
182
|
+
export { Manifestation as _, ClientKnobs as a, firstDetector as b, ClientSpec as c, Factory as d, STARTING_POLL as f, MANIFESTATIONS as g, Detector as h, ClientJoin as i, ClientStep as l, Sent as m, CheckOptions as n, ClientOptions as o, SendOptions as p, Client as r, ClientSocket as s, Attempt as t, DialFn as u, Meeting as v, unwatched as x, Situation as y };
|
|
183
|
+
//# sourceMappingURL=core-C2wnF4mg.d.ts.map
|
package/build/heartbeat.d.ts
CHANGED
package/build/http.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Clock } from "./clock-
|
|
1
|
+
import { n as Clock } from "./clock-mVqhXD0b.js";
|
|
2
2
|
import { d as Refused } from "./policy-G4QJ1ZZq.js";
|
|
3
|
-
import { d as TransportImpl, m as RequestEnd, n as HealthServer, r as Lifecycle, v as RequestStream, w as ProbeKind, x as Health, y as RequestWork } from "./lifecycle-
|
|
3
|
+
import { d as TransportImpl, m as RequestEnd, n as HealthServer, r as Lifecycle, v as RequestStream, w as ProbeKind, x as Health, y as RequestWork } from "./lifecycle-fgYfxrHK.js";
|
|
4
4
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
5
5
|
import { ListenOptions } from "node:net";
|
|
6
6
|
import { IncomingMessage, Server, ServerEventMap, ServerResponse } from "node:http";
|
package/build/index.d.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { a as backoffDelay, i as backoffBand, n as DelayBand, o as backoffProblems, r as Jitter, t as Backoff } from "./backoff-B-jGWVDm.js";
|
|
2
|
-
import { a as realClock, i as platformClock, n as Clock, r as PlatformClockOptions, t as Cancel } from "./clock-
|
|
2
|
+
import { a as realClock, i as platformClock, n as Clock, r as PlatformClockOptions, t as Cancel } from "./clock-mVqhXD0b.js";
|
|
3
3
|
import { Heartbeat, HeartbeatOptions, detectionTime, heartbeat } from "./heartbeat.js";
|
|
4
4
|
import { S as retryAfterSeconds, _ as freeAt, a as LimitRule, b as limiterProblems, c as LimiterSpec, d as Refused, f as SlidingWindow, g as decide, h as TokenBucket, i as LimitPolicy, l as LimiterStoreSpec, m as TakeStep, n as Decision, o as Limiter, p as StoreFailure, r as KeyState, s as LimiterEviction, t as Allowed, u as RefusalCause, v as idleSpan, x as longestRetryAfter, y as limitRule } from "./policy-G4QJ1ZZq.js";
|
|
5
|
-
import { $ as
|
|
6
|
-
import { a as WatchdogSpec, c as Profile, d as kubernetes, f as localDev, i as Watchdog, l as daemon, n as ServiceBuilder, o as watchdog, r as service, s as PodTiming, t as ControllerBuilder, u as ephemeral } from "./builder-
|
|
7
|
-
import { a as keyedLimiter, i as TakeRequest, n as LimiterStore, o as memoryStore, r as MemoryStore, t as KeyedLimiter } from "./store-
|
|
8
|
-
import { a as limiterStateOf, i as limiterMachine, n as SLIDING_WINDOW_MACHINE, r as TOKEN_BUCKET_MACHINE, t as LimiterState } from "./limiter-
|
|
5
|
+
import { $ as asWindow, A as LifecycleEvent, B as Gate, C as ProbeAnswer, Ct as Idempotency, D as Outcome, E as CheckFn, F as CooperativeFloor, G as ServiceDescription, H as Phase, I as Coupling, J as FailsBy, K as Step, L as Dependency, M as Recorder, N as Check, O as Result, P as Controller, Q as asDebounce, R as ExitCodes, S as HealthVerdict, St as processPortOf, T as StartOptions, Tt as mayReissue, U as ProgressMarks, V as MessageTrigger, W as RepeatSignal, X as Span, Y as Poll, Z as Timing, _ as RequestOptions, _t as isExitCode, a as PhaseContext, at as RouteRequest, b as CheckVerdict, bt as matchesMessage, c as STAGES, ct as ExitSignal, d as TransportImpl, dt as MessageShape, et as failSpan, f as cooperativeAbortAt, ft as PROCESS_TRIGGERS, g as RequestFn, gt as embeddedProcess, h as RequestEvent, ht as ProcessTrigger, i as LifecycleState, it as RoutePattern, j as MachineName, l as ShutdownOptions, lt as ExitTrigger, m as RequestEnd, mt as ProcessPort, n as HealthServer, nt as recoverSpan, o as PhaseWork, ot as EXIT_SIGNALS, p as stageRank, pt as ProcessHost, q as Transport, r as Lifecycle, rt as OperationOf, s as RunOptions, st as EmbeddedProcess, t as DependencyHandle, tt as heartbeatDetection, u as Stage, ut as HostStream, v as RequestStream, vt as isExitSignal, w as ProbeKind, wt as Operation, x as Health, xt as nodeProcess, y as RequestWork, yt as isMessageShape, z as FORMAT } from "./lifecycle-fgYfxrHK.js";
|
|
6
|
+
import { a as WatchdogSpec, c as Profile, d as kubernetes, f as localDev, i as Watchdog, l as daemon, n as ServiceBuilder, o as watchdog, r as service, s as PodTiming, t as ControllerBuilder, u as ephemeral } from "./builder-DawJhq4p.js";
|
|
7
|
+
import { a as keyedLimiter, i as TakeRequest, n as LimiterStore, o as memoryStore, r as MemoryStore, t as KeyedLimiter } from "./store-D5HLgBnW.js";
|
|
8
|
+
import { a as limiterStateOf, i as limiterMachine, n as SLIDING_WINDOW_MACHINE, r as TOKEN_BUCKET_MACHINE, t as LimiterState } from "./limiter-B0849Vhp.js";
|
|
9
9
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
10
10
|
import { replay } from "@mark1russell7/algebra/replay";
|
|
11
11
|
import { Machine } from "@mark1russell7/algebra";
|
|
12
12
|
//#region src/law.d.ts
|
|
13
13
|
/**
|
|
14
14
|
* This module is the evaluator of the timer-ordering law. Its decisions are the same as the
|
|
15
|
-
* decisions of the research evaluator
|
|
15
|
+
* decisions of the research evaluator, except when absent timers leave no order (`evaluate`). The
|
|
16
|
+
* rules are data, and the caller gives them. Each rule
|
|
16
17
|
* is one or more linear inequalities over symbols at a hop (`readiness_detection_window@pod`),
|
|
17
18
|
* with a margin. A binding maps `symbol@hop` to seconds, or to "inf" for a timer that is absent.
|
|
18
19
|
*/
|
|
@@ -71,7 +72,8 @@ export declare const symbolsOf: (rule: Rule) => string[];
|
|
|
71
72
|
/**
|
|
72
73
|
* This function evaluates each inequality on one binding. "<" holds when lhs + margin < rhs, and
|
|
73
74
|
* ">" holds when lhs > rhs + margin. Only the inequalities with all their symbols bound apply.
|
|
74
|
-
* The others are null.
|
|
75
|
+
* The others are null. Absent timers can leave no order: the same infinity on each side, or both
|
|
76
|
+
* signs of infinity on one side. Then the inequality holds only because a timer is absent.
|
|
75
77
|
*/
|
|
76
78
|
export declare const evaluate: (rule: Rule, bind: Binding) => Evaluated[];
|
|
77
79
|
/**
|
|
@@ -150,10 +152,13 @@ export declare const serviceBindings: (svc: ServiceDescription, scenario: Scenar
|
|
|
150
152
|
};
|
|
151
153
|
/** This identifier is the rule of the findings about a field that the declaration does not give. */
|
|
152
154
|
export declare const DECLARATION_RULE = "declaration";
|
|
155
|
+
/** This identifier is the rule of the findings about the stall time of a progress check (`Check.marks`). */
|
|
156
|
+
export declare const PROGRESS_RULE = "progress";
|
|
153
157
|
/**
|
|
154
158
|
* This function applies each service rule to a declaration and a scenario. A rule applies one time
|
|
155
159
|
* for the service, for each client, for each consumer and worker, or for each limiter. The function
|
|
156
160
|
* also gives a finding for each necessary field that the description does not give (`DECLARATION_RULE`).
|
|
161
|
+
* Each progress check that names its loops also gets its findings (`PROGRESS_RULE`).
|
|
157
162
|
*/
|
|
158
163
|
export declare const lint: (svc: ServiceDescription, scenario: Scenario, rules: readonly Rule[]) => Finding[];
|
|
159
164
|
//#endregion
|
|
@@ -431,5 +436,5 @@ export declare const drainMachine: (description: ServiceDescription) => Machine;
|
|
|
431
436
|
/** These are the static machines of the runtime, by the name that their events carry. */
|
|
432
437
|
export declare const MACHINES: Readonly<Record<Exclude<MachineName, "drain" | "client">, Machine>>;
|
|
433
438
|
//#endregion
|
|
434
|
-
export { type Allowed, type Backoff, type Binding, type Bound, type Cancel, type Check, type CheckFn, type CheckVerdict, type Clock, type Controller, type ControllerBuilder, type CooperativeFloor, type Coupling, type Decision, type DelayBand, type Dependency, type DependencyHandle, EXIT_SIGNALS, type EmbeddedProcess, type Evaluated, type ExitCodes, type ExitSignal, type ExitTrigger, FORMAT, type FailsBy, type Finding, type Gate, type Health, type HealthServer, type HealthVerdict, type Heartbeat, type HeartbeatOptions, type HostStream, type Idempotency, type Inequality, type IterationContext, type Jitter, type JobAction, type JobContext, type JobFailure, type JobSettle, type JobSource, type KeyState, type KeyedLimiter, type Lifecycle, type LifecycleEvent, type LifecycleState, type LimitPolicy, type LimitRule, type Limiter, type LimiterEviction, type LimiterSpec, type LimiterState, type LimiterStore, type LimiterStoreSpec, type MachineName, type MemoryStore, type MessageShape, type MessageTrigger, type Operation, type OperationOf, type Outcome, PROCESS_TRIGGERS, type Phase, type PhaseContext, type PhaseWork, type PlatformClockOptions, type PodTiming, type Poll, type ProbeAnswer, type ProbeKind, type ProcessHost, type ProcessPort, type ProcessTrigger, type Profile, type QueueDrain, type QueueDrainOptions, type QueueKnobs, type Recorder, type RedeliveryPolicy, type RefusalCause, type Refused, type RepeatSignal, type RequestEnd, type RequestEvent, type RequestFn, type RequestOptions, type RequestStream, type RequestWork, type RequeueCause, type Result, type RoutePattern, type RouteRequest, type Rule, type RunOptions, SLIDING_WINDOW_MACHINE, STAGES, type Scenario, type ServiceBuilder, type ServiceDescription, type ShutdownOptions, type Side, type SlidingWindow, type Span, type Stage, type StartOptions, type Step, type StoreFailure, TOKEN_BUCKET_MACHINE, type TakeRequest, type TakeStep, type Term, type Timing, type TokenBucket, type Transport, type TransportImpl, type UnitRequest, type Verdict, type Watchdog, type WatchdogSpec, type WorkerKnobs, type WorkerLoop, type WorkerLoopOptions, asDebounce, asWindow, backoffBand, backoffDelay, backoffProblems, cooperativeAbortAt, daemon, decide, detectionTime, embeddedProcess, ephemeral, failSpan, freeAt, heartbeat, heartbeatDetection, idleSpan, isExitCode, isExitSignal, isMessageShape, keyedLimiter, kubernetes, limitRule, limiterMachine, limiterProblems, limiterStateOf, localDev, longestRetryAfter, matchesMessage, mayReissue, memoryStore, nodeProcess, platformClock, processPortOf, realClock, recoverSpan, replay, retryAfterSeconds, service, stageRank, watchdog };
|
|
439
|
+
export { type Allowed, type Backoff, type Binding, type Bound, type Cancel, type Check, type CheckFn, type CheckVerdict, type Clock, type Controller, type ControllerBuilder, type CooperativeFloor, type Coupling, type Decision, type DelayBand, type Dependency, type DependencyHandle, EXIT_SIGNALS, type EmbeddedProcess, type Evaluated, type ExitCodes, type ExitSignal, type ExitTrigger, FORMAT, type FailsBy, type Finding, type Gate, type Health, type HealthServer, type HealthVerdict, type Heartbeat, type HeartbeatOptions, type HostStream, type Idempotency, type Inequality, type IterationContext, type Jitter, type JobAction, type JobContext, type JobFailure, type JobSettle, type JobSource, type KeyState, type KeyedLimiter, type Lifecycle, type LifecycleEvent, type LifecycleState, type LimitPolicy, type LimitRule, type Limiter, type LimiterEviction, type LimiterSpec, type LimiterState, type LimiterStore, type LimiterStoreSpec, type MachineName, type MemoryStore, type MessageShape, type MessageTrigger, type Operation, type OperationOf, type Outcome, PROCESS_TRIGGERS, type Phase, type PhaseContext, type PhaseWork, type PlatformClockOptions, type PodTiming, type Poll, type ProbeAnswer, type ProbeKind, type ProcessHost, type ProcessPort, type ProcessTrigger, type Profile, type ProgressMarks, type QueueDrain, type QueueDrainOptions, type QueueKnobs, type Recorder, type RedeliveryPolicy, type RefusalCause, type Refused, type RepeatSignal, type RequestEnd, type RequestEvent, type RequestFn, type RequestOptions, type RequestStream, type RequestWork, type RequeueCause, type Result, type RoutePattern, type RouteRequest, type Rule, type RunOptions, SLIDING_WINDOW_MACHINE, STAGES, type Scenario, type ServiceBuilder, type ServiceDescription, type ShutdownOptions, type Side, type SlidingWindow, type Span, type Stage, type StartOptions, type Step, type StoreFailure, TOKEN_BUCKET_MACHINE, type TakeRequest, type TakeStep, type Term, type Timing, type TokenBucket, type Transport, type TransportImpl, type UnitRequest, type Verdict, type Watchdog, type WatchdogSpec, type WorkerKnobs, type WorkerLoop, type WorkerLoopOptions, asDebounce, asWindow, backoffBand, backoffDelay, backoffProblems, cooperativeAbortAt, daemon, decide, detectionTime, embeddedProcess, ephemeral, failSpan, freeAt, heartbeat, heartbeatDetection, idleSpan, isExitCode, isExitSignal, isMessageShape, keyedLimiter, kubernetes, limitRule, limiterMachine, limiterProblems, limiterStateOf, localDev, longestRetryAfter, matchesMessage, mayReissue, memoryStore, nodeProcess, platformClock, processPortOf, realClock, recoverSpan, replay, retryAfterSeconds, service, stageRank, watchdog };
|
|
435
440
|
//# sourceMappingURL=index.d.ts.map
|