【发布时间】:2022-06-17 12:11:04
【问题描述】:
我可以通过不同的方式实现信号方法(处理程序)。但是,我有时会遇到以下问题:
- 我要保证 FIFO 处理
- 我想处理过早调用信号方法的 signalWithStart 的“比赛条件”
- 我希望安全地重置工作流程。重置后,信号可以在历史早期重新应用
- 我想确保工作流不会在处理信号之前提前完成
【问题讨论】:
标签: cadence-workflow temporal-workflow uber-cadence
我可以通过不同的方式实现信号方法(处理程序)。但是,我有时会遇到以下问题:
【问题讨论】:
标签: cadence-workflow temporal-workflow uber-cadence
这些是在 Cadence/Temporal 工作流程中使用信号时最常见的错误。
您可以应用一种设计模式来共同解决所有问题。
这个想法是简化信号处理程序以始终将信号放入队列中,并且工作流方法将启动另一个工作流线程来处理队列。
public class MyWorkflow{
private Queue<SignalRequest> signalRequestQueue = new LinkedList<>();
public void mySignalMethod(SignalRequest req){
signalRequestQueue.add(req);
}
public Output myWorkflwMethod(Input input){
//1. do everything necessary/needed before actually processing a signal
...
//2. spin up a workflow thread to process
Async.procedure(
() -> {
while (true) {
Workflow.await(() -> !signalRequestQueue.isEmpty());
final SignalRequest request = signalRequestQueue.poll();
processSignal(request);
}
});
//3. always wait for queue to be empty before completing the workflow(return)
Workflow.await(() -> signalRequestQueue.isEmpty());
return output
}
private void processSignal(request){
// do your actual processing here.
// If a process a single signal may take too much time and you don't care about FIFO, you could also start another workflow thread to process signals in parallel.
...
}
}
Golang SDK 没有 1/2/3 的相同问题。这是 Golang SDK 提供了一个完全不同的 API 来处理信号。
Golang SDK 不需要将信号方法定义为处理程序,而是需要工作流侦听通道来处理信号,这正是这个答案所建议的。查看信号 API 的示例。
唯一的问题是 4 - 确保工作流程不会在处理信号之前提前完成。这是 Golang SDK 的常见错误。建议是在完成或 continueAsNew 工作流之前始终排空信号通道。 See this sample of how to drain signal channel in Golang.
【讨论】: