当前位置: 首页 > 知识库问答 >
问题:

将外部事件发送到工作流

屈昊天
2023-03-14

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

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

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

共有1个答案

楚墨一
2023-03-14

信令是向工作流发送事件的推荐方式。

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

Go示例:

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分钟收到信号,而所有工作流工作人员都已关闭。在这种情况下,当工作人员被带回时,timeoutFuture和signCh都不会为空。由于Selector不保证排序,因此信号可能会在计时器之前传递,即使它是在计时器之后收到的。因此您的代码逻辑应该考虑到这一点。例如,有一个硬性要求,必须忽略自工作流启动30分钟后收到的信号。然后必须将上述示例修改为:

Go示例:

...
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
}

即使工作流执行延迟了一个小时,更新后的代码也会正常运行。

Go示例:

c, err := client.NewClient(client.Options{
    HostPort: client.DefaultHostPort,
})
if err != nil {
    log.Fatalln("Unable to create client", err)
}
defer c.Close()

err := c.SignalWorkflow(context.Background(), <workflowId>, "", "signal1", Signal1Struct{})

Java示例:

WorkflowServiceStubs service = WorkflowServiceStubs.newInstance();
WorkflowClient client = WorkflowClient.newInstance(service);
GreetingWorkflow myWorkflow = 
client.newWorkflowStub(MyWorkflow.class, <workflowId>);
myWorkflow.signal1(new Signal1Struct());
 类似资料:
  • 我有两个Rest终点。 -身份提供程序,在用户通过用户名/密码的身份验证后,发送JWT令牌作为响应。 -接受上述JWT令牌作为头,对其进行验证,如果令牌有效,则发送用户JSON作为响应。 我已经使用Angular2创建了我的UI null

  • 事件可以由Hyperledger Composer发出并由外部应用程序订阅。事件在业务网络定义的模型文件中定义,并由交易处理器函数文件中的交易JavaScript发出。 在你开始之前 在开始将事件添加到您的业务网络之前,您应该对业务网络的建模语言以及构成完整的业务网络定义的内容有深入的了解。 过程 1.事件在业务网络定义的模型文件(.cto)中定义,与资产和参与者相同。事件使用以下格式: e

  • 我想在使用nuxt auth模块的nuxt项目中,通过axios向外部API发送POST请求。 当用户通过身份验证时,axios似乎会自动添加授权头(这很好,并且经常需要调用我的后端API)。但是,在调用外部API时,标头可能不被接受,并导致调用失败。 有没有办法指定应该为哪些URL添加或排除授权头? 以下是my 更多背景:在我的特定用例中,我想将一个文件上传到AmazonS3存储桶中,因此我创建

  • 我在tomcat 8.0上使用java尝试了一个SSE(服务器发送事件)。以下是我注意到的几件事。 我单击一个按钮,它会自动向servlet发出请求。执行Servlet的GET方法,返回事件流。一旦收到完整的数据流,页面会再次自动发出另一个请求,再次接收相同的数据!!!我没有无限循环!!! > 什么是正确的方法来确保事件流只发送一次到同一个连接/浏览器会话? 什么是正确的方法来确保事件流被关闭并且

  • 问题内容: 我正在使用以下命令在ubuntu中连接“ / bin / bash”: 这里的cmd是一个字符串,其中包含我从进程读取和写入的不同命令。 现在我遇到了一种情况,我使用ssh登录到远程机器,并且在将信息写入ext进程时,要从远程计算机注销,我必须发送如下控制字符: 为了正常退出会话并返回我的本地计算机。假设cmd是String类型,我如何将此chracter 写入进程? 问题答案: AS

  • 我有一个Github repo项目,使用Github操作和一个docker文件来构建SpringBoot Java项目 我想从Github repo下载来自Github repo的定制工件包,并能够将工件上传到其中。 所以我按照配置Apache Maven用于GitHub包的链接,将该部分添加到settings.xml文件中: 为了从dockerfile构建中发布包,我在pom.xml中添加了以下