@nimbus-sh/platform 0.8.0 → 0.8.1
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/dist/limits.d.ts +2 -2
- package/dist/limits.js +2 -2
- package/dist/module-source.d.ts +31 -0
- package/dist/module-source.d.ts.map +1 -0
- package/dist/module-source.js +52 -0
- package/dist/retry.d.ts +2 -2
- package/dist/retry.js +2 -2
- package/dist/wave-writer.d.ts +21 -1
- package/dist/wave-writer.d.ts.map +1 -1
- package/dist/wave-writer.js +44 -2
- package/package.json +1 -1
- package/src/limits.ts +2 -2
- package/src/module-source.ts +57 -0
- package/src/retry.ts +2 -2
- package/src/wave-writer.ts +45 -2
package/dist/limits.d.ts
CHANGED
|
@@ -74,14 +74,14 @@ export declare const BLOCK_CONCURRENCY_CANCEL_MS = 30000;
|
|
|
74
74
|
*/
|
|
75
75
|
export declare const RESIDENT_KEEPALIVE_MS = 5000;
|
|
76
76
|
/**
|
|
77
|
-
* How long the keep-alive holds a
|
|
77
|
+
* How long the keep-alive holds a resident after its last client traffic.
|
|
78
78
|
*
|
|
79
79
|
* The keep-alive exists so a quiet process survives while its user is
|
|
80
80
|
* present. Unbounded, it made every abandoned session with a dev server
|
|
81
81
|
* run forever: the probe suite's cancelled runs left staging with resident
|
|
82
82
|
* watchers polling `stat` at ~7.5/s in the isolate every session shares,
|
|
83
83
|
* and launches that pass on a fresh Worker reset there (2026-09-22). Past
|
|
84
|
-
* this grace
|
|
84
|
+
* this grace without runtime client traffic, even with idle sockets, the session idles
|
|
85
85
|
* out as it did before the keep-alive, and the launch journal re-drives
|
|
86
86
|
* the process when a client returns. Long enough for a tab reload.
|
|
87
87
|
*/
|
package/dist/limits.js
CHANGED
|
@@ -87,14 +87,14 @@ export const BLOCK_CONCURRENCY_CANCEL_MS = 30_000;
|
|
|
87
87
|
*/
|
|
88
88
|
export const RESIDENT_KEEPALIVE_MS = 5_000;
|
|
89
89
|
/**
|
|
90
|
-
* How long the keep-alive holds a
|
|
90
|
+
* How long the keep-alive holds a resident after its last client traffic.
|
|
91
91
|
*
|
|
92
92
|
* The keep-alive exists so a quiet process survives while its user is
|
|
93
93
|
* present. Unbounded, it made every abandoned session with a dev server
|
|
94
94
|
* run forever: the probe suite's cancelled runs left staging with resident
|
|
95
95
|
* watchers polling `stat` at ~7.5/s in the isolate every session shares,
|
|
96
96
|
* and launches that pass on a fresh Worker reset there (2026-09-22). Past
|
|
97
|
-
* this grace
|
|
97
|
+
* this grace without runtime client traffic, even with idle sockets, the session idles
|
|
98
98
|
* out as it did before the keep-alive, and the launch journal re-drives
|
|
99
99
|
* the process when a client returns. Long enough for a tab reload.
|
|
100
100
|
*/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** A deployed source asset: its digest, not its pathname, is its identity. */
|
|
2
|
+
export interface ModuleSourceAsset {
|
|
3
|
+
path: string;
|
|
4
|
+
sha256: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ModuleSourceEnv {
|
|
7
|
+
ASSETS?: {
|
|
8
|
+
fetch(request: Request): Promise<Response>;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Source already verified against its deployment pin. Shared across generated programs. */
|
|
12
|
+
export declare class ImmutableModuleSource {
|
|
13
|
+
readonly asset: ModuleSourceAsset;
|
|
14
|
+
readonly byteLength: number;
|
|
15
|
+
readonly text: string;
|
|
16
|
+
constructor(bytes: ArrayBuffer | Uint8Array, asset: ModuleSourceAsset);
|
|
17
|
+
}
|
|
18
|
+
export type ModuleSourcePart = string | ImmutableModuleSource;
|
|
19
|
+
export type ModuleSourceRecipe = (string | ModuleSourceAsset)[];
|
|
20
|
+
/** A generated module retains its immutable pieces until the Loader needs its complete text. */
|
|
21
|
+
export declare class ModuleSource {
|
|
22
|
+
readonly parts: readonly ModuleSourcePart[];
|
|
23
|
+
private joined;
|
|
24
|
+
readonly byteLength: number;
|
|
25
|
+
constructor(parts: readonly ModuleSourcePart[]);
|
|
26
|
+
get text(): string;
|
|
27
|
+
recipe(): ModuleSourceRecipe;
|
|
28
|
+
}
|
|
29
|
+
/** Template interpolation without flattening immutable runtime libraries into process-owned text. */
|
|
30
|
+
export declare function moduleSource(strings: TemplateStringsArray, ...values: (string | number | boolean | null | undefined | ImmutableModuleSource | ModuleSource)[]): ModuleSource;
|
|
31
|
+
//# sourceMappingURL=module-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-source.d.ts","sourceRoot":"","sources":["../src/module-source.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;CACzD;AAED,4FAA4F;AAC5F,qBAAa,qBAAqB;IAGa,QAAQ,CAAC,KAAK,EAAE,iBAAiB;IAF9E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,KAAK,EAAE,WAAW,GAAG,UAAU,EAAW,KAAK,EAAE,iBAAiB;CAI/E;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,qBAAqB,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC,EAAE,CAAC;AAEhE,gGAAgG;AAChG,qBAAa,YAAY;IAGX,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE;IAFvD,OAAO,CAAC,MAAM,CAAqB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBACP,KAAK,EAAE,SAAS,gBAAgB,EAAE;IAGvD,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,MAAM,IAAI,kBAAkB;CAG7B;AAED,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,qBAAqB,GAAG,YAAY,CAAC,EAAE,GAAG,YAAY,CAiB5K"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Source already verified against its deployment pin. Shared across generated programs. */
|
|
2
|
+
export class ImmutableModuleSource {
|
|
3
|
+
asset;
|
|
4
|
+
byteLength;
|
|
5
|
+
text;
|
|
6
|
+
constructor(bytes, asset) {
|
|
7
|
+
this.asset = asset;
|
|
8
|
+
this.text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
9
|
+
this.byteLength = bytes.byteLength;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** A generated module retains its immutable pieces until the Loader needs its complete text. */
|
|
13
|
+
export class ModuleSource {
|
|
14
|
+
parts;
|
|
15
|
+
joined;
|
|
16
|
+
byteLength;
|
|
17
|
+
constructor(parts) {
|
|
18
|
+
this.parts = parts;
|
|
19
|
+
this.byteLength = parts.reduce((bytes, part) => bytes + (typeof part === 'string' ? new TextEncoder().encode(part).byteLength : part.byteLength), 0);
|
|
20
|
+
}
|
|
21
|
+
get text() {
|
|
22
|
+
return this.joined ??= this.parts.map((part) => typeof part === 'string' ? part : part.text).join('');
|
|
23
|
+
}
|
|
24
|
+
recipe() {
|
|
25
|
+
return this.parts.map((part) => typeof part === 'string' ? part : part.asset);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Template interpolation without flattening immutable runtime libraries into process-owned text. */
|
|
29
|
+
export function moduleSource(strings, ...values) {
|
|
30
|
+
const parts = [];
|
|
31
|
+
const append = (part) => {
|
|
32
|
+
if (part === '')
|
|
33
|
+
return;
|
|
34
|
+
const last = parts.length - 1;
|
|
35
|
+
const previous = parts[last];
|
|
36
|
+
if (typeof part === 'string' && typeof previous === 'string')
|
|
37
|
+
parts[last] = previous + part;
|
|
38
|
+
else
|
|
39
|
+
parts.push(part);
|
|
40
|
+
};
|
|
41
|
+
for (const [i, literal] of strings.entries()) {
|
|
42
|
+
append(literal);
|
|
43
|
+
if (i === values.length)
|
|
44
|
+
continue;
|
|
45
|
+
const value = values[i];
|
|
46
|
+
if (value instanceof ModuleSource)
|
|
47
|
+
value.parts.forEach(append);
|
|
48
|
+
else
|
|
49
|
+
append(value instanceof ImmutableModuleSource ? value : String(value));
|
|
50
|
+
}
|
|
51
|
+
return new ModuleSource(parts);
|
|
52
|
+
}
|
package/dist/retry.d.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
|
|
13
13
|
* that failed together do not try again together.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* A facet carries these same functions and their dependencies in its
|
|
16
|
+
* build-time compiled task expression (the npm install facet does).
|
|
17
17
|
*/
|
|
18
18
|
/**
|
|
19
19
|
* The wait before re-try `attempt` (0-based, the try that just failed):
|
package/dist/retry.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
|
|
13
13
|
* that failed together do not try again together.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* A facet carries these same functions and their dependencies in its
|
|
16
|
+
* build-time compiled task expression (the npm install facet does).
|
|
17
17
|
*/
|
|
18
18
|
/**
|
|
19
19
|
* The wait before re-try `attempt` (0-based, the try that just failed):
|
package/dist/wave-writer.d.ts
CHANGED
|
@@ -319,7 +319,9 @@ export declare class WaveWriter<Meta = undefined> {
|
|
|
319
319
|
/**
|
|
320
320
|
* The epoch this writer's waves are fenced under: opened before its first
|
|
321
321
|
* wave, and again once half of WAVE_EPOCH_TTL_MS has passed, so a wave is
|
|
322
|
-
* never sent under an epoch about to close.
|
|
322
|
+
* never sent under an epoch about to close. Opened under the lost-call
|
|
323
|
+
* policy (openWaveEpoch); an open that failed even so is not the writer's
|
|
324
|
+
* epoch, and the next wave opens again.
|
|
323
325
|
*/
|
|
324
326
|
private currentEpoch;
|
|
325
327
|
/** The directories the buffered records publish, shallowest first. */
|
|
@@ -366,6 +368,24 @@ export interface WaveTimers {
|
|
|
366
368
|
* W7 producer sends: the wave writer, and a process's filesystem client.
|
|
367
369
|
*/
|
|
368
370
|
export declare function sendWaveAttempts(options: WaveAttempts): Promise<unknown>;
|
|
371
|
+
/**
|
|
372
|
+
* Open a writer epoch (`open`: the supervisor's openWaveWriter, or a
|
|
373
|
+
* process's openWriter), again while the call is lost or shed, under a
|
|
374
|
+
* wave's lost-call policy and budget (isLostFencedCall,
|
|
375
|
+
* LOST_CALL_RESEND_BACKOFF_MS). Re-opening is safe: an open the session
|
|
376
|
+
* never ran issued nothing, and one whose answer was lost issued an epoch
|
|
377
|
+
* nothing is sent under, which closes at WAVE_EPOCH_TTL_MS. Anything else
|
|
378
|
+
* it answered is its verdict. A shed open would otherwise fail every write
|
|
379
|
+
* the epoch was for, unsent: measured, create-next-app lost 31 of 42
|
|
380
|
+
* packages to one.
|
|
381
|
+
*/
|
|
382
|
+
export declare function openWaveEpoch(open: () => Promise<string | null>, options?: {
|
|
383
|
+
retry?: {
|
|
384
|
+
backoffMs: readonly number[];
|
|
385
|
+
};
|
|
386
|
+
resent?: (lost: Record<string, string | number>) => void;
|
|
387
|
+
timers?: WaveTimers;
|
|
388
|
+
}): Promise<string | null>;
|
|
369
389
|
/** A wave's encoded bytes as each attempt's stream (in SEND_SLICE_BYTES pieces, each a copy). */
|
|
370
390
|
export declare function waveAttemptsOf(bytes: Uint8Array): () => ReadableStream<Uint8Array>;
|
|
371
391
|
export declare function createWaveWriter<Meta = undefined>(options: WaveWriterOptions<Meta>): WaveWriter<Meta>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wave-writer.d.ts","sourceRoot":"","sources":["../src/wave-writer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"wave-writer.d.ts","sourceRoot":"","sources":["../src/wave-writer.ts"],"names":[],"mappings":"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"}
|
package/dist/wave-writer.js
CHANGED
|
@@ -657,7 +657,9 @@ export class WaveWriter {
|
|
|
657
657
|
/**
|
|
658
658
|
* The epoch this writer's waves are fenced under: opened before its first
|
|
659
659
|
* wave, and again once half of WAVE_EPOCH_TTL_MS has passed, so a wave is
|
|
660
|
-
* never sent under an epoch about to close.
|
|
660
|
+
* never sent under an epoch about to close. Opened under the lost-call
|
|
661
|
+
* policy (openWaveEpoch); an open that failed even so is not the writer's
|
|
662
|
+
* epoch, and the next wave opens again.
|
|
661
663
|
*/
|
|
662
664
|
async currentEpoch() {
|
|
663
665
|
const supervisor = this.options.supervisor;
|
|
@@ -668,7 +670,16 @@ export class WaveWriter {
|
|
|
668
670
|
if (held === null || (held.writer !== null && now - held.openedAt >= WAVE_EPOCH_TTL_MS / 2)) {
|
|
669
671
|
// Called as a method of the supervisor, never through .call/.apply:
|
|
670
672
|
// on an RPC stub those are remote method names too.
|
|
671
|
-
|
|
673
|
+
const opening = openWaveEpoch(() => supervisor.openWaveWriter(), {
|
|
674
|
+
...(this.options.retry === undefined ? {} : { retry: this.options.retry }),
|
|
675
|
+
resent: (lost) => {
|
|
676
|
+
this.counters.retries++;
|
|
677
|
+
this.options.onResend?.(lost);
|
|
678
|
+
},
|
|
679
|
+
}).then((writer) => ({ writer, openedAt: now }));
|
|
680
|
+
this.epoch = opening;
|
|
681
|
+
opening.catch(() => { if (this.epoch === opening)
|
|
682
|
+
this.epoch = null; });
|
|
672
683
|
}
|
|
673
684
|
return (await this.epoch).writer;
|
|
674
685
|
}
|
|
@@ -759,6 +770,37 @@ export async function sendWaveAttempts(options) {
|
|
|
759
770
|
}
|
|
760
771
|
}
|
|
761
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Open a writer epoch (`open`: the supervisor's openWaveWriter, or a
|
|
775
|
+
* process's openWriter), again while the call is lost or shed, under a
|
|
776
|
+
* wave's lost-call policy and budget (isLostFencedCall,
|
|
777
|
+
* LOST_CALL_RESEND_BACKOFF_MS). Re-opening is safe: an open the session
|
|
778
|
+
* never ran issued nothing, and one whose answer was lost issued an epoch
|
|
779
|
+
* nothing is sent under, which closes at WAVE_EPOCH_TTL_MS. Anything else
|
|
780
|
+
* it answered is its verdict. A shed open would otherwise fail every write
|
|
781
|
+
* the epoch was for, unsent: measured, create-next-app lost 31 of 42
|
|
782
|
+
* packages to one.
|
|
783
|
+
*/
|
|
784
|
+
export async function openWaveEpoch(open, options = {}) {
|
|
785
|
+
const backoffMs = options.retry?.backoffMs ?? LOST_CALL_RESEND_BACKOFF_MS;
|
|
786
|
+
const timers = options.timers ?? GLOBAL_TIMERS;
|
|
787
|
+
for (let attempt = 0;; attempt++) {
|
|
788
|
+
try {
|
|
789
|
+
return await open();
|
|
790
|
+
}
|
|
791
|
+
catch (error) {
|
|
792
|
+
if (!isLostFencedCall(error) || attempt >= backoffMs.length)
|
|
793
|
+
throw error;
|
|
794
|
+
options.resent?.(lostCallAttributes({
|
|
795
|
+
operation: 'openWaveWriter',
|
|
796
|
+
attempt: attempt + 1,
|
|
797
|
+
of: backoffMs.length,
|
|
798
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
799
|
+
}));
|
|
800
|
+
await new Promise((resolve) => { timers.setTimeout(resolve, retryDelayMs(backoffMs, attempt)); });
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
762
804
|
/** A wave's encoded bytes as each attempt's stream (in SEND_SLICE_BYTES pieces, each a copy). */
|
|
763
805
|
export function waveAttemptsOf(bytes) {
|
|
764
806
|
return piecesOf(bytes, SEND_SLICE_BYTES);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimbus-sh/platform",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "The measured Cloudflare platform truths Nimbus is built on \u2014 error taxonomy, limits tables, budget coordination, and wire-format primitives, with zero runtime dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
package/src/limits.ts
CHANGED
|
@@ -101,14 +101,14 @@ export const BLOCK_CONCURRENCY_CANCEL_MS = 30_000;
|
|
|
101
101
|
export const RESIDENT_KEEPALIVE_MS = 5_000;
|
|
102
102
|
|
|
103
103
|
/**
|
|
104
|
-
* How long the keep-alive holds a
|
|
104
|
+
* How long the keep-alive holds a resident after its last client traffic.
|
|
105
105
|
*
|
|
106
106
|
* The keep-alive exists so a quiet process survives while its user is
|
|
107
107
|
* present. Unbounded, it made every abandoned session with a dev server
|
|
108
108
|
* run forever: the probe suite's cancelled runs left staging with resident
|
|
109
109
|
* watchers polling `stat` at ~7.5/s in the isolate every session shares,
|
|
110
110
|
* and launches that pass on a fresh Worker reset there (2026-09-22). Past
|
|
111
|
-
* this grace
|
|
111
|
+
* this grace without runtime client traffic, even with idle sockets, the session idles
|
|
112
112
|
* out as it did before the keep-alive, and the launch journal re-drives
|
|
113
113
|
* the process when a client returns. Long enough for a tab reload.
|
|
114
114
|
*/
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** A deployed source asset: its digest, not its pathname, is its identity. */
|
|
2
|
+
export interface ModuleSourceAsset {
|
|
3
|
+
path: string;
|
|
4
|
+
sha256: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ModuleSourceEnv {
|
|
8
|
+
ASSETS?: { fetch(request: Request): Promise<Response> };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Source already verified against its deployment pin. Shared across generated programs. */
|
|
12
|
+
export class ImmutableModuleSource {
|
|
13
|
+
readonly byteLength: number;
|
|
14
|
+
readonly text: string;
|
|
15
|
+
constructor(bytes: ArrayBuffer | Uint8Array, readonly asset: ModuleSourceAsset) {
|
|
16
|
+
this.text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
17
|
+
this.byteLength = bytes.byteLength;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ModuleSourcePart = string | ImmutableModuleSource;
|
|
22
|
+
export type ModuleSourceRecipe = (string | ModuleSourceAsset)[];
|
|
23
|
+
|
|
24
|
+
/** A generated module retains its immutable pieces until the Loader needs its complete text. */
|
|
25
|
+
export class ModuleSource {
|
|
26
|
+
private joined: string | undefined;
|
|
27
|
+
readonly byteLength: number;
|
|
28
|
+
constructor(readonly parts: readonly ModuleSourcePart[]) {
|
|
29
|
+
this.byteLength = parts.reduce((bytes, part) => bytes + (typeof part === 'string' ? new TextEncoder().encode(part).byteLength : part.byteLength), 0);
|
|
30
|
+
}
|
|
31
|
+
get text(): string {
|
|
32
|
+
return this.joined ??= this.parts.map((part) => typeof part === 'string' ? part : part.text).join('');
|
|
33
|
+
}
|
|
34
|
+
recipe(): ModuleSourceRecipe {
|
|
35
|
+
return this.parts.map((part) => typeof part === 'string' ? part : part.asset);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Template interpolation without flattening immutable runtime libraries into process-owned text. */
|
|
40
|
+
export function moduleSource(strings: TemplateStringsArray, ...values: (string | number | boolean | null | undefined | ImmutableModuleSource | ModuleSource)[]): ModuleSource {
|
|
41
|
+
const parts: ModuleSourcePart[] = [];
|
|
42
|
+
const append = (part: ModuleSourcePart) => {
|
|
43
|
+
if (part === '') return;
|
|
44
|
+
const last = parts.length - 1;
|
|
45
|
+
const previous = parts[last];
|
|
46
|
+
if (typeof part === 'string' && typeof previous === 'string') parts[last] = previous + part;
|
|
47
|
+
else parts.push(part);
|
|
48
|
+
};
|
|
49
|
+
for (const [i, literal] of strings.entries()) {
|
|
50
|
+
append(literal);
|
|
51
|
+
if (i === values.length) continue;
|
|
52
|
+
const value = values[i];
|
|
53
|
+
if (value instanceof ModuleSource) value.parts.forEach(append);
|
|
54
|
+
else append(value instanceof ImmutableModuleSource ? value : String(value));
|
|
55
|
+
}
|
|
56
|
+
return new ModuleSource(parts);
|
|
57
|
+
}
|
package/src/retry.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
|
|
13
13
|
* that failed together do not try again together.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* A facet carries these same functions and their dependencies in its
|
|
16
|
+
* build-time compiled task expression (the npm install facet does).
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
/**
|
package/src/wave-writer.ts
CHANGED
|
@@ -820,7 +820,9 @@ export class WaveWriter<Meta = undefined> {
|
|
|
820
820
|
/**
|
|
821
821
|
* The epoch this writer's waves are fenced under: opened before its first
|
|
822
822
|
* wave, and again once half of WAVE_EPOCH_TTL_MS has passed, so a wave is
|
|
823
|
-
* never sent under an epoch about to close.
|
|
823
|
+
* never sent under an epoch about to close. Opened under the lost-call
|
|
824
|
+
* policy (openWaveEpoch); an open that failed even so is not the writer's
|
|
825
|
+
* epoch, and the next wave opens again.
|
|
824
826
|
*/
|
|
825
827
|
private async currentEpoch(): Promise<string | null> {
|
|
826
828
|
const supervisor = this.options.supervisor;
|
|
@@ -830,7 +832,15 @@ export class WaveWriter<Meta = undefined> {
|
|
|
830
832
|
if (held === null || (held.writer !== null && now - held.openedAt >= WAVE_EPOCH_TTL_MS / 2)) {
|
|
831
833
|
// Called as a method of the supervisor, never through .call/.apply:
|
|
832
834
|
// on an RPC stub those are remote method names too.
|
|
833
|
-
|
|
835
|
+
const opening = openWaveEpoch(() => supervisor.openWaveWriter!(), {
|
|
836
|
+
...(this.options.retry === undefined ? {} : { retry: this.options.retry }),
|
|
837
|
+
resent: (lost) => {
|
|
838
|
+
this.counters.retries++;
|
|
839
|
+
this.options.onResend?.(lost);
|
|
840
|
+
},
|
|
841
|
+
}).then((writer) => ({ writer, openedAt: now }));
|
|
842
|
+
this.epoch = opening;
|
|
843
|
+
opening.catch(() => { if (this.epoch === opening) this.epoch = null; });
|
|
834
844
|
}
|
|
835
845
|
return (await this.epoch!).writer;
|
|
836
846
|
}
|
|
@@ -943,6 +953,39 @@ export async function sendWaveAttempts(options: WaveAttempts): Promise<unknown>
|
|
|
943
953
|
}
|
|
944
954
|
}
|
|
945
955
|
|
|
956
|
+
/**
|
|
957
|
+
* Open a writer epoch (`open`: the supervisor's openWaveWriter, or a
|
|
958
|
+
* process's openWriter), again while the call is lost or shed, under a
|
|
959
|
+
* wave's lost-call policy and budget (isLostFencedCall,
|
|
960
|
+
* LOST_CALL_RESEND_BACKOFF_MS). Re-opening is safe: an open the session
|
|
961
|
+
* never ran issued nothing, and one whose answer was lost issued an epoch
|
|
962
|
+
* nothing is sent under, which closes at WAVE_EPOCH_TTL_MS. Anything else
|
|
963
|
+
* it answered is its verdict. A shed open would otherwise fail every write
|
|
964
|
+
* the epoch was for, unsent: measured, create-next-app lost 31 of 42
|
|
965
|
+
* packages to one.
|
|
966
|
+
*/
|
|
967
|
+
export async function openWaveEpoch(
|
|
968
|
+
open: () => Promise<string | null>,
|
|
969
|
+
options: { retry?: { backoffMs: readonly number[] }; resent?: (lost: Record<string, string | number>) => void; timers?: WaveTimers } = {},
|
|
970
|
+
): Promise<string | null> {
|
|
971
|
+
const backoffMs = options.retry?.backoffMs ?? LOST_CALL_RESEND_BACKOFF_MS;
|
|
972
|
+
const timers = options.timers ?? GLOBAL_TIMERS;
|
|
973
|
+
for (let attempt = 0; ; attempt++) {
|
|
974
|
+
try {
|
|
975
|
+
return await open();
|
|
976
|
+
} catch (error) {
|
|
977
|
+
if (!isLostFencedCall(error) || attempt >= backoffMs.length) throw error;
|
|
978
|
+
options.resent?.(lostCallAttributes({
|
|
979
|
+
operation: 'openWaveWriter',
|
|
980
|
+
attempt: attempt + 1,
|
|
981
|
+
of: backoffMs.length,
|
|
982
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
983
|
+
}));
|
|
984
|
+
await new Promise<void>((resolve) => { timers.setTimeout(resolve, retryDelayMs(backoffMs, attempt)); });
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
946
989
|
/** A wave's encoded bytes as each attempt's stream (in SEND_SLICE_BYTES pieces, each a copy). */
|
|
947
990
|
export function waveAttemptsOf(bytes: Uint8Array): () => ReadableStream<Uint8Array> {
|
|
948
991
|
return piecesOf(bytes, SEND_SLICE_BYTES);
|