任务的输出指的是任务执行产生的输出结果,以 Key-Value 的形式体现,TCT SDK 从 2.1.7 版本开始支持输出结果。
注意:
由于 SDK 在 2.1.7 后续的几个版本中修复了几个重要的问题,建议使用 2.1.12 或之后的 SDK 版本。
上报输出结果
不同类型的任务(如 Java、Shell)上报输出结果的方式略有不同,我们将分别进行介绍。
Java 类型任务
在 TCT SDK 中,我们在 ProcessResult 类中新增了 output 字段(Map<String, String> 类型)用于收集任务执行后的输出结果。用户可以调用 ProcesResult 提供的以下方法添加输出结果:
public ProcessResult withOutput(String key, String value);
public ProcessResult withOutputs(Map<String, String> values);
例如:
public ProcessResult execute(ExecutableTaskData taskData) {
ProcessResult result = ProcessResult.newSuccessResult();
return result.withOutput("code", "OK").withOutput("score", "100");
}
Python/Shell 脚本任务
对于 Python 和 Shell 脚本任务,TCT 在执行的时候会自动注入上报日志的工具方法,业务脚本里可以直接调用。
Python 示例:
reportOutput("score", 100)
reportOutput("code", "OK")
Shell 示例:
reportOutput score 100
reportOutput code OK
外部任务
目前外部任务不支持上报输出结果。
获取输入数据
任务在工作流中执行的时候,可以获取该任务依赖的前置任务的输出结果,以作为该任务执行时的输入,TCT 会自动将这部分数据作为输入数据传递到任务执行中。

对于上图中的工作流,任务 A、B 已经执行成功,任务 C 正在执行,这时候任务 C 将会获得类似于以下的输入。其中 A、B 为任务 C 依赖的任务的 ID,每个 ID 下以 Key-Value 的形式列举出该任务执行的输出结果。
{
"A": {
"key1": "value1",
"key2": "value2"
},
"B": {
"key3": "value3"
}
}
Java 类型任务
在任务开发中,我们可以通过 ExecutableTaskData 的 getInput 方法获取任务的输入数据:
public Map<String, Map<String, Object>> getInput();
例如,在以下示例中我们将任务的输入数据打印到执行日志中:
public ProcessResult execute(ExecutableTaskData taskData) {
if (taskData.getInput() != null && taskData.getInput().size() > 0) {
LogReporter.log(taskData, JsonJackson.writeAsString(taskData.getInput()));
}
ProcessResult result = ProcessResult.newSuccessResult();
return result.withOutput("code", "OK").withOutput("score", "100");
}
需要特别注意的事,在工作流执行中以下情况并不会有数据传递到后续节点中:
场景一:子工作流执行的时候不会有输入数据,下图中,节点 C 是一个子工作流,那么在 C 执行的时候我们不会传递输入数据。
场景二:工作流节点不会有输出结果,下图中由于节点 B 是工作流,那么任务 C 执行的时候只会有 A 的数据输入,节点 B 并不会有数据输入到 C。
场景三:只有执行结束的任务节点才会有数据传递到后续节点中,执行中的任务节点不会传递数据。下图中的任务 B 节点仍处于执行中,所以节点 C 执行的时候只会有任务 A 的数据传递过来。
Python/Shell 类型任务
Python 和 Shell 任务,可以在脚本里通过环境变量 TCT_INPUT 获取工作流上游传递来的输入数据。例如:
echo "Input data: ${TCT_INPUT:-{}}"
echo "Shell task finished."
外部任务
对于外部任务,TCT 会在调用外部任务接口时,将输入数据以 HTTP Header 方式传递,Header 名为 TASK-INPUT,输入数据为 JSON 格式字符串 Base64 编码后的结果。
注意:
HTTP 的 Header 支持的数据量大小不是无限的,取决于具体的服务器、代理和服务端,一般都被限制在 4K-16K,因此需要关注外部任务输入数据的数据量。
任务批次输出结果
对于分片和广播任务,一次执行(一个任务执行批次)会产生多个子任务,每个子任务都会上报输出结果到 TCT 中。这样对于一个任务执行批次,同样的 Key 会有多个值(每个子任务一个)。对于这样的输出结果我们可以配置聚合规则,对这些值进行聚合。
在创建任务的时候,我们可以在高级设置中对输出结果进行聚合(注意只有分片执行和广播执行的时候才会有聚合输出配置)。这里的聚合规则会将原始的字段通过求和、求平均等操作聚合得到一个新的字段,例如下图中,对子任务上报的 score 字段,进行求和,得到新的 sum 字段。
注意:
需要用户确保这里配置的待聚合字段存在,并且数据的类型支持聚合,当前聚合操作只支持数值类型。
聚合的输出结果会和原始数据一起作为任务执行批次的输出结果,例如一下执行批次的输出结果包含原始的结果以及聚合后的结果:

对于原始的输出结果,可以展开查看是哪个子任务上报的:
注意:
控制台上,我们只对执行状态为成功的任务批次显示输出结果。

在工作流中,传递给任务节点的输入数据既包含原始的输出数据(数组形式)也包含聚合后的数据,假设上图中节点 B 是分片任务,而节点 A 是单播任务,那么任务 C 接收到的输入数据将是以下形式:
{
"A": {
"code": "ok",
"score": "84"
},
"B": {
"code": ["ok", "ok", "ok"],
"score": ["99", "100", "98"],
"aggregate_avg": 99,
"aggregate_max": 100
}
}