{"id":13620796,"url":"https://github.com/libi/dcron","last_synced_at":"2025-05-15T11:02:06.613Z","repository":{"id":37732328,"uuid":"156557164","full_name":"libi/dcron","owner":"libi","description":"轻量分布式定时任务库 a lightweight distributed job scheduler library","archived":false,"fork":false,"pushed_at":"2025-03-22T14:57:19.000Z","size":440,"stargazers_count":461,"open_issues_count":3,"forks_count":77,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-14T16:58:09.345Z","etag":null,"topics":["consistent-hashing","cron","crontab","distributed","distributed-cron","redis"],"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/libi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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}},"created_at":"2018-11-07T14:17:24.000Z","updated_at":"2025-04-14T04:32:04.000Z","dependencies_parsed_at":"2023-10-24T08:30:20.494Z","dependency_job_id":"c3dd21d1-49ea-4825-aee4-309211f7a43f","html_url":"https://github.com/libi/dcron","commit_stats":{"total_commits":151,"total_committers":12,"mean_commits":"12.583333333333334","dds":0.5231788079470199,"last_synced_commit":"e94415fcf4d6cfcd9cccc04315856ed12de16adb"},"previous_names":["libichai/dcron"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libi%2Fdcron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libi%2Fdcron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libi%2Fdcron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libi%2Fdcron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/libi","download_url":"https://codeload.github.com/libi/dcron/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254328384,"owners_count":22052632,"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","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":["consistent-hashing","cron","crontab","distributed","distributed-cron","redis"],"created_at":"2024-08-01T21:00:59.551Z","updated_at":"2025-05-15T11:02:06.531Z","avatar_url":"https://github.com/libi.png","language":"Go","readme":"Dcron\n==============\n[![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/)\n[![codecov](https://codecov.io/gh/libi/dcron/graph/badge.svg?token=TBW1NN43AZ)](https://codecov.io/gh/libi/dcron)\n[![Tests](https://github.com/libi/dcron/actions/workflows/test.yml/badge.svg)](https://github.com/libi/dcron/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/libi/dcron#1)](https://goreportcard.com/report/github.com/libi/dcron)\n\n[简体中文](README_CN.md) | [English](README.md)\n\na lightweight distributed job scheduler library based on redis or etcd\n\n### Theory\n\nUse redis or etcd to sync the services list and the state of services. Use consistent-hash\nto select the node which can execute the task.\n\n### Why not use distributed-lock?\n\nIf use distributed-lock to implement it. I will depends on the system-time of each node. There are some problems when the system-time is not synchronous: \n1. If the task executing time is shorter than the system time, the task will be excuted again. (some node unlock after execution, but the lock will be locked by the other node which reach the execution time)\n\n2. Whatever there is only a little miss in system time, the most fast node will catch the lock in the first time. It will cause a thing that all the task will be executed only by the most fast node.\n\n### Features \n- Robustness: The node assignment of tasks does not depend on the system time, so the system time error between nodes can also ensure uniform distribution and single node execution.\n- Load Balance: Distribute tasks evenly according to task and node.\n- Seamless capacity extention ：If the load of the task node is too large, some tasks will be automatically migrated to the new service after the new server is started directly to achieve seamless capacity extention. \n- Failover: If a single node fails, the task will be automatically transferred to other normal nodes after 10 seconds. \n- Unique: The same task in the same service will only start a single running instance, and will not be executed repeatedly. \n- Customized storage: add the node storage mode by implementing the driver interface.\n- Automatic recovery: if the process restart, the jobs which **have been store** will be recovered into memory.\n\n### Get Started\n\n1. Create redisDriver instance, set the `ServiceName` and initialize `dcron`. The `ServiceName` will defined the same task unit.\n```golang\nredisCli := redis.NewClient(\u0026redis.Options{\n  Addr: DefaultRedisAddr,\n})\ndrv := redisdriver.NewDriver(redisCli)\ndcron := NewDcron(\"server1\", drv)\n```\n2. Use cron-language to add task, you should set the `TaskName`, the `TaskName` is the primary-key of each task.\n```golang\ndcron.AddFunc(\"test1\",\"*/3 * * * *\",func(){\n  fmt.Println(\"execute test1 task\",time.Now().Format(\"15:04:05\"))\n})\n```\n3. Begin the task\n```golang\n// you can use Start() or Run() to start the dcron.\n// unblocking start.\ndcron.Start()\n\n// blocking start.\ndcron.Run()\n```\n### Drivers\n\nAfter v0.6.0, We split out Dcron's drivers like etcddriver and redisdriver from main repo, and maintain them in independent repos. For details, please refer to [dcron-contrib](https://github.com/dcron-contrib).\n\n\n### Example\n- [examples](examples/)\n- [example_app](https://github.com/dxyinme/dcron_example_app)\n\n\n### More configurations.\n\nDcron is based on https://github.com/robfig/cron, use `NewDcron` to initialize `Dcron`, the arg after the second argv will be passed to `cron`\n\nFor example, if you want to set the cron eval in second-level, you can use like that:\n```golang\ndcron := NewDcron(\"server1\", drv,cron.WithSeconds())\n```\n\nOtherwise, you can sue `NewDcronWithOption` to initialize, to set the logger or others. Optional configuration can be referred to: https://github.com/libi/dcron/blob/master/option.go\n\n### ServiceName\n\nThe `ServiceName` is used to define the same set of tasks, which can be understood as the boundary of task allocation and scheduling. \n\nMultiple nodes using the same service name will be considered as the same task group. Tasks in the same task group will be evenly distributed to each node in the group and will not be executed repeatedly.\n\n### Star history\n\n[![Star History Chart](https://api.star-history.com/svg?repos=libi/dcron\u0026type=Date)](https://star-history.com/#libi/dcron\u0026Date)\n\n### Thanks\n- [JetBrains](https://www.jetbrains.com/?from=dcron) Thanks for providing an All Products License!\n\n","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibi%2Fdcron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibi%2Fdcron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibi%2Fdcron/lists"}