-
Notifications
You must be signed in to change notification settings - Fork 130
chore(rivetkit): add runner sse ping interval #3362
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(rivetkit): add runner sse ping interval #3362
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
3 Skipped Deployments
|
PR Review: Add Runner SSE Ping IntervalSummaryThis PR adds a keepalive ping mechanism to the serverless runner's SSE connection to prevent premature connection closures. The implementation follows a similar pattern used elsewhere in the codebase. Positive Aspects✅ Follows Established Patterns: The ping loop implementation closely mirrors the existing pattern in ✅ Appropriate Interval: The 1-second ping interval matches ✅ Proper State Management: Added ✅ Good Logging: Debug logs help troubleshoot connection issues with clear messages about why the loop exits. Issues & Concerns🔴 Critical: Potential Race ConditionThere's a race condition in the state management: #isRunnerStopped: boolean = false;
// In onShutdown callback (line 147-150):
onShutdown: () => {
this.#runnerStopped.resolve(undefined);
this.#isRunnerStopped = true;
}Problem: The Impact: Low - likely harmless in practice since the stream will be closed, but not ideal for clean shutdown semantics. Recommendation: Consider if the 🟡 Minor: Error Handling GapThe ping loop doesn't have try-catch for await stream.writeSSE({ event: "ping", data: "" });
await stream.sleep(RUNNER_SSE_PING_INTERVAL);Problem: If Comparison: The similar implementation in Recommendation: Add try-catch around the ping loop or at least around 🟡 Minor: Inconsistent Constant NamingThe constant is named Recommendation: Consider reusing the existing 🟢 Nitpick: Stream Check OrderThe checks for Performance Considerations✅ The 1-second interval is reasonable and matches the existing pattern. No performance concerns. Security Considerations✅ No security issues identified. The ping mechanism is read-only and doesn't expose sensitive data. Test Coverage
Recommendations
Example Fix for Error Handling// Send ping every second to keep the connection alive
while (true) {
if (this.#isRunnerStopped) {
logger().debug({ msg: "runner is stopped" });
break;
}
if (stream.closed || stream.aborted) {
logger().debug({
msg: "runner sse stream closed",
closed: stream.closed,
aborted: stream.aborted,
});
break;
}
try {
await stream.writeSSE({ event: "ping", data: "" });
} catch (error) {
logger().debug({ msg: "failed to write sse ping", error });
break;
}
await stream.sleep(RUNNER_SSE_PING_INTERVAL);
}Overall, this is a solid addition that addresses a real need for keepalive on SSE connections. The main concern is the lack of error handling, which should be addressed before merging. |
45f6aba to
504772d
Compare
fb92df2 to
31223d5
Compare
Code ReviewThis PR adds a ping mechanism to the SSE (Server-Sent Events) connection for the runner to keep it alive. Overall, the implementation is solid, but I have a few observations and suggestions: Positive Aspects
Potential Issues & Suggestions1. Error Handling in the Ping LoopThe Suggestion: Wrap the ping write in a try-catch: try {
await stream.writeSSE({ event: "ping", data: "" });
} catch (err) {
logger().debug({
msg: "error sending ping, sse stream likely closed",
error: err,
});
break;
}2. Race Condition RiskThere's a potential race condition between checking The try-catch suggestion above would also mitigate this issue. 3. Duplicate CommentLine 623 has a comment about waiting for the runner to stop "if the SSE stream aborted early for any reason". This comment already existed before line 600, but now with the ping loop, the comment at line 623 is more relevant. Consider updating the comment to clarify why we still wait even after the ping loop exits. Suggestion: // Wait for the runner to fully stop. The ping loop may have exited early
// due to stream closure, but we need to ensure clean shutdown.
await this.#runnerStopped.promise;4. Consider Making Ping Interval ConfigurableThe 5. Memory Leak PreventionThe ping loop keeps a reference to the stream. If Test CoverageNo test changes were included in this PR. Consider adding:
Minor Style Notes
Security ConsiderationsNo security concerns identified. The ping mechanism doesn't expose sensitive data. Performance ConsiderationsThe 1-second ping interval is reasonable and shouldn't cause performance issues. Each ping is minimal overhead (empty data payload). Recommendation: The core implementation is good. I'd suggest adding error handling around the |
504772d to
ff28677
Compare
31223d5 to
b41010e
Compare
Code ReviewI've reviewed this PR which adds SSE ping functionality to keep the runner connection alive. Overall, the implementation looks solid and follows existing patterns in the codebase. Here are my findings: Positive Aspects ✅
Potential Issues & Recommendations 🔍1. Race Condition Risk (Minor)The
Recommendation: This is likely acceptable given JavaScript's execution model, but be aware of potential timing issues if the stream is closing simultaneously. 2. Error Handling (Moderate)The Looking at ```typescript 3. Constant Consistency (Minor)Consider exporting 4. Code Comment Clarity (Minor)The comment on line 623 says "Wait for the runner to stop if the SSE stream aborted early for any reason". This is accurate but could be clearer about why this is necessary. Consider: ```typescript Security Considerations 🔒No security concerns identified. The ping mechanism doesn't expose sensitive data. Performance Considerations ⚡
Test Coverage 🧪Missing: There don't appear to be tests for this new functionality. Consider adding tests for:
You could add tests in the driver test suite following patterns from other RivetKit tests. SummaryThis is a solid implementation that addresses a real need (keeping SSE connections alive). The main recommendation is to add error handling around the Approval Status: Approve with minor recommendations ✅ Review generated using Claude Code |
PR ReviewSummaryThis PR adds a ping interval mechanism to the engine actor driver's SSE (Server-Sent Events) stream to keep connections alive, similar to the existing pattern in Positive Aspects✅ Consistent with existing patterns - The implementation mirrors the pattern already used in ✅ Proper ping interval - Uses the same 1000ms interval as the existing ✅ Dual exit conditions - Checks both Issues & Recommendations🔴 Critical: Missing Error HandlingThe new ping loop lacks try-catch error handling. The reference implementation in try {
// ... SSE ping loop ...
} catch (error) {
loggerWithoutContext().error({
msg: "error in sse connection",
error,
});
// Cleanup on error
stream.close();
}Recommendation: Wrap the ping loop in a try-catch to handle potential errors from
|
b41010e to
ed48aff
Compare
ff28677 to
691501d
Compare
Code ReviewSummaryThis PR adds a ping mechanism to keep the SSE (Server-Sent Events) connection alive between the runner and the engine. The implementation sends periodic ping events every second to detect connection closures, particularly important for Cloudflare Workers environments. Positive Aspects ✅
Issues & Recommendations 🔍1. Potential Race Condition (Medium Priority)The
Recommendation: Consider using an AbortController pattern instead, which is more robust for async cancellation. 2. Missing Constant Export (Low Priority)The constant Recommendation: Consider exporting 3. No Test Coverage (Medium Priority)This critical connection management logic lacks test coverage. The ping mechanism and shutdown behavior should be tested. Recommendation: Add tests to verify:
4. Error Handling in Ping Loop (Low Priority)If Recommendation: Wrap the ping write in a try-catch: try {
await stream.writeSSE({ event: "ping", data: "" });
} catch (error) {
logger().debug({ msg: "ping write failed", error });
break;
}5. Comment Clarity (Minor)Line 623 says "Wait for the runner to stop if the SSE stream aborted early for any reason" - but this always waits, not just when aborting early. Recommendation: Update comment to: "Ensure runner cleanup completes before closing SSE handler" Performance Considerations
Security ConsiderationsNo security concerns identified. The ping mechanism doesn't expose sensitive data and follows secure SSE patterns. ConclusionThis is a solid addition that addresses a real need. The main concerns are around test coverage and the potential race condition with Overall: ✅ Approve with suggestions |
ed48aff to
a0b95ae
Compare
691501d to
e9b6bde
Compare
Code Review for PR #3362SummaryThis PR adds a ping mechanism to keep the SSE (Server-Sent Events) connection alive for serverless runners by sending a ping event every second. ✅ Positive Aspects
🔍 Potential Issues & Concerns1. Race Condition with
|
a0b95ae to
78391b5
Compare
e9b6bde to
1915f31
Compare
Code ReviewSummaryThis PR adds a ping mechanism to the SSE (Server-Sent Events) stream in the serverless runner to keep the connection alive. The implementation sends a ping event every second while the runner is active. Positive Aspects
Issues & Concerns1. Potential Resource Leak / Infinite Loop
|
Code ReviewI've reviewed this PR which adds SSE ping functionality to keep the runner connection alive. Overall, the implementation is solid and follows existing patterns in the codebase. Here are my detailed findings: ✅ Positive Aspects
🔍 Issues & Recommendations1. Missing Error Handling (High Priority)The new ping loop lacks try-catch error handling. The reference implementation in Current code: while (true) {
// ... checks ...
await stream.writeSSE({ event: "ping", data: "" });
await stream.sleep(RUNNER_SSE_PING_INTERVAL);
}Recommendation: Add error handling to prevent unhandled exceptions if try {
while (true) {
if (this.#isRunnerStopped) {
logger().debug({ msg: "runner is stopped" });
break;
}
if (stream.closed || stream.aborted) {
logger().debug({
msg: "runner sse stream closed",
closed: stream.closed,
aborted: stream.aborted,
});
break;
}
await stream.writeSSE({ event: "ping", data: "" });
await stream.sleep(RUNNER_SSE_PING_INTERVAL);
}
} catch (error) {
logger().error({
msg: "error in runner sse ping loop",
error: stringifyError(error),
});
// Stream cleanup happens when streamSSE callback returns
}2. Consider Reusing Existing Constant (Low Priority)There's already a import { SSE_PING_INTERVAL } from "@/actor/router-endpoints";This would ensure consistency if the ping interval ever needs to change globally. 3. Test Coverage (Medium Priority)No tests were added for this functionality. Consider adding tests for:
4. Minor: Potential Race Condition (Low Priority)The
Impact: Very low - the stream checks should catch this anyway, and one extra ping is harmless. The error handling suggestion above would also mitigate this. 🔒 Security ConsiderationsNo security concerns identified. The ping mechanism doesn't expose sensitive data. ⚡ Performance Considerations
SummaryThis is a solid implementation that addresses a real need (keeping SSE connections alive). The main recommendation is to add error handling around the ping loop to prevent potential unhandled exceptions. The other suggestions are minor improvements for code quality and consistency. Status: ✅ Approve with recommendations The error handling is the only critical item - the rest are nice-to-haves that can be addressed now or in a follow-up PR. |
Merge activity
|

No description provided.