Skip to content

Commit fa3f33a

Browse files
committed
Add dynamic workflow sample
1 parent 8334dee commit fa3f33a

File tree

6 files changed

+166
-0
lines changed

6 files changed

+166
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ Workflow Definition and an Activity Definition using API Key to authenticate wit
149149

150150
These samples demonstrate some common control flow patterns using Temporal's Go SDK API.
151151

152+
- [**Dynamic Workflows**](./dynamic-workflows): Demonstrates how to execute Workflows and Activities dynamically,
153+
using a single "Dynamic Workflow"
154+
152155
- [**Dynamic Execution**](./dynamic): Demonstrates how to execute
153156
Workflows and Activities using a name rather than a strongly typed function.
154157

dynamic-workflows/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Dynamic Workflows and Activities
2+
3+
The purpose of this sample is to demonstrate registering and using dynamic workflows and activities to
4+
handle various workflow types at runtime.
5+
6+
### Steps to run this sample:
7+
1) Run a [Temporal service](https://github.com/temporalio/samples-go/tree/main/#how-to-use).
8+
2) Run the following command to start the worker
9+
```
10+
go run dynamic-workflows/worker/main.go
11+
```
12+
3) Run the following command to start the example
13+
```
14+
go run dynamic-workflows/starter/main.go
15+
```

dynamic-workflows/activities.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dynamic_workflows
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"go.temporal.io/sdk/activity"
7+
"go.temporal.io/sdk/converter"
8+
)
9+
10+
func DynamicActivity(ctx context.Context, args converter.EncodedValues) (string, error) {
11+
var arg1, arg2 string
12+
err := args.Get(&arg1, &arg2)
13+
if err != nil {
14+
return "", fmt.Errorf("failed to decode arguments: %w", err)
15+
}
16+
17+
info := activity.GetInfo(ctx)
18+
result := fmt.Sprintf("%s - %s - %s", info.WorkflowType.Name, arg1, arg2)
19+
return result, nil
20+
}

dynamic-workflows/starter/main.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
7+
"github.com/pborman/uuid"
8+
"go.temporal.io/sdk/client"
9+
)
10+
11+
func main() {
12+
// The client is a heavyweight object that should be created once per process.
13+
c, err := client.Dial(client.Options{
14+
HostPort: client.DefaultHostPort,
15+
})
16+
if err != nil {
17+
log.Fatalln("Unable to create client", err)
18+
}
19+
defer c.Close()
20+
21+
// This workflow ID can be user business logic identifier as well.
22+
workflowID := "dynamic_workflows_" + uuid.New()
23+
workflowOptions := client.StartWorkflowOptions{
24+
ID: workflowID,
25+
TaskQueue: "dynamic-workflows",
26+
}
27+
28+
we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, "DurableExecution", "Hello", "Temporal")
29+
if err != nil {
30+
log.Fatalln("Unable to execute workflow", err)
31+
}
32+
log.Println("Started workflow", "WorkflowID", we.GetID(), "RunID", we.GetRunID())
33+
34+
var result string
35+
err = we.Get(context.Background(), &result)
36+
if err != nil {
37+
log.Fatalln("Unable get workflow result", err)
38+
}
39+
log.Println("Workflow result:", result)
40+
41+
we, err = c.ExecuteWorkflow(context.Background(), workflowOptions, "dynamic-activity", "Peanut", "Butter")
42+
if err != nil {
43+
log.Fatalln("Unable to execute workflow", err)
44+
}
45+
log.Println("Started workflow", "WorkflowID", we.GetID(), "RunID", we.GetRunID())
46+
47+
err = we.Get(context.Background(), &result)
48+
if err != nil {
49+
log.Fatalln("Unable get workflow result", err)
50+
}
51+
log.Println("Workflow result:", result)
52+
53+
we, err = c.ExecuteWorkflow(context.Background(), workflowOptions, "dynamic-activity123", "Jelly", "Time")
54+
if err != nil {
55+
log.Fatalln("Unable to execute workflow", err)
56+
}
57+
log.Println("Started workflow", "WorkflowID", we.GetID(), "RunID", we.GetRunID())
58+
59+
err = we.Get(context.Background(), &result)
60+
if err != nil {
61+
log.Fatalln("Unable get workflow result", err)
62+
}
63+
log.Println("Workflow result:", result)
64+
}

dynamic-workflows/worker/main.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"go.temporal.io/sdk/activity"
5+
"go.temporal.io/sdk/workflow"
6+
"log"
7+
8+
"go.temporal.io/sdk/client"
9+
"go.temporal.io/sdk/worker"
10+
11+
dynamic "github.com/temporalio/samples-go/dynamic-workflows"
12+
)
13+
14+
func main() {
15+
// The client and worker are heavyweight objects that should be created once per process.
16+
c, err := client.Dial(client.Options{
17+
HostPort: client.DefaultHostPort,
18+
})
19+
if err != nil {
20+
log.Fatalln("Unable to create client", err)
21+
}
22+
defer c.Close()
23+
24+
w := worker.New(c, "dynamic-workflows", worker.Options{})
25+
26+
w.RegisterDynamicWorkflow(dynamic.DynamicWorkflow, workflow.DynamicRegisterOptions{})
27+
w.RegisterDynamicActivity(dynamic.DynamicActivity, activity.DynamicRegisterOptions{})
28+
29+
err = w.Run(worker.InterruptCh())
30+
if err != nil {
31+
log.Fatalln("Unable to start worker", err)
32+
}
33+
}

dynamic-workflows/workflow.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dynamic_workflows
2+
3+
import (
4+
"fmt"
5+
"go.temporal.io/sdk/converter"
6+
"go.temporal.io/sdk/workflow"
7+
"strings"
8+
"time"
9+
)
10+
11+
func DynamicWorkflow(ctx workflow.Context, args converter.EncodedValues) (string, error) {
12+
var result string
13+
info := workflow.GetInfo(ctx)
14+
15+
var arg1, arg2 string
16+
err := args.Get(&arg1, &arg2)
17+
if err != nil {
18+
return "", fmt.Errorf("failed to decode arguments: %w", err)
19+
}
20+
21+
if strings.HasPrefix(info.WorkflowType.Name, "dynamic-activity") {
22+
ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{StartToCloseTimeout: 10 * time.Second})
23+
err := workflow.ExecuteActivity(ctx, "random-activity-name", arg1, arg2).Get(ctx, &result)
24+
if err != nil {
25+
return "", err
26+
}
27+
} else {
28+
result = fmt.Sprintf("%s - %s - %s", info.WorkflowType.Name, arg1, arg2)
29+
}
30+
return result, nil
31+
}

0 commit comments

Comments
 (0)