登录
首页 >  Golang >  Go问答

在 Cadence 工作流程中实现循环调用相同活动

来源:stackoverflow

时间:2024-02-21 13:57:23 306浏览 收藏

你在学习Golang相关的知识吗?本文《在 Cadence 工作流程中实现循环调用相同活动》,主要介绍的内容就涉及到,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺的哦!

问题内容

我在 cadence 工作流程中有一个问题,我们可以在 for 循环内使用不同的输入调用相同的活动吗?该代码是确定性的吗?如果执行工作流的工作线程在执行过程中停止并稍后重新启动,那么 cadence 重新构建工作流时是否能够重播事件。

例如,我有以下代码。

func init() {
    workflow.RegisterWithOptions(SampleWorkFlow, workflow.RegisterOptions{Name: "SampleWorkFlow"})
    activity.RegisterWithOptions(SampleActivity, activity.RegisterOptions{Name: "SampleActivity"})
    activity.RegisterWithOptions(SecondActivity, activity.RegisterOptions{Name: "SecondActivity"})
}

// SampleWorkFlow comment
func SampleWorkFlow(ctx workflow.Context, input string) error {

    fmt.Println("Workflow started")
    ctx = workflow.WithTaskList(ctx, sampleTaskList)
    ctx = workflow.WithActivityOptions(ctx, conf.ActivityOptions)

    var result string
    err := workflow.ExecuteActivity(ctx, "SampleActivity", input, "string-value").Get(ctx, &result)
    if err != nil {
        return err
    }

    for i := 1; i <= 10; i++ {
        value := i
        workflow.Go(ctx, func(ctx workflow.Context) {
            err := workflow.ExecuteActivity(ctx, "SecondActivity", input, value).Get(ctx, &result)
            if err != nil {
                log.Println("err=", err)
            }
        })
    }

    return nil

}

// SampleActivity comment
func SampleActivity(ctx context.Context, value, v1 string) (string, error) {
    fmt.Println("Sample activity start")
    for i := 0; i <= 10; i++ {
        fmt.Println(i)
    }
    return "Hello " + value, nil
}

// SecondActivity comment
func SecondActivity(ctx context.Context, value int) (string, error) {

    fmt.Println("Second  activity start")

    fmt.Println("value=", value)
    fmt.Println("Second activity going to end")
    return "Hello " + fmt.Sprintf("%d", value), nil
}

这里,第二个活动在 for 循环内并行调用。 我的第一个问题是这段代码是确定性的吗?

假设循环迭代 5 次后,当 i =5 时,执行此工作流程的工作人员终止,如果工作流程在另一个工作流程中启动,那么 cadence 是否能够重播事件 工人?

你能回答我的问题吗?


解决方案


是的,这段代码是确定性的。它不会调用任何非确定性操作(例如随机或 uuid 生成)并使用 workflow.go 来启动 goroutine。所以它是确定性的。代码的复杂性并不影响其确定性。

不相关的 nit。 无需在示例中使用 goroutine,因为 executeactivity 调用已通过返回 future 实现非阻塞。 因此示例可以简化为:

func sampleworkflow(ctx workflow.context, input string) error {

    fmt.println("workflow started")
    ctx = workflow.withtasklist(ctx, sampletasklist)
    ctx = workflow.withactivityoptions(ctx, conf.activityoptions)

    var result string
    err := workflow.executeactivity(ctx, "sampleactivity", input, "string-value").get(ctx, &result)
    if err != nil {
        return err
    }

    for i := 1; i <= 10; i++ {
       workflow.executeactivity(ctx, "secondactivity", input, i)
    }
    return nil
}

请注意,此示例仍然可能不会按照您期望的方式执行,因为它会在不等待活动完成的情况下完成工作流。所以这些活动根本就不会开始。

以下是等待活动完成的代码:

func SampleWorkFlow(ctx workflow.Context, input string) error {

    fmt.Println("Workflow started")
    ctx = workflow.WithTaskList(ctx, sampleTaskList)
    ctx = workflow.WithActivityOptions(ctx, conf.ActivityOptions)

    var result string
    err := workflow.ExecuteActivity(ctx, "SampleActivity", input, "string-value").Get(ctx, &result)
    if err != nil {
        return err
    }
    var results []workflow.Future
    for i := 1; i <= 10; i++ {
        future := workflow.ExecuteActivity(ctx, "SecondActivity", input, i)
        results = append(results, future)
    }
    for i := 0; i < 10; i++ {
        var result string
        err := results[i].Get(ctx, &result)
        if err != nil {
            log.Println("err=", err)
        }
    }
    return nil
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>