TimurRakhmatullin86 opened a new pull request, #20424:
URL: https://github.com/apache/druid/pull/20424

   ## Summary
   
   Restore the thread interrupt flag in `catch (InterruptedException)` blocks 
that swallow the exception without calling 
`Thread.currentThread().interrupt()`. This is a well-documented Java 
concurrency best practice (see *Java Concurrency in Practice*, Section 7.1.3).
   
   When `InterruptedException` is caught and not re-thrown, the thread's 
interrupt status is cleared. If the catch block does not restore it, 
higher-level code (thread pool executors, shutdown hooks, cooperative 
cancellation loops) cannot detect that an interruption was requested. This can 
cause threads to miss shutdown signals and continue running indefinitely.
   
   ### Notable fixes
   
   **`CommonCacheNotifier`** — The catch block inside a `while 
(!Thread.interrupted())` loop swallowed the interrupt, preventing the loop from 
ever terminating on shutdown. After `exec.shutdownNow()`, the thread would 
catch the `InterruptedException` from `updateQueue.take()`, lose the flag, and 
re-enter the loop — blocking on `take()` indefinitely.
   
   **`HttpPostEmitter`** — The `EmittingThread` run loop checks 
`Thread.interrupted()` in its `needsToShutdown()` method. The 
`sendWithRetries()` method caught `InterruptedException` without restoring the 
flag, so the emitting thread could miss its shutdown signal.
   
   ### All changes (12 files, 18 catch blocks)
   
   | Module | File | Description |
   |--------|------|-------------|
   | `extensions-core/druid-basic-security` | `CommonCacheNotifier` | Restore 
flag so `while (!Thread.interrupted())` loop can exit |
   | `extensions-core/druid-basic-security` | 
`CoordinatorPollingBasicAuthorizerCacheManager` | Restore flag in 4 catch 
blocks (scheduled poll tasks + fetch methods) |
   | `extensions-core/druid-basic-security` | 
`CoordinatorPollingBasicAuthenticatorCacheManager` | Restore flag in 2 catch 
blocks (scheduled poll task + fetch method) |
   | `extensions-core/kinesis-indexing-service` | `KinesisRecordSupplier` | 
Restore flag in `poll()` |
   | `extensions-core/kafka-extraction-namespace` | 
`KafkaLookupExtractorFactory` | Restore flag in multi-catch during `start()` |
   | `extensions-core/kubernetes-overlord-extensions` | 
`KubernetesPeonLifecycle` | Restore flag in `executeWithTimeout()` |
   | `extensions-contrib/rabbit-stream-indexing-service` | 
`RabbitStreamRecordSupplier` | Restore flag in 3 catch blocks (`close()`, 
message handler, `poll()`) |
   | `multi-stage-query` | `WorkerSketchFetcher` | Restore flag before 
`executorService.shutdownNow()` |
   | `processing` | `HttpPostEmitter` | Restore flag so 
`EmittingThread.needsToShutdown()` sees the interrupt |
   | `server` | `DirectDruidClient` | Restore flag in multi-catch during query 
cancellation |
   | `server` | `LookupReferencesManager` | Restore flag in multi-catch during 
lookup loading |
   | `server` | `LookupCoordinatorManager` | Restore flag in executor-submitted 
callable |
   
   ### Motivation
   
   All changes follow the same minimal pattern — adding 
`Thread.currentThread().interrupt()` as the first statement in the catch block. 
No behavioral logic is changed; this purely restores the interrupt flag that 
`InterruptedException` clears, so that callers can observe it.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to