schedo

package module
v0.0.25 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2025 License: MIT Imports: 13 Imported by: 0

README

schedo-go

Go Reference Go Report Card

The official Go SDK for Schedo, a job scheduling and execution management service.

Installation

go get github.com/useschedo/golang

Quick Start

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 {}
}

Core Concepts

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

Detailed Usage

Initializing the SDK
import (
	"github.com/useschedo/golang"
)

sdk := schedo.NewSchedo(
	schedo.WithApiKey("YOUR_API_KEY"),
	schedo.WithVerbose(true), // Optional: enables verbose logging
)
Scheduling Jobs
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
	},
)
Common Cron Expressions

Some common cron expressions for scheduling:

EveryMinute := "* * * * *"
Hourly := "0 * * * *"
Daily := "0 0 * * *"
Weekly := "0 0 * * 0"
Monthly := "0 0 1 * *"
Working with JobExecutionContext

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",
	}),
)
Starting and Stopping the SDK
// Start listening for job execution events
sdk.Start()

// Stop listening for job execution events (e.g., during graceful shutdown)
sdk.Stop()

Configuration Options

SDK Options
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
Job Definition Options
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

Error Handling

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)
}

Advanced Usage

Custom Error Handling
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
	},
)
Job with Timeout
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():
		}
	}
}
Graceful Shutdown
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...")
}

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Executor

type Executor func(ctx *JobExecutionContext) (string, error)

Executor is a function that takes a JobExecutionContext and returns a string and an error This function must be implemented by the user and is the main entry point for the job The string returned by this function will be stored in the database as the job's output The error returned by this function will be stored in the database as the job's error

type JobDefineOption

type JobDefineOption func(*JobDefineOptions)

func WithBlocking

func WithBlocking(blocking bool) JobDefineOption

func WithMetadata

func WithMetadata(metadata map[string]any) JobDefineOption

func WithTimeout

func WithTimeout(timeout time.Duration) JobDefineOption

type JobDefineOptions

type JobDefineOptions struct {
	Blocking bool
	Metadata map[string]any
	Timeout  int64
}

func NewJobDefineOptions

func NewJobDefineOptions(opts ...JobDefineOption) *JobDefineOptions

type JobExecutionContext

type JobExecutionContext struct {
	ExecutionID int64
	JobCode     string

	context.Context
	// contains filtered or unexported fields
}

func NewJobExecutionContext

func NewJobExecutionContext(ctx context.Context, client *schedo.Client, executionID int64, jobCode string, metadata map[string]any) *JobExecutionContext

func (*JobExecutionContext) ClearLogs added in v0.0.25

func (j *JobExecutionContext) ClearLogs()

ClearLogs removes all collected logs

func (*JobExecutionContext) GetLogs added in v0.0.25

func (j *JobExecutionContext) GetLogs() string

GetLogs returns all collected logs as a single string with each entry on a new line Format: [LEVEL] message

func (*JobExecutionContext) GetMetadata

func (j *JobExecutionContext) GetMetadata(key string) map[string]any

func (*JobExecutionContext) GetMetadataField

func (j *JobExecutionContext) GetMetadataField(key string) (any, bool)

func (*JobExecutionContext) WriteLog

func (j *JobExecutionContext) WriteLog(line string) error

func (*JobExecutionContext) WriteLogWithLevel added in v0.0.25

func (j *JobExecutionContext) WriteLogWithLevel(line string, level LogLevel) error

WriteLogWithLevel writes a log line with the specified log level

type LogEntry added in v0.0.25

type LogEntry struct {
	Level LogLevel
	Line  string
}

LogEntry represents a single log entry with its level

type LogLevel added in v0.0.25

type LogLevel string

LogLevel represents the severity level of a log entry

const (
	LogLevelInfo  LogLevel = "INFO"
	LogLevelWarn  LogLevel = "WARN"
	LogLevelError LogLevel = "ERROR"
	LogLevelDebug LogLevel = "DEBUG"
)

type Option

type Option func(*Options)

func WithApiKey

func WithApiKey(apiKey string) Option

func WithBaseURL

func WithBaseURL(baseURL string) Option

func WithVerbose

func WithVerbose(verbose bool) Option

type Options

type Options struct {
	ApiKey  string
	BaseURL string
	Verbose bool
}

func NewSDKOptions

func NewSDKOptions(opts ...Option) *Options

type Schedo

type Schedo struct {
	// contains filtered or unexported fields
}

func NewSchedo

func NewSchedo(options ...Option) *Schedo

func (*Schedo) DefineJob

func (s *Schedo) DefineJob(name, schedule string, executor Executor, options ...JobDefineOption) error

DefineJob defines a new job with the given name, schedule, and executor It sends the jobs to the Schedo API and stores the executor in the Schedo instance If the job is successfully defined, DefineJob returns nil In case of schedule change, the job will be updated in the Schedo API and its schedule will be changed

func (*Schedo) Start

func (s *Schedo) Start()

Start starts the Schedo instance

func (*Schedo) Stop

func (s *Schedo) Stop()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL