@mark1russell7/service 0.5.16 → 0.5.17
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 +4 -0
- package/build/{builder-CsSO4LzB.d.ts → builder-CfbN_nDW.d.ts} +2 -2
- package/build/{core-D8iXeoE4.d.ts → core-C8HD1stw.d.ts} +3 -3
- package/build/{dial-DJolDmOK.d.ts → dial-Bqx5jRXQ.d.ts} +2 -2
- package/build/grpc.d.ts +3 -3
- package/build/http-client.d.ts +3 -3
- package/build/http.d.ts +1 -1
- package/build/index.d.ts +4 -4
- package/build/index.js +156 -4
- package/build/index.js.map +1 -1
- package/build/{lifecycle-CMedxaQd.d.ts → lifecycle-CCDLvXLF.d.ts} +53 -2
- package/build/mongodb.d.ts +3 -3
- package/build/pg.d.ts +2 -2
- package/build/{queue-CndiCVaY.d.ts → queue-CQcMTKYX.d.ts} +2 -2
- package/build/rabbitmq.d.ts +4 -4
- package/build/redis.d.ts +2 -2
- package/build/testing.d.ts +13 -2
- package/build/testing.js +19 -1
- package/build/testing.js.map +1 -1
- package/build/websocket.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -81,6 +81,10 @@ The format of a description is `mark1russell7.service/1`.
|
|
|
81
81
|
- **The hold.** The lifecycle holds its process from its start to its exit, through `ProcessPort.hold`, as a listening socket does. The hold is one timer of the event loop, and the exit releases it. The other timers of the runtime still do not keep the process alive (A14).
|
|
82
82
|
- **Why the hold lasts to the exit.** A drain can wait on a timer that does not keep the process alive. Without the hold, Node then ends the process with the code 0 in the drain. The teardown and the declared exit code are then lost. Thus the hold does not end at the stop of the intake, and it is not a knob.
|
|
83
83
|
- **The watchdog.** `svc.watchdog(spec)` declares a check on the event loop. A blocked loop delays each timer, thus a tick that comes late by more than the threshold fails the check. A liveness window then reads the wedge of the process.
|
|
84
|
+
- **The logger.** `run({ logger })` and `start({ logger })` give each transition of the machines to a logger, as an entry with a level and fields. The logger is one sink of the same stream as `record` (`logEvents`).
|
|
85
|
+
- **The levels.** Each step of the startup, each phase with its cap, its outcome and its duration, and the exit code are `info`. A phase at its cap is `warn`, and an error of the lifecycle is `error`. The polls are `debug`.
|
|
86
|
+
- **The logger port.** A `Logger` has one method, `log(level, message, fields)`, thus an adapter to another logger is a few lines. `consoleLogger({ level })` writes to the console at `info` and above by default.
|
|
87
|
+
- **No logger.** Without a logger, the runtime writes no log, as before. `testLogger()` of `@mark1russell7/service/testing` keeps each entry, thus a test can examine the log.
|
|
84
88
|
|
|
85
89
|
## The machines
|
|
86
90
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as Clock } from "./clock-mVqhXD0b.js";
|
|
2
2
|
import { c as LimiterSpec } from "./policy-G4QJ1ZZq.js";
|
|
3
|
-
import {
|
|
3
|
+
import { $ as Coupling, E as CheckFn, Et as ExitTrigger, K as Trace, Mt as ProcessTrigger, Q as CooperativeFloor, T as StartOptions, Vt as Operation, W as Outcome, X as Check, at as Phase, bt as OperationOf, ct as ServiceDescription, d as TransportImpl, et as Dependency, ft as Poll, it as MessageTrigger, mt as Timing, n as HealthServer, o as PhaseWork, r as Lifecycle, rt as Gate, s as RunOptions, st as RepeatSignal, t as DependencyHandle, tt as ExitCodes, x as Health } from "./lifecycle-CCDLvXLF.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-CfbN_nDW.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as Backoff } from "./backoff-B-jGWVDm.js";
|
|
2
2
|
import { n as Clock } from "./clock-mVqhXD0b.js";
|
|
3
|
-
import {
|
|
4
|
-
import { n as ServiceBuilder } from "./builder-
|
|
3
|
+
import { E as CheckFn, Vt as Operation, X as Check, Y as Recorder, ct as ServiceDescription, et as Dependency, ft as Poll, lt as Step, rt as Gate, t as DependencyHandle } from "./lifecycle-CCDLvXLF.js";
|
|
4
|
+
import { n as ServiceBuilder } from "./builder-CfbN_nDW.js";
|
|
5
5
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
6
6
|
//#region src/client/meets.d.ts
|
|
7
7
|
/** A situation is what the connection did when the failure started: a command in flight, or idle. */
|
|
@@ -230,4 +230,4 @@ declare const retryProblems: (name: string, knobs: RetryKnobs) => string[];
|
|
|
230
230
|
declare const STARTING_POLL: Poll;
|
|
231
231
|
//#endregion
|
|
232
232
|
export { MANIFESTATIONS as C, firstDetector as D, Situation as E, unwatched as O, Detector as S, Meeting as T, Sent as _, ClientKnobs as a, retryProblems as b, ClientSpec as c, Factory as d, ReadyWait as f, SendOptions as g, STARTING_POLL as h, ClientJoin as i, ClientStep as l, RetrySchedule as m, CheckOptions as n, ClientOptions as o, RetryKnobs as p, Client as r, ClientSocket as s, Attempt as t, DialFn as u, readyWait as v, Manifestation as w, retrySchedule as x, retryBackoff as y };
|
|
233
|
-
//# sourceMappingURL=core-
|
|
233
|
+
//# sourceMappingURL=core-C8HD1stw.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./core-
|
|
1
|
+
import "./core-C8HD1stw.js";
|
|
2
2
|
//#region src/client/dial.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* A judge reads the bytes that the server sent so far. It gives null for a good answer, an error for
|
|
@@ -13,4 +13,4 @@ type Judge = (received: Buffer) => Error | null | "more";
|
|
|
13
13
|
declare const statusLineJudge: (accept: (status: number, line: string) => Error | null) => Judge;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { statusLineJudge as n, Judge as t };
|
|
16
|
-
//# sourceMappingURL=dial-
|
|
16
|
+
//# sourceMappingURL=dial-Bqx5jRXQ.d.ts.map
|
package/build/grpc.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as MANIFESTATIONS, D as firstDetector, E as Situation, O as unwatched, S as Detector, T as Meeting, _ as Sent, a as ClientKnobs, b as retryProblems, c as ClientSpec, d as Factory, f as ReadyWait, g as SendOptions, h as STARTING_POLL, i as ClientJoin, l as ClientStep, n as CheckOptions, o as ClientOptions, p as RetryKnobs, r as Client, s as ClientSocket, t as Attempt, u as DialFn, v as readyWait, w as Manifestation } from "./core-
|
|
3
|
-
import { t as Judge } from "./dial-
|
|
1
|
+
import { Vt as Operation, ft as Poll } from "./lifecycle-CCDLvXLF.js";
|
|
2
|
+
import { C as MANIFESTATIONS, D as firstDetector, E as Situation, O as unwatched, S as Detector, T as Meeting, _ as Sent, a as ClientKnobs, b as retryProblems, c as ClientSpec, d as Factory, f as ReadyWait, g as SendOptions, h as STARTING_POLL, i as ClientJoin, l as ClientStep, n as CheckOptions, o as ClientOptions, p as RetryKnobs, r as Client, s as ClientSocket, t as Attempt, u as DialFn, v as readyWait, w as Manifestation } from "./core-C8HD1stw.js";
|
|
3
|
+
import { t as Judge } from "./dial-Bqx5jRXQ.js";
|
|
4
4
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
5
5
|
import { Machine } from "@mark1russell7/algebra";
|
|
6
6
|
//#region src/grpc/connection.d.ts
|
package/build/http-client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as MANIFESTATIONS, D as firstDetector, E as Situation, O as unwatched, S as Detector, T as Meeting, _ as Sent, a as ClientKnobs, c as ClientSpec, d as Factory, g as SendOptions, h as STARTING_POLL, i as ClientJoin, l as ClientStep, n as CheckOptions, o as ClientOptions, r as Client, s as ClientSocket, t as Attempt, u as DialFn, w as Manifestation } from "./core-
|
|
3
|
-
import { t as Judge } from "./dial-
|
|
1
|
+
import { Vt as Operation, ft as Poll } from "./lifecycle-CCDLvXLF.js";
|
|
2
|
+
import { C as MANIFESTATIONS, D as firstDetector, E as Situation, O as unwatched, S as Detector, T as Meeting, _ as Sent, a as ClientKnobs, c as ClientSpec, d as Factory, g as SendOptions, h as STARTING_POLL, i as ClientJoin, l as ClientStep, n as CheckOptions, o as ClientOptions, r as Client, s as ClientSocket, t as Attempt, u as DialFn, w as Manifestation } from "./core-C8HD1stw.js";
|
|
3
|
+
import { t as Judge } from "./dial-Bqx5jRXQ.js";
|
|
4
4
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
5
5
|
import { Machine } from "@mark1russell7/algebra";
|
|
6
6
|
//#region src/http-client/connection.d.ts
|
package/build/http.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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-CCDLvXLF.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,12 +1,12 @@
|
|
|
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
2
|
import { a as realClock, i as platformClock, n as Clock, r as PlatformClockOptions, t as Cancel } from "./clock-mVqhXD0b.js";
|
|
3
3
|
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";
|
|
4
|
-
import { $ as
|
|
5
|
-
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-
|
|
4
|
+
import { $ as Coupling, A as EPISODES_KEPT, At as ProcessHost, B as Logger, Bt as Idempotency, C as ProbeAnswer, Ct as EXIT_SIGNALS, D as CheckMetrics, Dt as HostStream, E as CheckFn, Et as ExitTrigger, F as ConsoleTarget, Ft as isExitSignal, G as Result, H as consoleLogger, Ht as mayReissue, I as LOG_LEVELS, It as isMessageShape, J as MachineName, L as LogEntry, Lt as matchesMessage, M as HealthMetrics, Mt as ProcessTrigger, N as redact, Nt as embeddedProcess, O as DURATION_FRACTIONS, Ot as MessageShape, P as ConsoleLoggerOptions, Pt as isExitCode, Q as CooperativeFloor, R as LogFields, Rt as nodeProcess, S as HealthVerdict, St as RouteRequest, T as StartOptions, Tt as ExitSignal, U as logEvents, V as atLeast, Vt as Operation, W as Outcome, X as Check, Y as Recorder, Z as Controller, _ as RequestOptions, _t as failSpan, a as PhaseContext, at as Phase, b as CheckVerdict, bt as OperationOf, c as STAGES, ct as ServiceDescription, d as TransportImpl, dt as FailsBy, et as Dependency, f as cooperativeAbortAt, ft as Poll, g as RequestFn, gt as asWindow, h as RequestEvent, ht as asDebounce, i as LifecycleState, it as MessageTrigger, j as Episode, jt as ProcessPort, k as DurationHistogram, kt as PROCESS_TRIGGERS, l as ShutdownOptions, lt as Step, m as RequestEnd, mt as Timing, n as HealthServer, nt as FORMAT, o as PhaseWork, ot as ProgressMarks, p as stageRank, pt as Span, q as LifecycleEvent, r as Lifecycle, rt as Gate, s as RunOptions, st as RepeatSignal, t as DependencyHandle, tt as ExitCodes, u as Stage, ut as Transport, v as RequestStream, vt as heartbeatDetection, w as ProbeKind, wt as EmbeddedProcess, x as Health, xt as RoutePattern, y as RequestWork, yt as recoverSpan, z as LogLevel, zt as processPortOf } from "./lifecycle-CCDLvXLF.js";
|
|
5
|
+
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-CfbN_nDW.js";
|
|
6
6
|
import { Heartbeat, HeartbeatOptions, detectionTime, heartbeat } from "./heartbeat.js";
|
|
7
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
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
|
-
import { a as JobSource, c as QueueKnobs, d as queueDrain, f as redeliverOnce, i as JobSettle, l as RedeliveryPolicy, n as JobContext, o as QueueDrain, p as UnitRequest, r as JobFailure, s as QueueDrainOptions, t as JobAction, u as RequeueCause } from "./queue-
|
|
9
|
+
import { a as JobSource, c as QueueKnobs, d as queueDrain, f as redeliverOnce, i as JobSettle, l as RedeliveryPolicy, n as JobContext, o as QueueDrain, p as UnitRequest, r as JobFailure, s as QueueDrainOptions, t as JobAction, u as RequeueCause } from "./queue-CQcMTKYX.js";
|
|
10
10
|
import { Extent, Quantity } from "@mark1russell7/quantity";
|
|
11
11
|
import { replay } from "@mark1russell7/algebra/replay";
|
|
12
12
|
import { Machine } from "@mark1russell7/algebra";
|
|
@@ -432,5 +432,5 @@ export declare const drainMachine: (description: ServiceDescription) => Machine;
|
|
|
432
432
|
/** These are the static machines of the runtime, by the name that their events carry. */
|
|
433
433
|
export declare const MACHINES: Readonly<Record<Exclude<MachineName, "drain" | "client">, Machine>>;
|
|
434
434
|
//#endregion
|
|
435
|
-
export { type Allowed, type Backoff, type Binding, type Bound, type Cancel, type Change, type Check, type CheckFn, type CheckMetrics, type CheckVerdict, type Claim, type Clock, type Compressed, type Compression, type Controller, type ControllerBuilder, type CooperativeFloor, type Coupling, DURATION_FRACTIONS, type Decision, type DelayBand, type Dependency, type DependencyHandle, type DurationHistogram, EPISODES_KEPT, EXIT_SIGNALS, type EmbeddedProcess, type Episode, type Epochs, type Evaluated, type ExitCodes, type ExitSignal, type ExitTrigger, FORMAT, type FailsBy, type Finding, type Gate, type Health, type HealthMetrics, 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 ScenarioValue, type ScopedChange, type ServiceBuilder, type ServiceDescription, type ShutdownOptions, type Side, type SlidingWindow, type Span, type Stage, type StartOptions, type Statistic, type Step, type Stop, type StopWay, type StoreFailure, TOKEN_BUCKET_MACHINE, type TakeRequest, type TakeStep, type Term, type TimerMark, type TimerMarks, 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, queueDrain, realClock, recoverSpan, redact, redeliverOnce, replay, retryAfterSeconds, service, stageRank, watchdog };
|
|
435
|
+
export { type Allowed, type Backoff, type Binding, type Bound, type Cancel, type Change, type Check, type CheckFn, type CheckMetrics, type CheckVerdict, type Claim, type Clock, type Compressed, type Compression, type ConsoleLoggerOptions, type ConsoleTarget, type Controller, type ControllerBuilder, type CooperativeFloor, type Coupling, DURATION_FRACTIONS, type Decision, type DelayBand, type Dependency, type DependencyHandle, type DurationHistogram, EPISODES_KEPT, EXIT_SIGNALS, type EmbeddedProcess, type Episode, type Epochs, type Evaluated, type ExitCodes, type ExitSignal, type ExitTrigger, FORMAT, type FailsBy, type Finding, type Gate, type Health, type HealthMetrics, 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, LOG_LEVELS, type Lifecycle, type LifecycleEvent, type LifecycleState, type LimitPolicy, type LimitRule, type Limiter, type LimiterEviction, type LimiterSpec, type LimiterState, type LimiterStore, type LimiterStoreSpec, type LogEntry, type LogFields, type LogLevel, type Logger, 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 ScenarioValue, type ScopedChange, type ServiceBuilder, type ServiceDescription, type ShutdownOptions, type Side, type SlidingWindow, type Span, type Stage, type StartOptions, type Statistic, type Step, type Stop, type StopWay, type StoreFailure, TOKEN_BUCKET_MACHINE, type TakeRequest, type TakeStep, type Term, type TimerMark, type TimerMarks, type Timing, type TokenBucket, type Transport, type TransportImpl, type UnitRequest, type Verdict, type Watchdog, type WatchdogSpec, type WorkerKnobs, type WorkerLoop, type WorkerLoopOptions, asDebounce, asWindow, atLeast, backoffBand, backoffDelay, backoffProblems, consoleLogger, cooperativeAbortAt, daemon, decide, detectionTime, embeddedProcess, ephemeral, failSpan, freeAt, heartbeat, heartbeatDetection, idleSpan, isExitCode, isExitSignal, isMessageShape, keyedLimiter, kubernetes, limitRule, limiterMachine, limiterProblems, limiterStateOf, localDev, logEvents, longestRetryAfter, matchesMessage, mayReissue, memoryStore, nodeProcess, platformClock, processPortOf, queueDrain, realClock, recoverSpan, redact, redeliverOnce, replay, retryAfterSeconds, service, stageRank, watchdog };
|
|
436
436
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.js
CHANGED
|
@@ -609,6 +609,140 @@ const healthRuntime = (description, runs, options = {}) => {
|
|
|
609
609
|
};
|
|
610
610
|
};
|
|
611
611
|
//#endregion
|
|
612
|
+
//#region src/logger.ts
|
|
613
|
+
/** These are the levels of a log entry, from the least to the most severe. */
|
|
614
|
+
const LOG_LEVELS = [
|
|
615
|
+
"debug",
|
|
616
|
+
"info",
|
|
617
|
+
"warn",
|
|
618
|
+
"error"
|
|
619
|
+
];
|
|
620
|
+
/** This function tells if `level` is at `least` or more severe. */
|
|
621
|
+
const atLeast = (level, least) => LOG_LEVELS.indexOf(level) >= LOG_LEVELS.indexOf(least);
|
|
622
|
+
/**
|
|
623
|
+
* This function makes the console logger. It writes each entry at its level or more severe to the
|
|
624
|
+
* method of that level, with the message first and then the fields.
|
|
625
|
+
*/
|
|
626
|
+
const consoleLogger = (options = {}) => {
|
|
627
|
+
const least = options.level ?? "info";
|
|
628
|
+
return { log(level, message, fields) {
|
|
629
|
+
if (!atLeast(level, least)) return;
|
|
630
|
+
const target = options.console ?? globalThis.console;
|
|
631
|
+
if (Object.keys(fields).length === 0) target[level](message);
|
|
632
|
+
else target[level](message, fields);
|
|
633
|
+
} };
|
|
634
|
+
};
|
|
635
|
+
const seconds = (cap) => `${valueIn(cap, "s")} s`;
|
|
636
|
+
/** This function gives the exit code from the detail of an exit event, for example `exit 1`. */
|
|
637
|
+
const exitCodeOf = (detail) => {
|
|
638
|
+
const found = /^exit (\d+)$/.exec(detail ?? "");
|
|
639
|
+
return found === null ? null : Number(found[1]);
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* This function makes a recorder that writes each lifecycle event to a logger. Thus the logger is
|
|
643
|
+
* one sink of the same stream as the recorder, not a second set of calls. The levels are these:
|
|
644
|
+
* - `error`: each error of the lifecycle, and an exit at once on a repeat signal.
|
|
645
|
+
* - `warn`: a phase at its cap, a failed startup, a startup over its budget, a tripped latch and a blocked event loop.
|
|
646
|
+
* - `info`: each step of the startup, the start and the end of each phase, the exit, and each recovery.
|
|
647
|
+
* - `debug`: each other transition, for example each poll of a check.
|
|
648
|
+
* With the description, the entry of a phase also gives its cap. A failure of the logger does not stop the lifecycle.
|
|
649
|
+
*/
|
|
650
|
+
const logEvents = (logger, description) => {
|
|
651
|
+
const caps = new Map((description?.shutdown.phases ?? []).map((phase) => [phase.name, phase.cap]));
|
|
652
|
+
const startedAt = /* @__PURE__ */ new Map();
|
|
653
|
+
const write = (level, message, fields) => {
|
|
654
|
+
try {
|
|
655
|
+
logger.log(level, message, fields);
|
|
656
|
+
} catch {}
|
|
657
|
+
};
|
|
658
|
+
const phaseEnd = (event, base) => {
|
|
659
|
+
const phase = event.from;
|
|
660
|
+
const cap = caps.get(phase);
|
|
661
|
+
const begun = startedAt.get(phase);
|
|
662
|
+
const reached = event.on === "phase.cap";
|
|
663
|
+
const fields = {
|
|
664
|
+
...base,
|
|
665
|
+
phase,
|
|
666
|
+
outcome: reached ? "cap" : "done",
|
|
667
|
+
...cap === void 0 ? {} : { cap },
|
|
668
|
+
...begun === void 0 ? {} : { took: {
|
|
669
|
+
value: event.at - begun,
|
|
670
|
+
unit: "ms"
|
|
671
|
+
} }
|
|
672
|
+
};
|
|
673
|
+
if (reached) write("warn", `the phase ${phase} reached its cap${cap === void 0 ? "" : ` of ${seconds(cap)}`}`, fields);
|
|
674
|
+
else write("info", `the phase ${phase} ended in its cap`, fields);
|
|
675
|
+
};
|
|
676
|
+
const phaseStart = (event, base) => {
|
|
677
|
+
const phase = event.to;
|
|
678
|
+
const cap = caps.get(phase);
|
|
679
|
+
startedAt.set(phase, event.at);
|
|
680
|
+
write("info", `the phase ${phase} starts${cap === void 0 ? "" : `, with a cap of ${seconds(cap)}`}`, {
|
|
681
|
+
...base,
|
|
682
|
+
phase,
|
|
683
|
+
...cap === void 0 ? {} : { cap }
|
|
684
|
+
});
|
|
685
|
+
};
|
|
686
|
+
return (event) => {
|
|
687
|
+
const { machine, instance, from, to, on, at, detail } = event;
|
|
688
|
+
const base = {
|
|
689
|
+
machine,
|
|
690
|
+
instance,
|
|
691
|
+
from,
|
|
692
|
+
to,
|
|
693
|
+
on,
|
|
694
|
+
at,
|
|
695
|
+
...detail === void 0 ? {} : { detail }
|
|
696
|
+
};
|
|
697
|
+
switch (machine) {
|
|
698
|
+
case "gate":
|
|
699
|
+
if (on === "component.started") return write("info", `${detail ?? "a component"} started`, {
|
|
700
|
+
...base,
|
|
701
|
+
component: detail
|
|
702
|
+
});
|
|
703
|
+
if (on === "startup.begin") return write("info", `the startup of ${instance} begins`, base);
|
|
704
|
+
if (on === "mark-ready") return write("info", "the warm-up sweep begins", base);
|
|
705
|
+
if (on === "sweep.done") return write("info", `${instance} is ready: the startup gate is open`, base);
|
|
706
|
+
if (on === "startup.fail") return write("warn", `the startup of ${instance} failed`, base);
|
|
707
|
+
if (on === "startup.over-budget") return write("warn", `the startup of ${instance} is over its budget`, base);
|
|
708
|
+
break;
|
|
709
|
+
case "exit":
|
|
710
|
+
if (on === "error") return write("error", detail ?? "an error of the lifecycle", base);
|
|
711
|
+
if (to === "exited") {
|
|
712
|
+
const code = exitCodeOf(detail);
|
|
713
|
+
const fields = {
|
|
714
|
+
...base,
|
|
715
|
+
code
|
|
716
|
+
};
|
|
717
|
+
if (on === "exit.repeat") return write("error", `a signal came again, and ${instance} exits at once with the code ${code}`, fields);
|
|
718
|
+
return write("info", `${instance} exited with the code ${code}`, fields);
|
|
719
|
+
}
|
|
720
|
+
if (from === "running" && to === "stopping") return write("info", `the shutdown of ${instance} begins`, {
|
|
721
|
+
...base,
|
|
722
|
+
cause: detail
|
|
723
|
+
});
|
|
724
|
+
if (on === "exit.repeat") return write("info", "a trigger came again while the shutdown runs", base);
|
|
725
|
+
break;
|
|
726
|
+
case "drain":
|
|
727
|
+
if (on === "signal.abort") return write("info", `the signal of ${instance} aborts`, base);
|
|
728
|
+
if (on === "drain.cooperative-abort") return write("info", "the cooperative abort of the drain", base);
|
|
729
|
+
if (on === "phase.done" || on === "phase.cap") phaseEnd(event, base);
|
|
730
|
+
if (to !== "done" && from !== to) phaseStart(event, base);
|
|
731
|
+
else if (to === "done") write("info", `the shutdown of ${instance} ended its phases`, base);
|
|
732
|
+
return;
|
|
733
|
+
case "latch":
|
|
734
|
+
case "window":
|
|
735
|
+
if (to === "tripped" && from !== "tripped") return write("warn", `the check ${instance} tripped its latch`, base);
|
|
736
|
+
if (to === "released" && (from === "tripped" || from === "recovering")) return write("info", `the check ${instance} released its latch`, base);
|
|
737
|
+
break;
|
|
738
|
+
case "watchdog":
|
|
739
|
+
if (to === "blocked" && from !== "blocked") return write("warn", "the event loop is blocked", base);
|
|
740
|
+
if (to === "watching" && from === "blocked") return write("info", "the event loop is no longer blocked", base);
|
|
741
|
+
}
|
|
742
|
+
write("debug", `${machine} ${instance}: ${from} -> ${to} on ${on}`, base);
|
|
743
|
+
};
|
|
744
|
+
};
|
|
745
|
+
//#endregion
|
|
612
746
|
//#region src/process.ts
|
|
613
747
|
/** These are the signals that the runtime handles. */
|
|
614
748
|
const EXIT_SIGNALS = [
|
|
@@ -1820,6 +1954,22 @@ const shutdownProblems = (floor, repeat, triggers, exitCodes, messages) => {
|
|
|
1820
1954
|
}
|
|
1821
1955
|
return problems;
|
|
1822
1956
|
};
|
|
1957
|
+
/**
|
|
1958
|
+
* This function gives the options with one recorder for the recorder and the logger of the options.
|
|
1959
|
+
* Without a logger, it gives the same options.
|
|
1960
|
+
*/
|
|
1961
|
+
const withLogger = (options, description) => {
|
|
1962
|
+
if (options.logger === void 0) return options;
|
|
1963
|
+
const given = options.record;
|
|
1964
|
+
const log = logEvents(options.logger, description);
|
|
1965
|
+
return {
|
|
1966
|
+
...options,
|
|
1967
|
+
record: (event) => {
|
|
1968
|
+
given?.(event);
|
|
1969
|
+
log(event);
|
|
1970
|
+
}
|
|
1971
|
+
};
|
|
1972
|
+
};
|
|
1823
1973
|
/** This function starts the composition of a service. */
|
|
1824
1974
|
const service = (name) => {
|
|
1825
1975
|
if (name.trim().length === 0) throw new Error("a service needs a name");
|
|
@@ -1871,8 +2021,9 @@ const service = (name) => {
|
|
|
1871
2021
|
return builder;
|
|
1872
2022
|
};
|
|
1873
2023
|
/** This function makes the runtime of the declaration: its checks, and a watchdog for each spec. */
|
|
1874
|
-
const makeRuntime = (
|
|
2024
|
+
const makeRuntime = (given) => {
|
|
1875
2025
|
const description = builder.describe();
|
|
2026
|
+
const options = withLogger(given, description);
|
|
1876
2027
|
const clock = options.clock ?? realClock;
|
|
1877
2028
|
const dogs = [];
|
|
1878
2029
|
const all = new Map(runs);
|
|
@@ -1907,7 +2058,8 @@ const service = (name) => {
|
|
|
1907
2058
|
}
|
|
1908
2059
|
},
|
|
1909
2060
|
description,
|
|
1910
|
-
stopPollers
|
|
2061
|
+
stopPollers,
|
|
2062
|
+
options
|
|
1911
2063
|
};
|
|
1912
2064
|
};
|
|
1913
2065
|
const builder = {
|
|
@@ -2223,7 +2375,7 @@ const service = (name) => {
|
|
|
2223
2375
|
const ran = lifecycle(made.description, made.runtime, {
|
|
2224
2376
|
...components,
|
|
2225
2377
|
stopPollers: made.stopPollers
|
|
2226
|
-
}, options, (given) => {
|
|
2378
|
+
}, made.options, (given) => {
|
|
2227
2379
|
life = given;
|
|
2228
2380
|
});
|
|
2229
2381
|
running = ran.started.then(() => ran);
|
|
@@ -3927,6 +4079,6 @@ const MACHINES = {
|
|
|
3927
4079
|
watchdog: WATCHDOG_MACHINE
|
|
3928
4080
|
};
|
|
3929
4081
|
//#endregion
|
|
3930
|
-
export { DECLARATION_RULE, DRAIN_RULE_IDS, DURATION_FRACTIONS, EPISODES_KEPT, EXIT_MACHINE, EXIT_SIGNALS, FORMAT, GATE_MACHINE, LATCH_MACHINE, LAW_STATISTIC, LIMITER_RULES, MACHINES, PLATFORM_MARKS, POLLER_MACHINE, PROCESS_TRIGGERS, PROGRESS_RULE, SERVICE_RULES, SLIDING_WINDOW_MACHINE, STAGES, STOPS, STOP_RULE, TOKEN_BUCKET_MACHINE, WATCHDOG_MACHINE, WINDOW_MACHINE, asDebounce, asWindow, backoffBand, backoffDelay, backoffProblems, capKnob, compress, compression, compressionOf, cooperativeAbortAt, daemon, decide, detectionTime, drainMachine, embeddedProcess, ephemeral, evaluate, failSpan, freeAt, heartbeat, heartbeatDetection, idleSpan, inequalities, isExitCode, isExitSignal, isMessageShape, keyedLimiter, kubernetes, limitRule, limiterMachine, limiterProblems, limiterStateOf, lint, lintStop, localDev, longestRetryAfter, matchesMessage, mayReissue, memoryStore, nodeProcess, platformClock, processPortOf, queueDrain, realClock, recoverSpan, redact, redeliverOnce, replay, retryAfterSeconds, service, serviceBindings, stageRank, symbolsOf, verdictOf, watchdog, workerLoop };
|
|
4082
|
+
export { DECLARATION_RULE, DRAIN_RULE_IDS, DURATION_FRACTIONS, EPISODES_KEPT, EXIT_MACHINE, EXIT_SIGNALS, FORMAT, GATE_MACHINE, LATCH_MACHINE, LAW_STATISTIC, LIMITER_RULES, LOG_LEVELS, MACHINES, PLATFORM_MARKS, POLLER_MACHINE, PROCESS_TRIGGERS, PROGRESS_RULE, SERVICE_RULES, SLIDING_WINDOW_MACHINE, STAGES, STOPS, STOP_RULE, TOKEN_BUCKET_MACHINE, WATCHDOG_MACHINE, WINDOW_MACHINE, asDebounce, asWindow, atLeast, backoffBand, backoffDelay, backoffProblems, capKnob, compress, compression, compressionOf, consoleLogger, cooperativeAbortAt, daemon, decide, detectionTime, drainMachine, embeddedProcess, ephemeral, evaluate, failSpan, freeAt, heartbeat, heartbeatDetection, idleSpan, inequalities, isExitCode, isExitSignal, isMessageShape, keyedLimiter, kubernetes, limitRule, limiterMachine, limiterProblems, limiterStateOf, lint, lintStop, localDev, logEvents, longestRetryAfter, matchesMessage, mayReissue, memoryStore, nodeProcess, platformClock, processPortOf, queueDrain, realClock, recoverSpan, redact, redeliverOnce, replay, retryAfterSeconds, service, serviceBindings, stageRank, symbolsOf, verdictOf, watchdog, workerLoop };
|
|
3931
4083
|
|
|
3932
4084
|
//# sourceMappingURL=index.js.map
|