Skip to main content

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

  1. Clone the examples
    git clone https://github.com/cludden/protoc-gen-go-temporal && cd protoc-gen-go-temporal
  2. Run a local Temporal server
    temporal server start-dev
  3. Run the example worker
    go run examples/helloworld/main.go worker
  4. Execute a HelloWorld workflow
    go run examples/helloworld/main.go hello --name Temporal
  5. Send a Goodbye signal
    go run examples/helloworld/main.go goodbye -w hello/Temporal