### Install darkit/cron Source: https://context7.com/darkit/cron/llms.txt Use 'go get' to install the library. ```bash go get github.com/darkit/cron ``` -------------------------------- ### Install Darkit Cron Dashboard Source: https://github.com/darkit/cron/blob/master/dashboard/README.md Use 'go get' to install the dashboard as a separate sub-package. ```bash go get github.com/darkit/cron/dashboard ``` -------------------------------- ### Running Example Applications Source: https://github.com/darkit/cron/blob/master/README.md Commands to run various example applications included with the Darkit Cron library. These examples cover different features such as minimal setup, context lifecycle, retry mechanisms, history tracking, custom logging, panic recovery, and the web dashboard. ```bash go run examples/minimal/main.go go run examples/retry/main.go go run examples/history/main.go go run dashboard/examples/main.go ``` -------------------------------- ### Run Context Lifecycle Example Source: https://github.com/darkit/cron/blob/master/examples/context-lifecycle/README.md Navigate to the example directory and run the main Go program to observe the scheduler's behavior with context cancellation. ```bash cd examples/context-lifecycle go run main.go ``` -------------------------------- ### Running Minimal Example Source: https://github.com/darkit/cron/blob/master/docs/快速开始.md Execute the simplest cron job example. This is useful for a quick test of the library's basic functionality. ```bash go run examples/minimal/main.go ``` -------------------------------- ### Set up Web Dashboard and REST API in Go Source: https://context7.com/darkit/cron/llms.txt Integrate the optional dashboard sub-package to provide a web UI and RESTful API for monitoring and controlling scheduled tasks. This example shows how to initialize the cron scheduler, schedule a task, create and start the dashboard server with API key authentication and CORS configuration. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" "github.com/darkit/cron/dashboard" ) func main() { c := cron.New() c.Schedule("api-task", "@every 10s", func(ctx context.Context) { fmt.Println("Task running") }, cron.JobOptions{ Labels: map[string]string{"service": "api"}, }) c.Start() defer c.StopGracefully(10 * time.Second) // Create dashboard server srv := dashboard.NewServer(c, ":8080", dashboard.WithAPIKey("secret-api-key"), // Enable API key auth dashboard.WithAllowedOrigins([]string{"*"}), // CORS configuration ) // Start dashboard (non-blocking) if err := srv.Start(); err != nil { panic(err) } defer srv.Stop() fmt.Println("Dashboard available at http://localhost:8080") fmt.Println("API available at http://localhost:8080/api/") // Keep running select {} } ``` -------------------------------- ### Web API for Cron Task Control in Go Source: https://github.com/darkit/cron/blob/master/docs/运行时控制.md A full example demonstrating how to create a cron scheduler, add tasks, start it, and expose HTTP endpoints for controlling tasks (run, pause, resume, update). Includes graceful shutdown. ```go package main import ( "context" "encoding/json" "fmt" "net/http" "time" "github.com/darkit/cron" ) var scheduler *cron.Cron func main() { scheduler = cron.New() // 添加一些任务 scheduler.Schedule("task-1", "*/10 * * * * *", func(ctx context.Context) { fmt.Println("任务1执行") }) scheduler.Schedule("task-2", "*/20 * * * * *", func(ctx context.Context) { fmt.Println("任务2执行") }) scheduler.Start() defer scheduler.StopGracefully(5 * time.Second) // 设置 HTTP API http.HandleFunc("/tasks/run", handleRunNow) http.HandleFunc("/tasks/pause", handlePause) http.HandleFunc("/tasks/resume", handleResume) http.HandleFunc("/tasks/update", handleUpdate) fmt.Println("API 服务启动在 :8080") http.ListenAndServe(":8080", nil) } func handleRunNow(w http.ResponseWriter, r *http.Request) { taskID := r.URL.Query().Get("id") if taskID == "" { http.Error(w, "缺少任务ID", http.StatusBadRequest) return } if err := scheduler.RunNow(taskID); err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(map[string]string{ "message": "任务已触发", "task_id": taskID, }) } func handlePause(w http.ResponseWriter, r *http.Request) { taskID := r.URL.Query().Get("id") if taskID == "" { http.Error(w, "缺少任务ID", http.StatusBadRequest) return } if err := scheduler.Pause(taskID); err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(map[string]string{ "message": "任务已暂停", "task_id": taskID, }) } func handleResume(w http.ResponseWriter, r *http.Request) { taskID := r.URL.Query().Get("id") if taskID == "" { http.Error(w, "缺少任务ID", http.StatusBadRequest) return } if err := scheduler.Resume(taskID); err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(map[string]string{ "message": "任务已恢复", "task_id": taskID, }) } func handleUpdate(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Error(w, "仅支持POST请求", http.StatusMethodNotAllowed) return } var req struct { TaskID string `json:"task_id"` Schedule string `json:"schedule"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "无效的请求体", http.StatusBadRequest) return } if err := scheduler.Update(req.TaskID, req.Schedule); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } json.NewEncoder(w).Encode(map[string]string{ "message": "任务已更新", "task_id": req.TaskID, "schedule": req.Schedule, }) } ``` -------------------------------- ### Running Web Management Interface Example Source: https://github.com/darkit/cron/blob/master/docs/快速开始.md Run an example that includes a web-based management interface for the cron scheduler. This provides a UI for monitoring and managing tasks. ```bash go run dashboard/examples/main.go ``` -------------------------------- ### Minimal Function Task with darkit-cron Source: https://github.com/darkit/cron/blob/master/docs/darkit-cron/SKILL.md Demonstrates the basic setup for a recurring function-based task using cron.New(), Schedule(), and Start(). Includes graceful shutdown with StopGracefully(). ```go c := cron.New() if err := c.Schedule("sync-task", "@every 30s", func(ctx context.Context) { // do work }); err != nil { return err } if err := c.Start(); err != nil { return err } defer c.StopGracefully(5 * time.Second) ``` -------------------------------- ### Dashboard API: Curl Examples Source: https://github.com/darkit/cron/blob/master/README.md Provides example `curl` commands for interacting with the Web Dashboard API. These examples demonstrate how to trigger, pause, resume, and update tasks, as well as how to send schedule updates. ```bash # curl 示例 curl -X POST http://localhost:8080/api/tasks/{id}/run curl -X POST http://localhost:8080/api/tasks/{id}/pause curl -X POST http://localhost:8080/api/tasks/{id}/resume curl -X PATCH -H 'Content-Type: application/json' \ -d '{"schedule":"*/10 * * * * *"}' \ http://localhost:8080/api/tasks/{id}/schedule ``` -------------------------------- ### Running Retry Mechanism Example Source: https://github.com/darkit/cron/blob/master/docs/快速开始.md Run an example that demonstrates the retry mechanism for failed cron jobs. This helps in understanding how the library handles task failures and retries. ```bash go run examples/retry/main.go ``` -------------------------------- ### Scheduler Startup Flow Source: https://github.com/darkit/cron/blob/master/docs/技术选型和架构.md Diagram illustrating the sequence of events when the scheduler starts. ```APIDOC ## Scheduler Startup Flow ### Description This diagram illustrates the sequence of events from initializing the Cron instance to the scheduler starting its loop. ### Sequence Diagram ```mermaid sequenceDiagram participant U as User participant C as Cron participant S as Scheduler participant P as Parser U->>C: New() C->>S: newScheduler() S->>S: Initialize data structures U->>C: Schedule(id, schedule, handler) C->>P: parseSpec(spec) P->>P: Parse expression P-->>C: Return parsed result C->>S: addTask(task) S->>S: Store task U->>C: Start() C->>S: start() S->>S: Start scheduling loop loop Scheduling Loop S->>S: Check task execution time S->>S: Execute due tasks S->>S: Wait for next check end ``` ``` -------------------------------- ### Running History Log Example Source: https://github.com/darkit/cron/blob/master/docs/快速开始.md Execute an example showcasing the history logging feature of the cron library. This allows you to track the execution of scheduled tasks. ```bash go run examples/history/main.go ``` -------------------------------- ### API Call Examples for Cron Tasks Source: https://github.com/darkit/cron/blob/master/docs/运行时控制.md Provides command-line examples using curl to interact with the Web API for controlling cron tasks, including triggering, pausing, resuming, and updating schedules. ```bash # 立即触发任务 curl "http://localhost:8080/tasks/run?id=task-1" # 暂停任务 curl "http://localhost:8080/tasks/pause?id=task-1" # 恢复任务 curl "http://localhost:8080/tasks/resume?id=task-1" # 更新任务调度 curl -X POST http://localhost:8080/tasks/update \ -H "Content-Type: application/json" \ -d '{"task_id":"task-1","schedule":"*/5 * * * * *"}' ``` -------------------------------- ### Implement RegisteredJob: SimpleJob Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Example implementation of the RegisteredJob interface for a simple task that prints its name. ```go // 示例 1: 简单任务 type SimpleJob struct { name string } func NewSimpleJob(name string) *SimpleJob { return &SimpleJob{name: name} } func (j *SimpleJob) Name() string { return j.name } func (j *SimpleJob) Schedule() string { return "*/5 * * * * *" // 每 5 秒 } func (j *SimpleJob) Run(ctx context.Context) error { fmt.Printf("任务 %s 执行\n", j.name) return nil } ``` -------------------------------- ### Implement RegisteredJob: EmailJob Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Example implementation of RegisteredJob for an email sending task, demonstrating dependency injection for mailer and logger services. ```go // 示例 3: 带依赖注入的任务 type EmailJob struct { mailer EmailSender logger Logger } func NewEmailJob(mailer EmailSender, logger Logger) *EmailJob { return &EmailJob{ mailer: mailer, logger: logger, } } func (j *EmailJob) Name() string { return "email-sender" } func (j *EmailJob) Schedule() string { return "@hourly" } func (j *EmailJob) Run(ctx context.Context) error { j.logger.Info("开始发送邮件") if err := j.mailer.SendPendingEmails(ctx); err != nil { j.logger.Error("发送失败:", err) return err } j.logger.Info("发送完成") return nil } ``` -------------------------------- ### Paginated Query (First 10 Records) Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Example of querying the first 10 historical records for pagination. ```go // 查询前 10 条记录 records, err := c.QueryHistory(history.RecordFilter{ Limit: 10, }) ``` -------------------------------- ### Combined Query Example Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Demonstrates a combined query for a specific task's failed records within a time range, with pagination. Includes displaying detailed error information. ```go // 查询特定任务在指定时间范围内的失败记录,分页显示 yesterday := time.Now().Add(-24 * time.Hour) now := time.Now() records, err := c.QueryHistory(history.RecordFilter{ TaskID: "important-task", StartTime: &yesterday, EndTime: &now, FailedOnly: true, Offset: 0, Limit: 20, }) if err != nil { log.Printf("查询失败: %v", err) return } fmt.Printf("找到 %d 条失败记录:\n", len(records)) for _, record := range records { fmt.Printf(" 时间: %v\n", record.StartTime.Format("2006-01-02 15:04:05")) fmt.Printf(" 耗时: %v\n", record.Duration) fmt.Printf(" 重试: %d 次\n", record.RetryCount) fmt.Printf(" 错误: %s\n", record.Error) fmt.Println() } ``` -------------------------------- ### Implement RegisteredJob: DatabaseSyncJob Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Example implementation of RegisteredJob for a database synchronization task, taking a database connection and interval as parameters. ```go // 示例 2: 带配置的任务 type DatabaseSyncJob struct { db *sql.DB interval string } func NewDatabaseSyncJob(db *sql.DB, interval string) *DatabaseSyncJob { return &DatabaseSyncJob{ db: db, interval: interval, } } func (j *DatabaseSyncJob) Name() string { return "db-sync" } func (j *DatabaseSyncJob) Schedule() string { return j.interval } func (j *DatabaseSyncJob) Run(ctx context.Context) error { // 同步数据库 rows, err := j.db.QueryContext(ctx, "SELECT * FROM sync_table") if err != nil { return err } defer rows.Close() // 处理数据 return nil } ``` -------------------------------- ### Get All Task Details in Go Source: https://github.com/darkit/cron/blob/master/docs/运行时控制.md Retrieves a list of all tasks and their details. Useful for monitoring and auditing. ```go func (c *Cron) GetAllTasks() []*TaskInfo ``` -------------------------------- ### JSONL File Example Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Illustrates the format of a JSONL file used for storing historical execution records, with each line representing a single JSON object. ```json {"ID":"550e8400-e29b-41d4-a716-446655440000","TaskID":"backup-task","StartTime":"2025-01-15T10:00:00Z","EndTime":"2025-01-15T10:00:05Z","Duration":5000000000,"Success":true,"RetryCount":0,"Error":""} {"ID":"550e8400-e29b-41d4-a716-446655440001","TaskID":"backup-task","StartTime":"2025-01-15T10:05:00Z","EndTime":"2025-01-15T10:05:03Z","Duration":3000000000,"Success":true,"RetryCount":0,"Error":""} {"ID":"550e8400-e29b-41d4-a716-446655440002","TaskID":"backup-task","StartTime":"2025-01-15T10:10:00Z","EndTime":"2025-01-15T10:10:00Z","Duration":500000000,"Success":false,"RetryCount":2,"Error":"connection timeout"} ``` -------------------------------- ### Full Production Cron Configuration Example Source: https://github.com/darkit/cron/blob/master/docs/生产实践.md A complete Go program demonstrating how to set up and run a cron scheduler in a production environment. Includes logging, history recording, task registration, and server startup. ```go package main import ( "context" "log" "log/slog" "os" "time" "github.com/darkit/cron" "github.com/darkit/cron/history" ) func main() { // 1. 加载配置 config, err := loadConfig() if err != nil { log.Fatal(err) } // 2. 设置日志 logger := setupLogging() // 3. 创建历史记录存储 storage, err := history.NewFileStorage(config.HistoryDir) if err != nil { logger.Error("Failed to create storage", "error", err) os.Exit(1) } defer storage.Close() recorder := history.NewHistoryRecorder(storage) defer recorder.Close() // 4. 创建调度器 cronLogger := &SlogAdapter{logger: logger} eventHook := metricsEventHook c := cron.New( cron.WithLogger(cronLogger), cron.WithHistoryRecorder(recorder), cron.WithEventHook(eventHook), ) // 5. 注册任务 scheduleProductionJobs(c) // 6. 定期清理历史记录 c.Schedule("cleanup-history", "@daily", func(ctx context.Context) { before := time.Now().Add(-time.Duration(config.RetentionDays) * 24 * time.Hour) deleted, err := c.CleanupHistory(before) if err != nil { logger.Error("Failed to cleanup history", "error", err) return } logger.Info("Cleaned up history", "deleted", deleted) }) // 7. 启动监控 go monitorTasks(c, logger) // 8. 启动指标服务器 if config.EnableMetrics { startMetricsServer(config.MetricsPort) } // 9. 启动健康检查服务器 startHealthCheckServer(c, 8080) // 10. 启动调度器 c.Start() defer c.StopGracefully(30 * time.Second) logger.Info("Scheduler started successfully") // 11. 等待停止信号 select {} } ``` -------------------------------- ### Differentiate Start and End Events Source: https://github.com/darkit/cron/blob/master/docs/事件钩子.md Example of how to check if an event is a start or end event by inspecting the `End` field. The `End` field is zero for start events. ```go hook := func(ev cron.Event) { if ev.End.IsZero() { // 开始事件 fmt.Printf("任务 %s 开始执行\n", ev.TaskID) } else { // 结束事件 if ev.Success { fmt.Printf("任务 %s 成功完成,耗时 %v\n", ev.TaskID, ev.Duration) } else { fmt.Printf("任务 %s 执行失败: %s\n", ev.TaskID, ev.Error) } } } ``` -------------------------------- ### Recommended: Instantiate Job Registry Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Demonstrates the recommended approach for task management by instantiating a JobRegistry, registering tasks, and scheduling them. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" ) // 1. 定义任务 type BackupJob struct { path string } func (j *BackupJob) Name() string { return "backup-job" } func (j *BackupJob) Schedule() string { return "0 2 * * *" // 每天 2 点执行 } func (j *BackupJob) Run(ctx context.Context) error { fmt.Printf("执行备份: %s\n", j.path) return nil } // 2. 定义更多任务 type CleanupJob struct{} func (j *CleanupJob) Name() string { return "cleanup-job" } func (j *CleanupJob) Schedule() string { return "0 3 * * *" // 每天 3 点执行 } func (j *CleanupJob) Run(ctx context.Context) error { fmt.Println("执行清理") return nil } func main() { // 3. 创建独立注册表(推荐) registry := cron.NewJobRegistry() // 4. 注册任务 registry.SafeRegister(&BackupJob{path: "/data"}) registry.SafeRegister(&CleanupJob{}) // 5. 创建调度器 c := cron.New() // 6. 批量调度注册表中的任务 err := c.ScheduleFromRegistry(registry) if err != nil { fmt.Printf("调度失败: %v\n", err) return } // 7. 启动调度器 c.Start() defer c.StopGracefully(5 * time.Second) // 保持运行 select {} } ``` -------------------------------- ### Get System Statistics API Response Source: https://github.com/darkit/cron/blob/master/dashboard/README.md Example JSON response for the GET /api/stats endpoint, providing system-wide cron job statistics. ```json { "totalTasks": 5, "runningTasks": 2, "totalRuns": 1250, "successRuns": 1200, "failedRuns": 50, "totalRetries": 25, "successRate": 96.0, "avgDuration": "N/A", "totalDuration": "N/A", "historyRecords": 1250 } ``` -------------------------------- ### Get All Tasks API Response Source: https://github.com/darkit/cron/blob/master/dashboard/README.md Example JSON response for the GET /api/tasks endpoint, listing all registered cron tasks with their status and statistics. ```json [ { "id": "task-1", "schedule": "@every 10s", "nextRun": "2025-10-30T18:00:10Z", "isRunning": false, "runCount": 120, "successCount": 118, "failCount": 2, "retryCount": 5, "lastRunTime": "2025-10-30T18:00:00Z", "lastRunStatus": "success", "lastError": "", "descriptions": {} } ] ``` -------------------------------- ### Go Event Hook Best Practices: Differentiating Event Types Source: https://github.com/darkit/cron/blob/master/docs/事件钩子.md Handle cron job start and end events differently based on your application's needs. The example shows how to conditionally execute logic, such as logging a start message or processing the completion of a task. ```go hook := func(ev cron.Event) { if ev.End.IsZero() { // 处理开始事件 fmt.Printf("任务 %s 开始执行\n", ev.TaskID) return } // 处理结束事件 fmt.Printf("任务 %s 执行完成\n", ev.TaskID) } ``` -------------------------------- ### Query History Records API Response Source: https://github.com/darkit/cron/blob/master/dashboard/README.md Example JSON response for the GET /api/history endpoint, showing a paginated list of task execution records. ```json { "records": [ { "id": "task-1_1730304000123", "taskID": "task-1", "startTime": "2025-10-30T18:00:00Z", "endTime": "2025-10-30T18:00:01Z", "duration": 1000000000, "success": true, "retryCount": 0, "error": "" } ], "total": 1250, "page": 1, "pageSize": 50, "totalPages": 25 } ``` -------------------------------- ### Register and Schedule Jobs with Options Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Initializes dependencies, creates a job registry, registers various jobs, and then schedules them in bulk with common options like timeout and asynchronous execution. This is useful for setting up a cron service with a predefined set of tasks. ```go func main() { // 初始化依赖 db := initDatabase() mailer := initMailer() logger := initLogger() // 创建注册表 registry := cron.NewJobRegistry() // 注册任务 registry.SafeRegister(NewSimpleJob("job-1")) registry.SafeRegister(NewDatabaseSyncJob(db, "@every 10m")) registry.SafeRegister(NewEmailJob(mailer, logger)) // 创建调度器 c := cron.New() // 批量调度,可以为所有任务设置统一的默认选项 err := c.ScheduleFromRegistry(registry, cron.JobOptions{ Timeout: 5 * time.Minute, // 统一超时 Async: true, // 统一异步执行 }) if err != nil { log.Fatal(err) } // 启动 c.Start() defer c.StopGracefully(10 * time.Second) select {} } ``` -------------------------------- ### Create and Configure a Cron Scheduler in Go Source: https://context7.com/darkit/cron/llms.txt Demonstrates creating a new cron scheduler with options for context, history recording, logging, and event hooks. Includes graceful shutdown handling. ```go package main import ( "context" "fmt" "os" "os/signal" "syscall" "time" "github.com/darkit/cron" "github.com/darkit/cron/history" ) func main() { // Basic scheduler c := cron.New() // Scheduler with custom context for graceful shutdown ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer cancel() // Scheduler with history recording storage, _ := history.NewFileStorage("./task-history") recorder := history.NewHistoryRecorder(storage) defer recorder.Close() c = cron.New( cron.WithContext(ctx), cron.WithHistoryRecorder(recorder), cron.WithLogger(&cron.NoOpLogger{}), // Disable logging cron.WithEventHook(func(ev cron.Event) { if ev.End.IsZero() { fmt.Printf("Task %s started\n", ev.TaskID) } else { fmt.Printf("Task %s completed in %v, success=%v\n", ev.TaskID, ev.Duration, ev.Success) } }), ) c.Schedule("example", "@every 5s", func(ctx context.Context) { fmt.Println("Running task...") }) c.Start() <-ctx.Done() c.StopGracefully(30 * time.Second) } ``` -------------------------------- ### Implement Custom Event Hooks in Go Source: https://context7.com/darkit/cron/llms.txt Subscribe to task lifecycle events like start, completion, and failure using custom functions. This allows for detailed logging, monitoring, and alerting. The example shows how to define a hook function and pass it to the cron scheduler. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" ) func main() { // Custom event hook function eventHook := func(ev cron.Event) { if ev.End.IsZero() { // Task started fmt.Printf("[START] Task %s started at %v\n", ev.TaskID, ev.Start) } else { // Task completed status := "SUCCESS" if !ev.Success { status = "FAILED" } fmt.Printf("[%s] Task %s completed in %v (retries: %d)\n", status, ev.TaskID, ev.Duration, ev.Retries) if ev.Error != "" fmt.Printf(" Error: %s\n", ev.Error) } } } c := cron.New(cron.WithEventHook(eventHook)) // Alternative: Built-in logger hook // c := cron.New(cron.WithEventHook(cron.NewEventLoggerHook(myLogger))) // Alternative: Channel-based hook for async processing eventChan := make(chan cron.Event, 100) c2 := cron.New(cron.WithEventHook(cron.NewEventChannelHook(eventChan))) go func() { for ev := range eventChan { // Process events asynchronously fmt.Printf("Async event: %s\n", ev.TaskID) } }() c.Schedule("hook-demo", "@every 3s", func(ctx context.Context) { fmt.Println(" Task executing...") }) c.Start() defer c.StopGracefully(10 * time.Second) time.Sleep(15 * time.Second) _ = c2 // Prevent unused variable warning } ``` -------------------------------- ### Interact with Dashboard REST API using cURL Source: https://context7.com/darkit/cron/llms.txt Examples of cURL commands to interact with the Darkit Cron dashboard's REST API for managing tasks, retrieving statistics, and accessing history. Demonstrates endpoints for listing, getting, triggering, pausing, resuming, updating, and deleting tasks, as well as filtering history data and using API key authentication. ```bash # List all tasks curl http://localhost:8080/api/tasks # Get task details curl http://localhost:8080/api/tasks/api-task # Trigger task immediately curl -X POST http://localhost:8080/api/tasks/api-task/run # Pause task curl -X POST http://localhost:8080/api/tasks/api-task/pause # Resume task curl -X POST http://localhost:8080/api/tasks/api-task/resume # Update schedule curl -X PATCH -H 'Content-Type: application/json' \ -d '{"schedule":"*/5 * * * * *"}' \ http://localhost:8080/api/tasks/api-task/schedule # Remove task curl -X DELETE http://localhost:8080/api/tasks/api-task # Get statistics curl http://localhost:8080/api/stats # Get history with pagination and filters curl "http://localhost:8080/api/history?taskId=api-task&limit=10&offset=0" curl "http://localhost:8080/api/history?failedOnly=true&startTime=2024-01-01T00:00:00Z" # With API key authentication curl -H "X-API-Key: secret-api-key" http://localhost:8080/api/tasks curl -H "Authorization: Bearer secret-api-key" http://localhost:8080/api/tasks curl "http://localhost:8080/api/tasks?api_key=secret-api-key" ``` -------------------------------- ### Register Job with Registry Source: https://github.com/darkit/cron/blob/master/docs/技术选型和架构.md Demonstrates recommended and compatible patterns for registering jobs with the cron system, either through a job registry or global registration. ```go // 推荐:实例化注册表 reg := cron.NewJobRegistry() reg.SafeRegister(job) c.ScheduleFromRegistry(reg) // 兼容:全局注册 func init() { cron.SafeRegisterJob(job) } c.ScheduleRegistered() ``` -------------------------------- ### Basic Usage of History Recorder Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Demonstrates how to set up and use the history recorder with a cron scheduler. Includes creating storage, initializing the recorder, adding a task, starting the scheduler, and querying history. ```go package main import ( "context" "fmt" "log" "time" "github.com/darkit/cron" "github.com/darkit/cron/history" ) func main() { // 1. 创建历史记录存储 storage, err := history.NewFileStorage("./history") if err != nil { log.Fatal(err) } defer storage.Close() // 2. 创建历史记录器 recorder := history.NewHistoryRecorder(storage) defer recorder.Close() // 3. 创建启用历史记录的调度器 c := cron.New(cron.WithHistoryRecorder(recorder)) // 4. 添加任务 c.Schedule("demo-task", "@every 5s", func(ctx context.Context) { fmt.Println("任务执行") }) // 5. 启动调度器 c.Start() defer c.StopGracefully(5 * time.Second) // 等待一段时间后查询历史 time.Sleep(30 * time.Second) // 6. 查询历史记录 records, err := c.QueryHistory(history.RecordFilter{ TaskID: "demo-task", Limit: 10, }) if err != nil { log.Printf("查询失败: %v", err) return } // 7. 显示结果 fmt.Printf("找到 %d 条记录:\n", len(records)) for _, record := range records { fmt.Printf(" 时间: %v, 成功: %v, 耗时: %v\n", record.StartTime.Format("15:04:05"), record.Success, record.Duration, ) } } ``` -------------------------------- ### Real-time Task Monitoring with Event Channel Hook Source: https://github.com/darkit/cron/blob/master/docs/事件钩子.md This example demonstrates how to monitor task execution in real-time using an event channel hook. It collects metrics like total count, success count, failure count, and total duration for each task. The statistics are printed to the console every 10 seconds. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" ) type TaskMetrics struct { totalCount int successCount int failCount int totalDuration time.Duration } func main() { eventChan := make(chan cron.Event, 100) metrics := make(map[string]*TaskMetrics) // 启动统计协程 go func() { ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() for { select { case ev := <-eventChan: if ev.End.IsZero() { continue } // 更新统计 if metrics[ev.TaskID] == nil { metrics[ev.TaskID] = &TaskMetrics{} } m := metrics[ev.TaskID] m.totalCount++ m.totalDuration += ev.Duration if ev.Success { m.successCount++ } else { m.failCount++ } case <-ticker.C: // 打印统计信息 fmt.Println("\n===== 任务执行统计 =====") for taskID, m := range metrics { successRate := float64(m.successCount) / float64(m.totalCount) * 100 avgDuration := m.totalDuration / time.Duration(m.totalCount) fmt.Printf("任务: %s\n", taskID) fmt.Printf(" 总次数: %d\n", m.totalCount) fmt.Printf(" 成功率: %.2f%%\n", successRate) fmt.Printf(" 平均耗时: %v\n", avgDuration) } fmt.Println("========================") } } }() c := cron.New(cron.WithEventHook(cron.NewEventChannelHook(eventChan))) c.Schedule("task-1", "*/3 * * * * *", func(ctx context.Context) { time.Sleep(500 * time.Millisecond) }) c.Schedule("task-2", "*/5 * * * * *", func(ctx context.Context) { time.Sleep(1 * time.Second) }) c.Start() defer c.Stop() time.Sleep(1 * time.Minute) } ``` -------------------------------- ### Limited Run Task with Start Time Source: https://github.com/darkit/cron/blob/master/docs/darkit-cron/SKILL.md Schedules a task to run a maximum number of times, starting at a specific time, using ScheduleLimitedFrom(). ```go startAt := time.Now().Add(30 * time.Minute) err := c.ScheduleLimitedFrom("campaign-task", "@every 10m", startAt, 3, func(ctx context.Context) { // run at most 3 planned times }) ``` -------------------------------- ### Create Job Instances Using Factory Functions Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Illustrates the use of factory functions to create job instances, promoting code reusability and maintainability. This pattern is helpful when jobs require specific configurations or parameters during instantiation. ```go // 定义工厂函数 func NewBackupJob(path string, interval string) *BackupJob { return &BackupJob{ path: path, interval: interval, logger: log.Default(), } } // 使用工厂创建和注册 registry := cron.NewJobRegistry() registry.SafeRegister(NewBackupJob("/data", "@daily")) registry.SafeRegister(NewBackupJob("/logs", "@weekly")) ``` -------------------------------- ### 提交代码 Source: https://github.com/darkit/cron/blob/master/CONTRIBUTING.md 添加修改的文件,使用中文提交信息进行提交,然后推送到您的Fork。 ```bash git add . git commit -m "feat: 添加新功能描述" git push origin feature/your-feature-name ``` -------------------------------- ### Iterate and Display Task Information in Go Source: https://github.com/darkit/cron/blob/master/docs/运行时控制.md Demonstrates how to iterate through the task details obtained from GetAllTasks and display their status and next run time. Also shows how to count paused tasks. ```go // 获取所有任务详情 tasks := c.GetAllTasks() for _, info := range tasks { status := "运行中" if info.IsPaused { status = "已暂停" } fmt.Printf("任务 %s [%s]: 下次执行 %v\n", info.ID, status, info.NextRun) } // 统计暂停的任务数量 pausedCount := 0 for _, info := range tasks { if info.IsPaused { pausedCount++ } } fmt.Printf("共 %d 个任务,其中 %d 个已暂停\n", len(tasks), pausedCount) ``` -------------------------------- ### Query History Records Examples Source: https://github.com/darkit/cron/blob/master/dashboard/README.md Examples of curl commands to query task execution history with various filters like task ID, success status, time range, and pagination. ```bash # 查询特定任务的历史 curl "http://localhost:8080/api/history?taskId=task-1&limit=10" # 查询最近 1 小时的失败记录 curl "http://localhost:8080/api/history?failedOnly=true&startTime=2025-10-30T17:00:00Z" # 分页查询 curl "http://localhost:8080/api/history?limit=20&offset=40" ``` -------------------------------- ### Conditionally Register Jobs Based on Configuration Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Demonstrates how to conditionally register jobs based on application configuration and environment. This allows for flexible job management, enabling or disabling specific tasks as needed. ```go func registerJobs(registry *cron.JobRegistry, config *Config) { // 始终注册核心任务 registry.SafeRegister(NewCoreJob()) // 根据配置注册可选任务 if config.EnableBackup { registry.SafeRegister(NewBackupJob(config.BackupPath)) } if config.EnableSync { registry.SafeRegister(NewSyncJob(config.SyncInterval)) } if config.EnableCleanup { registry.SafeRegister(NewCleanupJob()) } // 根据环境注册不同任务 switch config.Environment { case "production": registry.SafeRegister(NewMonitorJob("prod")) registry.SafeRegister(NewAlertJob()) case "staging": registry.SafeRegister(NewMonitorJob("staging")) case "development": registry.SafeRegister(NewDebugJob()) } } func main() { config := loadConfig() registry := cron.NewJobRegistry() registerJobs(registry, config) c := cron.New() c.ScheduleFromRegistry(registry) c.Start() select {} } ``` -------------------------------- ### Compatible: Global Registration Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Illustrates the global registration method for simpler scenarios, where jobs are registered in package init functions. ```go package jobs import ( "context" "fmt" "github.com/darkit/cron" ) type BackupJob struct{} func (j *BackupJob) Name() string { return "backup" } func (j *BackupJob) Schedule() string { return "@daily" } func (j *BackupJob) Run(ctx context.Context) error { fmt.Println("执行备份") return nil } // 在包初始化时自动注册 func init() { cron.SafeRegisterJob(&BackupJob{}) } ``` ```go package main import ( _ "yourproject/jobs" // 导入触发 init() "github.com/darkit/cron" ) func main() { c := cron.New() // 批量调度所有全局注册的任务 c.ScheduleRegistered() c.Start() defer c.Stop() select {} } ``` -------------------------------- ### CatchUp Misfire Strategy Example Source: https://github.com/darkit/cron/blob/master/docs/Misfire策略详解.md Demonstrates the CatchUp Misfire policy, which attempts to run all missed job executions (up to 5) after the scheduler resumes. This is ideal for batch processing or incremental updates where data integrity is paramount. The example simulates pausing and resuming a batch job. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" ) func main() { c := cron.New() // 配置 CatchUp 策略:尽可能补跑错过的执行 c.Schedule("batch", "*/10 * * * * *", func(ctx context.Context) { fmt.Printf("[%s] 批处理任务执行\n", time.Now().Format("15:04:05")) time.Sleep(3 * time.Second) // 快速处理 }, cron.JobOptions{ MisfirePolicy: cron.MisfireCatchUp, Async: true, // 异步执行提高效率 }) c.Start() // 模拟系统暂停 time.Sleep(15 * time.Second) fmt.Println("暂停任务...") c.Pause("batch") // 暂停30秒(错过3次执行) time.Sleep(30 * time.Second) fmt.Println("恢复任务...") c.Resume("batch") // 观察补跑 time.Sleep(1 * time.Minute) c.Stop() } ``` -------------------------------- ### Manage Job Lifecycle with Initialize and Cleanup Source: https://github.com/darkit/cron/blob/master/docs/任务注册.md Implements job initialization and cleanup methods to manage resources effectively. This pattern ensures that resources used by a job are properly set up before execution and released afterward, especially during graceful shutdown. ```go type ManagedJob struct { name string client *http.Client } func NewManagedJob(name string) *ManagedJob { job := &ManagedJob{ name: name, } job.Initialize() return job } func (j *ManagedJob) Initialize() { // 初始化资源 j.client = &http.Client{ Timeout: 30 * time.Second, } } func (j *ManagedJob) Cleanup() { // 清理资源 j.client.CloseIdleConnections() } func (j *ManagedJob) Name() string { return j.name } func (j *ManagedJob) Schedule() string { return "@every 5m" } func (j *ManagedJob) Run(ctx context.Context) error { // 使用资源 resp, err := j.client.Get("https://api.example.com/data") if err != nil { return err } defer resp.Body.Close() // 处理响应 return nil } func main() { registry := cron.NewJobRegistry() job := NewManagedJob("api-poller") registry.SafeRegister(job) c := cron.New() c.ScheduleFromRegistry(registry) c.Start() // 优雅停止时清理资源 defer func() { c.StopGracefully(10 * time.Second) job.Cleanup() }() select {} } ``` -------------------------------- ### Query Failed Records Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Example of querying only failed historical records. ```go // 查询失败的记录 records, err = c.QueryHistory(history.RecordFilter{ FailedOnly: true, }) ``` -------------------------------- ### Query Successful Records Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Example of querying only successful historical records. ```go // 查询成功的记录 records, err = c.QueryHistory(history.RecordFilter{ SuccessOnly: true, }) ``` -------------------------------- ### Once Misfire Strategy Example Source: https://github.com/darkit/cron/blob/master/docs/Misfire策略详解.md Illustrates the Once Misfire policy, which runs a missed job execution once immediately after the missed interval. This is useful for tasks like data synchronization where at least one execution is necessary. The example uses an asynchronous job that sleeps for 25 seconds, missing 10-second intervals. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" ) func main() { c := cron.New() // 配置 Once 策略:错过后补跑一次 c.Schedule("sync", "*/10 * * * * *", func(ctx context.Context) { fmt.Printf("[%s] 数据同步任务执行\n", time.Now().Format("15:04:05")) time.Sleep(25 * time.Second) // 模拟耗时任务 }, cron.JobOptions{ MisfirePolicy: cron.MisfireRunOnce, Async: true, // 异步执行避免阻塞 }) c.Start() defer c.Stop() time.Sleep(2 * time.Minute) } ``` -------------------------------- ### Skip Misfire Strategy Example Source: https://github.com/darkit/cron/blob/master/docs/Misfire策略详解.md Demonstrates the Skip Misfire policy where missed job executions are skipped. This is suitable for real-time tasks where historical data is not critical and system overload should be avoided. The example shows a monitoring task that sleeps for 25 seconds, missing subsequent 10-second intervals. ```go package main import ( "context" "fmt" "time" "github.com/darkit/cron" ) func main() { c := cron.New() // 配置 Skip 策略:错过的执行直接跳过 c.Schedule("monitor", "*/10 * * * * *", func(ctx context.Context) { fmt.Printf("[%s] 监控任务执行\n", time.Now().Format("15:04:05")) time.Sleep(25 * time.Second) // 模拟耗时任务 }, cron.JobOptions{ MisfirePolicy: cron.MisfireSkip, }) c.Start() defer c.Stop() time.Sleep(2 * time.Minute) } ``` -------------------------------- ### Implement Custom MySQL Storage for History Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Provides an example of implementing a custom `Storage` interface for saving execution records to a MySQL database. Includes a `Save` method for inserting records. ```go type MySQLStorage struct { db *sql.DB } func (s *MySQLStorage) Save(record *history.ExecutionRecord) error { _, err := s.db.Exec( "INSERT INTO execution_history (id, task_id, start_time, ...) VALUES (?, ?, ?, ...)", record.ID, record.TaskID, record.StartTime, ..., ) return err } // 实现其他接口方法... ``` -------------------------------- ### Query All History Records Source: https://github.com/darkit/cron/blob/master/docs/历史记录.md Example of querying all historical records without any filters. ```go // 查询所有历史记录 records, err := c.QueryHistory(history.RecordFilter{}) ```