{"record":{"id":"ade0708bd83d27d0","repo":"prestodb/presto","slug":"statementclient-thread-was-interrupted","errorCode":null,"errorMessage":"StatementClient thread was interrupted","messagePattern":"StatementClient thread was interrupted","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"presto-client/src/main/java/com/facebook/presto/client/StatementClientV1.java","lineNumber":408,"sourceCode":"            if (attempts > 0 && sinceStart.compareTo(requestTimeoutNanos) > 0) {\n                state.compareAndSet(State.RUNNING, State.CLIENT_ERROR);\n                throw new RuntimeException(format(\"Error fetching next (attempts: %s, duration: %s)\", attempts, sinceStart), cause);\n            }\n\n            if (attempts > 0) {\n                // back-off on retry\n                try {\n                    MILLISECONDS.sleep(attempts * 100);\n                }\n                catch (InterruptedException e) {\n                    try {\n                        close();\n                    }\n                    finally {\n                        Thread.currentThread().interrupt();\n                    }\n                    state.compareAndSet(State.RUNNING, State.CLIENT_ERROR);\n                    throw new RuntimeException(\"StatementClient thread was interrupted\");\n                }\n            }\n            attempts++;\n\n            JsonResponse<QueryResults> response;\n            try {\n                response = JsonResponse.execute(QUERY_RESULTS_CODEC, httpClient, request);\n            }\n            catch (RuntimeException e) {\n                cause = e;\n                continue;\n            }\n\n            if ((response.getStatusCode() == HTTP_OK) && response.hasValue()) {\n                processResponse(response.getHeaders(), response.getValue());\n                return true;\n            }\n","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-client/src/main/java/com/facebook/presto/client/StatementClientV1.java#L390-L426","documentation":"While backing off between retry attempts inside advance(), the sleep can be interrupted; the client closes itself, re-asserts the interrupt flag, sets CLIENT_ERROR, and throws RuntimeException 'StatementClient thread was interrupted'. This signals that another thread cancelled the statement client's worker, typically during shutdown.","triggerScenarios":"Calling advance() and having Thread.interrupt() invoked on the executing thread while it sleeps between retries — e.g. executor shutdownNow(), future.cancel(true), or application shutdown hooks.","commonSituations":"Cancelling a query future with cancel(true); shutting down an ExecutorService running Presto queries; JVM shutdown while a CLI/JDBC fetch is in its retry backoff.","solutions":["Treat this as cancellation: do not retry blindly; check your application's shutdown/cancel logic.","Avoid interrupting the thread running the statement client unless cancellation is intended; use client.close()/cancelLeafStage for orderly stop.","Ensure cancel(true) is only called on futures you intend to abort.","If seen unexpectedly, audit thread-pool lifecycle (shutdownNow vs shutdown) in your code."],"exampleFix":"// before\nexecutor.shutdownNow();  // interrupts in-flight Presto fetch\n// after\nclient.close();\nexecutor.shutdown();\nexecutor.awaitTermination(30, TimeUnit.SECONDS);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    while (client.isRunning()) client.advance();\n} catch (RuntimeException e) {\n    if (Thread.currentThread().isInterrupted() || \"StatementClient thread was interrupted\".equals(e.getMessage())) {\n        // treat as cancellation: clean up, don't retry\n    } else throw e;\n}","preventionTips":["Don't call shutdownNow()/cancel(true) on threads running Presto fetches","Use client.close() for orderly cancellation","Allow executor tasks to finish before JVM shutdown","Keep interrupt handling semantics clear in worker code"],"tags":["interruption","threading","shutdown"],"backgroundTag":"thread-interrupted","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}