{"record":{"id":"5b193444264c6377","repo":"apache/beam","slug":"interrupted-closing-flightclient","errorCode":null,"errorMessage":"Interrupted closing FlightClient","messagePattern":"Interrupted closing FlightClient","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"sdks/java/io/arrow-flight/src/main/java/org/apache/beam/sdk/io/arrowflight/ArrowFlightIO.java","lineNumber":497,"sourceCode":"      return current;\n    }\n\n    @Override\n    public void close() throws IOException {\n      try {\n        if (stream != null) {\n          stream.close();\n        }\n      } catch (Exception e) {\n        LOG.warn(\"Error closing FlightStream\", e);\n      }\n      try {\n        if (client != null) {\n          client.close();\n        }\n      } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n        LOG.warn(\"Interrupted closing FlightClient\", e);\n      }\n      try {\n        if (allocator != null) {\n          allocator.close();\n        }\n      } catch (Exception e) {\n        LOG.warn(\"Error closing BufferAllocator\", e);\n      }\n    }\n\n    @Override\n    public BoundedSource<Row> getCurrentSource() {\n      return currentSource;\n    }\n  }\n\n  // ======================== WRITE ========================\n","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/arrow-flight/src/main/java/org/apache/beam/sdk/io/arrowflight/ArrowFlightIO.java#L479-L515","documentation":"This is a warning logged in ArrowFlightIO's UnboundedArrowSource close() when Thread.interrupt() arrives while the FlightClient.close() call (which blocks on gRPC teardown) is in progress. The library catches InterruptedException, restores the interrupt flag with Thread.currentThread().interrupt(), and continues closing the allocator. It is not thrown at the caller; it signals that the client close did not finish gracefully.","triggerScenarios":"Pipeline teardown of an Arrow Flight Read UnboundedSource while Thread.interrupt() is delivered to the closing thread, e.g. worker shutdown, bundle cancellation, or pipeline cancellation racing with close().","commonSituations":"Runner-initiated cancellation of a streaming pipeline; autoscaling draining workers; a test harness or executor shutting down while FlightClient.close() blocks on network teardown; container kill with graceful-stop signaling.","solutions":["Ignore if seen during normal pipeline cancellation/worker shutdown; the interrupt flag is restored and resources are still released.","Avoid cancelling the pipeline while Flight reads are mid-teardown; drain the source before stopping workers.","Check the Arrow Flight server for slow/hanging connections that make client.close() block long enough to be interrupted.","Upgrade beam-sdks-java-io-arrow-flight and arrow versions to pick up teardown robustness fixes."],"exampleFix":"// before: client.close() blocks indefinitely and can be interrupted\nclient.close();\n// after: bound the blocking window so interruption is unlikely\nclient.withCloseTimeout(java.time.Duration.ofSeconds(30)).close();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// interruption is already handled internally; at call sites, restore interrupt status\ntry {\n  client.close();\n} catch (InterruptedException e) {\n  Thread.currentThread().interrupt();\n}","preventionTips":["Don't interrupt worker threads during graceful pipeline teardown.","Use runner-supported drain/cancel APIs instead of raw thread interruption.","Keep the Arrow Flight server responsive so close() finishes quickly."],"tags":["java","interruption","grpc","resource-cleanup"],"backgroundTag":"thread-interrupted","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-15T02:17:10.978Z"}