From 681e6913a8568e9d90756edb30fd10ff41421fcf Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Thu, 9 Apr 2026 03:06:24 -0700 Subject: [PATCH 1/5] fix(rivetkit): temporarily disable HWS for action/event connections The gateway tunnel ping (ToRunnerPing) is not handled for serverless TS runners since there is no Rust pegboard-runner bridge to respond with ToGatewayPong. This causes the gateway to close every WebSocket with ws.downstream_closed after 30s, triggering a reconnect cycle. Disable hibernation on PATH_CONNECT WebSockets until the engine implements ping/pong for serverless runners. --- .../packages/rivetkit/src/drivers/engine/actor-driver.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rivetkit-typescript/packages/rivetkit/src/drivers/engine/actor-driver.ts b/rivetkit-typescript/packages/rivetkit/src/drivers/engine/actor-driver.ts index 409c583ecb..feee90b0c4 100644 --- a/rivetkit-typescript/packages/rivetkit/src/drivers/engine/actor-driver.ts +++ b/rivetkit-typescript/packages/rivetkit/src/drivers/engine/actor-driver.ts @@ -1078,7 +1078,10 @@ export class EngineActorDriver implements ActorDriver { requestId: idToStr(requestId), }); if (path === PATH_CONNECT) { - return true; + // Temporarily disable HWS for action/event connections. + // The gateway tunnel ping is not handled for serverless TS + // runners, causing ws.downstream_closed every ~30s. + return false; } else if ( path === PATH_WEBSOCKET_BASE || path.startsWith(PATH_WEBSOCKET_PREFIX) From db7985fed710c9bd0b3b8f18dd944c2f122d3d0d Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Fri, 10 Apr 2026 15:22:09 -0700 Subject: [PATCH 2/5] chore(examples/sandbox): run as persistent runner instead of serverless --- examples/sandbox/Dockerfile | 3 --- examples/sandbox/package.json | 6 +++--- examples/sandbox/src/server.ts | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/examples/sandbox/Dockerfile b/examples/sandbox/Dockerfile index 48152a1273..94dfc63c3e 100644 --- a/examples/sandbox/Dockerfile +++ b/examples/sandbox/Dockerfile @@ -11,10 +11,7 @@ COPY shared/typescript/ ./shared/typescript/ RUN pnpm install --frozen-lockfile RUN mkdir -p rivetkit-openapi rivetkit-asyncapi -RUN pnpm build --filter=sandbox -COPY examples/sandbox/public ./examples/sandbox/dist/public WORKDIR /app/examples/sandbox -EXPOSE 8080 CMD ["pnpm", "start"] diff --git a/examples/sandbox/package.json b/examples/sandbox/package.json index 026e70e7a4..08b40c0e6d 100644 --- a/examples/sandbox/package.json +++ b/examples/sandbox/package.json @@ -5,10 +5,10 @@ "type": "module", "packageManager": "pnpm@10.13.1", "scripts": { - "dev": "vite", + "dev": "tsx --watch src/server.ts", "check-types": "echo 'skipped - workflow history types broken'", - "build": "vite build && vite build --mode server", - "start": "srvx dist/server.js", + "build": "echo 'no build step - running via tsx'", + "start": "tsx src/server.ts", "benchmark": "tsx scripts/benchmark.ts", "db:generate": "find src/actors -name drizzle.config.ts -exec drizzle-kit generate --config {} \\;" }, diff --git a/examples/sandbox/src/server.ts b/examples/sandbox/src/server.ts index ce03591313..8260069847 100644 --- a/examples/sandbox/src/server.ts +++ b/examples/sandbox/src/server.ts @@ -1,3 +1,3 @@ import { registry } from "./index.ts"; -export default registry.serve(); +registry.start(); From 10bb9591d4d342bd41b16298ad51ff24831ddeaa Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Fri, 10 Apr 2026 15:25:37 -0700 Subject: [PATCH 3/5] fix(examples/sandbox): build rivetkit in docker before runtime --- examples/sandbox/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/sandbox/Dockerfile b/examples/sandbox/Dockerfile index 94dfc63c3e..422fceeeac 100644 --- a/examples/sandbox/Dockerfile +++ b/examples/sandbox/Dockerfile @@ -11,6 +11,7 @@ COPY shared/typescript/ ./shared/typescript/ RUN pnpm install --frozen-lockfile RUN mkdir -p rivetkit-openapi rivetkit-asyncapi +RUN pnpm build --filter=rivetkit... WORKDIR /app/examples/sandbox From 6e8e2c4006c9234c11f95dec056b64e3a7777237 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Fri, 10 Apr 2026 15:27:32 -0700 Subject: [PATCH 4/5] fix(examples/sandbox): read drizzle migration sql at runtime for tsx compatibility --- .../sqlite-drizzle/drizzle/migrations.js | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js b/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js index 23ed81f26d..7b9779628f 100644 --- a/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js +++ b/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js @@ -1,10 +1,14 @@ -import journal from './meta/_journal.json'; -import m0000 from './0000_left_wrecking_crew.sql'; +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname, join } from "node:path"; +import journal from './meta/_journal.json' with { type: 'json' }; - export default { - journal, - migrations: { - m0000 - } +const __dirname = dirname(fileURLToPath(import.meta.url)); +const m0000 = readFileSync(join(__dirname, '0000_left_wrecking_crew.sql'), 'utf-8'); + +export default { + journal, + migrations: { + m0000 } - \ No newline at end of file +} From 192bbe4102eb1392821491567e592e233c3bbf86 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Fri, 10 Apr 2026 18:50:51 -0700 Subject: [PATCH 5/5] chore(examples/sandbox): split runner and serverless entries for dual deploy --- examples/sandbox/Dockerfile | 6 +++++- examples/sandbox/package.json | 6 +++--- .../actors/state/sqlite-drizzle/drizzle/migrations.js | 11 ++++++----- examples/sandbox/src/server-runner.ts | 3 +++ examples/sandbox/src/server.ts | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 examples/sandbox/src/server-runner.ts diff --git a/examples/sandbox/Dockerfile b/examples/sandbox/Dockerfile index 422fceeeac..ecc8040e47 100644 --- a/examples/sandbox/Dockerfile +++ b/examples/sandbox/Dockerfile @@ -12,7 +12,11 @@ COPY shared/typescript/ ./shared/typescript/ RUN pnpm install --frozen-lockfile RUN mkdir -p rivetkit-openapi rivetkit-asyncapi RUN pnpm build --filter=rivetkit... +RUN pnpm --filter=sandbox run build WORKDIR /app/examples/sandbox -CMD ["pnpm", "start"] +EXPOSE 8080 +ENV PORT=8080 + +CMD ["sh", "-c", "if [ \"$SANDBOX_MODE\" = \"serverless\" ]; then srvx dist/server.js; else tsx src/server-runner.ts; fi"] diff --git a/examples/sandbox/package.json b/examples/sandbox/package.json index 08b40c0e6d..7650d58acd 100644 --- a/examples/sandbox/package.json +++ b/examples/sandbox/package.json @@ -5,10 +5,10 @@ "type": "module", "packageManager": "pnpm@10.13.1", "scripts": { - "dev": "tsx --watch src/server.ts", + "dev": "vite", "check-types": "echo 'skipped - workflow history types broken'", - "build": "echo 'no build step - running via tsx'", - "start": "tsx src/server.ts", + "build": "vite build --mode server", + "start": "tsx src/server-runner.ts", "benchmark": "tsx scripts/benchmark.ts", "db:generate": "find src/actors -name drizzle.config.ts -exec drizzle-kit generate --config {} \\;" }, diff --git a/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js b/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js index 7b9779628f..0ea941b398 100644 --- a/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js +++ b/examples/sandbox/src/actors/state/sqlite-drizzle/drizzle/migrations.js @@ -1,10 +1,11 @@ -import { readFileSync } from "node:fs"; -import { fileURLToPath } from "node:url"; -import { dirname, join } from "node:path"; import journal from './meta/_journal.json' with { type: 'json' }; -const __dirname = dirname(fileURLToPath(import.meta.url)); -const m0000 = readFileSync(join(__dirname, '0000_left_wrecking_crew.sql'), 'utf-8'); +const m0000 = `CREATE TABLE \`todos\` ( +\t\`id\` integer PRIMARY KEY AUTOINCREMENT NOT NULL, +\t\`title\` text NOT NULL, +\t\`completed\` integer DEFAULT 0, +\t\`created_at\` integer NOT NULL +);`; export default { journal, diff --git a/examples/sandbox/src/server-runner.ts b/examples/sandbox/src/server-runner.ts new file mode 100644 index 0000000000..8260069847 --- /dev/null +++ b/examples/sandbox/src/server-runner.ts @@ -0,0 +1,3 @@ +import { registry } from "./index.ts"; + +registry.start(); diff --git a/examples/sandbox/src/server.ts b/examples/sandbox/src/server.ts index 8260069847..ce03591313 100644 --- a/examples/sandbox/src/server.ts +++ b/examples/sandbox/src/server.ts @@ -1,3 +1,3 @@ import { registry } from "./index.ts"; -registry.start(); +export default registry.serve();