{"id":16484747,"url":"https://github.com/damdo/grontab","last_synced_at":"2025-07-04T09:02:41.402Z","repository":{"id":33413211,"uuid":"116591546","full_name":"damdo/grontab","owner":"damdo","description":":clock3: :arrows_counterclockwise:  lib for parallel \u0026 persistent job scheduling and running, like crontab but for Go","archived":false,"fork":false,"pushed_at":"2022-02-05T21:54:13.000Z","size":2290,"stargazers_count":13,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T20:22:18.503Z","etag":null,"topics":["cron","cronjob","crontab","go","golang","jobs","scheduler"],"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/damdo.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}},"created_at":"2018-01-07T19:06:52.000Z","updated_at":"2023-04-23T09:31:29.000Z","dependencies_parsed_at":"2022-08-07T21:15:19.509Z","dependency_job_id":null,"html_url":"https://github.com/damdo/grontab","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/damdo%2Fgrontab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/damdo%2Fgrontab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/damdo%2Fgrontab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/damdo%2Fgrontab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/damdo","download_url":"https://codeload.github.com/damdo/grontab/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245104464,"owners_count":20561376,"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":["cron","cronjob","crontab","go","golang","jobs","scheduler"],"created_at":"2024-10-11T13:18:08.444Z","updated_at":"2025-03-23T12:32:45.398Z","avatar_url":"https://github.com/damdo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\t\u003cdiv\u003e\n\t\t\u003cimg width=\"400\" src=\"assets/grontab.svg\" alt=\"grontab\"\u003e\n\t\u003c/div\u003e\n\u003c/div\u003e\n\n##  damdo/grontab\n[![GoDoc](http://godoc.org/github.com/damdo/grontab?status.svg)](http://godoc.org/github.com/damdo/grontab) \n[![Build Status](https://travis-ci.org/damdo/grontab.svg?branch=master)](https://travis-ci.org/damdo/grontab)\n[![Coverage Status](https://coveralls.io/repos/github/damdo/grontab/badge.svg?branch=master)](https://coveralls.io/github/damdo/grontab?branch=master)\n\n:clock3: :arrows_counterclockwise: lib for parallel \u0026 persistent job scheduling and running, like crontab but for Go\n\n**grontab** provides a simple way to time schedule *nix commands the same way we are all accustomed to do in crontab, thanks to the stable `robfig/cron` golang library.\n\nIt works as a normal golang package and provides persistency of the scheduled jobs across restarts thanks to a local k/v storage built with the lightning fast `coreos/bbolt`\n\n**FEATURES**:\n- **crontab syntax** : stable crontab like syntax for scheduling\n- **parallel/non parallel** : jobs execution in parallel or not at the same schedule\n- **persistency** : jobs persist across restarts\n- **consistency** : jobs consistency and duplicate avoidance due to lightning fast ACID transactions in bbolt\n- **safe and tested** : comes with high test coverage and it has been already used in production for several services and considered safe\n\nIt doesn't want to replace crontab in its day to day usefulness but it does want to provide some **advantages** in certain situations like:\nintegration in the language, easy to use APIs, programmble capabilities, optional job parallelism execution \n\n### Install\n\n```bash\ngo get github.com/damdo/grontab\n```\n\nNote that the `vendor` folder is here for stability. Remove the folder if you\nalready have the dependencies in your GOPATH.\n\n### Usage\n\n#### tl;dr;\n```go\npackage main\n\nimport (\n        \"log\"\n        \"os\"\n        \"os/signal\"\n        \"github.com/damdo/grontab\"\n)\n\nfunc main() {\n    // create a new grontab configuration\n    newConfig := grontab.Config{\n            BucketName:         \"jobs\",\n            PersistencePath:    \"./db.db\",\n            DisableParallelism: false,\n            HideBanner:         false,\n            TurnOffLogs:        false,\n    }\n\n    // initialize grontab with the new configuration\n    err := grontab.Init(newConfig)\n    if err != nil {\n            log.Fatal(err)\n    }\n\n    // create a new grontab job\n    newJob := grontab.Job{Task: \"ping -c 4 8.8.8.8\", Enabled: true}\n\n    // a new grontab job to be executed at the specified schedule\n    idPing, err := grontab.Add(\"00 00 06 * * *\", newJob)\n    if err != nil {\n            log.Println(err)\n    }\n\n    // start grontab\n    grontab.Start()\n\n    // update the existing idPing job with a new schedule and a new command task\n    err = grontab.Update(\"*/10 * * * * *\", grontab.Job{ID: idPing, Task: \"echo 'ciaone'\", Enabled: true})\n    if err != nil {\n    \tlog.Println(err)\n    }\n\n    // // optionally remove the existing job\n    // err = grontab.Remove(idPing)\n    // if err != nil {\n    //     log.Println(err)\n    // }\n\n    // this is needed to keep awake the execution\n    sig := make(chan os.Signal)\n    signal.Notify(sig, os.Interrupt, os.Kill)\n    \u003c-sig\n}\n```\n\n#### 1) import\nThe first step is to import the package\n```go\nimport(\n    \"github.com/damdo/grontab\"\n)\n```\n\n#### 2) grontab.Init()\n\nThen grontab has to be initialized, with the Init() command, specifing the desired configuration.\nBoolean parameters have default value to false.\nThe configuration lives in a `grontab.Config` that takes various parameters:\n\n- *PersistencePath*: will be the path of the storage file\n- *BucketName*: will be the data collection name\n- *DisableParallelism*: allow to choose if jobs at the same schedule will run in parallel or sequentially\n- *HideBanner*: allow to choose if the grontab banner will be shown at runtime\n- *TurnOffLogs*: allow to choose if the grontab logs will be shown at runtime\n\nOnce the config is defined, it should be passed to Init() to complete the initialization\n\n```go\nnewConfig := grontab.Config{\n    BucketName: \"jobs\",\n    PersistencePath: \"./db.db\",\n    DisableParallelism: false,\n    HideBanner: false,\n    TurnOffLogs: false,\n}\n\nerr := grontab.Init(newConfig)\n\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n#### 3) grontab.Start()\nThe next step can be to spin up the grontab engine to start processing the schedule.\nStart(), however, can be invoked at anytime, even after the Add()'s commands, provided that grontab as been Initialized.\n\n```go\ngrontab.Start()\n```\n\n#### 4) grontab.Add()\nOne of the possibilities after the Init() (and optionally after Start())\nis the *Add()* command. This command is meant to be used to add a new entry in grontab, a new schedule.\nIt takes as parameters:\n1) a crontab like schedule string, [syntax here](https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format)\n2) a `grontab.Job` which takes:\n    - `Task`: a unix command `string`\n    - `Enabled`: a true/false `boolean` flag to enable/disable the execution of the task\n\n```go\nnewJob := grontab.Job{Task: \"ping -c 4 8.8.8.8\", Enabled: true}\nidPing, err := grontab.Add(\"00 00 06 * * *\", newJob)\n\nif err != nil {\n    log.Println(err)\n}\nlog.Println(idPing)\n```\n\n#### 5) grontab.Update()\nOne of the possibilities after the Init() (and optionally after Start())\nis the *Update()* command. This command is meant to be used to update tasks already present in grontab.\nIt takes as parameters:\n1) optionally an updated crontab like schedule string, [syntax here](https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format)\n2) a `grontab.Job` which takes:\n    - `ID`: the id of the job to be updated `string` (MANDATORY)\n    - `Task`: the updated unix command `string` (OPTIONAL)\n    - `Enabled`: the updated true/false `boolean` flag to enable/disable the execution of the task (OPTIONAL)\n\n```go\nnewJob := grontab.Job{Task: \"ping -c 4 8.8.8.8\", Enabled: true}\nidPing, err := grontab.Add(\"00 00 06 * * *\", newJob)\nif err != nil {\n    log.Println(err)\n}\n\n// VALID\n// in this case both the schedule and the command/task of the job will be updated\nerr = grontab.Update(\"00 10 07 * 1 *\", grontab.Job{ID: idPing, Task: \"echo 'ciaone'\", Enabled: true})\nif err != nil {\n\tlog.Println(err)\n}\n\n// VALID\n// in this case the schedule of the job will be updated\nerr = grontab.Update(\"00 12 08 * 1 *\", grontab.Job{ID: idPing})\nif err != nil {\n\tlog.Println(err)\n}\n\n// VALID\n// in this case the schedule of the job and the Enabled status will be updated\nerr = grontab.Update(\"00 12 08 * 1 *\", grontab.Job{ID: idPing, Enabled: false})\nif err != nil {\n\tlog.Println(err)\n}\n\n// INVALID\n// the Update is invalid because the job ID is missing\nerr = grontab.Update(\"00 12 08 * 1 *\", grontab.Job{Enabled: false})\nif err != nil {\n\tlog.Println(err)\n}\n```\n\n#### 6) grontab.Remove()\nOne of the possibilities after the Init() (and optionally after Start())\nis the *Remove()* command. This command is meant to be used to remove an entry in grontab.\nIt takes as parameter:\n1) `ID` of the job to be removed\n\n```go\nnewJob := grontab.Job{Task: \"ping -c 4 8.8.8.8\", Enabled: true}\nidPing, err := grontab.Add(\"00 00 06 * * *\", newJob)\nif err != nil {\n    log.Println(err)\n}\n\nerr := grontab.Remove(idPing)\nif err != nil {\n    log.Println(err)\n}\n```\n\n#### 7) grontab.Stop()\nThe *Stop()* command is meant to be used to stop the started grontab engine.\nIt should be run only after Init() and Start() have been invoked.\n\n```go\ngrontab.Stop()\n```\n\n#### 8) grontab.List()\nThe *List()* command is meant to be used to list the schedules and jobs already in the grontab engine.\nIt should be run only after Init() have been invoked.\n\n```go\noccurrencies := grontab.List()\n```\n\n### Credits\n\n * [`@asdine`](https://github.com/asdine) for `github.com/asdine/storm`\n * [`@etcd-io`](https://github.com/etcd-io) for `github.com/etcd-io/bbolt`\n * [`@damdo`](https://github.com/damdo) for `github.com/damdo/randid`\n * [`@fatih`](https://github.com/fatih) for `github.com/fatih/color`\n * [`@davecheney`](https://github.com/davecheney) for `github.com/pkg/errors`\n * [`@robfig`](https://github.com/robfig) and [`@wgliang`](https://github.com/wgliang) for `github.com/wgliang/cron`\n\n### License\n- This project uses third party libraries that are distributed under their own terms. See [`3RD-PARTY`](https://github.com/damdo/grontab/blob/master/3RD-PARTY)\n- For the rest of it the MIT License (MIT) applies. See [`LICENSE`](https://github.com/damdo/grontab/blob/master/LICENSE)  for more details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdamdo%2Fgrontab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdamdo%2Fgrontab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdamdo%2Fgrontab/lists"}