@rivetkit/engine-runner 2.1.4 → 2.1.6-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/dist/mod.cjs +51 -12
- package/dist/mod.cjs.map +1 -1
- package/dist/mod.d.cts +9 -1
- package/dist/mod.d.ts +9 -1
- package/dist/mod.js +51 -12
- package/dist/mod.js.map +1 -1
- package/package.json +2 -2
- package/src/mod.ts +68 -12
- package/src/stringify.ts +4 -0
- package/src/tunnel.ts +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivetkit/engine-runner",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6-rc.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"pino": "^9.9.5",
|
|
23
23
|
"ws": "^8.18.3",
|
|
24
24
|
"@rivetkit/virtual-websocket": "2.0.33",
|
|
25
|
-
"@rivetkit/engine-runner-protocol": "2.1.
|
|
25
|
+
"@rivetkit/engine-runner-protocol": "2.1.6-rc.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.18.1",
|
package/src/mod.ts
CHANGED
|
@@ -12,13 +12,16 @@ import {
|
|
|
12
12
|
unreachable,
|
|
13
13
|
} from "./utils";
|
|
14
14
|
import { importWebSocket } from "./websocket.js";
|
|
15
|
+
import {
|
|
16
|
+
v4 as uuidv4,
|
|
17
|
+
} from "uuid";
|
|
15
18
|
|
|
16
19
|
export type { HibernatingWebSocketMetadata };
|
|
17
20
|
export { RunnerActor, type ActorConfig };
|
|
18
21
|
export { idToStr } from "./utils";
|
|
19
22
|
|
|
20
23
|
const KV_EXPIRE: number = 30_000;
|
|
21
|
-
const PROTOCOL_VERSION: number =
|
|
24
|
+
const PROTOCOL_VERSION: number = 7;
|
|
22
25
|
|
|
23
26
|
/** Warn once the backlog significantly exceeds the server's ack batch size. */
|
|
24
27
|
const EVENT_BACKLOG_WARN_THRESHOLD = 10_000;
|
|
@@ -40,7 +43,6 @@ export interface RunnerConfig {
|
|
|
40
43
|
namespace: string;
|
|
41
44
|
totalSlots: number;
|
|
42
45
|
runnerName: string;
|
|
43
|
-
runnerKey: string;
|
|
44
46
|
prepopulateActorNames: Record<string, { metadata: Record<string, any> }>;
|
|
45
47
|
metadata?: Record<string, any>;
|
|
46
48
|
onConnected: () => void;
|
|
@@ -175,6 +177,15 @@ export interface RunnerConfig {
|
|
|
175
177
|
|
|
176
178
|
onActorStop: (actorId: string, generation: number) => Promise<void>;
|
|
177
179
|
noAutoShutdown?: boolean;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Debug option to inject artificial latency (in ms) into WebSocket
|
|
183
|
+
* communication. Messages are queued and delivered in order after the
|
|
184
|
+
* configured delay.
|
|
185
|
+
*
|
|
186
|
+
* @experimental For testing only.
|
|
187
|
+
*/
|
|
188
|
+
debugLatencyMs?: number;
|
|
178
189
|
}
|
|
179
190
|
|
|
180
191
|
export interface KvListOptions {
|
|
@@ -193,6 +204,7 @@ interface KvRequestEntry {
|
|
|
193
204
|
|
|
194
205
|
export class Runner {
|
|
195
206
|
#config: RunnerConfig;
|
|
207
|
+
#runnerKey: string = uuidv4();
|
|
196
208
|
|
|
197
209
|
get config(): RunnerConfig {
|
|
198
210
|
return this.#config;
|
|
@@ -443,6 +455,8 @@ export class Runner {
|
|
|
443
455
|
throw error;
|
|
444
456
|
}
|
|
445
457
|
|
|
458
|
+
// When changing SIGTERM/shutdown behavior, update
|
|
459
|
+
// website/src/content/docs/actors/versions.mdx (SIGTERM Handling section).
|
|
446
460
|
if (!this.#config.noAutoShutdown) {
|
|
447
461
|
if (!SIGNAL_HANDLERS.length) {
|
|
448
462
|
process.on("SIGTERM", async () => {
|
|
@@ -614,6 +628,9 @@ export class Runner {
|
|
|
614
628
|
* - All actors are stopped
|
|
615
629
|
* - The WebSocket connection is closed
|
|
616
630
|
* - The shutdown timeout is reached (120 seconds)
|
|
631
|
+
*
|
|
632
|
+
* When changing this timeout, update
|
|
633
|
+
* website/src/content/docs/actors/versions.mdx (SIGTERM Handling section).
|
|
617
634
|
*/
|
|
618
635
|
async #waitForActorsToStop(ws: WebSocket): Promise<void> {
|
|
619
636
|
const shutdownTimeout = 120_000; // 120 seconds
|
|
@@ -705,7 +722,7 @@ export class Runner {
|
|
|
705
722
|
const baseUrl = wsEndpoint.endsWith("/")
|
|
706
723
|
? wsEndpoint.slice(0, -1)
|
|
707
724
|
: wsEndpoint;
|
|
708
|
-
return `${baseUrl}/runners/connect?protocol_version=${PROTOCOL_VERSION}&namespace=${encodeURIComponent(this.#config.namespace)}&runner_key=${encodeURIComponent(this.#
|
|
725
|
+
return `${baseUrl}/runners/connect?protocol_version=${PROTOCOL_VERSION}&namespace=${encodeURIComponent(this.#config.namespace)}&runner_key=${encodeURIComponent(this.#runnerKey)}`;
|
|
709
726
|
}
|
|
710
727
|
|
|
711
728
|
// MARK: Runner protocol
|
|
@@ -735,7 +752,7 @@ export class Runner {
|
|
|
735
752
|
msg: "connecting",
|
|
736
753
|
endpoint: this.pegboardEndpoint,
|
|
737
754
|
namespace: this.#config.namespace,
|
|
738
|
-
runnerKey: this.#
|
|
755
|
+
runnerKey: this.#runnerKey,
|
|
739
756
|
hasToken: !!this.config.token,
|
|
740
757
|
});
|
|
741
758
|
|
|
@@ -823,6 +840,8 @@ export class Runner {
|
|
|
823
840
|
throw new Error(`expected binary data, got ${typeof ev.data}`);
|
|
824
841
|
}
|
|
825
842
|
|
|
843
|
+
await this.#injectLatency();
|
|
844
|
+
|
|
826
845
|
// Parse message
|
|
827
846
|
const message = protocol.decodeToClient(buf);
|
|
828
847
|
this.log?.debug({
|
|
@@ -1551,6 +1570,31 @@ export class Runner {
|
|
|
1551
1570
|
await this.#sendKvRequest(actorId, requestData);
|
|
1552
1571
|
}
|
|
1553
1572
|
|
|
1573
|
+
async kvDeleteRange(
|
|
1574
|
+
actorId: string,
|
|
1575
|
+
start: Uint8Array,
|
|
1576
|
+
end: Uint8Array,
|
|
1577
|
+
): Promise<void> {
|
|
1578
|
+
const startKey: protocol.KvKey = start.buffer.slice(
|
|
1579
|
+
start.byteOffset,
|
|
1580
|
+
start.byteOffset + start.byteLength,
|
|
1581
|
+
) as ArrayBuffer;
|
|
1582
|
+
const endKey: protocol.KvKey = end.buffer.slice(
|
|
1583
|
+
end.byteOffset,
|
|
1584
|
+
end.byteOffset + end.byteLength,
|
|
1585
|
+
) as ArrayBuffer;
|
|
1586
|
+
|
|
1587
|
+
const requestData: protocol.KvRequestData = {
|
|
1588
|
+
tag: "KvDeleteRangeRequest",
|
|
1589
|
+
val: {
|
|
1590
|
+
start: startKey,
|
|
1591
|
+
end: endKey,
|
|
1592
|
+
},
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
await this.#sendKvRequest(actorId, requestData);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1554
1598
|
async kvDrop(actorId: string): Promise<void> {
|
|
1555
1599
|
const requestData: protocol.KvRequestData = {
|
|
1556
1600
|
tag: "KvDropRequest",
|
|
@@ -1662,6 +1706,13 @@ export class Runner {
|
|
|
1662
1706
|
}
|
|
1663
1707
|
}
|
|
1664
1708
|
|
|
1709
|
+
/** Resolves after the configured debug latency, or immediately if none. */
|
|
1710
|
+
#injectLatency(): Promise<void> {
|
|
1711
|
+
const ms = this.#config.debugLatencyMs;
|
|
1712
|
+
if (!ms) return Promise.resolve();
|
|
1713
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1665
1716
|
/** Asserts WebSocket exists and is ready. */
|
|
1666
1717
|
getPegboardWebSocketIfReady(): WebSocket | undefined {
|
|
1667
1718
|
if (
|
|
@@ -1681,14 +1732,19 @@ export class Runner {
|
|
|
1681
1732
|
});
|
|
1682
1733
|
|
|
1683
1734
|
const encoded = protocol.encodeToServer(message);
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
this.
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1735
|
+
|
|
1736
|
+
// Normally synchronous. When debugLatencyMs is set, the send is
|
|
1737
|
+
// deferred but message order is preserved.
|
|
1738
|
+
this.#injectLatency().then(() => {
|
|
1739
|
+
const pegboardWebSocket = this.getPegboardWebSocketIfReady();
|
|
1740
|
+
if (pegboardWebSocket) {
|
|
1741
|
+
pegboardWebSocket.send(encoded);
|
|
1742
|
+
} else {
|
|
1743
|
+
this.log?.error({
|
|
1744
|
+
msg: "WebSocket not available or not open for sending data",
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
});
|
|
1692
1748
|
}
|
|
1693
1749
|
|
|
1694
1750
|
sendHibernatableWebSocketMessageAck(
|
package/src/stringify.ts
CHANGED
|
@@ -303,6 +303,10 @@ function stringifyKvRequestData(data: protocol.KvRequestData): string {
|
|
|
303
303
|
const { keys } = data.val;
|
|
304
304
|
return `KvDeleteRequest{keys: ${keys.length}}`;
|
|
305
305
|
}
|
|
306
|
+
case "KvDeleteRangeRequest": {
|
|
307
|
+
const { start, end } = data.val;
|
|
308
|
+
return `KvDeleteRangeRequest{start: ${stringifyArrayBuffer(start)}, end: ${stringifyArrayBuffer(end)}}`;
|
|
309
|
+
}
|
|
306
310
|
case "KvDropRequest":
|
|
307
311
|
return "KvDropRequest";
|
|
308
312
|
}
|
package/src/tunnel.ts
CHANGED
|
@@ -5,11 +5,6 @@ import type {
|
|
|
5
5
|
RequestId,
|
|
6
6
|
} from "@rivetkit/engine-runner-protocol";
|
|
7
7
|
import type { Logger } from "pino";
|
|
8
|
-
import {
|
|
9
|
-
parse as uuidparse,
|
|
10
|
-
stringify as uuidstringify,
|
|
11
|
-
v4 as uuidv4,
|
|
12
|
-
} from "uuid";
|
|
13
8
|
import { type Runner, type RunnerActor, RunnerShutdownError } from "./mod";
|
|
14
9
|
import {
|
|
15
10
|
stringifyToClientTunnelMessageKind,
|