{"record":{"id":"25c104673900f8c1","repo":"apache/seatunnel","slug":"python-source-process-did-not-terminate-after-forc","errorCode":null,"errorMessage":"Python source process did not terminate after forced shutdown","messagePattern":"Python source process did not terminate after forced shutdown","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceReader.java","lineNumber":753,"sourceCode":"    private static void destroyProcess(Process runningProcess, long timeoutMillis) {\n        if (!runningProcess.isAlive()) {\n            return;\n        }\n\n        boolean interrupted = false;\n        runningProcess.destroy();\n        try {\n            if (!runningProcess.waitFor(timeoutMillis, TimeUnit.MILLISECONDS)) {\n                runningProcess.destroyForcibly();\n            }\n        } catch (InterruptedException e) {\n            interrupted = true;\n            runningProcess.destroyForcibly();\n        }\n        if (runningProcess.isAlive()) {\n            try {\n                if (!runningProcess.waitFor(timeoutMillis, TimeUnit.MILLISECONDS)) {\n                    LOG.warn(\"Python source process did not terminate after forced shutdown\");\n                }\n            } catch (InterruptedException e) {\n                interrupted = true;\n            }\n        }\n        if (interrupted) {\n            Thread.currentThread().interrupt();\n        }\n    }\n\n    /**\n     * Closes all Java pipe endpoints so blocked reader and writer threads can terminate.\n     *\n     * <p>Bounded on purpose. When a child process inherited stdout, the pipe stays open on the\n     * child's side and closing the read end blocks behind the pump thread's pending read until that\n     * child exits. On Windows that wait is not interruptible by the close itself, so performing it\n     * inline would let cancellation exceed the reader's bounded shutdown window. The close is\n     * handed to a daemon thread instead: the process has already been destroyed by this point, so","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceReader.java#L735-L771","documentation":"During close(), after the Python process fails to terminate gracefully (interrupt signal), the reader calls destroyForcibly() and waits. If the process is still alive after the forced-shutdown wait times out, this warning is logged — the OS-level process could not be killed within the timeout window.","triggerScenarios":"close() -> destroyProcess(): runningProcess.destroy() then destroyForcibly() both fail to end the process within timeoutMillis, detected via waitFor returning false.","commonSituations":"Python process stuck in uninterruptible I/O or ignoring SIGTERM/SIGKILL delivery windows; D-state processes on overloaded hosts; detached grandchildren keeping the session busy.","solutions":["Investigate the Python script for uninterruptible operations (D-state I/O, native calls)","Kill the process manually at the OS level (kill -9 <pid>) and check for zombie/descendant processes","Increase the destroy timeout on slow hosts","Avoid Python scripts that fork detached children which survive cancellation"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// verify the script handles SIGTERM and exits within a few seconds before deploying\n// timeout 5s python3 script.py < /dev/null && echo exits-cleanly","typeGuard":null,"tryCatchPattern":"try { reader.close(); } catch (IOException e) { /* surfaced close failure */ log.warn(\"python process cleanup incomplete: {}\", e.getMessage()); }","preventionTips":["Avoid native/blocking calls that ignore signals","Kill orphaned processes after jobs (process supervisor)","Test script termination behavior under load","Increase timeouts on slow/loaded hosts"],"tags":["python","process-kill","shutdown"],"backgroundTag":"request-timeout","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}