Skip to content

Latest commit

 

History

History
290 lines (217 loc) · 7.12 KB

File metadata and controls

290 lines (217 loc) · 7.12 KB

Note

This content is translated by LLM. Original text can be found here

Cron Job Scheduler (Golang)

Ultra-lightweight Golang scheduler supporting standard cron expressions, custom descriptors, and custom intervals. A minimalist scheduler for Go that makes scheduling effortless.
Originally designed for the scheduling functionality used in threat score decay calculations for pardnchiu/go-ip-sentry.

license version readme

Three Core Features

Ultra-Low Learning Curve

Built with Go's standard library heap, focusing on core functionality with minimal memory usage and zero learning cost - if you can write cron expressions, you can use this

Flexible Syntax

Supports standard cron expressions, custom descriptors (@hourly, @daily, @weekly, etc.), and custom interval (@every) syntax

Efficient Architecture

Min-heap based task scheduling algorithm with concurrent task execution and management, panic recovery mechanism, and dynamic task addition/removal, ensuring optimal performance in high-volume task scenarios

Flow Chart

Click to view
flowchart TD
  A[Initialize] --> B[Setup Logger]
  B --> C[Initialize Task Heap]
  C --> D{Already Running?}
  D -->|Yes| D1[No Action]
  D -->|No| D2[Start Execution]
  
  D2 --> E[Calculate Initial Task Times]
  E --> F[Initialize Min Heap]
  F --> G[Start Main Loop]
  
  G --> H{Check Heap Status}
  G -->|No Tasks<br>Wait for Events| Q[Listen for Events]
  G -->|Has Tasks<br>Set Timer to Next Task| Q
  
  Q --> R{Event Type}
  R -->|Timer Expires| R1[Execute Due Tasks]
  R -->|Add Task| R2[Add to Heap]
  R -->|Remove Task| R3[Remove from Heap]
  R -->|Stop Signal| R4[Cleanup and Exit]
  
  R1 --> S[Pop Task from Heap]
  S --> T{Check if Enabled}
  T -->|Disabled| T0[Skip Task]
  T0 --> G
  T -->|Enabled| T1{Execute Task Function}
  T1 --> T11[Calculate Next Execution Time]
  T1 -->|Panic| T10[Recover]
  T10 --> T11[Calculate Next Execution Time]
  T11 --> U[Re-add to Heap if Recurring]
  
  R2 --> V[Parse Schedule]
  V --> W[Create Task Object]
  W --> X[Add to Heap]
  
  R3 --> Y[Find Task by ID]
  Y --> Z[Mark as Disabled]
  Z --> AA[Remove from Heap]
  
  U --> G
  X --> G
  AA --> G
  
  R4 --> BB[Wait for Running Tasks to Complete]
  BB --> CC[Close Channels]
  CC --> DD[Scheduler Stopped]
Loading

Dependencies

Usage

Installation

go get github.com/pardnchiu/go-cron

Initialization

package main

import (
  "fmt"
  "log"
  "time"
  
  cron "github.com/pardnchiu/go-cron"
)

func main() {
  // Initialize (optional configuration)
  scheduler, err := cron.New(cron.Config{
    Log: &cron.Log{Stdout: true},
    Location: time.Local,
  })
  if err != nil {
    log.Fatal(err)
  }
  
  // Start scheduler
  scheduler.Start()
  
  // Add tasks
  id1, _ := scheduler.Add("@daily", func() {
    fmt.Println("Daily execution")
  }, "Backup task")
  
  id2, _ := scheduler.Add("@every 5m", func() {
    fmt.Println("Execute every 5 minutes")
  })
  
  // View task list
  tasks := scheduler.List()
  fmt.Printf("Currently have %d tasks\n", len(tasks))
  
  // Remove specific task
  scheduler.Remove(id1)
  
  // Remove all tasks
  scheduler.RemoveAll()
  
  // Graceful shutdown
  ctx := scheduler.Stop()
  <-ctx.Done()
}

Configuration

type Config struct {
  Log      *Log           // Logger configuration
  Location *time.Location // Timezone setting (default: time.Local)
}

type Log struct {
  Path      string // Log file path (default: ./logs/cron.log)
  Stdout    bool   // Output to stdout (default: false)
  MaxSize   int64  // Maximum log file size in bytes (default: 16MB)
  MaxBackup int    // Number of backup files to retain (default: 5)
  Type      string // Output format: "json" for slog standard, "text" for tree format (default: "text")
}

Supported Formats

Standard Cron

5-field format: minute hour day month weekday

// Every minute
scheduler.Add("* * * * *", task)

// Daily at midnight
scheduler.Add("0 0 * * *", task)

// Weekdays at 9 AM
scheduler.Add("0 9 * * 1-5", task)

// Every 15 minutes
scheduler.Add("*/15 * * * *", task)

// First day of month at 6 AM
scheduler.Add("0 6 1 * *", task)

Custom Descriptors

// January 1st at midnight
scheduler.Add("@yearly", task)

// First day of month at midnight
scheduler.Add("@monthly", task)

// Every Sunday at midnight
scheduler.Add("@weekly", task)

// Daily at midnight
scheduler.Add("@daily", task)

// Every hour on the hour
scheduler.Add("@hourly", task)

// Every 30 seconds
scheduler.Add("@every 30s", task)

// Every 5 minutes
scheduler.Add("@every 5m", task)

// Every 2 hours
scheduler.Add("@every 2h", task)

// Every 12 hours
scheduler.Add("@every 12h", task)

Available Functions

Scheduler Management

  • New - Create new scheduler instance

    scheduler, err := cron.New(config)
    • Sets up task heap and communication channels
  • Start - Start scheduler instance

    scheduler.Start()
    • Starts scheduling loop
  • Stop - Gracefully stop scheduler

    ctx := scheduler.Stop()
    <-ctx.Done() // Wait for all tasks to complete
    • Sends stop signal to main loop
    • Returns context that completes when all running tasks finish
    • Ensures graceful shutdown without interrupting tasks

Task Management

  • Add - Add scheduled task

    taskID, err := scheduler.Add("0 */2 * * *", func() {
      // Task logic
    })
    • Parses schedule syntax
    • Generates unique task ID for management
  • Remove - Cancel task schedule

    scheduler.Remove(taskID)
    • Removes task from scheduling queue
    • Safe to call regardless of scheduler state
  • RemoveAll - Remove all tasks

    scheduler.RemoveAll()
    • Immediately removes all scheduled tasks
    • Does not affect currently running tasks
  • List - Get task list

    tasks := scheduler.List()

Upcoming Features

  • Task dependency management similar to php-async
    • Pre-dependencies: Task B executes after Task A completes
    • Post-dependencies: Task B executes before Task A starts
    • Multiple dependencies: Task C waits for both Tasks A and B to complete before executing

License

This project is licensed under the MIT License.

Author

邱敬幃 Pardn Chiu


©️ 2025 邱敬幃 Pardn Chiu