Hello World
A simple example inspired by temporalio/samples-go/helloworld
example.proto
syntax="proto3";
package example.helloworld.v1;
import "google/protobuf/empty.proto";
import "temporal/v1/temporal.proto";
service Example {
option (temporal.v1.service) = {
task_queue: "hello-world"
};
// Hello prints a friendly greeting and waits for goodbye
rpc Hello(HelloRequest) returns (HelloResponse) {
option (temporal.v1.workflow) = {
name: "example.v1.Hello"
id: 'hello/${! name.or("World") }'
signal: { ref: "Goodbye" }
};
}
// Goodbye signals a running workflow to exit
rpc Goodbye(GoodbyeRequest) returns (google.protobuf.Empty) {
option (temporal.v1.signal) = {};
}
}
// HelloRequest describes the input to a Hello workflow
message HelloRequest {
string name = 1;
}
// HelloResponse describes the output from a Hello workflow
message HelloResponse {
string result = 1;
}
message GoodbyeRequest {
string message = 1;
}
example.go
package example
import (
helloworldv1 "github.com/cludden/protoc-gen-go-temporal/gen/example/helloworld/v1"
"go.temporal.io/sdk/log"
"go.temporal.io/sdk/workflow"
)
type (
Workflows struct{}
// HelloWorkflow provides a helloworldv1.HelloWorkflow implementation
HelloWorkflow struct {
*helloworldv1.HelloWorkflowInput
log log.Logger
}
)
// NewHelloWorkflow initializes a new helloworldv1.HelloWorkflow value
func (w *Workflows) Hello(ctx workflow.Context, input *helloworldv1.HelloWorkflowInput) (helloworldv1.HelloWorkflow, error) {
return &HelloWorkflow{input, workflow.GetLogger(ctx)}, nil
}
// Execute defines the entrypoint to a Hello workflow
func (w *HelloWorkflow) Execute(ctx workflow.Context) (*helloworldv1.HelloResponse, error) {
w.log.Info("Hello workflow started", "request", w.Req)
goodbye, _ := w.Goodbye.Receive(ctx)
w.log.Info("Goodbye received", "signal", goodbye)
return &helloworldv1.HelloResponse{}, nil
}
main.go
package main
import (
"log"
"os"
example "github.com/cludden/protoc-gen-go-temporal/examples/helloworld/internal"
helloworldv1 "github.com/cludden/protoc-gen-go-temporal/gen/example/helloworld/v1"
"github.com/urfave/cli/v2"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
)
func main() {
app, err := helloworldv1.NewExampleCli(
helloworldv1.NewExampleCliOptions().
WithWorker(func(cmd *cli.Context, c client.Client) (worker.Worker, error) {
w := worker.New(c, helloworldv1.ExampleTaskQueue, worker.Options{})
helloworldv1.RegisterExampleWorkflows(w, &example.Workflows{})
return w, nil
}),
)
if err != nil {
log.Fatal(err)
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}
Run this example
- Clone the examples
git clone https://github.com/cludden/protoc-gen-go-temporal && cd protoc-gen-go-temporal
- Run a local Temporal server
temporal server start-dev
- Run the example worker
go run examples/helloworld/main.go worker
- Execute a
HelloWorld
workflowgo run examples/helloworld/main.go hello --name Temporal
- Send a
Goodbye
signalgo run examples/helloworld/main.go goodbye -w hello/Temporal