【问题标题】:Custom TeamCity plugin with a Build Feature that executes a long running process具有执行长时间运行过程的构建功能的自定义 TeamCity 插件
【发布时间】:2018-11-07 16:33:51
【问题描述】:

我正在开发一个与企业部署平台集成的自定义 TeamCity 插件。它应该在构建结束时通过执行命令行命令将二进制文件部署到某个部署平台。目前有一个类扩展了服务器端的 BuildFeature 类来设置要部署的工件的详细信息。在代理端有一个扩展 AgentLifeCycleAdapter 类的类,它覆盖 beforeBuildFinish() 方法并执行长时间运行的命令行进程。我正在使用 SimpleCommandLineProcessRunner 类来执行外部命令行进程:

final ExecResult result = SimpleCommandLineProcessRunner.runCommand(commandLine,
        null,
        new SimpleCommandLineProcessRunner.RunCommandEventsAdapter());

进程在两分钟后停止,看起来像是超时了:

[18:13:50]作为 atom_builder 运行 [18:13:50]执行 C:\TeamCity\buildAgent\work\db4107aa7e390a67\adeploy\adeploy.exe 神器版本推送 C:\TeamCity\buildAgent\work\db4107aa7e390a67\agent\atom-agent-artifact-version.xml [18:13:50]在 C:\TeamCity\buildAgent\work\db4107aa7e390a67\agent 运行 [18:15:22]2018-11-07 18:13:51 [信息] ["ArtifactPushService:PushArtifactAsync"] 使用参数调用方法 '"adeploy.exe" [18:15:22]退出代码:-1

当构建配置具有自定义构建功能时,在构建过程中执行长时间运行的进程的正确方法是什么?

【问题讨论】:

  • 默认情况下对执行时间没有任何限制。您通常使用ping localhost -n 3600 之类的命令构建命令行步骤,它将在 1 小时内成功运行。我猜你的代码中有一些东西。
  • @daggett 你是对的,这与我的代码有关。我找到了原因。

标签: teamcity


【解决方案1】:

我找到了答案,所以我会在这里发布,以防其他人遇到同样的问题。

既然我们在谈论自定义插件,它完全是在执行外部进程的插件的代理端的代码中。如问题所述,外部进程使用 SimpleCommandLineProcessRunner 类执行,并传递 RunCommandEventsAdapter 类的实例。最后一个在 getOutputIdleSecondsTimeout() 方法中返回 null。这意味着 SimpleCommandLineProcessRunner 将使用 90 秒的默认超时,除非它在 ​​teamcity.execution.timeout 参数中定义。

所以解决方法是定义一个实现ProcessRunCallback接口的LongRunningProcessRunCallback类。注意 getOutputIdleSecondsTimeout() 返回的超时时间很长。

public class LongRunningProcessRunCallback implements SimpleCommandLineProcessRunner.ProcessRunCallback {

    private static final int DEFAULT_TIMEOUT_SECONDS = 60 * 60 * 24;

    @Nullable
    @Override
    public Integer getMaxAcceptedOutputSize() {
        return null;
    }

    @Override
    public void onProcessStarted(@NotNull Process process) {

    }

    @Override
    public void onProcessFinished(@NotNull Process process) {

    }

    @Nullable
    @Override
    public Integer getOutputIdleSecondsTimeout() {
        return TeamCityProperties.getInteger("teamcity.execution.timeout", DEFAULT_TIMEOUT_SECONDS);
    }
}

然后将其传递给 SimpleCommandLieProcessRunner:

final ExecResult result = SimpleCommandLineProcessRunner.runCommand(commandLine,
                null,
                new LongRunningProcessRunCallback());

【讨论】:

    猜你喜欢
    • 2017-09-07
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    相关资源
    最近更新 更多