rivetkit 2.3.0-rc.9 → 2.3.0
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/browser/client.d.ts +498 -62
- package/dist/browser/client.js +227 -171
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +50 -20
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.cjs +2 -2
- package/dist/tsup/actor/errors.d.cts +1 -1
- package/dist/tsup/actor/errors.d.ts +1 -1
- package/dist/tsup/actor/errors.js +1 -1
- package/dist/tsup/agent-os/index.cjs +2163 -2087
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +496 -69
- package/dist/tsup/agent-os/index.d.ts +496 -69
- package/dist/tsup/agent-os/index.js +2163 -2087
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-W7EYSYVI.js → chunk-2OTRTA3J.js} +134 -20
- package/dist/tsup/chunk-2OTRTA3J.js.map +1 -0
- package/dist/tsup/{chunk-VJFRBJVQ.cjs → chunk-3677IIOV.cjs} +138 -24
- package/dist/tsup/chunk-3677IIOV.cjs.map +1 -0
- package/dist/tsup/{chunk-4CGA6QJO.cjs → chunk-47HHIEXH.cjs} +24 -9
- package/dist/tsup/chunk-47HHIEXH.cjs.map +1 -0
- package/dist/tsup/{chunk-F3Q5BFQ6.js → chunk-4JDSFJS5.js} +66 -79
- package/dist/tsup/chunk-4JDSFJS5.js.map +1 -0
- package/dist/tsup/{chunk-GVTOE34S.cjs → chunk-7QKCIVAY.cjs} +222 -235
- package/dist/tsup/chunk-7QKCIVAY.cjs.map +1 -0
- package/dist/tsup/{chunk-CPA4Y3RG.cjs → chunk-B6VUNZUD.cjs} +10 -10
- package/dist/tsup/chunk-B6VUNZUD.cjs.map +1 -0
- package/dist/tsup/{chunk-H37XQU3I.js → chunk-BEI24WTI.js} +2 -2
- package/dist/tsup/{chunk-KIWH5H3K.js → chunk-BRP62GZC.js} +3 -3
- package/dist/tsup/chunk-BRP62GZC.js.map +1 -0
- package/dist/tsup/{chunk-T6YVRM4K.js → chunk-DPIMKYNB.js} +63 -2
- package/dist/tsup/chunk-DPIMKYNB.js.map +1 -0
- package/dist/tsup/{chunk-Y5NSCZA2.cjs → chunk-DXXJPH55.cjs} +44 -15
- package/dist/tsup/chunk-DXXJPH55.cjs.map +1 -0
- package/dist/tsup/{chunk-3YY5S6TV.js → chunk-HXUEHHJF.js} +2 -2
- package/dist/tsup/chunk-HXUEHHJF.js.map +1 -0
- package/dist/tsup/{chunk-4WPEZBK4.cjs → chunk-I4LN3FNT.cjs} +10 -10
- package/dist/tsup/chunk-I4LN3FNT.cjs.map +1 -0
- package/dist/tsup/{chunk-PCBNKI2J.js → chunk-JZ7TWV65.js} +1 -1
- package/dist/tsup/chunk-JZ7TWV65.js.map +1 -0
- package/dist/tsup/{chunk-QAZLM4WT.cjs → chunk-KORQB2IR.cjs} +3 -3
- package/dist/tsup/{chunk-QAZLM4WT.cjs.map → chunk-KORQB2IR.cjs.map} +1 -1
- package/dist/tsup/{chunk-MALSPBAF.cjs → chunk-LVTBW2RE.cjs} +3 -3
- package/dist/tsup/{chunk-MALSPBAF.cjs.map → chunk-LVTBW2RE.cjs.map} +1 -1
- package/dist/tsup/{chunk-H7P7WR2Y.js → chunk-MEHBWPLJ.js} +6 -6
- package/dist/tsup/chunk-MEHBWPLJ.js.map +1 -0
- package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-NIY3RSPX.cjs} +64 -3
- package/dist/tsup/chunk-NIY3RSPX.cjs.map +1 -0
- package/dist/tsup/{chunk-MMMEZM5J.js → chunk-P2GNQ4RN.js} +4 -4
- package/dist/tsup/chunk-P2GNQ4RN.js.map +1 -0
- package/dist/tsup/{chunk-KJTA3ATT.js → chunk-UMZVD6DQ.js} +22 -7
- package/dist/tsup/chunk-UMZVD6DQ.js.map +1 -0
- package/dist/tsup/{chunk-LD5YASJU.cjs → chunk-VE2X4KMG.cjs} +2 -2
- package/dist/tsup/{chunk-LD5YASJU.cjs.map → chunk-VE2X4KMG.cjs.map} +1 -1
- package/dist/tsup/{chunk-VRCIXJRN.js → chunk-VTTFNQQI.js} +36 -7
- package/dist/tsup/chunk-VTTFNQQI.js.map +1 -0
- package/dist/tsup/{chunk-2NDZ7JCR.cjs → chunk-ZA7FLHKH.cjs} +1 -1
- package/dist/tsup/chunk-ZA7FLHKH.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +5 -5
- package/dist/tsup/client/mod.d.ts +5 -5
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{config-0Ta55UV0.d.ts → config-BxWAw3iH.d.ts} +529 -23
- package/dist/tsup/{config-Ca8dN4cS.d.cts → config-CZQQ-mso.d.cts} +529 -23
- package/dist/tsup/{config-CxjGYf4K.d.cts → config-D49x8NpL.d.cts} +1 -2
- package/dist/tsup/{config-CxjGYf4K.d.ts → config-D49x8NpL.d.ts} +1 -2
- package/dist/tsup/{context-B_IWbWne.d.ts → context-Bw7xq8w3.d.cts} +8 -8
- package/dist/tsup/{context-CUrQ9MHc.d.cts → context-D8QA76sV.d.ts} +8 -8
- package/dist/tsup/db/drizzle.cjs +3 -3
- package/dist/tsup/db/drizzle.d.cts +1 -1
- package/dist/tsup/db/drizzle.d.ts +1 -1
- package/dist/tsup/db/drizzle.js +1 -1
- package/dist/tsup/db/mod.cjs +2 -2
- package/dist/tsup/db/mod.d.cts +2 -2
- package/dist/tsup/db/mod.d.ts +2 -2
- package/dist/tsup/db/mod.js +1 -1
- package/dist/tsup/dynamic/mod.cjs +24 -0
- package/dist/tsup/dynamic/mod.cjs.map +1 -0
- package/dist/tsup/dynamic/mod.d.cts +37 -0
- package/dist/tsup/dynamic/mod.d.ts +37 -0
- package/dist/tsup/dynamic/mod.js +24 -0
- package/dist/tsup/dynamic/mod.js.map +1 -0
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/inspector-tab/mod.cjs +173 -0
- package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
- package/dist/tsup/inspector-tab/mod.d.cts +250 -0
- package/dist/tsup/inspector-tab/mod.d.ts +250 -0
- package/dist/tsup/inspector-tab/mod.js +173 -0
- package/dist/tsup/inspector-tab/mod.js.map +1 -0
- package/dist/tsup/mod.cjs +730 -336
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +5 -5
- package/dist/tsup/mod.d.ts +5 -5
- package/dist/tsup/mod.js +633 -239
- package/dist/tsup/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +21 -18
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +4 -4
- package/dist/tsup/test/mod.d.ts +4 -4
- package/dist/tsup/test/mod.js +18 -15
- package/dist/tsup/test/mod.js.map +1 -1
- package/dist/tsup/{utils-DVekpm4I.d.cts → utils-DQosb24I.d.cts} +1 -1
- package/dist/tsup/{utils-DVekpm4I.d.ts → utils-DQosb24I.d.ts} +1 -1
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.d.cts +1 -1
- package/dist/tsup/utils.d.ts +1 -1
- package/dist/tsup/utils.js +2 -2
- package/dist/tsup/workflow/mod.cjs +307 -282
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +6 -6
- package/dist/tsup/workflow/mod.d.ts +6 -6
- package/dist/tsup/workflow/mod.js +501 -476
- package/dist/tsup/workflow/mod.js.map +1 -1
- package/package.json +32 -11
- package/src/actor/config.ts +159 -51
- package/src/actor/contexts/index.ts +7 -2
- package/src/actor/definition.ts +17 -19
- package/src/actor/driver.ts +3 -3
- package/src/actor/errors.ts +9 -3
- package/src/actor/instance/mod.ts +26 -34
- package/src/actor/keys.ts +1 -1
- package/src/actor/mod.ts +22 -20
- package/src/actor/schema.ts +2 -2
- package/src/agent-os/actor/index.ts +38 -18
- package/src/agent-os/actor/preview.ts +1 -2
- package/src/agent-os/actor/session.ts +2 -2
- package/src/agent-os/config.ts +1 -1
- package/src/agent-os/fs/database-vfs.ts +1 -1
- package/src/agent-os/index.ts +16 -15
- package/src/client/actor-common.ts +87 -54
- package/src/client/actor-conn.ts +8 -36
- package/src/client/actor-handle.ts +69 -51
- package/src/client/actor-query.ts +5 -5
- package/src/client/errors.ts +1 -1
- package/src/client/lifecycle-errors.ts +2 -4
- package/src/client/query.ts +1 -1
- package/src/client/queue.ts +8 -3
- package/src/client/raw-utils.ts +8 -6
- package/src/client/resolve-gateway-target.ts +1 -1
- package/src/client/utils.ts +2 -7
- package/src/common/actor-websocket.ts +3 -1
- package/src/common/bare/actor-persist/v1.ts +205 -163
- package/src/common/bare/actor-persist/v2.ts +265 -213
- package/src/common/bare/actor-persist/v3.ts +176 -172
- package/src/common/bare/actor-persist/v4.ts +254 -253
- package/src/common/bare/transport/v1.ts +659 -543
- package/src/common/client-protocol-versioned.ts +66 -64
- package/src/common/database/config.ts +2 -8
- package/src/common/database/native-database.ts +1 -1
- package/src/common/database/shared.ts +1 -0
- package/src/common/encoding.ts +250 -16
- package/src/common/engine.ts +28 -1
- package/src/common/eventsource.ts +1 -1
- package/src/common/inline-websocket-adapter.ts +14 -13
- package/src/common/log.ts +1 -0
- package/src/common/router.ts +13 -17
- package/src/common/utils.ts +1 -150
- package/src/common/websocket-interface.ts +1 -1
- package/src/db/mod.ts +1 -1
- package/src/devtools-loader/index.ts +4 -7
- package/src/devtools-loader/serve-devtools.ts +26 -0
- package/src/drivers/engine/actor-driver.ts +58 -56
- package/src/dynamic/instance.ts +32 -0
- package/src/dynamic/internal.ts +50 -0
- package/src/dynamic/isolate-runtime.ts +66 -0
- package/src/dynamic/mod.ts +32 -0
- package/src/engine-client/actor-http-client.ts +3 -3
- package/src/engine-client/actor-websocket-client.ts +6 -5
- package/src/engine-client/api-endpoints.ts +51 -2
- package/src/engine-client/api-utils.ts +2 -2
- package/src/engine-client/driver.ts +1 -1
- package/src/engine-client/mod.ts +6 -3
- package/src/engine-client/ws-proxy.ts +9 -4
- package/src/inspector/client.browser.ts +5 -11
- package/src/inspector/mod.ts +1 -3
- package/src/inspector-tab/mod.ts +315 -0
- package/src/registry/config/envoy.ts +1 -2
- package/src/registry/config/index.ts +40 -16
- package/src/registry/index.ts +154 -74
- package/src/registry/napi-runtime.ts +13 -2
- package/src/registry/native-validation.ts +10 -12
- package/src/registry/native.ts +367 -181
- package/src/registry/process-metrics.ts +250 -0
- package/src/registry/runtime.ts +41 -1
- package/src/registry/wasm-runtime.ts +18 -2
- package/src/registry/write-through-proxy.ts +40 -0
- package/src/serde.ts +2 -2
- package/src/serverless/configure.ts +18 -7
- package/src/test/mod.ts +11 -8
- package/src/utils/endpoint-parser.ts +1 -1
- package/src/utils/env-vars.ts +6 -0
- package/src/utils/router.ts +1 -1
- package/src/utils/serve.ts +4 -5
- package/src/utils.ts +1 -2
- package/src/workflow/context.ts +61 -33
- package/src/workflow/driver.ts +4 -6
- package/src/workflow/inspector.ts +4 -3
- package/src/workflow/mod.ts +15 -17
- package/dist/tsup/chunk-2NDZ7JCR.cjs.map +0 -1
- package/dist/tsup/chunk-3YY5S6TV.js.map +0 -1
- package/dist/tsup/chunk-4CGA6QJO.cjs.map +0 -1
- package/dist/tsup/chunk-4WPEZBK4.cjs.map +0 -1
- package/dist/tsup/chunk-CPA4Y3RG.cjs.map +0 -1
- package/dist/tsup/chunk-F3Q5BFQ6.js.map +0 -1
- package/dist/tsup/chunk-GVTOE34S.cjs.map +0 -1
- package/dist/tsup/chunk-H7P7WR2Y.js.map +0 -1
- package/dist/tsup/chunk-KIWH5H3K.js.map +0 -1
- package/dist/tsup/chunk-KJTA3ATT.js.map +0 -1
- package/dist/tsup/chunk-MMMEZM5J.js.map +0 -1
- package/dist/tsup/chunk-PCBNKI2J.js.map +0 -1
- package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
- package/dist/tsup/chunk-VJFRBJVQ.cjs.map +0 -1
- package/dist/tsup/chunk-VRCIXJRN.js.map +0 -1
- package/dist/tsup/chunk-W7EYSYVI.js.map +0 -1
- package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
- package/dist/tsup/chunk-Y5NSCZA2.cjs.map +0 -1
- /package/dist/tsup/{chunk-H37XQU3I.js.map → chunk-BEI24WTI.js.map} +0 -0
package/src/registry/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { isLocalEngineEndpoint } from "@/common/engine";
|
|
2
3
|
import { configureServerlessPool } from "@/serverless/configure";
|
|
3
|
-
import { VERSION } from "@/utils";
|
|
4
|
+
import { detectRuntime, VERSION } from "@/utils";
|
|
5
|
+
import { crossPlatformServe, loadRuntimeServeStatic } from "@/utils/serve";
|
|
4
6
|
import {
|
|
5
7
|
type RegistryActors,
|
|
6
8
|
type RegistryConfig,
|
|
@@ -44,8 +46,18 @@ export interface RegistryRoutes {
|
|
|
44
46
|
prometheusMetrics(request?: Request): Promise<Response>;
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Injectable dependencies for {@link Registry}. Production code uses the
|
|
51
|
+
* defaults. Tests override `buildConfiguredRegistry` to drive lifecycle
|
|
52
|
+
* orchestration against a fake `CoreRuntime` without an engine.
|
|
53
|
+
*/
|
|
54
|
+
export interface RegistryDeps {
|
|
55
|
+
buildConfiguredRegistry: typeof buildConfiguredRegistry;
|
|
56
|
+
}
|
|
57
|
+
|
|
47
58
|
export class Registry<A extends RegistryActors> {
|
|
48
59
|
#config: RegistryConfigInput<A>;
|
|
60
|
+
#buildConfiguredRegistry: typeof buildConfiguredRegistry;
|
|
49
61
|
public readonly routes: RegistryRoutes;
|
|
50
62
|
|
|
51
63
|
get config(): RegistryConfigInput<A> {
|
|
@@ -65,8 +77,10 @@ export class Registry<A extends RegistryActors> {
|
|
|
65
77
|
#shutdownInFlight: Promise<void> | null = null;
|
|
66
78
|
#signalHandlers: Partial<Record<ShutdownSignal, () => void>> = {};
|
|
67
79
|
|
|
68
|
-
constructor(config: RegistryConfigInput<A>) {
|
|
80
|
+
constructor(config: RegistryConfigInput<A>, deps?: Partial<RegistryDeps>) {
|
|
69
81
|
this.#config = config;
|
|
82
|
+
this.#buildConfiguredRegistry =
|
|
83
|
+
deps?.buildConfiguredRegistry ?? buildConfiguredRegistry;
|
|
70
84
|
this.routes = {
|
|
71
85
|
health: () => this.#healthRoute(),
|
|
72
86
|
metadata: () => this.#metadataRoute(),
|
|
@@ -75,16 +89,18 @@ export class Registry<A extends RegistryActors> {
|
|
|
75
89
|
};
|
|
76
90
|
}
|
|
77
91
|
|
|
78
|
-
#ensureServerlessPoolConfigured(
|
|
92
|
+
#ensureServerlessPoolConfigured(
|
|
93
|
+
config: RegistryConfig,
|
|
94
|
+
): Promise<void> | undefined {
|
|
79
95
|
if (!config.configurePool) return undefined;
|
|
80
96
|
|
|
81
97
|
if (!this.#configureServerlessPoolPromise) {
|
|
82
|
-
this.#configureServerlessPoolPromise = configureServerlessPool(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
);
|
|
98
|
+
this.#configureServerlessPoolPromise = configureServerlessPool(
|
|
99
|
+
config,
|
|
100
|
+
).catch((error) => {
|
|
101
|
+
this.#configureServerlessPoolPromise = undefined;
|
|
102
|
+
throw error;
|
|
103
|
+
});
|
|
88
104
|
this.#configureServerlessPoolPromise.catch(() => {});
|
|
89
105
|
}
|
|
90
106
|
|
|
@@ -106,7 +122,8 @@ export class Registry<A extends RegistryActors> {
|
|
|
106
122
|
this.#printWelcome(config, "serverless");
|
|
107
123
|
|
|
108
124
|
if (!this.#runtimeServerlessPromise) {
|
|
109
|
-
this.#runtimeServerlessPromise =
|
|
125
|
+
this.#runtimeServerlessPromise =
|
|
126
|
+
this.#buildConfiguredRegistry(config);
|
|
110
127
|
}
|
|
111
128
|
|
|
112
129
|
const { runtime, registry, serveConfig } =
|
|
@@ -120,12 +137,13 @@ export class Registry<A extends RegistryActors> {
|
|
|
120
137
|
serveConfig.serverlessBasePath ?? "/api/rivet",
|
|
121
138
|
);
|
|
122
139
|
const isEngineMetadataRequest =
|
|
123
|
-
request.headers.get("user-agent")?.startsWith("RivetEngine/") ??
|
|
140
|
+
request.headers.get("user-agent")?.startsWith("RivetEngine/") ??
|
|
141
|
+
false;
|
|
124
142
|
|
|
125
143
|
if (isStartRequest) {
|
|
126
144
|
try {
|
|
127
145
|
await this.#ensureServerlessPoolConfigured(config);
|
|
128
|
-
} catch (
|
|
146
|
+
} catch (_error) {
|
|
129
147
|
return new Response(
|
|
130
148
|
JSON.stringify({
|
|
131
149
|
group: "guard",
|
|
@@ -267,7 +285,7 @@ export class Registry<A extends RegistryActors> {
|
|
|
267
285
|
if (isMetadataRequest && !isEngineMetadataRequest) {
|
|
268
286
|
try {
|
|
269
287
|
await this.#ensureServerlessPoolConfigured(config);
|
|
270
|
-
} catch (
|
|
288
|
+
} catch (_error) {
|
|
271
289
|
return new Response(
|
|
272
290
|
JSON.stringify({
|
|
273
291
|
group: "guard",
|
|
@@ -303,6 +321,36 @@ export class Registry<A extends RegistryActors> {
|
|
|
303
321
|
};
|
|
304
322
|
}
|
|
305
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Starts an HTTP server that dispatches every request through the
|
|
326
|
+
* serverless handler. Uses `crossPlatformServe` to pick the right
|
|
327
|
+
* runtime (Node, Bun, Deno).
|
|
328
|
+
*
|
|
329
|
+
* @param opts.port Port to listen on. Defaults to 3000.
|
|
330
|
+
* @param opts.publicDir If set, serves static files from this directory
|
|
331
|
+
* before falling through to the registry handler.
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* ```ts
|
|
335
|
+
* await registry.listen();
|
|
336
|
+
* await registry.listen({ port: 8080, publicDir: "./public" });
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
public async listen(
|
|
340
|
+
opts: { port?: number; publicDir?: string } = {},
|
|
341
|
+
): Promise<void> {
|
|
342
|
+
const port = opts.port ?? 3000;
|
|
343
|
+
const config = this.parseConfig();
|
|
344
|
+
const runtime = detectRuntime();
|
|
345
|
+
const app = new Hono();
|
|
346
|
+
if (opts.publicDir) {
|
|
347
|
+
const serveStatic = await loadRuntimeServeStatic(runtime);
|
|
348
|
+
app.use("*", serveStatic({ root: opts.publicDir }));
|
|
349
|
+
}
|
|
350
|
+
app.all("*", (c) => this.handler(c.req.raw));
|
|
351
|
+
await crossPlatformServe(config, port, app, runtime);
|
|
352
|
+
}
|
|
353
|
+
|
|
306
354
|
/**
|
|
307
355
|
* Returns a health response suitable for mounting in a user-owned router.
|
|
308
356
|
*/
|
|
@@ -392,8 +440,11 @@ export class Registry<A extends RegistryActors> {
|
|
|
392
440
|
const candidates = [
|
|
393
441
|
this.#runtimeServerlessPromise,
|
|
394
442
|
this.#runtimeServeConfiguredPromise,
|
|
395
|
-
].filter(
|
|
396
|
-
|
|
443
|
+
].filter(
|
|
444
|
+
(
|
|
445
|
+
candidate,
|
|
446
|
+
): candidate is ReturnType<typeof buildConfiguredRegistry> =>
|
|
447
|
+
candidate !== undefined,
|
|
397
448
|
);
|
|
398
449
|
|
|
399
450
|
if (candidates.length === 0) return undefined;
|
|
@@ -405,35 +456,33 @@ export class Registry<A extends RegistryActors> {
|
|
|
405
456
|
*/
|
|
406
457
|
#startEnvoy(config: RegistryConfig, printWelcome: boolean) {
|
|
407
458
|
if (!this.#runtimeServePromise) {
|
|
408
|
-
const configuredRegistryPromise =
|
|
459
|
+
const configuredRegistryPromise =
|
|
460
|
+
this.#buildConfiguredRegistry(config);
|
|
409
461
|
this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
|
|
410
462
|
this.#runtimeServePromise = configuredRegistryPromise
|
|
411
463
|
.then(async ({ runtime, registry, serveConfig }) => {
|
|
412
464
|
await runtime.serveRegistry(registry, serveConfig);
|
|
413
465
|
})
|
|
414
|
-
.catch((
|
|
466
|
+
.catch((error) => {
|
|
415
467
|
// Always-attached catch so the stored promise never leaves a
|
|
416
468
|
// rejection unhandled. Downstream awaits (e.g. #runShutdown's
|
|
417
469
|
// Promise.race) attach their own catches and still observe
|
|
418
470
|
// resolution via the race.
|
|
419
|
-
logger().warn({
|
|
471
|
+
logger().warn({ error }, "runtime registry serve errored");
|
|
420
472
|
});
|
|
421
473
|
// Install signal handlers once an envoy lifecycle has begun. Only
|
|
422
474
|
// Mode A ever reaches here. Mode B (handler(request)) intentionally
|
|
423
475
|
// does not install handlers because it runs on Workers/Vercel/Deno
|
|
424
476
|
// Deploy where `process.on` is absent or forbidden; those platforms
|
|
425
477
|
// own their own signal policy.
|
|
426
|
-
this.#installSignalHandlers(config
|
|
478
|
+
this.#installSignalHandlers(config);
|
|
427
479
|
}
|
|
428
480
|
if (printWelcome) {
|
|
429
481
|
this.#printWelcome(config, "serverful");
|
|
430
482
|
}
|
|
431
483
|
}
|
|
432
484
|
|
|
433
|
-
#installSignalHandlers(
|
|
434
|
-
config: RegistryConfig,
|
|
435
|
-
configuredRegistryPromise: ReturnType<typeof buildConfiguredRegistry>,
|
|
436
|
-
): void {
|
|
485
|
+
#installSignalHandlers(config: RegistryConfig): void {
|
|
437
486
|
if (this.#shutdownInstalled) return;
|
|
438
487
|
if (config.shutdown?.disableSignalHandlers) return;
|
|
439
488
|
// Guard against non-Node runtimes (Workers/Edge) where `process` may
|
|
@@ -448,12 +497,7 @@ export class Registry<A extends RegistryActors> {
|
|
|
448
497
|
this.#shutdownInstalled = true;
|
|
449
498
|
|
|
450
499
|
const install = (signal: ShutdownSignal) => {
|
|
451
|
-
const handler = () =>
|
|
452
|
-
this.#onShutdownSignal(
|
|
453
|
-
signal,
|
|
454
|
-
config,
|
|
455
|
-
configuredRegistryPromise,
|
|
456
|
-
);
|
|
500
|
+
const handler = () => this.#onShutdownSignal(signal, config);
|
|
457
501
|
this.#signalHandlers[signal] = handler;
|
|
458
502
|
process.on(signal, handler);
|
|
459
503
|
};
|
|
@@ -461,37 +505,67 @@ export class Registry<A extends RegistryActors> {
|
|
|
461
505
|
install("SIGTERM");
|
|
462
506
|
}
|
|
463
507
|
|
|
464
|
-
#onShutdownSignal(
|
|
465
|
-
signal: ShutdownSignal,
|
|
466
|
-
config: RegistryConfig,
|
|
467
|
-
configuredRegistryPromise: ReturnType<typeof buildConfiguredRegistry>,
|
|
468
|
-
): void {
|
|
508
|
+
#onShutdownSignal(signal: ShutdownSignal, config: RegistryConfig): void {
|
|
469
509
|
if (this.#shutdownInFlight !== null) {
|
|
470
|
-
// Second delivery of the same (or another) shutdown signal
|
|
471
|
-
//
|
|
472
|
-
//
|
|
510
|
+
// Second delivery of the same (or another) shutdown signal, or a
|
|
511
|
+
// drain already started by an explicit `shutdown()` call. Remove
|
|
512
|
+
// our handler only, preserving any user-installed listeners. PID 1
|
|
513
|
+
// must exit directly because re-raised default signals can be
|
|
473
514
|
// swallowed by the container signal path.
|
|
474
515
|
this.#removeSignalHandlers();
|
|
475
516
|
finishShutdownSignal(signal);
|
|
476
517
|
return;
|
|
477
518
|
}
|
|
478
|
-
this.#shutdownInFlight = this.#
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
519
|
+
this.#shutdownInFlight = this.#drain(config)
|
|
520
|
+
.catch((err) => {
|
|
521
|
+
logger().warn({ err }, "shutdown error");
|
|
522
|
+
})
|
|
523
|
+
.then(() => {
|
|
524
|
+
this.#removeSignalHandlers();
|
|
525
|
+
finishShutdownSignal(signal);
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Gracefully drains all live registries.
|
|
531
|
+
*
|
|
532
|
+
* Programmatic counterpart to the SIGINT/SIGTERM handlers: tears down
|
|
533
|
+
* every live `CoreRegistry` (both `start()` and `handler()` modes) and
|
|
534
|
+
* waits for the serve promise to resolve, all bounded by the shutdown
|
|
535
|
+
* grace period. Unlike a signal-driven shutdown, this does not re-raise a
|
|
536
|
+
* signal or exit the process. The caller owns process lifetime.
|
|
537
|
+
*
|
|
538
|
+
* Idempotent: concurrent or repeated calls share a single drain. Safe to
|
|
539
|
+
* call even if nothing has been started.
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* ```ts
|
|
543
|
+
* const registry = setup({ use: { counter } });
|
|
544
|
+
* registry.start();
|
|
545
|
+
* // ...later, on your own shutdown trigger:
|
|
546
|
+
* await registry.shutdown();
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
public async shutdown(): Promise<void> {
|
|
550
|
+
if (this.#shutdownInFlight !== null) return this.#shutdownInFlight;
|
|
551
|
+
const config = this.parseConfig();
|
|
552
|
+
// Uninstall our signal handlers so a later SIGINT/SIGTERM does not
|
|
553
|
+
// re-trigger a drain on already-torn-down registries. Subsequent
|
|
554
|
+
// signals fall back to Node's default termination behavior.
|
|
555
|
+
this.#removeSignalHandlers();
|
|
556
|
+
this.#shutdownInFlight = this.#drain(config).catch((err) => {
|
|
483
557
|
logger().warn({ err }, "shutdown error");
|
|
484
558
|
});
|
|
559
|
+
return this.#shutdownInFlight;
|
|
485
560
|
}
|
|
486
561
|
|
|
487
|
-
async #
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
): Promise<void> {
|
|
562
|
+
async #drain(config: RegistryConfig): Promise<void> {
|
|
563
|
+
const modeAPromise = this.#runtimeServeConfiguredPromise;
|
|
564
|
+
const modeBPromise = this.#runtimeServerlessPromise;
|
|
565
|
+
|
|
492
566
|
const gracePeriodMs =
|
|
493
567
|
config.shutdown?.gracePeriodMs ??
|
|
494
|
-
(await this.#actorStopThresholdMs(
|
|
568
|
+
(await this.#actorStopThresholdMs(modeAPromise ?? modeBPromise)) ??
|
|
495
569
|
30 * 60 * 1000;
|
|
496
570
|
// Race the entire drain sequence (both modes + serve promise) against
|
|
497
571
|
// a single grace ceiling. By default, this uses the engine-provided
|
|
@@ -499,33 +573,33 @@ export class Registry<A extends RegistryActors> {
|
|
|
499
573
|
const drain = async () => {
|
|
500
574
|
// Shut down every live `CoreRegistry` we know about. Mode A
|
|
501
575
|
// (`start()`) and Mode B (`handler()`) each build a separate
|
|
502
|
-
// runtime registry, so one
|
|
503
|
-
//
|
|
504
|
-
const registries: Promise<void>[] = [
|
|
505
|
-
|
|
506
|
-
try {
|
|
507
|
-
const { runtime, registry } =
|
|
508
|
-
await configuredRegistryPromise;
|
|
509
|
-
await runtime.shutdownRegistry(registry);
|
|
510
|
-
} catch (err) {
|
|
511
|
-
logger().warn(
|
|
512
|
-
{ err },
|
|
513
|
-
"runtime registry shutdown errored (mode A)",
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
})(),
|
|
517
|
-
];
|
|
518
|
-
const runtimeServerlessPromise = this.#runtimeServerlessPromise;
|
|
519
|
-
if (runtimeServerlessPromise !== undefined) {
|
|
576
|
+
// runtime registry, so one drain fans out to both to honor the
|
|
577
|
+
// spec invariant "single shutdown tears down both modes".
|
|
578
|
+
const registries: Promise<void>[] = [];
|
|
579
|
+
if (modeAPromise !== undefined) {
|
|
520
580
|
registries.push(
|
|
521
581
|
(async () => {
|
|
522
582
|
try {
|
|
523
|
-
const { runtime, registry } =
|
|
524
|
-
await runtimeServerlessPromise;
|
|
583
|
+
const { runtime, registry } = await modeAPromise;
|
|
525
584
|
await runtime.shutdownRegistry(registry);
|
|
526
585
|
} catch (err) {
|
|
527
586
|
logger().warn(
|
|
528
587
|
{ err },
|
|
588
|
+
"runtime registry shutdown errored (mode A)",
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
})(),
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
if (modeBPromise !== undefined) {
|
|
595
|
+
registries.push(
|
|
596
|
+
(async () => {
|
|
597
|
+
try {
|
|
598
|
+
const { runtime, registry } = await modeBPromise;
|
|
599
|
+
await runtime.shutdownRegistry(registry);
|
|
600
|
+
} catch (err) {
|
|
601
|
+
logger().warn(
|
|
602
|
+
{ error: err },
|
|
529
603
|
"runtime registry shutdown errored (mode B)",
|
|
530
604
|
);
|
|
531
605
|
}
|
|
@@ -548,13 +622,14 @@ export class Registry<A extends RegistryActors> {
|
|
|
548
622
|
setTimeout(resolve, gracePeriodMs).unref?.(),
|
|
549
623
|
),
|
|
550
624
|
]);
|
|
551
|
-
this.#removeSignalHandlers();
|
|
552
|
-
finishShutdownSignal(signal);
|
|
553
625
|
}
|
|
554
626
|
|
|
555
627
|
async #actorStopThresholdMs(
|
|
556
|
-
configuredRegistryPromise:
|
|
628
|
+
configuredRegistryPromise:
|
|
629
|
+
| ReturnType<typeof buildConfiguredRegistry>
|
|
630
|
+
| undefined,
|
|
557
631
|
): Promise<number | undefined> {
|
|
632
|
+
if (configuredRegistryPromise === undefined) return undefined;
|
|
558
633
|
try {
|
|
559
634
|
const { runtime, registry } = await configuredRegistryPromise;
|
|
560
635
|
const thresholdMs =
|
|
@@ -625,7 +700,9 @@ export class Registry<A extends RegistryActors> {
|
|
|
625
700
|
|
|
626
701
|
if (config.endpoint) {
|
|
627
702
|
const endpointType =
|
|
628
|
-
config.
|
|
703
|
+
config.startEngine || isLocalEngineEndpoint(config.endpoint)
|
|
704
|
+
? "local native"
|
|
705
|
+
: "remote";
|
|
629
706
|
logLine("Endpoint", `${config.endpoint} (${endpointType})`);
|
|
630
707
|
}
|
|
631
708
|
|
|
@@ -646,7 +723,10 @@ function isServerlessStartRequest(request: Request, basePath: string): boolean {
|
|
|
646
723
|
return parsed.pathname === `${normalizedBase}/start`;
|
|
647
724
|
}
|
|
648
725
|
|
|
649
|
-
function isServerlessMetadataRequest(
|
|
726
|
+
function isServerlessMetadataRequest(
|
|
727
|
+
request: Request,
|
|
728
|
+
basePath: string,
|
|
729
|
+
): boolean {
|
|
650
730
|
if (request.method !== "GET") return false;
|
|
651
731
|
const parsed = new URL(request.url);
|
|
652
732
|
const normalizedBase =
|
|
@@ -23,8 +23,8 @@ import type {
|
|
|
23
23
|
RuntimeQueueNextBatchOptions,
|
|
24
24
|
RuntimeQueueTryNextBatchOptions,
|
|
25
25
|
RuntimeQueueWaitOptions,
|
|
26
|
-
RuntimeRequestSaveOpts,
|
|
27
26
|
RuntimeRegistryRouteResponse,
|
|
27
|
+
RuntimeRequestSaveOpts,
|
|
28
28
|
RuntimeServeConfig,
|
|
29
29
|
RuntimeServerlessRequest,
|
|
30
30
|
RuntimeServerlessResponseHead,
|
|
@@ -452,6 +452,12 @@ export class NapiCoreRuntime implements CoreRuntime {
|
|
|
452
452
|
return await asNativeActorContext(ctx).waitForTrackedShutdownWork();
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
async actorWaitForTrackedShutdownWorkUnbounded(
|
|
456
|
+
ctx: ActorContextHandle,
|
|
457
|
+
): Promise<void> {
|
|
458
|
+
await asNativeActorContext(ctx).waitForTrackedShutdownWorkUnbounded();
|
|
459
|
+
}
|
|
460
|
+
|
|
455
461
|
actorKeepAwake(ctx: ActorContextHandle, promise: Promise<unknown>): void {
|
|
456
462
|
asNativeActorContext(ctx).keepAwake(promise);
|
|
457
463
|
}
|
|
@@ -677,10 +683,15 @@ export class NapiCoreRuntime implements CoreRuntime {
|
|
|
677
683
|
ctx: ActorContextHandle,
|
|
678
684
|
names: string[],
|
|
679
685
|
options?: RuntimeQueueWaitOptions | undefined | null,
|
|
686
|
+
signal?: CancellationTokenHandle | undefined | null,
|
|
680
687
|
): Promise<void> {
|
|
681
688
|
await asNativeActorContext(ctx)
|
|
682
689
|
.queue()
|
|
683
|
-
.waitForNamesAvailable(
|
|
690
|
+
.waitForNamesAvailable(
|
|
691
|
+
names,
|
|
692
|
+
options,
|
|
693
|
+
signal ? asNativeCancellationToken(signal) : signal,
|
|
694
|
+
);
|
|
684
695
|
}
|
|
685
696
|
|
|
686
697
|
async actorQueueEnqueueAndWait(
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { RivetError } from "@/actor/errors";
|
|
2
2
|
import {
|
|
3
|
+
type EventSchemaConfig,
|
|
3
4
|
isEventSchemaDefinition,
|
|
4
5
|
isQueueSchemaDefinition,
|
|
5
6
|
isStandardSchema,
|
|
6
|
-
validateSchemaSync,
|
|
7
|
-
type EventSchemaConfig,
|
|
8
7
|
type PrimitiveSchema,
|
|
9
8
|
type QueueSchemaConfig,
|
|
9
|
+
validateSchemaSync,
|
|
10
10
|
} from "@/actor/schema";
|
|
11
11
|
|
|
12
12
|
const CONN_PARAMS_KEY = "__conn_params__";
|
|
@@ -126,19 +126,17 @@ export function validateQueueComplete(
|
|
|
126
126
|
response,
|
|
127
127
|
);
|
|
128
128
|
if (!result.success) {
|
|
129
|
-
throw validationError(
|
|
129
|
+
throw validationError(
|
|
130
|
+
`queue \`${name}\` completion response`,
|
|
131
|
+
result.issues,
|
|
132
|
+
);
|
|
130
133
|
}
|
|
131
134
|
return result.data;
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
function validationError(target: string, issues: unknown[]): RivetError {
|
|
135
|
-
return new RivetError(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
public: true,
|
|
141
|
-
metadata: { issues },
|
|
142
|
-
},
|
|
143
|
-
);
|
|
138
|
+
return new RivetError("actor", "validation_error", `Invalid ${target}`, {
|
|
139
|
+
public: true,
|
|
140
|
+
metadata: { issues },
|
|
141
|
+
});
|
|
144
142
|
}
|