The official Go SDK for Schedo, a job scheduling and execution management service.
go get github.com/useschedo/golang
package main
import (
"fmt"
"time"
"github.com/useschedo/golang"
)
func main() {
// Initialize the SDK with your API key
sdk := schedo.NewSchedo(
schedo.WithApiKey("YOUR_API_KEY"),
)
// Define a job that runs every minute
err := sdk.DefineJob(
"example_job",
"* * * * *", // Run every minute
func(ctx *schedo.JobExecutionContext) (string, error) {
fmt.Println("Executing job...")
return "Job completed successfully", nil
},
)
if err != nil {
fmt.Printf("Failed to define job: %v\n", err)
return
}
// Start listening for job execution events
sdk.Start()
// Keep the process running
select {}
}
The Schedo Go SDK allows you to define jobs with specific schedules and execute them when triggered. The main components are:
- Schedo: The main struct for job scheduling and execution management
- Jobs: Tasks defined with a name, schedule, and execution function
- Executors: Functions that run when a job is triggered
- JobExecutionContext: Context object available to executors containing job metadata and utilities
import (
"github.com/useschedo/golang"
)
sdk := schedo.NewSchedo(
schedo.WithApiKey("YOUR_API_KEY"),
schedo.WithVerbose(true), // Optional: enables verbose logging
)
import (
"fmt"
"time"
"github.com/useschedo/schedo-go"
)
// Define a job with a cron expression
err := sdk.DefineJob(
"cron_job_example",
"0 9 * * 1-5", // Runs at 9 AM on weekdays
func(ctx *schedo.JobExecutionContext) (string, error) {
fmt.Println("Running weekday morning job")
return `{"status": "success"}`, nil
},
schedo.WithTimeout(30*time.Second), // Optional: 30 second timeout
schedo.WithMetadata(map[string]any{"category": "reports"}), // Optional: adds metadata
schedo.WithBlocking(true), // Optional: makes job execution blocking
)
if err != nil {
fmt.Printf("Failed to define job: %v\n", err)
return
}
// Define a job with common schedule
err = sdk.DefineJob(
"hourly_job_example",
"0 * * * *", // Run hourly
func(ctx *schedo.JobExecutionContext) (string, error) {
fmt.Println("Running hourly job")
return fmt.Sprintf(`{"processedAt": "%s"}`, time.Now().Format(time.RFC3339)), nil
},
)
Some common cron expressions for scheduling:
EveryMinute := "* * * * *"
Hourly := "0 * * * *"
Daily := "0 0 * * *"
Weekly := "0 0 * * 0"
Monthly := "0 0 1 * *"
Every job executor receives a context object with useful information and utilities:
err := sdk.DefineJob(
"context_example",
"0 0 * * *", // Daily
func(ctx *schedo.JobExecutionContext) (string, error) {
// Access job metadata
metadata := ctx.GetMetadata()
// Access specific metadata field
if category, ok := ctx.GetMetadataField("category"); ok {
fmt.Printf("Category: %v\n", category)
}
// Access execution info
fmt.Printf("Executing job: %s\n", ctx.JobCode)
fmt.Printf("Execution ID: %d\n", ctx.ExecutionID)
// Perform job work...
// Return JSON string as result
return `{"completed": true, "timestamp": "` + time.Now().Format(time.RFC3339) + `"}`, nil
},
schedo.WithMetadata(map[string]any{
"owner": "analytics-team",
"priority": "high",
}),
)
// Start listening for job execution events
sdk.Start()
// Stop listening for job execution events (e.g., during graceful shutdown)
sdk.Stop()
Option | Function | Description | Default |
---|---|---|---|
API Key | WithApiKey(key) |
Sets the API key for authentication | Required |
Base URL | WithBaseURL(url) |
Sets the API base URL | https://api.schedo.dev |
Verbose | WithVerbose(boolean) |
Enables verbose logging | false |
Option | Function | Description | Default |
---|---|---|---|
Blocking | WithBlocking(boolean) |
Sets whether job execution should block | false |
Metadata | WithMetadata(map[string]any) |
Sets metadata for the job | nil |
Timeout | WithTimeout(time.Duration) |
Sets timeout duration | 0 |
The SDK automatically handles many types of errors, including:
- Job execution timeouts
- Executor failures
- Network and connection issues
err := sdk.DefineJob(
"error_handling_example",
"0 0 * * *", // Daily
func(ctx *schedo.JobExecutionContext) (string, error) {
// This job might fail
if rand.Float64() > 0.5 {
return "", fmt.Errorf("random failure")
}
return `{"success": true}`, nil
},
schedo.WithTimeout(5*time.Second), // Set a 5-second timeout
)
if err != nil {
fmt.Printf("Failed to define job: %v\n", err)
}
err := sdk.DefineJob(
"custom_error_handler",
"0 * * * *", // Hourly
func(ctx *schedo.JobExecutionContext) (string, error) {
result, err := performRiskyOperation()
if err != nil {
// Log error details but return structured error response
fmt.Printf("Operation failed: %v\n", err)
return fmt.Sprintf(`{"success": false, "error": "%s"}`, err.Error()), nil
}
return fmt.Sprintf(`{"success": true, "result": "%s"}`, result), nil
},
)
func TestNewSchedo(t *testing.T) {
s := NewSchedo(WithApiKey("YOUR_API_KEY"))
if s == nil {
t.Fatal("NewSchedo() returned nil")
}
err := s.DefineJob("test_job", "* * * * *", func(ctx *JobExecutionContext) (string, error) {
<-time.After(time.Second * 20)
return "test", nil
}, WithTimeout(time.Second*10))
if err != nil {
t.Fatal("DefineJob() returned error:", err)
}
fmt.Println("Job has been defined")
s.Start()
// Keep running until context is done
for {
select {
case <-s.ctx.Done():
}
}
}
func main() {
sdk := schedo.NewSchedo(
schedo.WithApiKey("YOUR_API_KEY"),
)
// Define jobs...
// Start the SDK
sdk.Start()
// Setup signal handling
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
// Wait for termination signal
<-c
// Stop SDK cleanly
sdk.Stop()
fmt.Println("Shutting down gracefully...")
}
MIT