Jobsy is a robust, flexible, and efficient background job processing library for Go applications. It provides a simple yet powerful API for scheduling and managing tasks, supporting various job types and execution patterns.
- Multiple task types: one-time, recurring, and interval-based tasks
- Flexible scheduling options: immediate execution, scheduled execution, and periodic execution
- Priority-based task execution
- Automatic task retries with exponential backoff
- Concurrent task execution with configurable worker pool
- In-memory storage with extensible storage interface
- Graceful shutdown and task recovery
To install Jobsy, use go get:
go get github.com/nex-gen-tech/jobsyHere's a simple example to get you started with Jobsy:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/nex-gen-tech/jobsy"
)
func main() {
// Create a new worker
w := jobsy.NewWorker(&jobsy.WorkerOptions{})
// Create a context for graceful shutdown
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Start the worker
go func() {
if err := w.Start(ctx); err != nil {
log.Printf("Worker stopped with error: %v", err)
}
}()
// Schedule an immediate task
_, err := w.RunNow("Immediate Task", func() error {
fmt.Println("Executing Immediate Task")
return nil
})
if err != nil {
log.Fatalf("Failed to schedule immediate task: %v", err)
}
// Schedule a task to run after 5 seconds
_, err = w.RunAt("Delayed Task", func() error {
fmt.Println("Executing Delayed Task")
return nil
}, time.Now().Add(5*time.Second))
if err != nil {
log.Fatalf("Failed to schedule delayed task: %v", err)
}
// Run the worker for 10 seconds
time.Sleep(10 * time.Second)
// Graceful shutdown
cancel()
w.WaitForShutdown(5 * time.Second)
}w := jobsy.NewWorker(&jobsy.WorkerOptions{
Concurrency: 5,
Timeout: 30 * time.Second,
Priority: task.MediumPriority,
MaxRetry: 3,
})ctx, cancel := context.WithCancel(context.Background())
defer cancel()
err := w.Start(ctx)- Run a task immediately:
task, err := w.RunNow("Immediate Task", func() error {
// Task logic here
return nil
})- Schedule a task for future execution:
task, err := w.RunAt("Scheduled Task", func() error {
// Task logic here
return nil
}, time.Now().Add(1*time.Hour))- Schedule a recurring task:
task, err := w.RunEvery("Recurring Task", func() error {
// Task logic here
return nil
}, 5*time.Minute)- Schedule a task with custom options:
task, err := w.Schedule("Custom Task", func() error {
// Task logic here
return nil
}, "*/5 * * * *", jobsy.TaskOptions{
MaxRetry: 5,
TimeOut: 10 * time.Second,
})- Get task status:
status, err := w.GetTaskStatus(taskID)- Get all tasks:
tasks, err := w.GetAllTasks()cancel() // Cancel the context
w.WaitForShutdown(5 * time.Second)Jobsy uses in-memory storage by default, but you can implement your own storage backend by implementing the storage.Storage interface:
type Storage interface {
SaveTask(t *task.Task) error
LoadTask(id uuid.UUID) (*task.Task, error)
LoadAllTasks() ([]*task.Task, error)
DeleteTask(id uuid.UUID) error
UpdateTaskStatus(id uuid.UUID, status task.Status) error
}Then, pass your custom storage implementation when creating a new worker:
customStorage := NewCustomStorage()
w := jobsy.NewWorker(&jobsy.WorkerOptions{
Storage: customStorage,
})Jobsy automatically retries failed tasks with an exponential backoff strategy. You can customize the maximum number of retries:
task, err := w.RunNow("Retry Task", func() error {
// Task logic that might fail
return errors.New("temporary error")
}, jobsy.TaskOptions{MaxRetry: 5})You can set task priorities to control execution order:
task.Priority = task.HighPriorityTo run the test suite, use the following command:
go test ./...Contributions to Jobsy are welcome! Please feel free to submit a Pull Request.
Jobsy is released under the MIT License. See the LICENSE file for details.