Temporal Getting Started Guide
Overview
In this article we will walk through setup of a development environment for Temporal. There are of course, several ways you can run the Temporal server locally. You can use Docker compose, helm or an operator on minikube and temporalite. In addition you can also consume Temporal namespaces as-a-service via the Temporal cloud. I would recommend temporalite if you want to run the Temporal server disconnected on your laptop otherwise the Temporal cloud is definitely the best option. I will cover getting started with the Temporal cloud in a future post.
Temporalite Install
Temporalite is a simple packaging of the Temporal server. It uses SQLite, instead of a full blown backend database for simplicity and less resource consumption. It is intended only for development or testing and not production use. In order to install it you need to have a Go environment to build the binary.
Configure Go
Create directory structure for Go in your home directory.
$ mkdir -p ~/go/src/github.com
Install Go
$ sudo dnf install -y go
Update Profile with Go Environment
$ vi ~/.bash_profile
export GOBIN=/home/username
export GOPATH=/home/username/src
export EDITOR=vim
Build Temporalite
Create directory for Temporal
$ mkdir ~/go/src/github.com/temporalio
Change directory to temporalio
$ cd temporalio
Clone temporalite GitHub repository
$ git clone https://github.com/temporalio/temporalite.git
Build temporalite binary
$ go install github.com/temporalio/temporalite/cmd/temporalite@latest
Copy temporalite binary to bin Directory
$ sudo cp /home/ktenzer/go/bin/temporalite /usr/local/bin
Create Directory for local Temporal Database
$ mkdir -p /home/ktenzer/.config/temporalite/db
Start temporalite
$ temporalite start --namespace default
Build CLI
Now that we have the Temporal server running via temporalite we need to build the CLI.
Change directory to temporalio
$ cd ~/go/src/github.com/temporalio
Clone Temporal GitHub repository
$ git clone https://github.com/temporalio/temporal.git
Run tctl Makefile
$ make update-tctl
Copy tctl binary to bin directory
$ sudo cp ~/go/bin/tctl /usr/local/bin
Start Temporal Workflow
In this case we will just run the helloworld sample from the many samples that Temporal provides.
Change directory to temporalio
$ cd ~/go/src/github.com/temporalio
Clone samples GitHub repository
$ git clone https://github.com/temporalio/samples-go.git
Change directory to samples
$ cd samples-go
Start workflow
$ go run helloworld/starter/main.go
2022/08/24 11:46:11 INFO No logger configured for temporal client. Created default one.
2022/08/24 11:46:11 Started workflow WorkflowID hello_world_workflowID RunID b93ef614-e6df-4578-a31b-7ebd3f59df55
Notice that the workflow starts but is waiting to execute. This is because there is no worker. The starter program will tell the Temporal server to execute a workflow however, since no worker is attached the Temporal server namespace, the workflow will be in running state until a worker becomes available.
The Temporal UI will also show that we are waiting for a worker.
Start Temporal Worker
Now that we have our Temporal server and a workflow running all that is needed is a worker. We will start the corresponding helloworld worker.
$ go run helloworld/worker/main.go
The worker should immediately run and complete the workflow.
2022/08/24 11:55:26 INFO HelloWorld workflow completed. Namespace default TaskQueue hello-world WorkerID 7576@fedora@ WorkflowType Workflow WorkflowID hello_world_workflowID RunID b93ef614-e6df-4578-a31b-7ebd3f59df55 Attempt 1 result Hello Temporal!
If you look at your starter it also has now returned and displays the workflow result returned from the workflow.
2022/08/24 11:55:26 Workflow result: Hello Temporal!
In the UI we can now also see the workflow has completed.
View Workflow in CLI
Temporal provides the tctl CLI for interacting with the Temporal server.
List workflows
$ tctl workflow list
WORKFLOW TYPE | WORKFLOW ID | RUN ID | TASK QUEUE | START TIME | EXECUTION TIME | END TIME
Workflow | hello_world_workflowID | b93ef614-e6df-4578-a31b-7ebd3f59df55 | hello-world | 18:46:11 | 18:46:11 | 18:55:26
Show workflow details
$ tctl workflow show --workflow_id hello_world_workflowID --run_id b93ef614-e6df-4578-a31b-7ebd3f59df55
1 WorkflowExecutionStarted {WorkflowType:{Name:Workflow},
ParentInitiatedEventId:0, TaskQueue:{Name:hello-world,
Kind:Normal}, Input:["Temporal"],
WorkflowExecutionTimeout:0s, WorkflowRunTimeout:0s,
WorkflowTaskTimeout:10s, Initiator:Unspecified,
OriginalExecutionRunId:b93ef614-e6df-4578-a31b-7ebd3f59df55,
Identity:5846@fedora@,
FirstExecutionRunId:b93ef614-e6df-4578-a31b-7ebd3f59df55,
Attempt:1, FirstWorkflowTaskBackoff:0s,
ParentInitiatedEventVersion:0}
2 WorkflowTaskScheduled {TaskQueue:{Name:hello-world,
Kind:Normal},
StartToCloseTimeout:10s,
Attempt:1}
3 WorkflowTaskStarted {ScheduledEventId:2, Identity:7576@fedora@,
RequestId:3c597463-65e4-4d61-b014-484634f32c37,
SuggestContinueAsNew:false, HistorySizeBytes:0}
4 WorkflowTaskCompleted {ScheduledEventId:2, StartedEventId:3,
Identity:7576@fedora@,
BinaryChecksum:0990e4a32efe7cd9c6c127b9cb51ecfc}
5 ActivityTaskScheduled {ActivityId:5,
ActivityType:{Name:Activity},
TaskQueue:{Name:hello-world,
Kind:Normal},
Input:["Temporal"],
ScheduleToCloseTimeout:0s,
ScheduleToStartTimeout:0s,
StartToCloseTimeout:10s,
HeartbeatTimeout:0s,
WorkflowTaskCompletedEventId:4,
RetryPolicy:{InitialInterval:1s,
BackoffCoefficient:2,
MaximumInterval:1m40s,
MaximumAttempts:0,
NonRetryableErrorTypes:[]}}
6 ActivityTaskStarted {ScheduledEventId:5, Identity:7576@fedora@,
RequestId:9a1da09d-2b00-4c46-a945-9e24adc10c04,
Attempt:1}
7 ActivityTaskCompleted {Result:["Hello
Temporal!"],
ScheduledEventId:5,
StartedEventId:6,
Identity:7576@fedora@}
8 WorkflowTaskScheduled {TaskQueue:{Name:fedora:e78b4021-eed7-4cb9-880e-9a7354471838,
Kind:Sticky}, StartToCloseTimeout:10s, Attempt:1}
9 WorkflowTaskStarted {ScheduledEventId:8, Identity:7576@fedora@,
RequestId:8cc430d3-3d73-4261-961e-7dacd1b13005,
SuggestContinueAsNew:false, HistorySizeBytes:0}
10 WorkflowTaskCompleted {ScheduledEventId:8, StartedEventId:9,
Identity:7576@fedora@,
BinaryChecksum:0990e4a32efe7cd9c6c127b9cb51ecfc}
11 WorkflowExecutionCompleted {Result:["Hello
Temporal!"],
WorkflowTaskCompletedEventId:10}
Summary
In this article we discussed several options for running the Temporal server, including using the Temporal cloud. We walked through the steps; deploying a quick local development environment using temporalite. Finally we showed how to execute and get workflow details using both the Temporal CLI and UI. Best of luck in your journey to more reliable applications with Temporal! If you have any questions reach out on Temporal community slack.
(c) 2022 Keith Tenzer