Heim >Backend-Entwicklung >Golang >Wie kann ich denselben Workflow mit Cadence RegisterDelayedCallback in einem Komponententest ausführen?

Wie kann ich denselben Workflow mit Cadence RegisterDelayedCallback in einem Komponententest ausführen?

WBOY
WBOYnach vorne
2024-02-10 10:50:09679Durchsuche

如何在单元测试中使用 cadence RegisterDelayedCallback 执行相同的工作流程?

php-Editor Baicao stellt Ihnen vor, wie Sie Cadence RegisterDelayedCallback in Unit-Tests verwenden, um denselben Workflow auszuführen. Bei Unit-Tests müssen wir häufig asynchrone Vorgänge simulieren, um die Korrektheit des Codes unter verschiedenen Umständen sicherzustellen. Cadence RegisterDelayedCallback ist ein leistungsstarkes Tool, mit dem wir verzögerte Rückruffunktionen in Tests simulieren können. Durch die Verwendung von RegisterDelayedCallback können wir asynchrone Vorgänge einfach simulieren, die Korrektheit des Codes in verschiedenen Situationen sicherstellen und potenzielle Probleme reproduzieren und beheben. In diesem Artikel erfahren Sie, wie Sie mit Cadence RegisterDelayedCallback denselben Workflow ausführen, um den Unit-Test zu verbessern.

Frageninhalt

Ist es möglich, Komponententests mit registerdelayedcallback durchzuführen, die den gleichen Rhythmus-Workflow ausführen?

Ich habe den folgenden Code, der den Workflow zweimal ausführt. Bei der ersten Ausführung wird das Rückruftoken gespeichert und bei der zweiten Ausführung wird das gespeicherte Token abgerufen, um die Aktivität asynchron abzuschließen.

workflow.go

package workflow

import (
    "context"
    "encoding/base64"
    "fmt"

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

type workflowimpl struct {
    worker.worker
    client.client
}

func (w workflowimpl) tactivity(ctx context.context, action string) error {
    fmt.println("tactivity started", action)
    if action != "approved" {
        activityinfo := activity.getinfo(ctx)
        callbacktoken := base64.stdencoding.encodetostring(activityinfo.tasktoken)
        fmt.println("save callbacktoken", callbacktoken)
        // saves callbacktoken.

        return activity.errresultpending
    }

    fmt.println("approved")
    // do some approved things.
    // get saved callback token.
    // call w.completeactivity() with the saved callback token.
    return nil
}

func (w workflowimpl) tworkflow(ctx workflow.context, action string) (result string, err error) {
    fmt.println("tworkflow started", action)

    waitchannel := workflow.newchannel(ctx)
    workflow.go(ctx, func(ctx workflow.context) {
        if err := workflow.executeactivity(ctx, w.tactivity, action).get(ctx, nil); err != nil {
            // do nothing, keep workflow open.
            return
        }

        waitchannel.send(ctx, "ok")
    })

    var signal string
    waitchannel.receive(ctx, &signal)

    return signal, nil
}

workflow_test.go

package workflow_test

import (
    "time"
    "go.uber.org/cadence/worker"
)

func (s *UnitTestSuite) Test_TWorkflow() {
    env := s.NewTestWorkflowEnvironment()

    worker := workflow.WorkflowImpl{
         Worker: ...
         Client: ...
    }

    s.worker = &worker

    env.RegisterActivity(s.worker.TActivity)

    // Delay second TWorkflow.
    env.RegisterDelayedCallback(func() {
        env.ExecuteWorkflow(s.worker.TWorkflow, "Approved")
    }, time.Second*2)

    env.ExecuteWorkflow(s.worker.TWorkflow, "Noop")
    s.True(env.IsWorkflowCompleted())
    s.NoError(env.GetWorkflowError())
}

Der obige Code ist nicht vollständig, er speichert nicht das Rückruftoken und ruft keine vollständige Aktivität auf. Um die Sequenz zu testen, würde ich gerne das Protokoll des Workflow-Starts und der Aktivität sehen, die zweimal gestartet werden, aber das wird mir nicht angezeigt. Wenn nach dem Start des ersten Workflows keine aktiven Protokolle vorhanden sind, bleibt der Test hängen, bis das Zeitlimit überschritten wird.

Was übersehe ich oder ist es möglich, denselben Workflow zweimal auf diese Weise auszuführen?

Lösung

env.registerdelayedcallback(func() {
    env.executeworkflow(s.worker.tworkflow, "approved")
}, time.second*2)

Hier herrscht eine Sackgasse. Holen Sie sich die gleiche Sperre env 在回调运行时被锁定(请参阅 源代码)。并且回调想要在同一个 env 上执行工作流,这需要在 env (siehe Quellcode).

Versuchen wir, den Stillstand zu überwinden, indem wir den Rückruf in einer neuen Goroutine ausführen:

env.registerdelayedcallback(func() {
    go env.executeworkflow(s.worker.tworkflow, "approved")
}, time.second*2)

Jetzt geraten wir in Panik:

panic: Current TestWorkflowEnvironment is used to execute s.worker.TWorkflow. Please create a new TestWorkflowEnvironment for s.worker.TWorkflow.

Derzeit testworkflowenvironment können keine 2 Nicht-Parent-Child-Workflows ausgeführt werden. Sehen Sie sich das Problem der Nachverfolgung von Aufgaben an, um die Testworkflowumgebung so zu aktivieren, dass sie das Testen mehrerer Workflows unterstützt .

Wie die Panikmeldung andeutet, müssen Sie ein neues testworkflowenvironment erstellen, um einen anderen Workflow auszuführen (ich bin mir jedoch nicht sicher, ob es für Ihren Anwendungsfall geeignet ist).

Das obige ist der detaillierte Inhalt vonWie kann ich denselben Workflow mit Cadence RegisterDelayedCallback in einem Komponententest ausführen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen