Add Temporal worker and test client programs

Creates:
- cmd/worker/main.go: Worker that registers workflows and activities
- cmd/test-workflow/main.go: Test client to trigger workflows

Adds go.temporal.io/sdk dependency to go.mod.
This commit is contained in:
Story Crater Bot
2026-08-21 16:49:44 -07:00
parent 9127076f1b
commit fb1a97e8d0
6 changed files with 476 additions and 2 deletions
+88
View File
@@ -0,0 +1,88 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"time"
"go.temporal.io/sdk/client"
"github.com/Riotpiaole/homelab-frontend/internal/workflow"
)
func main() {
hostPort := flag.String("host", "temporal.temporal:7233", "Temporal server host:port")
namespace := flag.String("namespace", "production", "Temporal namespace")
taskQueue := flag.String("queue", "worker-production", "Task queue")
workflowType := flag.String("workflow", "HelloWorldWorkflow", "Workflow type")
workflowID := flag.String("id", "", "Workflow ID (auto-generated if not set)")
flag.Parse()
// Auto-generate ID
if *workflowID == "" {
*workflowID = fmt.Sprintf("test-%s-%d", *workflowType, time.Now().Unix())
}
log.Printf("Connecting to Temporal at %s (namespace: %s)", *hostPort, *namespace)
// Connect to Temporal
c, err := client.Dial(client.Options{
HostPort: *hostPort,
Namespace: *namespace,
})
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer c.Close()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Start workflow
log.Printf("Starting %s (ID: %s)", *workflowType, *workflowID)
var run client.WorkflowRun
switch *workflowType {
case "HelloWorldWorkflow":
run, err = c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
ID: *workflowID,
TaskQueue: *taskQueue,
}, workflow.HelloWorldWorkflow, "World")
case "GreeterWorkflow":
run, err = c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
ID: *workflowID,
TaskQueue: *taskQueue,
}, workflow.GreeterWorkflow, "Alice")
case "ProcessOrderWorkflow":
run, err = c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
ID: *workflowID,
TaskQueue: *taskQueue,
}, workflow.ProcessOrderWorkflow, "ORDER-12345")
default:
log.Fatalf("Unknown workflow type: %s", *workflowType)
}
if err != nil {
log.Fatalf("Failed to start workflow: %v", err)
}
log.Printf("✓ Workflow submitted")
log.Printf(" Run ID: %s", run.GetRunID())
log.Printf(" Workflow ID: %s", *workflowID)
log.Printf(" Watch at: http://localhost:8080/namespaces/%s/workflows/%s", *namespace, *workflowID)
// Try to get result
ctx2, cancel2 := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel2()
var result string
if err := run.Get(ctx2, &result); err != nil {
log.Printf("⏳ Workflow executing (or error): %v", err)
} else {
log.Printf("✓ Result: %s", result)
}
}
+63
View File
@@ -0,0 +1,63 @@
package main
import (
"flag"
"log"
"os"
"os/signal"
"syscall"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"github.com/Riotpiaole/homelab-frontend/internal/workflow"
)
func main() {
hostPort := flag.String("host", "temporal.temporal:7233", "Temporal server host:port")
namespace := flag.String("namespace", "production", "Temporal namespace")
taskQueue := flag.String("queue", "worker-production", "Task queue")
flag.Parse()
// Connect to Temporal server
c, err := client.Dial(client.Options{
HostPort: *hostPort,
Namespace: *namespace,
})
if err != nil {
log.Fatalf("Failed to connect to Temporal: %v", err)
}
defer c.Close()
log.Printf("Connected to Temporal at %s (namespace: %s)", *hostPort, *namespace)
// Create worker
w := worker.New(c, *taskQueue, worker.Options{})
// Register workflows
w.RegisterWorkflow(workflow.HelloWorldWorkflow)
w.RegisterWorkflow(workflow.GreeterWorkflow)
w.RegisterWorkflow(workflow.ProcessOrderWorkflow)
// Register activities
w.RegisterActivity(workflow.GreetActivity)
w.RegisterActivity(workflow.ValidateOrderActivity)
w.RegisterActivity(workflow.ProcessPaymentActivity)
w.RegisterActivity(workflow.NotifyCustomerActivity)
log.Printf("Starting worker on task queue: %s", *taskQueue)
// Handle graceful shutdown
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigChan
log.Println("Shutting down worker...")
w.Stop()
}()
// Run worker (blocks)
if err := w.Run(worker.InterruptCh()); err != nil {
log.Fatalf("Worker error: %v", err)
}
}