Skip to content

Commit 798a5b9

Browse files
committed
Add self-contained samples: branch, timer, greetings, pickfirst, choice
Signed-off-by: Diana Zawadzki <[email protected]>
1 parent 3486cf9 commit 798a5b9

35 files changed

+1523
-0
lines changed

new_samples/branch/README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!-- THIS IS A GENERATED FILE -->
2+
<!-- PLEASE DO NOT EDIT -->
3+
4+
# Branch Sample
5+
6+
## Prerequisites
7+
8+
0. Install Cadence CLI. See instruction [here](https://cadenceworkflow.io/docs/cli/).
9+
1. Run the Cadence server:
10+
1. Clone the [Cadence](https://github.com/cadence-workflow/cadence) repository if you haven't done already: `git clone https://github.com/cadence-workflow/cadence.git`
11+
2. Run `docker compose -f docker/docker-compose.yml up` to start Cadence server
12+
3. See more details at https://github.com/uber/cadence/blob/master/README.md
13+
2. Once everything is up and running in Docker, open [localhost:8088](localhost:8088) to view Cadence UI.
14+
3. Register the `cadence-samples` domain:
15+
16+
```bash
17+
cadence --env development --domain cadence-samples domain register
18+
```
19+
20+
Refresh the [domains page](http://localhost:8088/domains) from step 2 to verify `cadence-samples` is registered.
21+
22+
## Steps to run sample
23+
24+
Inside the folder this sample is defined, run the following command:
25+
26+
```bash
27+
go run .
28+
```
29+
30+
This will call the main function in main.go which starts the worker, which will be execute the sample workflow code
31+
32+
## Branch Workflow Sample
33+
34+
This sample demonstrates **parallel activity execution** using Futures.
35+
36+
### Start the Workflow
37+
38+
```bash
39+
cadence --env development \
40+
--domain cadence-samples \
41+
workflow start \
42+
--tl cadence-samples-worker \
43+
--et 60 \
44+
--workflow_type cadence_samples.BranchWorkflow
45+
```
46+
47+
### Key Concept: Parallel Execution with Futures
48+
49+
```go
50+
var futures []workflow.Future
51+
for i := 1; i <= 3; i++ {
52+
future := workflow.ExecuteActivity(ctx, BranchActivity, input)
53+
futures = append(futures, future)
54+
}
55+
// Wait for all
56+
for _, f := range futures {
57+
f.Get(ctx, nil)
58+
}
59+
```
60+
61+
62+
## References
63+
64+
* The website: https://cadenceworkflow.io
65+
* Cadence's server: https://github.com/uber/cadence
66+
* Cadence's Go client: https://github.com/uber-go/cadence-client
67+

new_samples/branch/branch.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"go.uber.org/cadence/workflow"
8+
)
9+
10+
const totalBranches = 3
11+
12+
// BranchWorkflow executes multiple activities in parallel and waits for all.
13+
func BranchWorkflow(ctx workflow.Context) error {
14+
logger := workflow.GetLogger(ctx)
15+
logger.Info("BranchWorkflow started")
16+
17+
ao := workflow.ActivityOptions{
18+
ScheduleToStartTimeout: time.Minute,
19+
StartToCloseTimeout: time.Minute,
20+
}
21+
ctx = workflow.WithActivityOptions(ctx, ao)
22+
23+
var futures []workflow.Future
24+
for i := 1; i <= totalBranches; i++ {
25+
input := fmt.Sprintf("branch %d of %d", i, totalBranches)
26+
future := workflow.ExecuteActivity(ctx, BranchActivity, input)
27+
futures = append(futures, future)
28+
}
29+
30+
for _, f := range futures {
31+
if err := f.Get(ctx, nil); err != nil {
32+
return err
33+
}
34+
}
35+
36+
logger.Info("BranchWorkflow completed")
37+
return nil
38+
}
39+
40+
// BranchActivity processes a single branch.
41+
func BranchActivity(input string) (string, error) {
42+
fmt.Printf("BranchActivity: %s\n", input)
43+
return "Result_" + input, nil
44+
}
45+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!-- THIS IS A GENERATED FILE -->
2+
<!-- PLEASE DO NOT EDIT -->
3+
4+
# Sample Generator
5+
6+
This folder is NOT part of the actual sample. It exists only for contributors who work on this sample. Please disregard it if you are trying to learn about Cadence.
7+
8+
To create a better learning experience for Cadence users, each sample folder is designed to be self contained. Users can view every part of writing and running workflows, including:
9+
10+
* Cadence client initialization
11+
* Worker with workflow and activity registrations
12+
* Workflow starter
13+
* and the workflow code itself
14+
15+
Some samples may have more or fewer parts depending on what they need to demonstrate.
16+
17+
In most cases, the workflow code (e.g. `workflow.go`) is the part that users care about. The rest is boilerplate needed to run that workflow. For each sample folder, the workflow code should be written by hand. The boilerplate can be generated. Keeping all parts inside one folder gives early learners more value because they can see everything together rather than jumping across directories.
18+
19+
## Contributing
20+
21+
* When creating a new sample, follow the steps mentioned in the README file in the main samples folder.
22+
* To update the sample workflow code, edit the workflow file directly.
23+
* To update the worker, client, or other boilerplate logic, edit the generator file. If your change applies to all samples, update the common generator file inside the `template` folder. Edit the generator file in this folder only when the change should affect this sample alone.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Branch Workflow Sample
2+
3+
This sample demonstrates **parallel activity execution** using Futures.
4+
5+
### Start the Workflow
6+
7+
```bash
8+
cadence --env development \
9+
--domain cadence-samples \
10+
workflow start \
11+
--tl cadence-samples-worker \
12+
--et 60 \
13+
--workflow_type cadence_samples.BranchWorkflow
14+
```
15+
16+
### Key Concept: Parallel Execution with Futures
17+
18+
```go
19+
var futures []workflow.Future
20+
for i := 1; i <= 3; i++ {
21+
future := workflow.ExecuteActivity(ctx, BranchActivity, input)
22+
futures = append(futures, future)
23+
}
24+
// Wait for all
25+
for _, f := range futures {
26+
f.Get(ctx, nil)
27+
}
28+
```
29+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import "github.com/uber-common/cadence-samples/new_samples/template"
4+
5+
func main() {
6+
data := template.TemplateData{
7+
SampleName: "Branch",
8+
Workflows: []string{"BranchWorkflow"},
9+
Activities: []string{"BranchActivity"},
10+
}
11+
template.GenerateAll(data)
12+
}
13+

new_samples/branch/main.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// THIS IS A GENERATED FILE
2+
// PLEASE DO NOT EDIT
3+
4+
package main
5+
6+
import (
7+
"fmt"
8+
"os"
9+
"os/signal"
10+
"syscall"
11+
)
12+
13+
func main() {
14+
StartWorker()
15+
16+
done := make(chan os.Signal, 1)
17+
signal.Notify(done, syscall.SIGINT)
18+
fmt.Println("Cadence worker started, press ctrl+c to terminate...")
19+
<-done
20+
}

new_samples/branch/worker.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// THIS IS A GENERATED FILE
2+
// PLEASE DO NOT EDIT
3+
4+
// Package worker implements a Cadence worker with basic configurations.
5+
package main
6+
7+
import (
8+
"github.com/uber-go/tally"
9+
apiv1 "github.com/uber/cadence-idl/go/proto/api/v1"
10+
"go.uber.org/cadence/.gen/go/cadence/workflowserviceclient"
11+
"go.uber.org/cadence/activity"
12+
"go.uber.org/cadence/compatibility"
13+
"go.uber.org/cadence/worker"
14+
"go.uber.org/cadence/workflow"
15+
"go.uber.org/yarpc"
16+
"go.uber.org/yarpc/peer"
17+
yarpchostport "go.uber.org/yarpc/peer/hostport"
18+
"go.uber.org/yarpc/transport/grpc"
19+
"go.uber.org/zap"
20+
"go.uber.org/zap/zapcore"
21+
)
22+
23+
const (
24+
HostPort = "127.0.0.1:7833"
25+
Domain = "cadence-samples"
26+
// TaskListName identifies set of client workflows, activities, and workers.
27+
// It could be your group or client or application name.
28+
TaskListName = "cadence-samples-worker"
29+
ClientName = "cadence-samples-worker"
30+
CadenceService = "cadence-frontend"
31+
)
32+
33+
// StartWorker creates and starts a basic Cadence worker.
34+
func StartWorker() {
35+
logger, cadenceClient := BuildLogger(), BuildCadenceClient()
36+
workerOptions := worker.Options{
37+
Logger: logger,
38+
MetricsScope: tally.NewTestScope(TaskListName, nil),
39+
}
40+
41+
w := worker.New(
42+
cadenceClient,
43+
Domain,
44+
TaskListName,
45+
workerOptions)
46+
// HelloWorld workflow registration
47+
w.RegisterWorkflowWithOptions(BranchWorkflow, workflow.RegisterOptions{Name: "cadence_samples.BranchWorkflow"})
48+
w.RegisterActivityWithOptions(BranchActivity, activity.RegisterOptions{Name: "cadence_samples.BranchActivity"})
49+
50+
err := w.Start()
51+
if err != nil {
52+
panic("Failed to start worker: " + err.Error())
53+
}
54+
logger.Info("Started Worker.", zap.String("worker", TaskListName))
55+
56+
}
57+
58+
func BuildCadenceClient(dialOptions ...grpc.DialOption) workflowserviceclient.Interface {
59+
grpcTransport := grpc.NewTransport()
60+
// Create a single peer chooser that identifies the host/port and configures
61+
// a gRPC dialer with TLS credentials
62+
myChooser := peer.NewSingle(
63+
yarpchostport.Identify(HostPort),
64+
grpcTransport.NewDialer(dialOptions...),
65+
)
66+
outbound := grpcTransport.NewOutbound(myChooser)
67+
68+
dispatcher := yarpc.NewDispatcher(yarpc.Config{
69+
Name: ClientName,
70+
Outbounds: yarpc.Outbounds{
71+
CadenceService: {Unary: outbound},
72+
},
73+
})
74+
if err := dispatcher.Start(); err != nil {
75+
panic("Failed to start dispatcher: " + err.Error())
76+
}
77+
78+
clientConfig := dispatcher.ClientConfig(CadenceService)
79+
80+
// Create a compatibility adapter that wraps proto-based YARPC clients
81+
// to provide a unified interface for domain, workflow, worker, and visibility APIs
82+
return compatibility.NewThrift2ProtoAdapter(
83+
apiv1.NewDomainAPIYARPCClient(clientConfig),
84+
apiv1.NewWorkflowAPIYARPCClient(clientConfig),
85+
apiv1.NewWorkerAPIYARPCClient(clientConfig),
86+
apiv1.NewVisibilityAPIYARPCClient(clientConfig),
87+
)
88+
}
89+
90+
func BuildLogger() *zap.Logger {
91+
config := zap.NewDevelopmentConfig()
92+
config.Level.SetLevel(zapcore.InfoLevel)
93+
94+
var err error
95+
logger, err := config.Build()
96+
if err != nil {
97+
panic("Failed to setup logger: " + err.Error())
98+
}
99+
100+
return logger
101+
}

new_samples/choice/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<!-- THIS IS A GENERATED FILE -->
2+
<!-- PLEASE DO NOT EDIT -->
3+
4+
# Choice Sample
5+
6+
## Prerequisites
7+
8+
0. Install Cadence CLI. See instruction [here](https://cadenceworkflow.io/docs/cli/).
9+
1. Run the Cadence server:
10+
1. Clone the [Cadence](https://github.com/cadence-workflow/cadence) repository if you haven't done already: `git clone https://github.com/cadence-workflow/cadence.git`
11+
2. Run `docker compose -f docker/docker-compose.yml up` to start Cadence server
12+
3. See more details at https://github.com/uber/cadence/blob/master/README.md
13+
2. Once everything is up and running in Docker, open [localhost:8088](localhost:8088) to view Cadence UI.
14+
3. Register the `cadence-samples` domain:
15+
16+
```bash
17+
cadence --env development --domain cadence-samples domain register
18+
```
19+
20+
Refresh the [domains page](http://localhost:8088/domains) from step 2 to verify `cadence-samples` is registered.
21+
22+
## Steps to run sample
23+
24+
Inside the folder this sample is defined, run the following command:
25+
26+
```bash
27+
go run .
28+
```
29+
30+
This will call the main function in main.go which starts the worker, which will be execute the sample workflow code
31+
32+
## Choice Workflow Sample
33+
34+
This sample demonstrates **conditional execution** based on activity results.
35+
36+
### Start the Workflow
37+
38+
```bash
39+
cadence --env development \
40+
--domain cadence-samples \
41+
workflow start \
42+
--tl cadence-samples-worker \
43+
--et 60 \
44+
--workflow_type cadence_samples.ChoiceWorkflow
45+
```
46+
47+
### Key Concept: Conditional Branching
48+
49+
```go
50+
var order string
51+
workflow.ExecuteActivity(ctx, GetOrderActivity).Get(ctx, &order)
52+
switch order {
53+
case "apple":
54+
workflow.ExecuteActivity(ctx, ProcessAppleActivity)
55+
case "banana":
56+
workflow.ExecuteActivity(ctx, ProcessBananaActivity)
57+
}
58+
```
59+
60+
61+
## References
62+
63+
* The website: https://cadenceworkflow.io
64+
* Cadence's server: https://github.com/uber/cadence
65+
* Cadence's Go client: https://github.com/uber-go/cadence-client
66+

0 commit comments

Comments
 (0)