簡體   English   中英

在節奏工作流的循環內調用相同的活動

[英]Invoking the same activity inside a loop in cadence workflow

我在 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 .Go 來啟動一個 goroutine。 所以它是確定性的。 代碼的復雜性在定義其確定性方面不起作用。

無關的尼特。 沒有必要在您的示例中使用 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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM