{"id":40955672,"url":"https://github.com/gochore/dcron","last_synced_at":"2026-01-22T05:36:35.531Z","repository":{"id":54583927,"uuid":"244110845","full_name":"gochore/dcron","owner":"gochore","description":"A distributed cron framework.","archived":false,"fork":false,"pushed_at":"2023-11-10T03:36:03.000Z","size":65,"stargazers_count":18,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-15T09:27:37.076Z","etag":null,"topics":["cron","cronjob","distributed","distributed-cron","go","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gochore.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2020-03-01T08:08:46.000Z","updated_at":"2025-05-09T02:37:44.000Z","dependencies_parsed_at":"2024-06-21T19:13:49.592Z","dependency_job_id":null,"html_url":"https://github.com/gochore/dcron","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/gochore/dcron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gochore%2Fdcron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gochore%2Fdcron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gochore%2Fdcron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gochore%2Fdcron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gochore","download_url":"https://codeload.github.com/gochore/dcron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gochore%2Fdcron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28656383,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"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","cronjob","distributed","distributed-cron","go","golang"],"created_at":"2026-01-22T05:36:31.425Z","updated_at":"2026-01-22T05:36:35.522Z","avatar_url":"https://github.com/gochore.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dcron\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/gochore/dcron.svg)](https://pkg.go.dev/github.com/gochore/dcron)\n[![Actions](https://github.com/gochore/dcron/actions/workflows/test.yaml/badge.svg)](https://github.com/gochore/dcron/actions)\n[![Codecov](https://codecov.io/gh/gochore/dcron/branch/master/graph/badge.svg)](https://codecov.io/gh/gochore/dcron)\n[![Go Report Card](https://goreportcard.com/badge/github.com/gochore/dcron)](https://goreportcard.com/report/github.com/gochore/dcron)\n[![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/gochore/dcron)](https://github.com/gochore/dcron/blob/master/go.mod)\n[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/gochore/dcron)](https://github.com/gochore/dcron/releases)\n\nA distributed cron framework.\n\n## Install\n\n```shell\ngo get github.com/gochore/dcron\n```\n\n## Quick Start\n\nFirst, implement a distributed atomic operation that only requires support for one method: `SetIfNotExists`.\nYou can implement it in any way you prefer, such as using Redis `SetNX`.\n\n```go\nimport \"github.com/redis/go-redis/v9\"\n\ntype RedisAtomic struct {\n\tclient *redis.Client\n}\n\nfunc (m *RedisAtomic) SetIfNotExists(ctx context.Context, key, value string) bool {\n\tret := m.client.SetNX(ctx, key, value, time.Hour)\n\treturn ret.Err() == nil \u0026\u0026 ret.Val()\n}\n```\n\nNow you can create a cron with that:\n\n```go\nfunc main() {\n\tatomic := \u0026RedisAtomic{\n\t\tclient: redis.NewClient(\u0026redis.Options{\n\t\t\tAddr: \"localhost:6379\",\n\t\t}),\n\t}\n\tcron := dcron.NewCron(dcron.WithKey(\"TestCron\"), dcron.WithAtomic(atomic))\n}\n```\n\nThen, create a job and add it to the cron.\n\n```go\n\tjob1 := dcron.NewJob(\"Job1\", \"*/15 * * * * *\", func(ctx context.Context) error {\n\t\tif task, ok := dcron.TaskFromContext(ctx); ok {\n\t\t\tlog.Println(\"run:\", task.Job.Spec(), task.Key)\n\t\t}\n\t\t// do something\n\t\treturn nil\n\t})\n\tif err := cron.AddJobs(job1); err != nil {\n\t\tlog.Fatal(err)\n\t}\n```\n\nFinally, start the cron:\n\n```go\n\tcron.Start()\n\tlog.Println(\"cron started\")\n\ttime.Sleep(time.Minute)\n\t\u003c-cron.Stop().Done()\n```\n\nIf you start the program multiple times, you will notice that the cron will run the job once every 15 seconds on only one of the processes.\n\n| process 1                                                              | process 2                                                              | process 3                                                              |\n|------------------------------------------------------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------|\n| 2023/10/13 11:39:45 cron started                                       | 2023/10/13 11:39:47 cron started                                       | 2023/10/13 11:39:48 cron started                                       |\n|                                                                        |                                                                        | 2023/10/13 11:40:00 run: */15 * * * * * dcron:TestCron.Job1@1697168400 |\n|                                                                        | 2023/10/13 11:40:15 run: */15 * * * * * dcron:TestCron.Job1@1697168415 |                                                                        |\n|                                                                        |                                                                        | 2023/10/13 11:40:30 run: */15 * * * * * dcron:TestCron.Job1@1697168430 |\n| 2023/10/13 11:40:45 run: */15 * * * * * dcron:TestCron.Job1@1697168445 |                                                                        |                                                                        |\n\nOne more thing, since `dcron.WithAtomic(atomic)` is optional, it's also a good idea to use it as a local cron.\n\n```go\n\tcron := dcron.NewCron()\n\tjob2 := dcron.NewJob(\"A local job\", \"*/15 * * * * *\", func(ctx context.Context) error {\n\t\t// do something\n\t\treturn nil\n\t})\n\tif err := cron.AddJobs(job2); err != nil {\n\t\tlog.Fatal(err)\n\t}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgochore%2Fdcron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgochore%2Fdcron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgochore%2Fdcron/lists"}