-
Notifications
You must be signed in to change notification settings - Fork 114
feat(pb): get multi-actors working e2e, add resources for builds #2465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,22 @@ | ||||||
import { serve } from "@hono/node-server"; | ||||||
import { createNodeWebSocket } from "@hono/node-ws"; | ||||||
import { createAndStartHttpServer } from "./httpServer.js"; | ||||||
import { createAndStartUdpServer } from "./udpServer.js"; | ||||||
import { connectToManager } from "./managerClient.js"; | ||||||
|
||||||
let injectWebSocket: any; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: avoid using 'any' type - should define proper type from @hono/node-ws |
||||||
const { app, port } = createAndStartHttpServer((app) => { | ||||||
// Get Node.js WebSocket handler | ||||||
const result = createNodeWebSocket({ app }); | ||||||
injectWebSocket = result.injectWebSocket; | ||||||
return result.upgradeWebSocket; | ||||||
}); | ||||||
|
||||||
const server = serve({ fetch: app.fetch, port }); | ||||||
injectWebSocket(server); | ||||||
Comment on lines
+15
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: server instance should be handled for graceful shutdown (e.g., process.on('SIGTERM')) |
||||||
|
||||||
createAndStartUdpServer(); | ||||||
|
||||||
if (process.env.MULTI) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: use explicit boolean check for environment variable
Suggested change
|
||||||
connectToManager(); | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,85 @@ | ||||||||||
import WebSocket from "ws"; | ||||||||||
|
||||||||||
export function connectToManager() { | ||||||||||
let managerIp = process.env.RIVET_MANAGER_IP; | ||||||||||
let managerPort = process.env.RIVET_MANAGER_PORT; | ||||||||||
let pingInterval: NodeJS.Timeout; | ||||||||||
|
||||||||||
if (!managerIp || !managerPort) { | ||||||||||
console.error("Missing RIVET_MANAGER_IP or RIVET_MANAGER_PORT environment variables"); | ||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
let wsUrl = `ws://${managerIp}:${managerPort}`; | ||||||||||
console.log(`Connecting to manager WebSocket at ${wsUrl}`); | ||||||||||
|
||||||||||
let ws = new WebSocket(wsUrl); | ||||||||||
|
||||||||||
ws.on("open", () => { | ||||||||||
console.log("Connected to manager WebSocket"); | ||||||||||
|
||||||||||
let message = { | ||||||||||
init: { | ||||||||||
runner_id: process.env.RIVET_RUNNER_ID | ||||||||||
} | ||||||||||
}; | ||||||||||
let buffer = Buffer.from(JSON.stringify(message)); | ||||||||||
ws.send(buffer); | ||||||||||
|
||||||||||
// Start ping loop to keep connection alive | ||||||||||
pingInterval = setInterval(() => { | ||||||||||
if (ws.readyState === WebSocket.OPEN) { | ||||||||||
ws.ping(); | ||||||||||
} | ||||||||||
}, 2000); | ||||||||||
}); | ||||||||||
|
||||||||||
ws.on("message", (data) => { | ||||||||||
let json = data.toString(); | ||||||||||
|
||||||||||
console.log("Received message from manager:", json); | ||||||||||
|
||||||||||
let packet = JSON.parse(json); | ||||||||||
|
||||||||||
if (packet.start_actor) { | ||||||||||
let message = { | ||||||||||
actor_state_update: { | ||||||||||
actor_id: packet.start_actor.actor_id, | ||||||||||
generation: packet.start_actor.generation, | ||||||||||
state: { | ||||||||||
running: null, | ||||||||||
}, | ||||||||||
} | ||||||||||
}; | ||||||||||
let buffer = Buffer.from(JSON.stringify(message)); | ||||||||||
ws.send(buffer); | ||||||||||
} else if (packet.signal_actor) { | ||||||||||
let message = { | ||||||||||
actor_state_update: { | ||||||||||
actor_id: packet.start_actor.actor_id, | ||||||||||
generation: packet.start_actor.generation, | ||||||||||
Comment on lines
+59
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: Incorrect property access - using packet.start_actor instead of packet.signal_actor in the signal_actor handler
Suggested change
|
||||||||||
state: { | ||||||||||
exited: { | ||||||||||
exit_code: 0, | ||||||||||
} | ||||||||||
}, | ||||||||||
} | ||||||||||
}; | ||||||||||
let buffer = Buffer.from(JSON.stringify(message)); | ||||||||||
ws.send(buffer); | ||||||||||
} | ||||||||||
}); | ||||||||||
|
||||||||||
ws.on("error", (error) => { | ||||||||||
console.error("WebSocket error:", error); | ||||||||||
}); | ||||||||||
|
||||||||||
ws.on("close", code => { | ||||||||||
console.log("WebSocket connection closed, attempting to reconnect...", code); | ||||||||||
|
||||||||||
// Clear ping interval when connection closes | ||||||||||
if (pingInterval) clearInterval(pingInterval); | ||||||||||
|
||||||||||
setTimeout(connectToManager, 5000); | ||||||||||
}); | ||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,36 @@ | ||||||||||||||||||||||||
import dgram from 'dgram'; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
export function createAndStartUdpServer() { | ||||||||||||||||||||||||
// Get port from environment | ||||||||||||||||||||||||
const portEnv = process.env.PORT_UDP; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
if (portEnv) { | ||||||||||||||||||||||||
// Create a UDP socket | ||||||||||||||||||||||||
const udpServer = dgram.createSocket('udp4'); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
// Listen for incoming messages | ||||||||||||||||||||||||
udpServer.on('message', (msg, rinfo) => { | ||||||||||||||||||||||||
console.log(`UDP server received: ${msg} from ${rinfo.address}:${rinfo.port}`); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
// Echo the message back to the sender | ||||||||||||||||||||||||
udpServer.send(msg, rinfo.port, rinfo.address, (err) => { | ||||||||||||||||||||||||
if (err) console.error('Failed to send UDP response:', err); | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
// Handle errors | ||||||||||||||||||||||||
udpServer.on('error', (err) => { | ||||||||||||||||||||||||
console.error('UDP server error:', err); | ||||||||||||||||||||||||
udpServer.close(); | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
const port2 = Number.parseInt(portEnv); | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: port validation should happen before socket creation to avoid creating resources that may need cleanup |
||||||||||||||||||||||||
|
||||||||||||||||||||||||
udpServer.bind(port2, () => { | ||||||||||||||||||||||||
console.log(`UDP echo server running on port ${port2}`); | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
Comment on lines
+30
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: bind callback should include error handling in case port binding fails
Suggested change
|
||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||
console.warn("missing PORT_UDP"); | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,4 +30,4 @@ | |
"esbuild": "^0.25.5", | ||
"actor-core": "file:./frontend/packages/actor-core.tgz" | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: unreachable code after process.exit() should be removed