将外部事件发送到工作流

时间:2019-06-12 19:06:58

标签: cadence-workflow

在节奏工作流程中,我们通常需要等待一定时间的外部事件才能继续(例如,读取电子邮件,单击链接等)。

我想知道将这些事件通知我们的工作流程的最佳方法是什么。信号是正确的方式,还是我们应该创建一个等待事件的活动?

根据我所看到的,我们需要创建一个信号通道ch := workflow.GetSignalChannel(ctx, SignalName),但是活动中没有上下文。

1 个答案:

答案 0 :(得分:2)

信令是将事件发送到工作流的推荐方法。

Go工作流程的常用模式是使用Selector等待多个信号通道以及一个计时器将来。

去样本:

sig1Ch := workflow.GetSignalChannel(ctx, "signal1")
sig2Ch := workflow.GetSignalChannel(ctx, "signal2")
timeout := workflow.NewTimer(ctx, time.Minute * 30)

s := workflow.NewSelector(ctx)

var signal1 *Signal1Struct
var signal2 *Signal2Struct
s.AddFuture(timeout, func(f Future) {
})
s.AddReceive(sig1Ch, func(c Channel, more bool) {
    c.Receive(ctx, signal1)
})
s.AddReceive(sig2Ch, func(c Channel, more bool) {
    c.Receive(ctx, signal2)
})

s.Select(ctx)

if signal1 == nil && signal2 == nil {
   // handle timeout
} else {
  // process signals
}

Java示例:

public interface MyWorkflow {

    @WorkflowMethod
    void main();

    @SignalMethod
    void signal1(Signal1Struct signal);

    @SignalMethod
    void signal2(Signal2Struct signal);

}

public class MyWorkflowImpl implements MyWorkflow {

    private Signal1Struct signal1;
    private Signal2Struct signal2;

    @Override
    public void main() {
        Workflow.await(Duration.ofMinutes(30), 
            () -> signal1 != null || signal2 != null);

        if (signal1 == null && signal2 == null) {
            // handle timeout
        }
        // process signals
    }

    @Override
    public void signal1(Signal1Struct signal) {
        signal1 = signal;
    }

    @Override
    public void signal2(Signal2Struct signal) {
        signal2 = signal;
    }
}

请注意,考虑到工作流工作者的中断是一个好主意。例如,假设上面的工作流程已启动,并且在所有工作流程工作人员都关闭的情况下,启动后40分钟收到了一个信号。在这种情况下,将工作人员带回timeout的将来和signCh都不会为空。由于选择器不能保证排序,因此即使在计时器之后接收到信号,也有可能在计时器之前发送信号。因此,您的代码逻辑应对此进行说明。例如,有一个严格的要求,即必须忽略自工作流程开始以来30分钟之后收到的信号。然后,必须将以上示例修改为:

去样本:

...
start := workflow.Now(ctx); // must use workflow clock
s.Select(ctx)
duration := workflow.Now(ctx).Sub(start)
if duration.Minutes() >= 30 || (signal1 == nil && signal2 == nil) {
   // handle timeout
} else {
  // process signals
}

Java示例:

public void main() {
    long start = Workflow.currentTimeMillis(); // must use workflow clock
    Duration timeout = Duration.ofMinutes(30);
    Workflow.await(timeout, () -> signal1 != null || signal2 != null);
    long duration = Workflow.currentTimeMillis() - start;
    if (timeout.toMillis() <= duration || (signal1 == null && signal2 == null)) {
        // handle timeout
    }
    // process signals
}

即使工作流执行延迟了一个小时,更新的代码仍可以正常工作。