程序在尝试终止进程时挂起,直到最终被终止



我正在努力修复一个使我们的 CI/CD 管道失败的错误。在集成测试期间,我们启动了一个本地数据库实例。为了做到这一点,我们使用一些mariadb包装器从java代码库启动它。

此过程可能(可能(需要很长时间才能完成,这将导致我们的测试超时。在这种情况下,我们添加了一项功能,如果进程无法在 20 秒内安装并且应重试,则可以终止该进程。

这部分似乎正在工作。

奇怪的一点是在试图破坏该过程时出现的。似乎随机需要~2-3分钟才能解锁。这是有问题的,原因与上述问题有问题的原因相同。

在对底层库进行调查后,我们似乎正在使用 ExecuteWatchdog 来管理该过程。阻塞的代码是:

watchDog.destroyProcess();
// this part usually returns nearly instantly
try {
// this part can take minutes...
resultHandler.waitFor();
} catch (InterruptedException e) {
throw handleInterruptedException(e);
}

除此之外,Mac/Linux上还有不同的行为。如果我做类似resultHandler.waitFor(1000) // Wait with 1000ms timeout before just exiting,它可以在 macbook 上运行良好,但在 Linux 上我看到如下错误:java.io.FileNotFoundException: {{executable}} (Text file busy)

对此有什么想法吗?

我做了一些研究,似乎watchDog.destroyProcess发送的是SIGTERM而不是SIGKILL。但是我没有任何钩子来获取Process对象以向其发送 KILL 代替。

谢谢。

使用进程时阻塞的常见原因是进程在输出时被阻塞,无论是 stdout 还是(更有可能被忽略(stderr。

在此上下文中,在 CI 服务器上设置测试时,可以尝试将输出和错误输出设置为INHERIT

请注意,这意味着您将无法读取 Java 代码中的子流程输出或错误流。我的假设是,无论如何你都不会试图这样做,这就是这个过程挂起的原因。相反,该输出将被重定向到 Java 进程的输出,我希望您的 CI 服务器会将其记录为构建的一部分。

最新更新