@jami-studio/core 0.92.26 → 0.92.27
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/observability/store.ts +1313 -1321
- package/corpus/core/src/shared/init-memo.ts +94 -0
- package/dist/observability/store.d.ts +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +311 -316
- package/dist/observability/store.js.map +1 -1
- package/dist/shared/init-memo.d.ts +34 -0
- package/dist/shared/init-memo.d.ts.map +1 -0
- package/dist/shared/init-memo.js +80 -0
- package/dist/shared/init-memo.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workerd-safe memoization for module-scope init promises.
|
|
3
|
+
*
|
|
4
|
+
* Nearly every SQL-backed store memoizes its table-creation promise at module
|
|
5
|
+
* scope (`let _initPromise`). On Cloudflare Workers (workerd) that pattern has
|
|
6
|
+
* a lethal failure mode: workerd cancels a request's pending I/O the moment
|
|
7
|
+
* its response returns, so an init promise CREATED during an early-responding
|
|
8
|
+
* request (auth probe, 404) FREEZES forever — and every later caller that
|
|
9
|
+
* awaits the memo hangs permanently. Proven live: `ensureObservabilityTables`
|
|
10
|
+
* frozen by a `get-session`-first ordering wedged every agent chat run at
|
|
11
|
+
* "Starting agent" on the unified Cloudflare runtime.
|
|
12
|
+
*
|
|
13
|
+
* `createInitMemo` keeps the single-flight memo semantics everywhere, and on
|
|
14
|
+
* workerd adds two layers of defense:
|
|
15
|
+
* 1. The init promise is tied to the creating request's lifetime via
|
|
16
|
+
* `__cf_ctx.waitUntil`, so workerd keeps its I/O alive to completion
|
|
17
|
+
* even when the response returns first (same remedy as the plugin-init
|
|
18
|
+
* freeze fix in framework-request-handler.ts).
|
|
19
|
+
* 2. Awaits on a still-pending memo are bounded; on timeout the memo is
|
|
20
|
+
* re-run under the CURRENT (live) request. Init bodies are idempotent
|
|
21
|
+
* (CREATE TABLE IF NOT EXISTS / guarded ALTERs), so a re-run is safe.
|
|
22
|
+
*
|
|
23
|
+
* On Node the behavior is identical to the raw memo pattern (single flight,
|
|
24
|
+
* failed init clears the memo so the next caller retries).
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { isCloudflareRuntime } from "./runtime.js";
|
|
28
|
+
|
|
29
|
+
/** How long a pending memo may be awaited on workerd before it is presumed
|
|
30
|
+
* frozen and re-run. Long enough for a slow cold init (Neon DDL over HTTP),
|
|
31
|
+
* short enough that a frozen memo degrades to a slow call, not a hang. */
|
|
32
|
+
export const INIT_MEMO_FROZEN_RETRY_MS = 15_000;
|
|
33
|
+
|
|
34
|
+
const FROZEN = Symbol("init-memo-frozen");
|
|
35
|
+
|
|
36
|
+
export function createInitMemo(
|
|
37
|
+
init: () => Promise<void>,
|
|
38
|
+
options?: { frozenRetryMs?: number; label?: string },
|
|
39
|
+
): () => Promise<void> {
|
|
40
|
+
const frozenRetryMs = options?.frozenRetryMs ?? INIT_MEMO_FROZEN_RETRY_MS;
|
|
41
|
+
let promise: Promise<void> | undefined;
|
|
42
|
+
let settled = false;
|
|
43
|
+
|
|
44
|
+
const start = (): Promise<void> => {
|
|
45
|
+
settled = false;
|
|
46
|
+
const p = init().then(
|
|
47
|
+
() => {
|
|
48
|
+
settled = true;
|
|
49
|
+
},
|
|
50
|
+
(err) => {
|
|
51
|
+
// Failed init must not be memoized — the next caller retries.
|
|
52
|
+
promise = undefined;
|
|
53
|
+
throw err;
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
// Keep the init's I/O alive past the creating request's response on
|
|
57
|
+
// workerd. The extra catch keeps waitUntil from surfacing the rejection
|
|
58
|
+
// twice; callers still see it through the memoized promise.
|
|
59
|
+
try {
|
|
60
|
+
(
|
|
61
|
+
globalThis as {
|
|
62
|
+
__cf_ctx?: { waitUntil?: (p: Promise<unknown>) => void };
|
|
63
|
+
}
|
|
64
|
+
).__cf_ctx?.waitUntil?.(p.catch(() => {}));
|
|
65
|
+
} catch {
|
|
66
|
+
/* not on Cloudflare — nothing to extend */
|
|
67
|
+
}
|
|
68
|
+
return p;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return async (): Promise<void> => {
|
|
72
|
+
if (!promise) promise = start();
|
|
73
|
+
if (settled || !isCloudflareRuntime()) return promise;
|
|
74
|
+
|
|
75
|
+
// workerd + still pending: the memo may belong to a completed request
|
|
76
|
+
// whose I/O was frozen. Bounded wait, then re-run under this request.
|
|
77
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
78
|
+
const raced = await Promise.race([
|
|
79
|
+
promise,
|
|
80
|
+
new Promise<typeof FROZEN>((resolve) => {
|
|
81
|
+
timer = setTimeout(() => resolve(FROZEN), frozenRetryMs);
|
|
82
|
+
}),
|
|
83
|
+
]).finally(() => {
|
|
84
|
+
if (timer) clearTimeout(timer);
|
|
85
|
+
});
|
|
86
|
+
if (raced !== FROZEN) return;
|
|
87
|
+
|
|
88
|
+
console.warn(
|
|
89
|
+
`[agent-native] init memo${options?.label ? ` (${options.label})` : ""} still pending after ${frozenRetryMs}ms — presumed frozen by a completed request; re-running under the current request`,
|
|
90
|
+
);
|
|
91
|
+
promise = start();
|
|
92
|
+
return promise;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TraceSpan, TraceSummary, FeedbackEntry, SatisfactionScore, EvalResult, EvalDataset, Experiment, ExperimentAssignment, ExperimentMetricResult } from "./types.js";
|
|
2
|
-
export declare
|
|
2
|
+
export declare const ensureObservabilityTables: () => Promise<void>;
|
|
3
3
|
export declare function insertTraceSpan(span: TraceSpan): Promise<void>;
|
|
4
4
|
export declare function upsertTraceSummary(summary: TraceSummary): Promise<void>;
|
|
5
5
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/observability/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/observability/store.ts"],"names":[],"mappings":"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"}
|