@mark1russell7/service 0.5.11 → 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-Dn0cby6Q.d.ts → builder-DawJhq4p.d.ts} +2 -2
- package/build/core-C2wnF4mg.d.ts +183 -0
- package/build/http.d.ts +1 -1
- package/build/index.d.ts +6 -3
- package/build/index.js +155 -11
- package/build/index.js.map +1 -1
- package/build/{lifecycle-CGEegMI0.d.ts → lifecycle-fgYfxrHK.d.ts} +17 -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 +24 -137
- package/build/redis.js +72 -279
- package/build/redis.js.map +1 -1
- package/build/testing.d.ts +2 -2
- package/package.json +9 -1
package/build/pg.d.ts
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Y as Poll, wt as Operation } from "./lifecycle-fgYfxrHK.js";
|
|
2
|
+
import { _ as Manifestation, a as ClientKnobs, b as firstDetector, c as ClientSpec, d as Factory, f as STARTING_POLL, g as MANIFESTATIONS, h as Detector, i as ClientJoin, l as ClientStep, m as Sent, n as CheckOptions, o as ClientOptions, p as SendOptions, r as Client, s as ClientSocket, t as Attempt, u as DialFn, v as Meeting, x as unwatched, y as Situation } from "./core-C2wnF4mg.js";
|
|
3
|
+
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
4
|
+
import { Machine } from "@mark1russell7/algebra";
|
|
5
|
+
//#region src/pg/connection.d.ts
|
|
6
|
+
/** A pg socket is the socket of a client in the core: the join of the prober and the bounded close read it. */
|
|
7
|
+
type PgSocket = ClientSocket;
|
|
8
|
+
/** A query result is the part of a result of pg that the wrapper gives back. */
|
|
9
|
+
interface PgResult<Row = Record<string, unknown>> {
|
|
10
|
+
readonly rows: Row[];
|
|
11
|
+
readonly rowCount: number | null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A pool client is the part of a `pg.PoolClient` that the wrapper uses. A pg 8 client has each part.
|
|
15
|
+
* A fake for tests has them too. Thus the package depends on no type of pg.
|
|
16
|
+
*/
|
|
17
|
+
interface PgPoolClient {
|
|
18
|
+
/** This number is the id of the backend from BackendKeyData, which the server sends at the startup. */
|
|
19
|
+
readonly processID?: number | null | undefined;
|
|
20
|
+
/** This connection holds the socket of the client. */
|
|
21
|
+
readonly connection?: {
|
|
22
|
+
readonly stream?: PgSocket | undefined;
|
|
23
|
+
} | undefined;
|
|
24
|
+
query(text: string, values?: readonly unknown[]): Promise<PgResult<never>>;
|
|
25
|
+
/** This method gives the client back to the pool. With an error, the pool ends the client. */
|
|
26
|
+
release(error?: Error | boolean): void;
|
|
27
|
+
on(event: "error", listener: (error: Error) => void): unknown;
|
|
28
|
+
off(event: "error", listener: (error: Error) => void): unknown;
|
|
29
|
+
}
|
|
30
|
+
/** A pool is the part of a `pg.Pool` that the wrapper uses. */
|
|
31
|
+
interface PgPool {
|
|
32
|
+
readonly totalCount: number;
|
|
33
|
+
readonly idleCount: number;
|
|
34
|
+
readonly waitingCount: number;
|
|
35
|
+
connect(): Promise<PgPoolClient>;
|
|
36
|
+
end(): Promise<void>;
|
|
37
|
+
on(event: "connect" | "remove", listener: (client: PgPoolClient) => void): unknown;
|
|
38
|
+
on(event: "error", listener: (error: Error, client: PgPoolClient) => void): unknown;
|
|
39
|
+
off(event: "connect" | "remove", listener: (client: PgPoolClient) => void): unknown;
|
|
40
|
+
off(event: "error", listener: (error: Error, client: PgPoolClient) => void): unknown;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* These are the options that the wrapper gives `pg.Pool`. Each one comes from the declaration. The
|
|
44
|
+
* wrapper sets each option that has an effect on a timer, thus no default of pg decides one. A knob
|
|
45
|
+
* of pg at 0 has no timer. The wrapper writes "infinite" as 0, and it refuses a bound of 0.
|
|
46
|
+
*/
|
|
47
|
+
interface PgPoolOptions {
|
|
48
|
+
readonly host: string;
|
|
49
|
+
readonly port: number;
|
|
50
|
+
readonly database?: string | undefined;
|
|
51
|
+
readonly user?: string | undefined;
|
|
52
|
+
readonly password?: string | undefined;
|
|
53
|
+
/** The server shows this name in `pg_stat_activity`, thus the prober can join on it too. */
|
|
54
|
+
readonly application_name: string;
|
|
55
|
+
readonly max: number;
|
|
56
|
+
readonly min: number;
|
|
57
|
+
/** This time bounds the TCP connect, the startup and the authentication. It also bounds a checkout from a full pool. */
|
|
58
|
+
readonly connectionTimeoutMillis: number;
|
|
59
|
+
/** This time bounds each query on the client, from `client.query`. The client sends no cancel at its end. */
|
|
60
|
+
readonly query_timeout: number;
|
|
61
|
+
/** This time is the deadline of each statement on the server. The client sends it in the startup message. Undefined does not send it. */
|
|
62
|
+
readonly statement_timeout: number | undefined;
|
|
63
|
+
/** This time ends an idle client of the pool. 0 is no idle timer. */
|
|
64
|
+
readonly idleTimeoutMillis: number;
|
|
65
|
+
/** This time ends a client at this age from its connect, in whole seconds. 0 is no age. */
|
|
66
|
+
readonly maxLifetimeSeconds: number;
|
|
67
|
+
readonly keepAlive: boolean;
|
|
68
|
+
/** This time is the idle time of TCP keepalive. Node truncates it to whole seconds. */
|
|
69
|
+
readonly keepAliveInitialDelayMillis: number;
|
|
70
|
+
/** The idle timer and the idle sockets do not keep the process alive (A14). The lifecycle holds the process. */
|
|
71
|
+
readonly allowExitOnIdle: true;
|
|
72
|
+
}
|
|
73
|
+
/** A pool factory makes the pool of the client from its options. */
|
|
74
|
+
type PoolFactory = Factory<PgPoolOptions, PgPool>;
|
|
75
|
+
/**
|
|
76
|
+
* This factory makes a `pg.Pool`. It loads pg only when a client connects, thus a service that does
|
|
77
|
+
* not use PostgreSQL does not need pg. The specifier is a value, thus the package needs no types of pg.
|
|
78
|
+
*/
|
|
79
|
+
export declare const nodePostgres: PoolFactory;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/pg/client.d.ts
|
|
82
|
+
/**
|
|
83
|
+
* These are the knobs of the client, each a time, by the names of the ordering law where the law
|
|
84
|
+
* has them. The runtime has no defaults, thus each knob is necessary. A bound that nobody gives is
|
|
85
|
+
* "infinite", not zero. `PG_STARTING_KNOBS` gives a declaration from the cells of S1. The knobs
|
|
86
|
+
* that each client has come from the core.
|
|
87
|
+
*/
|
|
88
|
+
interface PgKnobs extends ClientKnobs {
|
|
89
|
+
/**
|
|
90
|
+
* This time bounds a new connection (`connectionTimeoutMillis`): the TCP connect, the startup and
|
|
91
|
+
* the authentication. The pool uses the same knob to bound a checkout from a full pool.
|
|
92
|
+
* At the defaults pg has no bound, and the kernel gives up on the SYNs only after 131 s (A3, O15).
|
|
93
|
+
*/
|
|
94
|
+
readonly connect_bound: Quantity;
|
|
95
|
+
/** This time bounds each query on the client (`query_timeout`). pg sends no cancel at its end. */
|
|
96
|
+
readonly request_timeout: Quantity;
|
|
97
|
+
/**
|
|
98
|
+
* This time is the deadline of each statement on the server (`statement_timeout`). The server then
|
|
99
|
+
* ends the statement with ERROR 57014, a certain outcome. "infinite" sends no deadline.
|
|
100
|
+
*/
|
|
101
|
+
readonly statement_timeout: Extent;
|
|
102
|
+
/** This time ends an idle client of the pool (`idleTimeoutMillis`). The pool sends no test on an idle client. */
|
|
103
|
+
readonly pool_idle_expiry: Extent;
|
|
104
|
+
/** This time is the idle time of TCP keepalive, in whole seconds. Node then sends 10 probes 1 s apart. */
|
|
105
|
+
readonly keepalive_idle: Extent;
|
|
106
|
+
/** This time is the age at which the pool replaces a client (`maxLifetimeSeconds`), in whole seconds. */
|
|
107
|
+
readonly max_connection_age: Extent;
|
|
108
|
+
/** This time bounds the close of the pool at the shutdown: its end, then a destroy of each socket that stays. */
|
|
109
|
+
readonly close_bound: Quantity;
|
|
110
|
+
}
|
|
111
|
+
/** A pg client spec is the declaration of one PostgreSQL client: where it connects, its pool, and its knobs. */
|
|
112
|
+
interface PgClientSpec extends ClientSpec<PgKnobs> {
|
|
113
|
+
readonly database?: string | undefined;
|
|
114
|
+
readonly user?: string | undefined;
|
|
115
|
+
/** These counts are the sizes of the pool: at most `max` clients, and an idle timer only above `min`. */
|
|
116
|
+
readonly pool: {
|
|
117
|
+
readonly max: number;
|
|
118
|
+
readonly min: number;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* These operations are the queries of the service, by name, with their idempotency. SQL text does
|
|
122
|
+
* not tell if a statement changes a state, thus the client sends again only a query that this table names.
|
|
123
|
+
*/
|
|
124
|
+
readonly operations?: Readonly<Record<string, Operation>> | undefined;
|
|
125
|
+
}
|
|
126
|
+
/** These options make a client. Without them, it uses pg, the real clock, and a dial with an SSLRequest. */
|
|
127
|
+
type PgClientOptions = ClientOptions<PoolFactory>;
|
|
128
|
+
/**
|
|
129
|
+
* A join is one connection of the pool, at its connect (D1, D2). The prober joins its kernel records
|
|
130
|
+
* to the server's view of the connection through it. The server's view is the process id of the backend.
|
|
131
|
+
*/
|
|
132
|
+
interface PgJoin extends ClientJoin {
|
|
133
|
+
/** This number is the process id of the backend, or null when the server gave none. Through a pooler, it is the id that the pooler gives. */
|
|
134
|
+
readonly backendPid: number | null;
|
|
135
|
+
}
|
|
136
|
+
/** The steps that the pg client gives a check for: the steps of each client, and a checkout from the pool (B14). */
|
|
137
|
+
type PgStep = ClientStep | "checkout";
|
|
138
|
+
/** A pg client is a dependency of a service: its declaration, its handle, its checks and its queries. */
|
|
139
|
+
interface PgClient extends Client<PgStep, PgJoin> {
|
|
140
|
+
/** This text is the state of the client, as `PG_CLIENT_MACHINE` names it. */
|
|
141
|
+
readonly status: string;
|
|
142
|
+
/**
|
|
143
|
+
* This method sends a query, and gives its outcome in three values. `operation` names the query
|
|
144
|
+
* in the table of operations. The client sends again only an idempotent operation, one time at
|
|
145
|
+
* most, after an outcome that is not certain. The second try stays in the bound of the request.
|
|
146
|
+
*/
|
|
147
|
+
query<Row = Record<string, unknown>>(operation: string, text: string, values?: readonly unknown[], options?: SendOptions): Promise<Sent<PgResult<Row>>>;
|
|
148
|
+
}
|
|
149
|
+
/** This function gives the problems of a spec: the knobs that pg cannot use. */
|
|
150
|
+
export declare const specProblems: (name: string, spec: PgClientSpec) => string[];
|
|
151
|
+
/** This function gives the options of `pg.Pool` from a spec. Each timer of pg comes from the declaration. */
|
|
152
|
+
export declare const poolOptions: (name: string, spec: PgClientSpec) => PgPoolOptions;
|
|
153
|
+
/**
|
|
154
|
+
* This dial function opens a TCP connection, sends an SSLRequest, and waits for its one byte. The
|
|
155
|
+
* server answers it before the authentication, thus the dial needs no password and opens no backend.
|
|
156
|
+
*/
|
|
157
|
+
export declare const sslRequestDial: DialFn;
|
|
158
|
+
/**
|
|
159
|
+
* This function makes a PostgreSQL client, a dependency of a service over a `pg.Pool`.
|
|
160
|
+
* - It sets each timer of pg from the declaration. The driver sends nothing again by itself, and the client
|
|
161
|
+
* sends again only an idempotent operation of its table.
|
|
162
|
+
* - It tells the outcome of a query in three values. An ERROR of the server is certain. A FATAL
|
|
163
|
+
* ends the session, thus its outcome is not certain.
|
|
164
|
+
* - It gives back a client whose query has no certain outcome with an error. The pool then ends it,
|
|
165
|
+
* thus an orphaned query does not hold the next checkout.
|
|
166
|
+
* - It listens to each error of the pool and of a client that it holds. In Node, an error with no
|
|
167
|
+
* listener throws, and library code does not end the process (A5).
|
|
168
|
+
* - It records the process id of the backend of each connection (D1).
|
|
169
|
+
*
|
|
170
|
+
* The outcomes, the second try, the queries in flight, the bounded close and the checks come from
|
|
171
|
+
* the core of the clients. This entry gives what pg does in its own way.
|
|
172
|
+
*/
|
|
173
|
+
export declare const pgClient: (name: string, spec: PgClientSpec, options?: PgClientOptions) => PgClient;
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region src/pg/machine.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* The pg client of the service as a `mark1russell7.machine/1` document. It is the pool as the
|
|
178
|
+
* wrapper sees it, not one connection: the document `node-postgres` of `@mark1russell7/machines`
|
|
179
|
+
* gives each client of the pool. The state is the outcome of the last connect:
|
|
180
|
+
* - `ready`: the last connect of the pool succeeded.
|
|
181
|
+
* - `failing`: the last connect failed. pg does not connect again by itself. The next checkout tries again.
|
|
182
|
+
*
|
|
183
|
+
* An idle client that fails and a client that the pool removes do not change the state. The pool
|
|
184
|
+
* removed that client, and the next checkout opens a new connection. A test records the transitions
|
|
185
|
+
* of the client and replays them against this document.
|
|
186
|
+
*/
|
|
187
|
+
export declare const PG_CLIENT_MACHINE: Machine;
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/pg/meets.d.ts
|
|
190
|
+
/**
|
|
191
|
+
* This function gives the manifestations that a pg client can meet, and the detectors of each, from
|
|
192
|
+
* its knobs. The cells of S1 measured each one on node-postgres 8.23.1:
|
|
193
|
+
* - A reset of a query gives ECONNRESET in 0.6 ms, and a FIN to an idle client gives EOF in 18 µs.
|
|
194
|
+
* - A frozen server and a black hole have no detector in 60 s at the defaults: pg has no timer on a query and no keepalive.
|
|
195
|
+
* - `query_timeout` ends a query in a black hole on time (9.503 s for 9.5 s).
|
|
196
|
+
* - `statement_timeout` ends a slow statement on the server with ERROR 57014 (10.002 s for 10 s).
|
|
197
|
+
*
|
|
198
|
+
* pg has no watchdog and does not test an idle client. In place of a watchdog, the pool ends an
|
|
199
|
+
* idle client at its idle timer. A later checkout then opens a new connection, which `connect_bound` bounds.
|
|
200
|
+
*/
|
|
201
|
+
export declare const pgMeetings: (name: string, knobs: PgKnobs) => Meeting[];
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/pg/starting.d.ts
|
|
204
|
+
/**
|
|
205
|
+
* This poll is the poll of the checks that `PG_STARTING_KNOBS` fits. It is `STARTING_POLL` of the
|
|
206
|
+
* core: each 5 s with a jitter of 20 %, and a timeout of 4 s (B6, O12). The poll does not depend on the driver.
|
|
207
|
+
*/
|
|
208
|
+
export declare const PG_STARTING_POLL: Poll;
|
|
209
|
+
/**
|
|
210
|
+
* These knobs are a declaration to start from, from what the cells of S1 measured on node-postgres
|
|
211
|
+
* 8.23.1 against PostgreSQL 17.11. The runtime has no defaults: a service gives these knobs, or its
|
|
212
|
+
* own. Each value holds the borders that the cells measured:
|
|
213
|
+
* - `connect_bound` 5 s: at the defaults pg has no bound, and the kernel gives up on the SYNs only
|
|
214
|
+
* after 131 s. The timer of the pool fired 7 ms late at most. Thus 5 s is in a startup budget of 30 s (O15).
|
|
215
|
+
* - `request_timeout` 9.5 s: the cells ended a query in a black hole at 9.503 s. That is in the slowest poll of 10 s (O13).
|
|
216
|
+
* - `statement_timeout` 9 s: below `request_timeout`, thus the server ends a slow statement first,
|
|
217
|
+
* with ERROR 57014 (O07). The cells measured that end 2 ms after the deadline.
|
|
218
|
+
* - `pool_idle_expiry` 10 s: the idle timer of pg-pool at its defaults, measured at 10.004 s. It is
|
|
219
|
+
* below a router that forgets an idle flow at 12 s (O03), and below a `client_idle_timeout` of PgBouncer at 12 s (O01).
|
|
220
|
+
* - `keepalive_idle` 30 s: at the defaults pg has no keepalive. This value refreshes a held idle
|
|
221
|
+
* connection through the NAT forms of the cells (240 s and 350 s).
|
|
222
|
+
* - `max_connection_age` "infinite": no cell measured an age, thus the declaration gives none.
|
|
223
|
+
* - `close_bound` 2 s: behind a black hole the end of the pool waits with no bound. The cells saw
|
|
224
|
+
* the pool emit `remove` only when the socket closes.
|
|
225
|
+
* - `retrans_giveup_time` 924.6 s: the give-up of Linux at `tcp_retries2 = 15`. The cells measured 3.120 s at `tcp_retries2 = 3`.
|
|
226
|
+
*/
|
|
227
|
+
export declare const PG_STARTING_KNOBS: PgKnobs;
|
|
228
|
+
//#endregion
|
|
229
|
+
export { type Attempt, type CheckOptions, type Client, type ClientJoin, type ClientKnobs, type ClientOptions, type ClientSocket, type ClientSpec, type ClientStep, type Detector, type DialFn, type Factory, MANIFESTATIONS, type Manifestation, type Meeting, type PgClient, type PgClientOptions, type PgClientSpec, type PgJoin, type PgKnobs, type PgPool, type PgPoolClient, type PgPoolOptions, type PgResult, type PgSocket, type PgStep, type PoolFactory, STARTING_POLL, type SendOptions, type Sent, type Situation, firstDetector, unwatched };
|
|
230
|
+
//# sourceMappingURL=pg.d.ts.map
|