@rivetkit/engine-runner 25.7.1-rc.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/.turbo/turbo-build.log +23 -0
- package/.turbo/turbo-check-types.log +5 -0
- package/.turbo/turbo-test.log +5537 -0
- package/benches/actor-lifecycle.bench.ts +190 -0
- package/benches/utils.ts +143 -0
- package/dist/mod.cjs +2044 -0
- package/dist/mod.cjs.map +1 -0
- package/dist/mod.d.cts +67 -0
- package/dist/mod.d.ts +67 -0
- package/dist/mod.js +2044 -0
- package/dist/mod.js.map +1 -0
- package/package.json +38 -0
- package/src/log.ts +11 -0
- package/src/mod.ts +1354 -0
- package/src/tunnel.ts +841 -0
- package/src/utils.ts +31 -0
- package/src/websocket-tunnel-adapter.ts +486 -0
- package/src/websocket.ts +43 -0
- package/tests/lifecycle.test.ts +596 -0
- package/tsconfig.json +13 -0
- package/tsup.config.ts +4 -0
- package/turbo.json +4 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// import { Bench } from "tinybench";
|
|
2
|
+
// import { Runner } from "@/mod";
|
|
3
|
+
// import type { ActorConfig } from "@/mod";
|
|
4
|
+
// import {
|
|
5
|
+
// createActor,
|
|
6
|
+
// destroyActor,
|
|
7
|
+
// setupBenchmarkRunner,
|
|
8
|
+
// createPromiseResolver,
|
|
9
|
+
// RIVET_ENDPOINT,
|
|
10
|
+
// } from "./utils.js";
|
|
11
|
+
// import { afterEach } from "node:test";
|
|
12
|
+
//
|
|
13
|
+
// async function runActorLifecycleBenchmark() {
|
|
14
|
+
// // Shared state for benchmarks
|
|
15
|
+
// let runner: Runner | null = null;
|
|
16
|
+
// let namespaceName: string;
|
|
17
|
+
// let runnerName: string;
|
|
18
|
+
// let createdActors: string[] = [];
|
|
19
|
+
// let wakeActorId: string | null = null;
|
|
20
|
+
// let stopped: { promise: Promise<void>; resolve: () => void };
|
|
21
|
+
// let started: { promise: Promise<void>; resolve: () => void };
|
|
22
|
+
//
|
|
23
|
+
// const bench = new Bench({
|
|
24
|
+
// time: 1000,
|
|
25
|
+
// iterations: 10,
|
|
26
|
+
// warmupTime: 0,
|
|
27
|
+
// warmupIterations: 0,
|
|
28
|
+
// throws: true,
|
|
29
|
+
// setup: async (task) => {
|
|
30
|
+
// // Setup benchmark runner
|
|
31
|
+
// console.log("Setting up benchmark runner...");
|
|
32
|
+
// stopped = createPromiseResolver<void>();
|
|
33
|
+
// started = createPromiseResolver<void>();
|
|
34
|
+
//
|
|
35
|
+
// const setup = await setupBenchmarkRunner(
|
|
36
|
+
// "lifecycle",
|
|
37
|
+
// 5054,
|
|
38
|
+
// async (
|
|
39
|
+
// _actorId: string,
|
|
40
|
+
// _generation: number,
|
|
41
|
+
// _config: ActorConfig,
|
|
42
|
+
// ) => {
|
|
43
|
+
// started.resolve();
|
|
44
|
+
// },
|
|
45
|
+
// async (_actorId: string, _generation: number) => {
|
|
46
|
+
// stopped.resolve();
|
|
47
|
+
// },
|
|
48
|
+
// );
|
|
49
|
+
// runner = setup.runner;
|
|
50
|
+
// namespaceName = setup.namespaceName;
|
|
51
|
+
// runnerName = setup.runnerName;
|
|
52
|
+
//
|
|
53
|
+
// console.log(
|
|
54
|
+
// `Benchmark setup complete. Namespace: ${namespaceName}, Runner: ${runnerName}`,
|
|
55
|
+
// );
|
|
56
|
+
// },
|
|
57
|
+
// teardown: async () => {
|
|
58
|
+
// if (runner) {
|
|
59
|
+
// await runner.shutdown(true);
|
|
60
|
+
// }
|
|
61
|
+
//
|
|
62
|
+
// // Clean up created actors from creation benchmark
|
|
63
|
+
// console.log(
|
|
64
|
+
// `Cleaning up ${createdActors.length} actors in ${namespaceName}...`,
|
|
65
|
+
// );
|
|
66
|
+
// const cleanupActor = createdActors;
|
|
67
|
+
// createdActors = [];
|
|
68
|
+
// wakeActorId = null;
|
|
69
|
+
// for (const actorId of cleanupActor) {
|
|
70
|
+
// try {
|
|
71
|
+
// await destroyActor(namespaceName, actorId);
|
|
72
|
+
// } catch (err) {
|
|
73
|
+
// console.warn(`Failed to clean up actor ${actorId}:`, err);
|
|
74
|
+
// }
|
|
75
|
+
// }
|
|
76
|
+
//
|
|
77
|
+
// console.log("Benchmark teardown complete!");
|
|
78
|
+
// },
|
|
79
|
+
// });
|
|
80
|
+
//
|
|
81
|
+
// bench.add("create actor", async () => {
|
|
82
|
+
// const actorResponse = await createActor(
|
|
83
|
+
// namespaceName,
|
|
84
|
+
// runnerName,
|
|
85
|
+
// false,
|
|
86
|
+
// );
|
|
87
|
+
// const actorId = actorResponse.actor.actor_id;
|
|
88
|
+
// createdActors.push(actorId);
|
|
89
|
+
//
|
|
90
|
+
// // Ping the actor
|
|
91
|
+
// const pingResponse = await fetch(`${RIVET_ENDPOINT}/ping`, {
|
|
92
|
+
// method: "GET",
|
|
93
|
+
// headers: {
|
|
94
|
+
// "x-rivet-target": "actor",
|
|
95
|
+
// "x-rivet-actor": actorId,
|
|
96
|
+
// },
|
|
97
|
+
// });
|
|
98
|
+
// if (!pingResponse.ok) throw "Request failed";
|
|
99
|
+
// });
|
|
100
|
+
//
|
|
101
|
+
// //bench.add(
|
|
102
|
+
// // "wake actor from sleep",
|
|
103
|
+
// // async () => {
|
|
104
|
+
// // if (!wakeActorId) throw "No wake actor ID";
|
|
105
|
+
// //
|
|
106
|
+
// // // Ping the actor
|
|
107
|
+
// // const pingResponse = await fetch(`${RIVET_ENDPOINT}/ping`, {
|
|
108
|
+
// // method: "GET",
|
|
109
|
+
// // headers: {
|
|
110
|
+
// // "x-rivet-target": "actor",
|
|
111
|
+
// // "x-rivet-actor": wakeActorId,
|
|
112
|
+
// // },
|
|
113
|
+
// // });
|
|
114
|
+
// //
|
|
115
|
+
// // if (!pingResponse.ok) {
|
|
116
|
+
// // console.error(
|
|
117
|
+
// // `Ping failed: ${pingResponse.status} ${pingResponse.statusText}`,
|
|
118
|
+
// // );
|
|
119
|
+
// // const errorText = await pingResponse.text();
|
|
120
|
+
// // console.error(`Error response: ${errorText}`);
|
|
121
|
+
// // throw `Request failed: ${pingResponse.status} ${pingResponse.statusText}`;
|
|
122
|
+
// // }
|
|
123
|
+
// // },
|
|
124
|
+
// // {
|
|
125
|
+
// // beforeEach: async () => {
|
|
126
|
+
// // // Reset promise resolvers for this iteration
|
|
127
|
+
// // started = createPromiseResolver<void>();
|
|
128
|
+
// // stopped = createPromiseResolver<void>();
|
|
129
|
+
// //
|
|
130
|
+
// // // Create the actor that will be used for wake benchmarking
|
|
131
|
+
// // console.log('Creating actor');
|
|
132
|
+
// // const wakeActorResponse = await createActor(
|
|
133
|
+
// // namespaceName,
|
|
134
|
+
// // runnerName,
|
|
135
|
+
// // false,
|
|
136
|
+
// // "wake-bench-actor",
|
|
137
|
+
// // );
|
|
138
|
+
// // wakeActorId = wakeActorResponse.actor.actor_id;
|
|
139
|
+
// // createdActors.push(wakeActorId!);
|
|
140
|
+
// //
|
|
141
|
+
// // // Wait for actor to start
|
|
142
|
+
// // await started.promise;
|
|
143
|
+
// //
|
|
144
|
+
// // // Put actor to sleep initially
|
|
145
|
+
// // runner!.sleepActor(wakeActorId!);
|
|
146
|
+
// // await stopped.promise;
|
|
147
|
+
// // },
|
|
148
|
+
// // },
|
|
149
|
+
// // // TODO(RVT-4979): Add back after sleep cycles fixed
|
|
150
|
+
// // //{
|
|
151
|
+
// // // beforeAll: async () => {
|
|
152
|
+
// // // // Create the actor that will be used for wake benchmarking
|
|
153
|
+
// // // console.log("Creating wake actor...");
|
|
154
|
+
// // // const wakeActorResponse = await createActor(
|
|
155
|
+
// // // namespaceName,
|
|
156
|
+
// // // runnerName,
|
|
157
|
+
// // // false,
|
|
158
|
+
// // // "wake-bench-actor",
|
|
159
|
+
// // // );
|
|
160
|
+
// // // wakeActorId = wakeActorResponse.actor.actor_id;
|
|
161
|
+
// // // createdActors.push(wakeActorId!);
|
|
162
|
+
// // //
|
|
163
|
+
// // // // Wait for actor to start
|
|
164
|
+
// // // await started.promise;
|
|
165
|
+
// // // },
|
|
166
|
+
// // // beforeEach: async () => {
|
|
167
|
+
// // // console.log("Putting actor to sleep...");
|
|
168
|
+
// // //
|
|
169
|
+
// // // // Put actor to sleep initially
|
|
170
|
+
// // // stopped = createPromiseResolver<void>();
|
|
171
|
+
// // // runner!.sleepActor(wakeActorId!);
|
|
172
|
+
// // // await stopped.promise;
|
|
173
|
+
// // // },
|
|
174
|
+
// // //},
|
|
175
|
+
// //);
|
|
176
|
+
//
|
|
177
|
+
// // Run the benchmark
|
|
178
|
+
// console.log("Running benchmarks...");
|
|
179
|
+
// await bench.run();
|
|
180
|
+
//
|
|
181
|
+
// // Display results
|
|
182
|
+
// console.table(bench.table());
|
|
183
|
+
//
|
|
184
|
+
// console.log("Benchmark complete!");
|
|
185
|
+
// }
|
|
186
|
+
//
|
|
187
|
+
// // Run the benchmark if this file is executed directly
|
|
188
|
+
// if (import.meta.url === `file://${process.argv[1]}`) {
|
|
189
|
+
// runActorLifecycleBenchmark();
|
|
190
|
+
// }
|
package/benches/utils.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// import { Runner } from "@/mod";
|
|
2
|
+
// import type { RunnerConfig, ActorConfig } from "@/mod";
|
|
3
|
+
//
|
|
4
|
+
// export const RIVET_ENDPOINT =
|
|
5
|
+
// process.env.RIVET_ENDPOINT ?? "http://localhost:6420";
|
|
6
|
+
//
|
|
7
|
+
// export async function createActor(
|
|
8
|
+
// namespaceName: string,
|
|
9
|
+
// runnerNameSelector: string,
|
|
10
|
+
// durable: boolean,
|
|
11
|
+
// actorName: string = "bench-actor",
|
|
12
|
+
// ): Promise<any> {
|
|
13
|
+
// const response = await fetch(
|
|
14
|
+
// `${RIVET_ENDPOINT}/actors?namespace=${namespaceName}`,
|
|
15
|
+
// {
|
|
16
|
+
// method: "POST",
|
|
17
|
+
// headers: {
|
|
18
|
+
// "Content-Type": "application/json",
|
|
19
|
+
// },
|
|
20
|
+
// body: JSON.stringify({
|
|
21
|
+
// name: actorName,
|
|
22
|
+
// input: btoa("bench-input"),
|
|
23
|
+
// runner_name_selector: runnerNameSelector,
|
|
24
|
+
// durable,
|
|
25
|
+
// }),
|
|
26
|
+
// },
|
|
27
|
+
// );
|
|
28
|
+
//
|
|
29
|
+
// if (!response.ok) {
|
|
30
|
+
// throw new Error(
|
|
31
|
+
// `Failed to create actor: ${response.status} ${response.statusText}\n${await response.text()}`,
|
|
32
|
+
// );
|
|
33
|
+
// }
|
|
34
|
+
//
|
|
35
|
+
// return response.json();
|
|
36
|
+
// }
|
|
37
|
+
//
|
|
38
|
+
// export async function destroyActor(
|
|
39
|
+
// namespaceName: string,
|
|
40
|
+
// actorId: string,
|
|
41
|
+
// ): Promise<void> {
|
|
42
|
+
// const response = await fetch(
|
|
43
|
+
// `${RIVET_ENDPOINT}/actors/${actorId}?namespace=${namespaceName}`,
|
|
44
|
+
// {
|
|
45
|
+
// method: "DELETE",
|
|
46
|
+
// },
|
|
47
|
+
// );
|
|
48
|
+
//
|
|
49
|
+
// if (!response.ok) {
|
|
50
|
+
// throw new Error(
|
|
51
|
+
// `Failed to delete actor: ${response.status} ${response.statusText}\n${await response.text()}`,
|
|
52
|
+
// );
|
|
53
|
+
// }
|
|
54
|
+
// }
|
|
55
|
+
//
|
|
56
|
+
// export async function createNamespace(
|
|
57
|
+
// name: string,
|
|
58
|
+
// displayName: string,
|
|
59
|
+
// ): Promise<any> {
|
|
60
|
+
// const response = await fetch(`${RIVET_ENDPOINT}/namespaces`, {
|
|
61
|
+
// method: "POST",
|
|
62
|
+
// headers: {
|
|
63
|
+
// "Content-Type": "application/json",
|
|
64
|
+
// },
|
|
65
|
+
// body: JSON.stringify({
|
|
66
|
+
// name,
|
|
67
|
+
// display_name: displayName,
|
|
68
|
+
// }),
|
|
69
|
+
// });
|
|
70
|
+
//
|
|
71
|
+
// if (!response.ok) {
|
|
72
|
+
// console.warn(
|
|
73
|
+
// `Failed to create namespace: ${response.status} ${response.statusText}\n${await response.text()}`,
|
|
74
|
+
// );
|
|
75
|
+
// }
|
|
76
|
+
// }
|
|
77
|
+
//
|
|
78
|
+
// export interface BenchmarkRunnerSetup {
|
|
79
|
+
// runner: Runner;
|
|
80
|
+
// namespaceName: string;
|
|
81
|
+
// runnerName: string;
|
|
82
|
+
// }
|
|
83
|
+
//
|
|
84
|
+
// export async function setupBenchmarkRunner(
|
|
85
|
+
// namespaceSuffix: string,
|
|
86
|
+
// port: number,
|
|
87
|
+
// onActorStart?: (
|
|
88
|
+
// actorId: string,
|
|
89
|
+
// generation: number,
|
|
90
|
+
// config: ActorConfig,
|
|
91
|
+
// ) => Promise<void>,
|
|
92
|
+
// onActorStop?: (actorId: string, generation: number) => Promise<void>,
|
|
93
|
+
// ): Promise<BenchmarkRunnerSetup> {
|
|
94
|
+
// const namespaceName = `bench-${crypto.randomUUID().slice(0, 8)}`;
|
|
95
|
+
// const runnerName = `bench-runner`;
|
|
96
|
+
//
|
|
97
|
+
// let runnerStartedResolver: () => void;
|
|
98
|
+
// const runnerStarted = new Promise<void>((resolve) => {
|
|
99
|
+
// runnerStartedResolver = resolve;
|
|
100
|
+
// });
|
|
101
|
+
//
|
|
102
|
+
// const config: RunnerConfig = {
|
|
103
|
+
// version: 1,
|
|
104
|
+
// endpoint: RIVET_ENDPOINT,
|
|
105
|
+
// namespace: namespaceName,
|
|
106
|
+
// addresses: { main: { host: "127.0.0.1", port } },
|
|
107
|
+
// totalSlots: 100,
|
|
108
|
+
// prepopulateActorNames: [],
|
|
109
|
+
// runnerName: runnerName,
|
|
110
|
+
// runnerKey: "default",
|
|
111
|
+
// onConnected: () => {
|
|
112
|
+
// runnerStartedResolver();
|
|
113
|
+
// },
|
|
114
|
+
// onDisconnected: () => {},
|
|
115
|
+
// fetch: async (_actorId: string, request: Request) => {
|
|
116
|
+
// return new Response("ok", { status: 200 });
|
|
117
|
+
// },
|
|
118
|
+
// onActorStart: onActorStart || (async () => {}),
|
|
119
|
+
// onActorStop: onActorStop || (async () => {}),
|
|
120
|
+
// };
|
|
121
|
+
//
|
|
122
|
+
// await createNamespace(namespaceName, `Bench ${namespaceSuffix} Namespace`);
|
|
123
|
+
// const runner = new Runner(config);
|
|
124
|
+
// runner.start();
|
|
125
|
+
// await runnerStarted;
|
|
126
|
+
//
|
|
127
|
+
// return { runner, namespaceName, runnerName };
|
|
128
|
+
// }
|
|
129
|
+
//
|
|
130
|
+
// export function createPromiseResolver<T = void>(): {
|
|
131
|
+
// promise: Promise<T>;
|
|
132
|
+
// resolve: (value: T) => void;
|
|
133
|
+
// reject: (error: any) => void;
|
|
134
|
+
// } {
|
|
135
|
+
// let resolve: (value: T) => void;
|
|
136
|
+
// let reject: (error: any) => void;
|
|
137
|
+
// const promise = new Promise<T>((res, rej) => {
|
|
138
|
+
// resolve = res;
|
|
139
|
+
// reject = rej;
|
|
140
|
+
// });
|
|
141
|
+
// return { promise, resolve: resolve!, reject: reject! };
|
|
142
|
+
// }
|
|
143
|
+
//
|