Skip to content

Commit 1da12da

Browse files
committed
chore(rivetkit): remove warnings for graceful runner shtudown
1 parent 2d85f31 commit 1da12da

File tree

4 files changed

+77
-39
lines changed

4 files changed

+77
-39
lines changed

engine/sdks/typescript/runner/src/mod.ts

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import type { Logger } from "pino";
33
import type WebSocket from "ws";
44
import { logger, setLogger } from "./log.js";
55
import { Tunnel } from "./tunnel";
6-
import { calculateBackoff, unreachable } from "./utils";
6+
import {
7+
calculateBackoff,
8+
parseWebSocketCloseReason,
9+
unreachable,
10+
} from "./utils";
711
import { importWebSocket } from "./websocket.js";
812
import type { WebSocketTunnelAdapter } from "./websocket-tunnel-adapter";
913

@@ -430,7 +434,9 @@ export class Runner {
430434
}
431435
}
432436
} else {
433-
logger()?.warn({
437+
// This is often logged when the serverless SSE stream closes after
438+
// the runner has already shut down
439+
logger()?.debug({
434440
msg: "no runner WebSocket to shutdown or already closed",
435441
runnerId: this.runnerId,
436442
readyState: this.#pegboardWebSocket?.readyState,
@@ -483,7 +489,20 @@ export class Runner {
483489
});
484490

485491
ws.addEventListener("open", () => {
486-
logger()?.info({ msg: "connected" });
492+
if (this.#reconnectAttempt > 0) {
493+
logger()?.info({
494+
msg: "runner reconnected",
495+
namespace: this.#config.namespace,
496+
runnerName: this.#config.runnerName,
497+
reconnectAttempt: this.#reconnectAttempt,
498+
});
499+
} else {
500+
logger()?.debug({
501+
msg: "runner connected",
502+
namespace: this.#config.namespace,
503+
runnerName: this.#config.runnerName,
504+
});
505+
}
487506

488507
// Reset reconnect attempt counter on successful connection
489508
this.#reconnectAttempt = 0;
@@ -650,22 +669,30 @@ export class Runner {
650669
});
651670

652671
ws.addEventListener("close", async (ev) => {
653-
logger()?.info({
654-
msg: "connection closed",
655-
runnerId: this.runnerId,
656-
code: ev.code,
657-
reason: ev.reason.toString(),
658-
});
659-
660-
this.#config.onDisconnected(ev.code, ev.reason);
661-
662-
if (ev.reason.toString().startsWith("ws.eviction")) {
672+
const closeError = parseWebSocketCloseReason(ev.reason);
673+
if (
674+
closeError?.group === "ws" &&
675+
closeError?.error === "eviction"
676+
) {
663677
logger()?.info({
664678
msg: "runner evicted",
665679
runnerId: this.runnerId,
666680
});
667681

682+
this.#config.onDisconnected(ev.code, ev.reason);
683+
668684
await this.shutdown(true);
685+
} else {
686+
logger()?.warn({
687+
msg: "runner disconnected",
688+
namespace: this.#config.namespace,
689+
runnerName: this.#config.runnerName,
690+
code: ev.code,
691+
reason: ev.reason.toString(),
692+
closeError,
693+
});
694+
695+
this.#config.onDisconnected(ev.code, ev.reason);
669696
}
670697

671698
// Clear ping loop on close

engine/sdks/typescript/runner/src/utils.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { logger } from "./log";
2+
13
export function unreachable(x: never): never {
24
throw `Unreachable: ${x}`;
35
}
@@ -29,3 +31,36 @@ export function calculateBackoff(
2931

3032
return Math.floor(delay);
3133
}
34+
35+
export interface ParsedCloseReason {
36+
group: string;
37+
error: string;
38+
rayId?: string;
39+
}
40+
41+
/**
42+
* Parses a WebSocket close reason in the format: {group}.{error} or {group}.{error}#{ray_id}
43+
*
44+
* Examples:
45+
* - "ws.eviction#t1s80so6h3irenp8ymzltfoittcl00"
46+
* - "ws.client_closed"
47+
*
48+
* Returns undefined if the format is invalid
49+
*/
50+
export function parseWebSocketCloseReason(
51+
reason: string,
52+
): ParsedCloseReason | undefined {
53+
const [mainPart, rayId] = reason.split("#");
54+
const [group, error] = mainPart.split(".");
55+
56+
if (!group || !error) {
57+
logger()?.warn({ msg: "failed to parse close reason", reason });
58+
return undefined;
59+
}
60+
61+
return {
62+
group,
63+
error,
64+
rayId,
65+
};
66+
}

rivetkit-openapi/openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"openapi": "3.0.0",
33
"info": {
4-
"version": "2.0.22-rc.2",
4+
"version": "2.0.22",
55
"title": "RivetKit API"
66
},
77
"components": {

rivetkit-typescript/packages/rivetkit/src/drivers/engine/actor-driver.ts

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ export class EngineActorDriver implements ActorDriver {
111111
);
112112

113113
// Create runner configuration
114-
let hasDisconnected = false;
115114
const engineRunnerConfig: EngineRunnerConfig = {
116115
version: this.#version,
117116
endpoint: getEndpoint(runConfig),
@@ -125,32 +124,9 @@ export class EngineActorDriver implements ActorDriver {
125124
},
126125
prepopulateActorNames: buildActorNames(registryConfig),
127126
onConnected: () => {
128-
if (hasDisconnected) {
129-
logger().info({
130-
msg: "runner reconnected",
131-
namespace: this.#runConfig.namespace,
132-
runnerName: this.#runConfig.runnerName,
133-
});
134-
} else {
135-
logger().debug({
136-
msg: "runner connected",
137-
namespace: this.#runConfig.namespace,
138-
runnerName: this.#runConfig.runnerName,
139-
});
140-
}
141-
142127
this.#runnerStarted.resolve(undefined);
143128
},
144-
onDisconnected: (code, reason) => {
145-
logger().warn({
146-
msg: "runner disconnected",
147-
namespace: this.#runConfig.namespace,
148-
runnerName: this.#runConfig.runnerName,
149-
code,
150-
reason,
151-
});
152-
hasDisconnected = true;
153-
},
129+
onDisconnected: (_code, _reason) => {},
154130
onShutdown: () => {
155131
this.#runnerStopped.resolve(undefined);
156132
this.#isRunnerStopped = true;

0 commit comments

Comments
 (0)