{"record":{"id":"ddb8aea2396c8bf5","repo":"apache/seatunnel","slug":"enumerator-thread-is-interrupted","errorCode":null,"errorMessage":"Enumerator thread is interrupted.","messagePattern":"Enumerator thread is interrupted\\.","errorType":"exception","errorClass":"InterruptedException","httpStatus":null,"severity":"info","filePath":"seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/source/enumerator/AbstractSplitEnumerator.java","lineNumber":189,"sourceCode":"\n    @SneakyThrows\n    @Override\n    public void close() throws IOException {\n        log.info(\"Close split enumerator.\");\n        if (icebergCatalog instanceof AutoCloseable) {\n            ((AutoCloseable) icebergCatalog).close();\n        }\n    }\n\n    protected Table loadTable(TablePath tablePath) {\n        return icebergCatalog.loadTable(\n                TableIdentifier.of(tablePath.getDatabaseName(), tablePath.getTableName()));\n    }\n\n    protected void checkThrowInterruptedException() throws InterruptedException {\n        if (Thread.currentThread().isInterrupted()) {\n            log.info(\"Enumerator thread is interrupted.\");\n            throw new InterruptedException(\"Enumerator thread is interrupted.\");\n        }\n    }\n\n    private static int getSplitOwner(String splitId, int numReaders) {\n        return HashUtils.bucketIndex(splitId.hashCode(), numReaders);\n    }\n\n    protected void addPendingSplits(Collection<IcebergFileScanTaskSplit> newSplits) {\n        int numReaders = context.currentParallelism();\n        for (IcebergFileScanTaskSplit newSplit : newSplits) {\n            int ownerReader = getSplitOwner(newSplit.splitId(), numReaders);\n            pendingSplits.computeIfAbsent(ownerReader, r -> new ArrayList<>()).add(newSplit);\n            log.info(\"Assigning {} to {} reader.\", newSplit, ownerReader);\n        }\n    }\n\n    protected void assignPendingSplits(Set<Integer> pendingReaders) {\n        for (int pendingReader : pendingReaders) {","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/source/enumerator/AbstractSplitEnumerator.java#L171-L207","documentation":"AbstractSplitEnumerator.checkThrowInterruptedException() polls the thread's interrupt flag and, if set, throws InterruptedException with this message. It lets the streaming enumerator exit promptly when SeaTunnel is cancelling the job instead of continuing to plan splits.","triggerScenarios":"Job cancellation or terminal failure while the enumerator thread runs; the interrupt flag is set (usually by the engine's job cancellation) and the enumerator next calls this check (e.g. before planning the next batch of splits).","commonSituations":"User cancels a streaming iceberg job via CLI/UI; job fails and the engine interrupts coordinator threads; slow split planning keeps the enumerator alive until the next check point.","solutions":["No fix needed — this is a normal, expected shutdown path; let the InterruptedException propagate","If it appears while the job should still be running, investigate what interrupted the thread (engine shutdown, master node restart)","Avoid swallowing InterruptedException in custom code around the enumerator, which delays clean shutdown"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { enumerator.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); /* clean exit, expected on cancel */ }","preventionTips":["Treat this as normal cancellation, not a failure","Don't clear or swallow the interrupt flag in wrapping code","Check engine logs to distinguish expected cancel from unexpected interruption"],"tags":["iceberg","interruption","shutdown"],"backgroundTag":"thread-interrupted","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}