fix: return "Session is closed" instead of NoNodeAvailableException during shutdown - #1023
Conversation
…uring shutdown
Route the four request handlers (CqlRequestHandler, CqlPrepareHandler, GraphRequestHandler, ContinuousRequestHandlerBase) through a new helper DefaultSession.queryPlanExhaustedError. When the errors list is empty and the session is closing or already closed, it returns IllegalStateException("Session is closed") -- matching what DefaultSession.execute() and the timer path already do for shutdown -- instead of the misleading NoNodeAvailableException.
Shutdown-in-progress is detected via a new isClosing() predicate on DefaultSession, set synchronously when closeAsync/forceCloseAsync is invoked. Relying solely on isClosed() would have missed the window between close initiation and closeFuture completion -- exactly when the load balancing policy starts returning empty query plans.
Genuine "no node available" outages on a healthy session are unchanged.
Fixes scylladb#846
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: QUIET Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
Suggested reviewers: Merge Risk: ⚪ Minimal · up to Requests that race with session shutdown now receive the intended "Session is closed" error, while genuine node-availability failures remain unchanged; no actionable merge-blocking risk remains beyond normal checks and review. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Linked Issues checkExplanation The changes satisfy issue
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Motivation
CqlSessionrequest handlers currently surfaceNoNodeAvailableExceptionwhen a request happens to be in flight while the session is shutting down. This is misleading — no node was even attempted; the load balancing policy simply returned an empty query plan because it had already transitioned toCLOSING. See #846 for the report and the exact stack trace.The existing
DefaultSession.execute()and the request handler's timer path already surfaceIllegalStateException("Session is closed")for this situation. The shutdown-race path should match.Modifications
DefaultSession.queryPlanExhaustedError(session, errors)— when the errors list is empty and the session is either closing or already closed, returnsIllegalStateException("Session is closed"); otherwise delegates toAllNodesFailedException.fromErrors(errors)as before.DefaultSession.isClosing(), backed by avolatile boolean closingflipped synchronously at the top ofcloseAsync()/forceCloseAsync().isClosed()alone would miss the window between close initiation andcloseFuturecompletion — exactly when the LB policy starts returning empty plans.CqlRequestHandler,CqlPrepareHandler,GraphRequestHandler, andContinuousRequestHandlerBasethrough the helper at their "query plan exhausted" branches.CqlRequestHandlerTestpin down each branch of the helper:isClosed()(post-shutdown-complete) andisClosing()(shutdown-in-progress).Result
IllegalStateException("Session is closed"), matching the error already produced elsewhere for the same condition.AllNodesFailedException).CqlSession/AsyncAutoCloseable;isClosing()is a new method on the internalDefaultSessiononly.Fixes #846