{"id":35672423,"url":"https://github.com/bborbe/cron","last_synced_at":"2026-01-05T19:04:28.484Z","repository":{"id":144201887,"uuid":"74575183","full_name":"bborbe/cron","owner":"bborbe","description":"Go library for robust cron job scheduling with multiple execution strategies, Prometheus metrics, and reliability features","archived":false,"fork":false,"pushed_at":"2025-11-28T09:07:30.000Z","size":8257,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-30T17:53:26.916Z","etag":null,"topics":["cron","go","golang","job-scheduler","library","metrics","prometheus","scheduler"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/bborbe/cron","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bborbe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-11-23T12:35:23.000Z","updated_at":"2025-11-28T09:07:33.000Z","dependencies_parsed_at":"2024-03-26T13:45:22.236Z","dependency_job_id":"d191e5b8-dcd6-48f3-8a53-97ed114db1f8","html_url":"https://github.com/bborbe/cron","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/bborbe/cron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fcron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fcron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fcron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fcron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bborbe","download_url":"https://codeload.github.com/bborbe/cron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bborbe%2Fcron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28218058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-05T02:00:06.358Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","go","golang","job-scheduler","library","metrics","prometheus","scheduler"],"created_at":"2026-01-05T19:02:28.165Z","updated_at":"2026-01-05T19:04:24.178Z","avatar_url":"https://github.com/bborbe.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cron\n\nA Go library for robust cron job scheduling with multiple execution strategies, observability, and reliability features.\n\n## Installation\n\n```bash\ngo get github.com/bborbe/cron\n```\n\n## Quick Start\n\n### Basic Usage\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \n    \"github.com/bborbe/cron\"\n    \"github.com/bborbe/run\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    \n    // Create an action to run\n    action := run.Func(func(ctx context.Context) error {\n        fmt.Println(\"Job executed!\")\n        return nil\n    })\n    \n    // Expression-based scheduling\n    cronJob := cron.NewCronJob(false, cron.Expression(\"@every 1h\"), 0, action)\n    cronJob.Run(ctx)\n}\n```\n\n### Enhanced Usage with Options\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"time\"\n    \n    \"github.com/bborbe/cron\"\n    \"github.com/bborbe/run\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    \n    action := run.Func(func(ctx context.Context) error {\n        // Your job logic here\n        return nil\n    })\n    \n    // Configure options\n    options := cron.CronJobOptions{\n        Name:          \"my-important-job\",\n        EnableMetrics: true,\n        Timeout:       5 * time.Minute,\n        ParallelSkip:  true,\n    }\n    \n    // Create job with options\n    cronJob := cron.NewCronJobWithOptions(\n        false,                      // not one-time\n        cron.Expression(\"0 */15 * * * ?\"), // every 15 minutes\n        0,                          // no wait duration\n        action,\n        options,\n    )\n    \n    cronJob.Run(ctx)\n}\n```\n\n## Execution Strategies\n\nThe library automatically selects the appropriate execution strategy based on the parameters provided to `NewCronJob` or `NewCronJobWithOptions`:\n\n### 1. Expression-Based (Cron Expressions)\n\nUses standard cron expressions or special formats:\n\n```go\n// Every hour\ncronJob := cron.NewCronJob(false, cron.Expression(\"@every 1h\"), 0, action)\n\n// Every 15 minutes using cron syntax\ncronJob := cron.NewCronJob(false, cron.Expression(\"0 */15 * * * ?\"), 0, action)\n\n// Daily at 2:30 AM\ncronJob := cron.NewCronJob(false, cron.Expression(\"0 30 2 * * ?\"), 0, action)\n```\n\n### 2. Duration-Based (Intervals)\n\nUses Go `time.Duration` for simple intervals:\n\n```go\n// Every 30 seconds\ncronJob := cron.NewCronJob(false, \"\", 30*time.Second, action)\n\n// Every 5 minutes\ncronJob := cron.NewCronJob(false, \"\", 5*time.Minute, action)\n```\n\n### 3. One-Time Execution\n\nExecutes the job once immediately:\n\n```go\n// Run once\ncronJob := cron.NewCronJob(true, \"\", 0, action)\n```\n\n## Configuration Options\n\nThe `CronJobOptions` struct provides fine-grained control over job behavior:\n\n```go\ntype CronJobOptions struct {\n    Name          string        // Job name for metrics and logging\n    EnableMetrics bool          // Enable Prometheus metrics collection  \n    Timeout       time.Duration // Execution timeout (0 = disabled)\n    ParallelSkip  bool          // Prevent concurrent executions\n}\n```\n\n### Default Options\n\n```go\noptions := cron.DefaultCronJobOptions()\n// Returns:\n// {\n//     Name:          \"unnamed-cron\", \n//     EnableMetrics: false,\n//     Timeout:       0,\n//     ParallelSkip:  false,\n// }\n```\n\n## Wrapper Functions\n\nFor maximum flexibility, you can use wrapper functions directly:\n\n### Metrics Wrapper\n\n```go\nimport \"github.com/prometheus/client_golang/prometheus\"\n\n// Wrap any action with metrics\nwrappedAction := cron.WrapWithMetrics(\"job-name\", originalAction)\n```\n\n**Metrics Collected:**\n- `cron_job_started{name=\"job-name\"}` - Number of job starts\n- `cron_job_completed{name=\"job-name\"}` - Number of successful completions  \n- `cron_job_failed{name=\"job-name\"}` - Number of failures\n- `cron_job_last_success{name=\"job-name\"}` - Timestamp of last success\n\n### Timeout Wrapper\n\n```go\n// Add 5-minute timeout\nwrappedAction := cron.WrapWithTimeout(\"job-name\", 5*time.Minute, originalAction)\n\n// Disable timeout (≤0 duration)\nwrappedAction := cron.WrapWithTimeout(\"job-name\", 0, originalAction)\n```\n\n### Chaining Wrappers\n\n```go\n// Chain multiple wrappers (order matters)\naction := cron.WrapWithTimeout(\"my-job\", 5*time.Minute, originalAction)\naction = cron.WrapWithMetrics(\"my-job\", action)\n```\n\n## Monitoring and Observability\n\n### Prometheus Integration\n\nWhen metrics are enabled, the library automatically registers Prometheus collectors. Expose them via HTTP:\n\n```go\nimport (\n    \"net/http\"\n    \"github.com/prometheus/client_golang/prometheus/promhttp\"\n)\n\nfunc main() {\n    // Your cron jobs with EnableMetrics: true\n    \n    // Expose metrics endpoint\n    http.Handle(\"/metrics\", promhttp.Handler())\n    http.ListenAndServe(\":8080\", nil)\n}\n```\n\n### Custom Metrics\n\nAccess the metrics interface directly:\n\n```go\nmetrics := cron.NewCronMetrics()\nmetrics.IncreaseStarted(\"custom-job\")\nmetrics.IncreaseCompleted(\"custom-job\") \nmetrics.SetLastSuccessToCurrent(\"custom-job\")\n```\n\n## Error Handling\n\nThe library provides proper error propagation through all wrapper layers:\n\n```go\naction := run.Func(func(ctx context.Context) error {\n    return errors.New(\"job failed\")\n})\n\ncronJob := cron.NewCronJobWithOptions(true, \"\", 0, action, options)\nerr := cronJob.Run(ctx)\nif err != nil {\n    // Handle error - will include context from wrappers\n    log.Printf(\"Cron job failed: %v\", err)\n}\n```\n\n## Testing\n\nThe library provides mock interfaces for testing:\n\n```go\n//go:generate go run -mod=mod github.com/maxbrunsfeld/counterfeiter/v6 -generate\n\nimport \"github.com/bborbe/cron/mocks\"\n\nfunc TestMyCronJob(t *testing.T) {\n    mockCronJob := \u0026mocks.CronJob{}\n    mockMetrics := \u0026mocks.CronMetrics{}\n    \n    // Set up expectations and test your code\n}\n```\n\n## Examples\n\n### Web Scraper with Monitoring\n\n```go\noptions := cron.CronJobOptions{\n    Name:          \"web-scraper\",\n    EnableMetrics: true,\n    Timeout:       30 * time.Second,\n    ParallelSkip:  true,\n}\n\nscraper := run.Func(func(ctx context.Context) error {\n    // Scrape website logic\n    return scrapeWebsite(ctx)\n})\n\ncronJob := cron.NewCronJobWithOptions(\n    false,\n    cron.Expression(\"0 */5 * * * ?\"), // Every 5 minutes\n    0,\n    scraper,\n    options,\n)\n```\n\n### Database Cleanup Job\n\n```go\ncleanup := run.Func(func(ctx context.Context) error {\n    return cleanupOldRecords(ctx)\n})\n\noptions := cron.CronJobOptions{\n    Name:          \"db-cleanup\",\n    EnableMetrics: true,\n    Timeout:       10 * time.Minute,\n}\n\ncronJob := cron.NewCronJobWithOptions(\n    false,\n    cron.Expression(\"0 0 2 * * ?\"), // Daily at 2 AM\n    0,\n    cleanup,\n    options,\n)\n```\n\n## License\n\nBSD-style license. See LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbborbe%2Fcron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbborbe%2Fcron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbborbe%2Fcron/lists"}