0

我们正在编写一个 .NET Cadence 客户端,并且对MutableSideEffect()应该如何工作感到有些困惑。我们一直认为传递的ID本质上是一个变量名,开发人员应该能够在工作流中更新可变值。但是,当我们尝试这样做时,第二个MutableSideEffect()调用失败并出现以下恐慌:

panic: adding duplicate decision DecisionType: Marker, ID: MutableSideEffect_value-1, state=Created, isDone()=false, history=[Created]

我们使用了问候工作流示例来进行这些调用:

package main

import (
    "fmt"
    "math/rand"
    "time"

    "go.uber.org/cadence/activity"
    "go.uber.org/cadence/workflow"
    "go.uber.org/zap"
)

/**
 * This greetings sample workflow executes 3 activities in sequential. It gets greeting and name from 2 different activities,
 * and then pass greeting and name as input to a 3rd activity to generate final greetings.
 */

// ApplicationName is the task list for this sample
const ApplicationName = "greetingsGroup"

// This is registration process where you register all your workflows
// and activity function handlers.
func init() {
    workflow.Register(SampleGreetingsWorkflow)
    activity.Register(getGreetingActivity)
    activity.Register(getNameActivity)
    activity.Register(sayGreetingActivity)
}

// SampleGreetingsWorkflow Workflow Decider.
func SampleGreetingsWorkflow(ctx workflow.Context) error {
    // Get Greeting.
    ao := workflow.ActivityOptions{
        ScheduleToStartTimeout: time.Minute,
        StartToCloseTimeout:    time.Minute,
        HeartbeatTimeout:       time.Second * 20,
    }
    ctx = workflow.WithActivityOptions(ctx, ao)

    logger := workflow.GetLogger(ctx)
    var greetResult string
    err := workflow.ExecuteActivity(ctx, getGreetingActivity).Get(ctx, &greetResult)
    if err != nil {
        logger.Error("Get greeting failed.", zap.Error(err))
        return err
    }

    f := func(ctx workflow.Context) interface{} {
        return rand.Intn(100)
    }

    e := func(a, b interface{}) bool {
        if a == b {
            return true
        }

        return false
    }

    var result int
    sideEffectValue := workflow.MutableSideEffect(ctx, "value-1", f, e)
    err = sideEffectValue.Get(&result)
    if err != nil {
        panic(err)
    }

    logger.Debug("MutableSideEffect-1", zap.Int("Value", result))

    //************** THIS CALL FAILS ************** 

    sideEffectValue = workflow.MutableSideEffect(ctx, "value-1", f, e)
    err = sideEffectValue.Get(&result)
    if err != nil {
        panic(err)
    }

    logger.Debug("MutableSideEffect-2", zap.Int("Value", result))

    // Get Name.
    var nameResult string
    err = workflow.ExecuteActivity(ctx, getNameActivity).Get(ctx, &nameResult)
    if err != nil {
        logger.Error("Get name failed.", zap.Error(err))
        return err
    }

    // Say Greeting.
    var sayResult string
    err = workflow.ExecuteActivity(ctx, sayGreetingActivity, greetResult, nameResult).Get(ctx, &sayResult)
    if err != nil {
        logger.Error("Marshalling failed with error.", zap.Error(err))
        return err
    }

    logger.Info("Workflow completed.", zap.String("Result", sayResult))
    return nil
}

// Get Name Activity.
func getNameActivity() (string, error) {
    return "Cadence", nil
}

// Get Greeting Activity.
func getGreetingActivity() (string, error) {
    return "Hello", nil
}

// Say Greeting Activity.
func sayGreetingActivity(greeting string, name string) (string, error) {
    result := fmt.Sprintf("Greeting: %s %s!\n", greeting, name)
    return result, nil
}

我们是否正确地考虑了这一点?

4

1 回答 1

0

这是 Go 客户端库中的一个错误。当在一个决策期间多次使用具有相同 id 的 MutableSideEffect 时,就会发生这种情况。

workflow.Sleep(ctx, time.Second)如果您通过在第二次通话之前提出单独的决定,MutableSideEffect问题就会消失。

我提出了一个问题来解决这个问题。

非常感谢您的报告!

于 2019-06-19T18:49:17.877 回答