diff --git a/README.md b/README.md index 85fdbbd5..03aeb1c3 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,46 @@ This downloads and starts all required dependencies including Cadence server, da make ``` +### Docker Troubleshooting + +The `docker-compose` command requires Docker daemon to be running. On macOS/Windows, open Docker Desktop. On Linux, run `sudo systemctl start docker`. + +
+Port conflicts + +If you see `Bind for 0.0.0.0: failed: port is already allocated`, find the process using that port: + +```bash +lsof -i tcp: +``` + +To find which container is using it: +```bash +docker ps --format '{{.ID}}\t{{.Ports}}\t{{.Names}}' | grep +``` + +Stop and remove the conflicting container: +```bash +docker stop && docker rm +``` + +Cadence uses these ports: `7833`, `7933`, `7939`, `8000-8003`, `8088` (Web UI), `9042` (Cassandra), `9090` (Prometheus), `3000` (Grafana). + +
+ +
+Reset everything + +```bash +docker-compose down +docker ps -a # check for leftover containers +docker rm # remove if needed +``` + +Verify with `docker ps` and visit [http://localhost:8088](http://localhost:8088). + +
+ ## 📚 Sample Categories ### Table of Contents diff --git a/config/development.yaml b/config/development.yaml index 2a7cd2c0..d9e39b1d 100644 --- a/config/development.yaml +++ b/config/development.yaml @@ -1,5 +1,5 @@ # config for sample -domain: "default" +domain: "cadence-samples" service: "cadence-frontend" host: "localhost:7833" # config for emitting metrics diff --git a/new_samples/README.md b/new_samples/README.md index 5ec4ee59..1b52a711 100644 --- a/new_samples/README.md +++ b/new_samples/README.md @@ -33,43 +33,41 @@ cadence --env development \ Try to inspect the log message for the output. ### Signal Workflow -This workflow demonstrate a basic signal workflow. It takes your name as input parameter -and greet you based on languages you pick. To start the workflow, try the following CLI. +This workflow demonstrates a basic signal workflow. It waits for a signal to complete. +To start the workflow, try the following CLI. ```bash cadence --env development \ --domain cadence-samples \ workflow start \ - --workflow_type cadence_samples.SignalGreeterMultiLanguageWorkflow \ + --workflow_type cadence_samples.SimpleSignalWorkflow \ --tl cadence-samples-worker \ - --et 6000 \ - --input '{"name":"Uber"}' + --et 600 ``` -A workflow ID and run ID will be return in your terminal. Copy the workflow ID and replace -to the CLI below to trigger the signal. Try to change the input language value and inspect what -happens in the log. Also, try to inspect what happened after you interact with the signal multiple times. +A workflow ID and run ID will be returned in your terminal. Copy the workflow ID and use +the CLI below to send a signal. The workflow will continue running until it receives a +`complete` signal with the value `true`. ```bash cadence --env development \ --domain cadence-samples \ workflow signal \ - --workflow_id \ - --name "language" \ - --input '"english"' + --wid \ + --name "complete" \ + --input 'false' ``` -To cancel the workflow, try the following CLI. +To complete the workflow, send the signal with `true`: ```bash cadence --env development \ --domain cadence-samples \ workflow signal \ - --workflow_id \ - --name "cancel" \ + --wid \ + --name "complete" \ --input 'true' ``` -The workflow should have a status of fail. ### Dynamic workflow This dynamic workflow is very similar to the Hello World workflow above, but instead of passing the diff --git a/new_samples/workflows/dynamic_workflow.go b/new_samples/activities/dynamic_workflow.go similarity index 100% rename from new_samples/workflows/dynamic_workflow.go rename to new_samples/activities/dynamic_workflow.go diff --git a/new_samples/workflows/parallel_pick_first_workflow.go b/new_samples/activities/parallel_pick_first_workflow.go similarity index 100% rename from new_samples/workflows/parallel_pick_first_workflow.go rename to new_samples/activities/parallel_pick_first_workflow.go diff --git a/new_samples/hello_world/README.md b/new_samples/hello_world/README.md index b4669315..9401700e 100644 --- a/new_samples/hello_world/README.md +++ b/new_samples/hello_world/README.md @@ -43,6 +43,14 @@ cadence --env development \ --input '{"message":"Cadence"}' ``` +You should see output like this: + +![Trigger command output](images/02-trigger-command-started-workflow.png) + +And the worker will log the completed workflow: + +![Worker output showing workflow completed](images/01-worker-output-workflow-completed.png) + Here are the details to this command: * `--domain` option describes under which domain to run this workflow @@ -60,15 +68,24 @@ To see more options run `cadence --help` Click on `cadence-samples` domain in cadence-web to view your workflow. +![Workflow list showing completed workflow](images/03-web-ui-workflow-list-completed.png) + +Click on the workflow to see details: + * In Summary tab, you will see the input and output to your workflow -* Click on History tab to see individual steps. + +![Summary tab](images/04-web-ui-summary-tab.png) + +* Click on History tab to see individual steps. Expand an activity to see its result: + +![History tab with activity result](images/05-web-ui-history-activity-result.png) #### CLI List workflows using the following command: ```bash - cadence --env development --domain cadence-samples --workflow list +cadence --env development --domain cadence-samples workflow list ``` You can view an individual workflow by using the following command: @@ -76,8 +93,8 @@ You can view an individual workflow by using the following command: ```bash cadence --env development \ --domain cadence-samples \ - --workflow describe \ - --wid + workflow describe \ + --wid ``` * `workflow` is the noun to run commands within workflow scope @@ -90,10 +107,18 @@ To view the entire history of the workflow, use the following command: ```bash cadence --env development \ --domain cadence-samples \ - --workflow show \ - --wid + workflow show \ + --wid ``` +## Troubleshooting + +If you see port conflicts when starting Docker, use `lsof` to find what's using the port: + +![Docker port conflict troubleshooting](images/06-docker-port-conflict-troubleshooting.png) + +See the main [README](../../README.md#docker-troubleshooting) for detailed Docker troubleshooting steps. + ## References * The website: https://cadenceworkflow.io diff --git a/new_samples/hello_world/generator/README_specific.md b/new_samples/hello_world/generator/README_specific.md index 48337826..907ff18a 100644 --- a/new_samples/hello_world/generator/README_specific.md +++ b/new_samples/hello_world/generator/README_specific.md @@ -37,7 +37,7 @@ Click on `cadence-samples` domain in cadence-web to view your workflow. List workflows using the following command: ```bash - cadence --env development --domain cadence-samples --workflow list +cadence --env development --domain cadence-samples workflow list ``` You can view an individual workflow by using the following command: @@ -45,8 +45,8 @@ You can view an individual workflow by using the following command: ```bash cadence --env development \ --domain cadence-samples \ - --workflow describe \ - --wid + workflow describe \ + --wid ``` * `workflow` is the noun to run commands within workflow scope @@ -59,6 +59,6 @@ To view the entire history of the workflow, use the following command: ```bash cadence --env development \ --domain cadence-samples \ - --workflow show \ - --wid + workflow show \ + --wid ``` diff --git a/new_samples/hello_world/images/01-worker-output-workflow-completed.png b/new_samples/hello_world/images/01-worker-output-workflow-completed.png new file mode 100644 index 00000000..c063d2ec Binary files /dev/null and b/new_samples/hello_world/images/01-worker-output-workflow-completed.png differ diff --git a/new_samples/hello_world/images/02-trigger-command-started-workflow.png b/new_samples/hello_world/images/02-trigger-command-started-workflow.png new file mode 100644 index 00000000..056ab9ae Binary files /dev/null and b/new_samples/hello_world/images/02-trigger-command-started-workflow.png differ diff --git a/new_samples/hello_world/images/03-web-ui-workflow-list-completed.png b/new_samples/hello_world/images/03-web-ui-workflow-list-completed.png new file mode 100644 index 00000000..b37f683e Binary files /dev/null and b/new_samples/hello_world/images/03-web-ui-workflow-list-completed.png differ diff --git a/new_samples/hello_world/images/04-web-ui-summary-tab.png b/new_samples/hello_world/images/04-web-ui-summary-tab.png new file mode 100644 index 00000000..bcb8af77 Binary files /dev/null and b/new_samples/hello_world/images/04-web-ui-summary-tab.png differ diff --git a/new_samples/hello_world/images/05-web-ui-history-activity-result.png b/new_samples/hello_world/images/05-web-ui-history-activity-result.png new file mode 100644 index 00000000..8681050e Binary files /dev/null and b/new_samples/hello_world/images/05-web-ui-history-activity-result.png differ diff --git a/new_samples/hello_world/images/06-docker-port-conflict-troubleshooting.png b/new_samples/hello_world/images/06-docker-port-conflict-troubleshooting.png new file mode 100644 index 00000000..b3775ea3 Binary files /dev/null and b/new_samples/hello_world/images/06-docker-port-conflict-troubleshooting.png differ diff --git a/new_samples/workflows/cancel_workflow.go b/new_samples/operations/cancel_workflow.go similarity index 100% rename from new_samples/workflows/cancel_workflow.go rename to new_samples/operations/cancel_workflow.go diff --git a/new_samples/worker/worker.go b/new_samples/worker/worker.go index e6c6869a..351157c2 100644 --- a/new_samples/worker/worker.go +++ b/new_samples/worker/worker.go @@ -46,8 +46,8 @@ func StartWorker() { w.RegisterActivityWithOptions(workflows.HelloWorldActivity, activity.RegisterOptions{Name: "cadence_samples.HelloWorldActivity"}) // Signal workflow registration - w.RegisterWorkflowWithOptions(workflows.SignalGreeterMultiLanguageWorkflow, workflow.RegisterOptions{Name: "cadence_samples.SignalGreeterMultiLanguageWorkflow"}) - w.RegisterActivityWithOptions(workflows.GenerateGreetingMessage, activity.RegisterOptions{Name: "cadence_samples.GenerateGreetingMessage"}) + w.RegisterWorkflowWithOptions(workflows.SimpleSignalWorkflow, workflow.RegisterOptions{Name: "cadence_samples.SimpleSignalWorkflow"}) + w.RegisterActivityWithOptions(workflows.SimpleSignalActivity, activity.RegisterOptions{Name: "cadence_samples.SimpleSignalActivity"}) // Dynamic workflow registration w.RegisterWorkflowWithOptions(workflows.DynamicWorkflow, workflow.RegisterOptions{Name: "cadence_samples.DynamicWorkflow"}) diff --git a/new_samples/workflows/signal_greeter_multi_language.go b/new_samples/workflows/signal_greeter_multi_language.go deleted file mode 100644 index ded8e0bf..00000000 --- a/new_samples/workflows/signal_greeter_multi_language.go +++ /dev/null @@ -1,92 +0,0 @@ -package workflows - -import ( - "context" - "errors" - "fmt" - "go.uber.org/cadence/activity" - "go.uber.org/cadence/workflow" - "go.uber.org/zap" - "time" -) - -// A workflow execution cannot receive infinite number of signals due to history limit -// By default 10000 is MaximumSignalsPerExecution which can be configured by DynamicConfig of Cadence cluster. -// But it's recommended to do continueAsNew after receiving certain number of signals(in production, use a number <1000) -const ( - MaxSignalCount = 3 - - LanguageChan = "language" - CancelChan = "cancel" -) - -type person struct { - Name string `json:"name"` -} - -func SignalGreeterMultiLanguageWorkflow(ctx workflow.Context, person person) error { - ao := workflow.ActivityOptions{ - ScheduleToStartTimeout: time.Minute * 60, - StartToCloseTimeout: time.Minute * 60, - } - ctx = workflow.WithActivityOptions(ctx, ao) - logger := workflow.GetLogger(ctx) - logger.Info("SignalGreeterMultiLanguageWorkflow started, ", zap.String("Name", person.Name)) - - signalCount := 0 - - var language string - var canceled bool - languageChan := workflow.GetSignalChannel(ctx, LanguageChan) - cancelChan := workflow.GetSignalChannel(ctx, CancelChan) - for { - s := workflow.NewSelector(ctx) - s.AddReceive(languageChan, func(ch workflow.Channel, ok bool) { - if ok { - ch.Receive(ctx, &language) - signalCount += 1 - } - }) - - s.AddReceive(cancelChan, func(ch workflow.Channel, ok bool) { - if ok { - ch.Receive(ctx, &canceled) - } - }) - s.Select(ctx) - - if canceled { - return errors.New("signal workflow canceled") - } - if signalCount >= MaxSignalCount { - return workflow.NewContinueAsNewError(ctx, SignalGreeterMultiLanguageWorkflow, person) - } - - var greeting string - err := workflow.ExecuteActivity(ctx, GenerateGreetingMessage, language, person.Name).Get(ctx, &greeting) - if err != nil { - return err - } - - logger.Info("Greeting message", zap.String("Greeting", greeting)) - } -} - -func GenerateGreetingMessage(ctx context.Context, language, name string) (string, error) { - logger := activity.GetLogger(ctx) - logger.Info("GenerateGreetingMessage started") - var greeting string - if language == "english" { - greeting = "Hello" - } - if language == "spanish" { - greeting = "Hola" - } - if language == "french" { - greeting = "bonjour" - } - if greeting == "" { - return "", errors.New("currently only support english, spanish and french") - } - return fmt.Sprintf("%s %s!", greeting, name), nil -} diff --git a/new_samples/workflows/simple_signal_workflow.go b/new_samples/workflows/simple_signal_workflow.go new file mode 100644 index 00000000..267b647a --- /dev/null +++ b/new_samples/workflows/simple_signal_workflow.go @@ -0,0 +1,60 @@ +package workflows + +import ( + "context" + "strconv" + "time" + + "go.uber.org/cadence/activity" + "go.uber.org/cadence/workflow" + "go.uber.org/zap" +) + +const ( + CompleteSignalChan = "complete" +) + +// SimpleSignalWorkflow demonstrates a basic signal workflow. +// It waits for a "complete" signal to finish. +func SimpleSignalWorkflow(ctx workflow.Context) error { + ao := workflow.ActivityOptions{ + ScheduleToStartTimeout: time.Minute * 60, + StartToCloseTimeout: time.Minute * 60, + } + ctx = workflow.WithActivityOptions(ctx, ao) + logger := workflow.GetLogger(ctx) + logger.Info("SimpleSignalWorkflow started") + + var complete bool + completeChan := workflow.GetSignalChannel(ctx, CompleteSignalChan) + for { + s := workflow.NewSelector(ctx) + s.AddReceive(completeChan, func(ch workflow.Channel, ok bool) { + if ok { + ch.Receive(ctx, &complete) + } + logger.Info("Signal input: " + strconv.FormatBool(complete)) + }) + s.Select(ctx) + + var result string + err := workflow.ExecuteActivity(ctx, SimpleSignalActivity, complete).Get(ctx, &result) + if err != nil { + return err + } + logger.Info("Activity result: " + result) + if complete { + return nil + } + } +} + +// SimpleSignalActivity logs the signal received and returns a status message. +func SimpleSignalActivity(ctx context.Context, complete bool) (string, error) { + logger := activity.GetLogger(ctx) + logger.Info("SimpleSignalActivity started, a new signal has been received", zap.Bool("complete", complete)) + if complete { + return "Workflow will complete now", nil + } + return "Workflow will continue to run", nil +}