Skip to content

Commit a636924

Browse files
Redefine hello world sample
Signed-off-by: Ender Demirkaya <[email protected]>
1 parent 90f978c commit a636924

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed

new_samples/hello_world/README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Cadence Samples
2+
3+
These are some samples to demonstrate various capabilities of Cadence client and server. You can learn more about cadence at:
4+
5+
* The website: https://cadenceworkflow.io
6+
* Cadence's server: https://github.com/uber/cadence
7+
* Cadence's Go client: https://github.com/uber-go/cadence-client
8+
9+
## Prerequisite
10+
11+
0. Install Cadence CLI. See instruction [here](https://cadenceworkflow.io/docs/cli/).
12+
1. Run the Cadence server:
13+
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`
14+
2. Run `docker compose -f docker/docker-compose.yml up` to start Cadence server
15+
3. See more details at https://github.com/uber/cadence/blob/master/README.md
16+
2. Once everything is up and running in Docker, open [localhost:8088](localhost:8088) to view Cadence UI.
17+
3. Register the `cadence-samples` domain:
18+
19+
```bash
20+
cadence --env development --domain cadence-samples domain register
21+
```
22+
23+
Refresh the [domains page](http://localhost:8088/domains) from step 2 to verify `cadence-samples` is registered.
24+
25+
## Steps to run sample
26+
27+
Inside the folder this sample is defined, run the following command:
28+
29+
```bash
30+
go run .
31+
```
32+
33+
This will call the main function in main.go which starts the worker, which will be execute the sample workflow code
34+
35+
### Start your workflow
36+
37+
This workflow takes an input message and greet you as response. Try the following CLI
38+
39+
```bash
40+
cadence --env development \
41+
--domain cadence-samples \
42+
workflow start \
43+
--workflow_type cadence_samples.HelloWorldWorkflow \
44+
--tl cadence-samples-worker \
45+
--et 60 \
46+
--input '{"message":"Cadence"}'
47+
```
48+
49+
Here are the details to this command:
50+
51+
* `--domain` option describes under which domain to run this workflow
52+
* `--env development` calls the "local" cadence server
53+
* `--workflow_type` option describes which workflow to execute
54+
* `-tl` (or `--tasklist`) tells cadence-server which tasklist to schedule tasks with. This is the same tasklist the worker polls tasks from. See worker.go
55+
* `--et` (or `--execution_timeout`) tells cadence server how long to wait until timing out the workflow
56+
* `--input` is the input to your workflow
57+
58+
To see more options run `cadence --help`
59+
60+
### View your workflow
61+
62+
#### Cadence UI (cadence-web)
63+
64+
Click on `cadence-samples` domain in cadence-web to view your workflow.
65+
66+
* In Summary tab, you will see the input and output to your workflow
67+
* Click on History tab to see individual steps.
68+
69+
#### CLI
70+
71+
List workflows using the following command:
72+
73+
```bash
74+
cadence --env development --domain cadence-samples --workflow list
75+
```
76+
77+
You can view an individual workflow by using the following command:
78+
79+
```bash
80+
cadence --env development \
81+
--domain cadence-samples \
82+
--workflow describe \
83+
--wid <workflow_id>
84+
```
85+
86+
* `workflow` is the noun to run commands within workflow scope
87+
* `describe` is the verb to return the summary of the workflow
88+
* `--wid` (or `--workflow_id`) is the option to pass the workflow id. If there are multiple "run"s, it will return the latest one.
89+
* (optional) `--rid` (or `--run_id`) is the option to pass the run id to describe a specific run, instead of the latest.
90+
91+
To view the entire history of the workflow, use the following command:
92+
93+
```bash
94+
cadence --env development \
95+
--domain cadence-samples \
96+
--workflow show \
97+
--wid <workflow_id>
98+
```

new_samples/hello_world/main.go

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

new_samples/hello_world/worker.go

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

0 commit comments

Comments
 (0)