Hello World with Temporal
Requirements
Install Temporal
https://docs.temporal.io/dev-guide/go/foundations#add-your-sdk
Start Temporal dev server
$ temporal server start-dev
Access Temporal UI
Go to URL http://localhost:8233/
Create a basic Go app
Create project folder <project>
Initialize go app
go mod init
Create
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
Well, that is a first Go Hello World.
Add Temporal SDK
Install go dependency
$ go get go.temporal.io/sdk
Create a Workflow Definition
I'll explain Temporal concepts later. For now, a Workflow Definition is a Golang function with this signature func Name(ctx workflow.Context, <params>) (<returns>, error)
So edit main.go
to add the Workflow Definition that prints Hello World
package main
import (
"fmt"
)
func Workflow(ctx workflow.Context) error {
fmt.Println("Hello World!")
return nil
}
func main() {
// fmt.Println("Hello World!")
}
Edit main function to start a Worker
A Worker is a process that will listen to events and act on them. It will receive commands from the Temporal server and execute a Workflow Definition that is registered for that process.
For this example:
We create a client that connects to the local development Temporal cluster
Register a Workflow Definition
Waits for a SIGTERM signal to stop the worker
So:
package main
import (
"fmt"
"log"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
)
func Workflow(ctx workflow.Context) error {
fmt.Println("Hello World!")
return nil
}
func main() {
// Create a Temporal Client
// A Temporal Client is a heavyweight object that should be created just once per process.
client, err := client.Dial(client.Options{})
if err != nil {
log.Fatalln("Unable to create client", err)
}
defer client.Close()
// Create a new Worker.
yourWorker := worker.New(client, "task-queue", worker.Options{})
// Register Workflow Definition
yourWorker.RegisterWorkflow(Workflow)
// Wait for interruption
err = yourWorker.Run(worker.InterruptCh())
if err != nil {
log.Fatalln("Unable to start Worker", err)
}
}
Running this main.go
:
$ go run main.go
2023/09/27 17:42:01 INFO No logger configured for temporal client. Created default one.
2023/09/27 17:42:01 INFO Started Worker Namespace default TaskQueue task-queue WorkerID 71190@localhost.local@
Ok, so you get a Worker process running, that will handle events from task-queue
and it will execute a Workflow Definition.
Starting a Workflow
For this, let's use the CLI, in another terminal session:
$ temporal workflow start --task-queue task-queue --type Workflow
Running execution:
WorkflowId 52f8a61f-ac78-4f80-ace1-3c5ba32b8b63
RunId 7e6411cb-dd8c-4879-a200-46d5b157f9c8
Type Workflow
Namespace default
TaskQueue task-queue
Args []
And you will get at the worker terminal
❯ go run .
2023/09/27 17:42:01 INFO No logger configured for temporal client. Created default one.
2023/09/27 17:42:01 INFO Started Worker Namespace default TaskQueue task-queue WorkerID 71190@localhost.local@
Hello World!
Temporal UI
In the browser (http://localhost:8233/)
You can see the entry for a Workflow Execution, with its ID and other meta information.
That is it!
Well, the basic basic basic basic example.
For the next posts, I will explain the Temporal Concepts and we are going to incrementally improve this example.
References
Subscribe to my newsletter
Read articles from Lucas Katayama directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Lucas Katayama
Lucas Katayama
I am a self-taught, quick learner and highly motivated Full Stack JavaScript Developer with more than 10 years of experience developing, designing and managing web and mobile applications in a startup environment, seeking to develop skills to ensure software quality and reliability. Also seeking other challenges and learn new technologies.