{"record":{"id":"10d7445a824ee4f0","repo":"redis/jedis","slug":"interrupted-while-waiting-for-health-check-result","errorCode":null,"errorMessage":"Interrupted while waiting for health check result","messagePattern":"Interrupted while waiting for health check result","errorType":"exception","errorClass":"JedisConnectionException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/mcf/StatusTracker.java","lineNumber":74,"sourceCode":"    try {\n      // Double-check status after registering listener (race condition protection)\n      currentStatus = healthStatusManager.getHealthStatus(endpoint);\n      if (currentStatus != HealthStatus.UNKNOWN) {\n        return currentStatus;\n      }\n\n      // Wait for the health status change event\n      // just for safety to not block indefinitely\n      boolean completed = latch.await(healthStatusManager.getMaxWaitFor(endpoint),\n        TimeUnit.MILLISECONDS);\n      if (!completed) {\n        throw new JedisValidationException(\"Timeout while waiting for health check result\");\n      }\n      return resultStatus.get();\n\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new JedisConnectionException(\"Interrupted while waiting for health check result\", e);\n    } finally {\n      // Clean up: unregister the temporary listener\n      healthStatusManager.unregisterListener(endpoint, tempListener);\n    }\n  }\n}\n","sourceCodeStart":56,"sourceCodeEnd":81,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/mcf/StatusTracker.java#L56-L81","documentation":"waitForHealthStatus catches InterruptedException while awaiting the health status latch, re-interrupts the current thread to preserve the interrupt flag, and rethrows as JedisConnectionException. This happens when the waiting thread is interrupted (task cancellation or shutdown) rather than when the health check times out.","triggerScenarios":"The thread blocked in latch.await() inside waitForHealthStatus (via waitForInitializationPolicy) receives Thread.interrupt() — e.g. client close() during initialization, executor shutdown, application shutdown hooks, or Future cancellation of the initialization task.","commonSituations":"Closing a MultiDb client from another thread while it is still initializing; shutting down an application server mid-initialization; cancelling an initialization Future; test frameworks interrupting leaked threads between tests.","solutions":["Avoid closing or shutting down the client while initialization is still in progress; await build()/initialization completion first.","Catch JedisConnectionException at the initialization call site and treat it as shutdown-in-progress rather than retrying.","Ensure worker threads executing initialization are not cancelled prematurely by executor shutdownNow().","If interrupts are intentional, rely on the exception to abort and clean up; the tracker already unregisters its listener in finally."],"exampleFix":"// before\nExecutorService es = Executors.newSingleThreadExecutor();\nes.shutdownNow(); // interrupts client init thread mid health-wait\n// after\nClientInitTask task = new ClientInitTask();\nFuture<?> f = es.submit(task);\nf.get(60, TimeUnit.SECONDS); // let init finish\nes.shutdown();\n// catch site\ntry {\n  client = buildClient();\n} catch (JedisConnectionException e) {\n  if (Thread.currentThread().isInterrupted()) {\n    // shutdown in progress; do not retry\n  }\n}","handlingStrategy":"try-catch","validationCode":"if (Thread.currentThread().isInterrupted()) { /* skip init */ }","typeGuard":null,"tryCatchPattern":"try {\n  tracker.waitForHealthStatus(endpoint);\n} catch (JedisConnectionException e) {\n  if (Thread.currentThread().isInterrupted()) {\n    // shutdown in progress; abort without retry\n    return;\n  }\n  throw e;\n}","preventionTips":["Do not interrupt threads while client initialization is running.","Await build()/init completion before calling close().","Use shutdown() (not shutdownNow()) for executors running client init."],"tags":["interrupt","health-check","multi-db","threading"],"backgroundTag":"operation-interrupted","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}