Problem
TraditionalWorkQueue.finalizeWorkQueue() is supposed to send a "server shutting down" cancel response to every operation still sitting in the queue:
// Send responses to any operations in the pending queue to indicate that
// they won't be processed because the server is shutting down.
CancelRequest cancelRequest = new CancelRequest(true, reason);
ArrayList<Operation> pendingOperations = new ArrayList<>();
opQueue.removeAll(pendingOperations);
for (Operation o : pendingOperations)
{
...
o.abort(cancelRequest);
...
}
Collection.removeAll(collection) removes from the queue the elements contained in the argument — and pendingOperations is a freshly created empty list, so the call removes nothing and leaves pendingOperations empty. The abort loop below never executes.
The intended call is clearly opQueue.drainTo(pendingOperations) (move all queued operations into the list, then abort each one).
Impact
Operations still queued at shutdown never receive the UNAVAILABLE/cancelled response promised by the surrounding code and the WARN_QUEUE_UNABLE_TO_CANCEL handling; clients block waiting for a response until their connection is torn down. Low severity in practice (shutdown path, queue is usually empty), but the code as written is a no-op.
Notes
This is a long-standing upstream bug: the same removeAll(new ArrayList<>()) pattern is already present in the OpenDS-era TraditionalWorkQueue (before the OpenDJ 3 rewrite), so it dates back to the original implementation.
Found while auditing the slow TestNG group (follow-up to #684/#688).
Problem
TraditionalWorkQueue.finalizeWorkQueue()is supposed to send a "server shutting down" cancel response to every operation still sitting in the queue:Collection.removeAll(collection)removes from the queue the elements contained in the argument — andpendingOperationsis a freshly created empty list, so the call removes nothing and leavespendingOperationsempty. The abort loop below never executes.The intended call is clearly
opQueue.drainTo(pendingOperations)(move all queued operations into the list, then abort each one).Impact
Operations still queued at shutdown never receive the
UNAVAILABLE/cancelled response promised by the surrounding code and theWARN_QUEUE_UNABLE_TO_CANCELhandling; clients block waiting for a response until their connection is torn down. Low severity in practice (shutdown path, queue is usually empty), but the code as written is a no-op.Notes
This is a long-standing upstream bug: the same
removeAll(new ArrayList<>())pattern is already present in the OpenDS-eraTraditionalWorkQueue(before the OpenDJ 3 rewrite), so it dates back to the original implementation.Found while auditing the
slowTestNG group (follow-up to #684/#688).