如何解决在节奏工作流中的循环内调用相同的活动
我在节奏工作流程中有一个疑问,我们是否可以在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",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时,执行此工作流程的工作人员将终止,如果工作流程在另一个环境中启动,则节奏可以重播事件。 工人?
你能回答我的问题吗?
解决方法
是的,此代码是确定性的。它不会调用任何非确定性操作(如随机或UUID生成),而是使用workflow.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",i)
}
return nil
}
请注意,此示例可能仍未按预期方式执行,因为它无需等待活动完成即可完成工作流。因此,这些活动甚至都不会开始。
这是等待活动完成的代码:
func SampleWorkFlow(ctx workflow.Context,&result)
if err != nil {
return err
}
var results []workflow.Future
for i := 1; i <= 10; i++ {
future := workflow.ExecuteActivity(ctx,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
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。