Remaining problem after #965
#965 fixed pre-acquired stream-ID ownership and also repaired the equivalent admin-request and continuous-request cleanup paths. This issue now tracks the remaining normal CQL request lifecycle failure.
ConcurrencyLimitingRequestThrottler.register() claims a concurrency slot and then invokes onThrottleReady() synchronously. If that callback throws, the exception escapes and the claimed slot is never returned.
The dequeue path has the same shape: signalSuccess() invokes the next delayed request's onThrottleReady(true) while completing the current request, so a throw can escape into an unrelated request's completion path.
Remaining affected path
CqlRequestHandler schedules its timeout and then registers with the throttler from its constructor. Admission can synchronously enter sendRequest(), where request-ID decoration, statement conversion, callback construction, or other pre-write setup can throw.
Current consequences:
- the throttler concurrency slot is permanently lost;
- the scheduled timeout is not cancelled and fires later against an unobserved result;
- the exception can escape
session.execute() synchronously instead of completing the returned stage;
- on delayed admission, the exception can escape through another request's throttler completion.
The regression test added by #965 verifies only that the pre-acquired stream ID is released on request-decoration failure. It intentionally does not close these lifecycle gaps.
Already fixed by #965
Expected behavior
A synchronous CQL pre-write failure after throttler admission must:
- release the pre-acquired stream-ID reservation;
- complete the request result exceptionally rather than escape from
session.execute();
- cancel scheduled timeout/speculative work through normal terminal cleanup;
- return the throttler permit exactly once;
- not propagate through an unrelated request when admission came from the delayed queue.
Implementation direction
Route synchronous failures from CQL admission/send setup through the handler's existing terminal-error path, which already owns timeout cancellation and throttler signaling. Add coverage for both immediate and delayed admission, including unchanged throttler capacity and completed result stage.
Related
Remaining problem after #965
#965 fixed pre-acquired stream-ID ownership and also repaired the equivalent admin-request and continuous-request cleanup paths. This issue now tracks the remaining normal CQL request lifecycle failure.
ConcurrencyLimitingRequestThrottler.register()claims a concurrency slot and then invokesonThrottleReady()synchronously. If that callback throws, the exception escapes and the claimed slot is never returned.The dequeue path has the same shape:
signalSuccess()invokes the next delayed request'sonThrottleReady(true)while completing the current request, so a throw can escape into an unrelated request's completion path.Remaining affected path
CqlRequestHandlerschedules its timeout and then registers with the throttler from its constructor. Admission can synchronously entersendRequest(), where request-ID decoration, statement conversion, callback construction, or other pre-write setup can throw.Current consequences:
session.execute()synchronously instead of completing the returned stage;The regression test added by #965 verifies only that the pre-acquired stream ID is released on request-decoration failure. It intentionally does not close these lifecycle gaps.
Already fixed by #965
ThrottledAdminRequestHandler.onThrottleReady()now releases its reservation and signals terminal error exactly once.ContinuousRequestHandlerBasenow unwinds active execution/callback bookkeeping and signals the throttler on terminal pre-write failure.Expected behavior
A synchronous CQL pre-write failure after throttler admission must:
session.execute();Implementation direction
Route synchronous failures from CQL admission/send setup through the handler's existing terminal-error path, which already owns timeout cancellation and throttler signaling. Add coverage for both immediate and delayed admission, including unchanged throttler capacity and completed result stage.
Related
InFlightHandler