Skip to content

Instantly share code, notes, and snippets.

@swyxio
Created April 16, 2024 18:35
Show Gist options
  • Save swyxio/27f2f74a5e8b59a7ef2ca3ad7da90a2e to your computer and use it in GitHub Desktop.
Save swyxio/27f2f74a5e8b59a7ef2ca3ad7da90a2e to your computer and use it in GitHub Desktop.
temporal workflow bootstrapped from a single instruction "browse the temporal.io docs to write a simple Golang workflow for sending an email at 9am PT every day, skipping a day when a signal has been sent to skip the day" on the livestream https://twitter.com/swyx/status/1778641185193730488
package main
import (
"context"
"log"
"time"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
)
// EmailWorkflow is the definition for the workflow responsible for sending emails.
func EmailWorkflow(ctx workflow.Context) error {
// Define the signal channel for skipping a day.
var skipDaySignal string
skipChannel := workflow.GetSignalChannel(ctx, "SkipDaySignal")
workflow.Go(ctx, func(ctx workflow.Context) {
skipChannel.Receive(ctx, &skipDaySignal)
})
// Define the activity options.
ao := workflow.ActivityOptions{
StartToCloseTimeout: 10 * time.Minute,
}
ctx = workflow.WithActivityOptions(ctx, ao)
// Run the email sending activity daily unless a skip signal is received.
for {
// Check if today is a skip day.
if skipDaySignal == "skip" {
// Reset the signal for the next day.
skipDaySignal = ""
// Skip today's email.
workflow.Sleep(ctx, 24*time.Hour)
continue
}
// Send the email.
err := workflow.ExecuteActivity(ctx, SendEmailActivity).Get(ctx, nil)
if err != nil {
return err
}
// Wait for the next day.
workflow.Sleep(ctx, 24*time.Hour)
}
return nil
}
// SendEmailActivity is a placeholder for the activity that sends the email.
func SendEmailActivity(ctx context.Context) error {
// Simulated email sending logic.
log.Println("Sending email...")
// Here you would integrate with an SMTP server or an email service provider's API.
// For simulation purposes, we're just logging the action.
return nil
}
func main() {
// Create the Temporal client.
c, err := client.NewClient(client.Options{})
if err != nil {
log.Fatalln("Error creating Temporal client:", err)
}
defer c.Close()
// Register the workflow and activity with the worker.
w := worker.New(c, "email-tasks", worker.Options{})
w.RegisterWorkflow(EmailWorkflow)
w.RegisterActivity(SendEmailActivity)
// Start the worker to listen to the task queue.
err = w.Start()
if err != nil {
log.Fatalln("Error starting worker:", err)
}
}
@swyxio
Copy link
Author

swyxio commented Apr 16, 2024

it even got a local temporal cluster running!
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment