fix(socket): clean up room listeners after unsubscribe#173
Conversation
|
Claude finished @yoavf's task —— View job PR Review: Entity Subscription Deduplication and Rate LimitingI've thoroughly reviewed this pull request that implements subscription deduplication, caps, and churn prevention for the entity realtime subscriptions. Here's my comprehensive feedback: 🟢 Code Quality & Best PracticesExcellent Architecture:
Strong Points:
Minor Suggestions:
🟡 Potential Bugs or IssuesEdge Case in Grace Period Logic: // In scheduleRoomClose (line 324-336)
const closeTimer = setTimeout(() => {
state.closeTimer = null;
if (state.callbacks.size === 0 && activeSubscriptions.get(state.room) === state) {
closeRoomSubscription(state);
}
}, normalizedOptions.emptyRoomGraceMs);If a new subscription comes in exactly when the timer fires but before Analytics Event Error Handling: 🟢 Performance ConsiderationsExcellent Optimizations:
Memory Management:
🟢 Security ConcernsNo significant security issues found:
🟢 Test CoverageComprehensive Test Suite:
Test Quality Highlights:
Additional Test Suggestions:
📊 Additional ObservationsObservability:
Documentation: Socket Utils Enhancement: ✅ VerdictThis is a well-implemented solution that addresses real-world issues with React effect churn and socket room management. The code is clean, performant, and thoroughly tested. The addition of client-side caps and diagnostic analytics will help developers identify and fix subscription issues early. Approved - Great work on this implementation! The subscription deduplication and grace period features will significantly improve the stability of realtime subscriptions in React applications. |
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/sdk@0.8.28-pr.173.b39e4d0Prefer not to change any import paths? Install using npm alias so your code still imports npm i "@base44/sdk@npm:@base44-preview/sdk@0.8.28-pr.173.b39e4d0"Or add it to your {
"dependencies": {
"@base44/sdk": "npm:@base44-preview/sdk@0.8.28-pr.173.b39e4d0"
}
}
Preview published to npm registry — try new features instantly! |
|
Claude finished @yoavf's task —— View job PR Review: Socket Room Unsubscribe Lifecycle FixI've reviewed this pull request that addresses important issues with socket room cleanup and unsubscription idempotency. Here's my comprehensive feedback: ✅ Code Quality and Best PracticesThe implementation follows excellent coding practices:
✅ Potential Bugs or IssuesNo bugs identified. The implementation correctly addresses the issues described:
One minor observation: The use of optional chaining ( ✅ Performance ConsiderationsThe changes have positive performance implications:
✅ Security ConcernsNo security issues identified. The changes:
✅ Test CoverageExcellent test coverage! The new test file comprehensively covers all scenarios:
The tests are well-structured with:
📊 Additional Observations
✅ VerdictThis is a well-crafted fix that addresses real issues in the socket room lifecycle management. The implementation is clean, the tests are comprehensive, and the change is minimal yet effective. The idempotent unsubscribe pattern will prevent the described React effect cleanup issues. Approved - Great work on identifying and fixing this subtle but important issue! |
Summary
leaveevents.RoomsSockettests for shared room joins, rejoining after the last unsubscribe, and duplicate unsubscribe calls.Why
A client can create room churn without having many users or many browser tabs. For example, a React effect can repeatedly clean up and recreate a realtime subscription as component state or query results change. Cleanup functions may also be called more than once by app code or lifecycle edge cases.
Before this change, the final unsubscribe emitted
leave, but the SDK kept an empty listener array for that room. That had two bad effects:join, so realtime updates could be missed;Duplicate calls to the same unsubscribe callback could also produce extra
leaveemissions for a room that was already cleaned up.Mitigation
The SDK now treats room membership as a real refcounted lifecycle:
leaveand deletes the room entry;This keeps the low-level socket behavior consistent and avoids stale empty-room state. It does not add new public options, analytics, caps, or entity-specific subscription behavior.
Risk / side effects
join. That restores the expected behavior for unsubscribe/resubscribe flows.Validation
npm run test:unit -- tests/unit/socket-utils.test.ts