-
Notifications
You must be signed in to change notification settings - Fork 114
chore(runner): connect tunnel before connecting pb ws #2872
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
chore(runner): connect tunnel before connecting pb ws #2872
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
commit: |
onDisconnected: () => { | ||
if (!connected) { | ||
// First connection attempt failed | ||
reject(new Error("Tunnel connection failed")); | ||
} | ||
// If already connected, tunnel will handle reconnection automatically | ||
}, |
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.
There's a potential race condition in the tunnel connection handling. If the tunnel disconnects immediately after connecting, the Promise will have already resolved successfully, but the system would be in a disconnected state.
Consider enhancing the connection state management by either:
- Using a timeout for the initial connection attempt
- Adding a state variable that tracks whether the connection is stable
- Implementing a more robust reconnection mechanism that handles the case where disconnection happens shortly after initial connection
This would prevent the code from proceeding with a tunnel that appears connected but actually isn't available for network requests, which seems to be the original issue this PR is trying to solve.
onDisconnected: () => { | |
if (!connected) { | |
// First connection attempt failed | |
reject(new Error("Tunnel connection failed")); | |
} | |
// If already connected, tunnel will handle reconnection automatically | |
}, | |
onDisconnected: () => { | |
if (!connected) { | |
// First connection attempt failed | |
reject(new Error("Tunnel connection failed")); | |
} else if (Date.now() - connectionEstablishedTime < 2000) { | |
// Connection was established but disconnected within 2 seconds | |
// This suggests an unstable connection that shouldn't be considered successful | |
reject(new Error("Tunnel connection unstable - disconnected shortly after connecting")); | |
} | |
// If already connected for a significant time, tunnel will handle reconnection automatically | |
}, |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
async #openTunnelAndWait(): Promise<void> { | ||
return new Promise((resolve, reject) => { | ||
const url = this.pegboardRelayUrl; | ||
//console.log("[RUNNER] Opening tunnel to:", url); | ||
//console.log("[RUNNER] Current runner ID:", this.runnerId || "none"); | ||
//console.log("[RUNNER] Active actors count:", this.#actors.size); | ||
|
||
let connected = false; | ||
|
||
this.#tunnel = new Tunnel(url); | ||
this.#tunnel.setCallbacks({ | ||
fetch: this.#config.fetch, | ||
websocket: this.#config.websocket, | ||
onConnected: () => { | ||
if (!connected) { | ||
connected = true; | ||
//console.log("[RUNNER] Tunnel connected"); | ||
resolve(); | ||
} | ||
}, | ||
onDisconnected: () => { | ||
if (!connected) { | ||
// First connection attempt failed | ||
reject(new Error("Tunnel connection failed")); | ||
} | ||
// If already connected, tunnel will handle reconnection automatically | ||
}, | ||
}); | ||
this.#tunnel.start(); | ||
|
||
// Re-register all active actors with the new tunnel | ||
for (const actorId of this.#actors.keys()) { | ||
//console.log("[RUNNER] Re-registering actor with tunnel:", actorId); | ||
this.#tunnel.registerActor(actorId); | ||
} | ||
}); | ||
} |
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.
The current implementation has a potential resource leak when the tunnel connection fails. If the Promise is rejected, the tunnel instance and its callbacks remain active without proper cleanup.
Consider adding cleanup code in the rejection path:
onDisconnected: () => {
if (!connected) {
// First connection attempt failed
this.#tunnel.shutdown();
this.#tunnel = null;
reject(new Error("Tunnel connection failed"));
}
// If already connected, tunnel will handle reconnection automatically
}
This ensures the tunnel is properly shut down when the connection fails, preventing resource leaks and avoiding callback execution on a failed connection.
async #openTunnelAndWait(): Promise<void> { | |
return new Promise((resolve, reject) => { | |
const url = this.pegboardRelayUrl; | |
//console.log("[RUNNER] Opening tunnel to:", url); | |
//console.log("[RUNNER] Current runner ID:", this.runnerId || "none"); | |
//console.log("[RUNNER] Active actors count:", this.#actors.size); | |
let connected = false; | |
this.#tunnel = new Tunnel(url); | |
this.#tunnel.setCallbacks({ | |
fetch: this.#config.fetch, | |
websocket: this.#config.websocket, | |
onConnected: () => { | |
if (!connected) { | |
connected = true; | |
//console.log("[RUNNER] Tunnel connected"); | |
resolve(); | |
} | |
}, | |
onDisconnected: () => { | |
if (!connected) { | |
// First connection attempt failed | |
reject(new Error("Tunnel connection failed")); | |
} | |
// If already connected, tunnel will handle reconnection automatically | |
}, | |
}); | |
this.#tunnel.start(); | |
// Re-register all active actors with the new tunnel | |
for (const actorId of this.#actors.keys()) { | |
//console.log("[RUNNER] Re-registering actor with tunnel:", actorId); | |
this.#tunnel.registerActor(actorId); | |
} | |
}); | |
} | |
async #openTunnelAndWait(): Promise<void> { | |
return new Promise((resolve, reject) => { | |
const url = this.pegboardRelayUrl; | |
//console.log("[RUNNER] Opening tunnel to:", url); | |
//console.log("[RUNNER] Current runner ID:", this.runnerId || "none"); | |
//console.log("[RUNNER] Active actors count:", this.#actors.size); | |
let connected = false; | |
this.#tunnel = new Tunnel(url); | |
this.#tunnel.setCallbacks({ | |
fetch: this.#config.fetch, | |
websocket: this.#config.websocket, | |
onConnected: () => { | |
if (!connected) { | |
connected = true; | |
//console.log("[RUNNER] Tunnel connected"); | |
resolve(); | |
} | |
}, | |
onDisconnected: () => { | |
if (!connected) { | |
// First connection attempt failed | |
this.#tunnel.shutdown(); | |
this.#tunnel = null; | |
reject(new Error("Tunnel connection failed")); | |
} | |
// If already connected, tunnel will handle reconnection automatically | |
}, | |
}); | |
this.#tunnel.start(); | |
// Re-register all active actors with the new tunnel | |
for (const actorId of this.#actors.keys()) { | |
//console.log("[RUNNER] Re-registering actor with tunnel:", actorId); | |
this.#tunnel.registerActor(actorId); | |
} | |
}); | |
} |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
cf0534f
to
90ce950
Compare
f957fbb
to
0678b46
Compare
Claude encountered an error —— View job I'll analyze this and get back to you. |
Claude encountered an error —— View job I'll analyze this and get back to you. |
0678b46
to
6b4c00b
Compare
90ce950
to
c140b96
Compare
c140b96
to
f452a88
Compare
Merge activity
|
No description provided.