{"id":206,"name":null,"description":"Scheduler / Cron for Sidekiq jobs","url":"https://github.com/sidekiq-cron/sidekiq-cron","last_synced_at":"2026-04-30T05:00:59.210Z","repository":{"id":10250039,"uuid":"12357002","full_name":"sidekiq-cron/sidekiq-cron","owner":"sidekiq-cron","description":"Scheduler / Cron for Sidekiq jobs","archived":false,"fork":false,"pushed_at":"2026-04-27T20:37:06.000Z","size":1225,"stargazers_count":1937,"open_issues_count":0,"forks_count":303,"subscribers_count":19,"default_branch":"master","last_synced_at":"2026-04-29T21:43:00.376Z","etag":null,"topics":["cron-jobs","ruby","ruby-gem","ruby-on-rails","scheduled-jobs","scheduler","sidekiq","sidekiq-cron","sidekiq-jobs","sidekiq-workers"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/sidekiq-cron.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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":"2013-08-25T09:43:05.000Z","updated_at":"2026-04-27T20:37:11.000Z","dependencies_parsed_at":"2024-04-09T10:29:34.882Z","dependency_job_id":"818d374f-8c05-4780-9bd0-de797b2971dc","html_url":"https://github.com/sidekiq-cron/sidekiq-cron","commit_stats":{"total_commits":457,"total_committers":113,"mean_commits":4.04424778761062,"dds":0.6345733041575492,"last_synced_commit":"8d0cf5ea18aa36957e45ca34fe1161fa6882d731"},"previous_names":["ondrejbartas/sidekiq-cron"],"tags_count":51,"template":false,"template_full_name":null,"purl":"pkg:github/sidekiq-cron/sidekiq-cron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sidekiq-cron","download_url":"https://codeload.github.com/sidekiq-cron/sidekiq-cron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32455234,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","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"}},"owner":{"login":"sidekiq-cron","name":"sidekiq-cron","uuid":"115579612","kind":"organization","description":"Scheduling add-on for Sidekiq","email":null,"website":null,"location":null,"twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/115579612?v=4","repositories_count":1,"last_synced_at":"2024-03-27T10:24:02.826Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/sidekiq-cron","funding_links":[],"total_stars":1809,"followers":0,"following":0,"created_at":"2022-11-06T00:25:51.651Z","updated_at":"2024-03-27T10:24:02.840Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sidekiq-cron","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sidekiq-cron/repositories"},"packages":[{"id":13407360,"name":"ruby-sidekiq-cron","ecosystem":"ubuntu","description":null,"homepage":"https://github.com/sidekiq-cron/sidekiq-cron","licenses":null,"normalized_licenses":[],"repository_url":"https://github.com/sidekiq-cron/sidekiq-cron","keywords_array":["universe/misc"],"namespace":"universe","versions_count":1,"first_release_published_at":"2026-02-06T16:04:19.991Z","latest_release_published_at":"2026-02-06T16:04:19.991Z","latest_release_number":"1.12.0-1","last_synced_at":"2026-03-06T16:42:25.228Z","created_at":"2026-02-06T16:04:19.228Z","updated_at":"2026-03-06T16:42:25.229Z","registry_url":"https://launchpad.net/ubuntu/+source/ruby-sidekiq-cron","install_command":"apt-get install ruby-sidekiq-cron","documentation_url":null,"metadata":{"component":"universe","architecture":"all","priority":"optional","binary":"ruby-sidekiq-cron","standards_version":"4.6.2","maintainer":"Debian Ruby Team \u003cpkg-ruby-extras-maintainers@lists.alioth.debian.org\u003e","build_depends":"debhelper-compat (= 13), gem2deb, rake, ruby-fugit, redis-server, ruby-mocha, ruby-rack-test, ruby-redis-namespace, ruby-shoulda-context, ruby-sidekiq, ruby-sinatra, ruby-simplecov, ruby-globalid (\u003e= 1.0.1~)","build_depends_indep":null,"build_depends_arch":null},"repo_metadata":{},"repo_metadata_updated_at":null,"dependent_packages_count":0,"downloads":null,"downloads_period":null,"dependent_repos_count":0,"rankings":{},"purl":"pkg:deb/ubuntu/ruby-sidekiq-cron?arch=source\u0026distro=ubuntu-24.04","advisories":[],"docker_usage_url":"https://docker.ecosyste.ms/usage/ubuntu/ruby-sidekiq-cron","docker_dependents_count":null,"docker_downloads_count":null,"usage_url":"https://repos.ecosyste.ms/usage/ubuntu/ruby-sidekiq-cron","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/ubuntu/ruby-sidekiq-cron/dependencies","status":null,"funding_links":[],"critical":null,"issue_metadata":null,"versions_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/packages/ruby-sidekiq-cron/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/packages/ruby-sidekiq-cron/version_numbers","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/packages/ruby-sidekiq-cron/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/packages/ruby-sidekiq-cron/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/packages/ruby-sidekiq-cron/codemeta","maintainers":[],"registry":{"name":"ubuntu-24.04","url":"https://launchpad.net/ubuntu/noble","ecosystem":"ubuntu","default":true,"packages_count":37306,"maintainers_count":0,"namespaces_count":4,"keywords_count":0,"github":"ubuntu","metadata":{"codename":"noble"},"icon_url":"https://github.com/ubuntu.png","created_at":"2026-02-04T11:01:45.928Z","updated_at":"2026-04-27T18:20:35.701Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/packages","maintainers_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/maintainers","namespaces_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.04/namespaces"}},{"id":11692454,"name":"github.com/sidekiq-cron/sidekiq-cron","ecosystem":"go","description":null,"homepage":null,"licenses":"mit","normalized_licenses":["MIT"],"repository_url":"https://github.com/sidekiq-cron/sidekiq-cron","keywords_array":[],"namespace":null,"versions_count":49,"first_release_published_at":"2013-08-25T19:34:12.000Z","latest_release_published_at":"2025-08-08T13:27:13.000Z","latest_release_number":"v2.3.1+incompatible","last_synced_at":"2026-04-26T03:01:20.679Z","created_at":"2025-05-27T08:23:50.485Z","updated_at":"2026-04-26T03:01:20.679Z","registry_url":"https://pkg.go.dev/github.com/sidekiq-cron/sidekiq-cron","install_command":"go get github.com/sidekiq-cron/sidekiq-cron","documentation_url":"https://pkg.go.dev/github.com/sidekiq-cron/sidekiq-cron#section-documentation","metadata":{},"repo_metadata":{"id":10250039,"uuid":"12357002","full_name":"sidekiq-cron/sidekiq-cron","owner":"sidekiq-cron","description":"Scheduler / Cron for Sidekiq jobs","archived":false,"fork":false,"pushed_at":"2025-05-12T11:27:39.000Z","size":1198,"stargazers_count":1897,"open_issues_count":3,"forks_count":296,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-05-21T00:12:47.173Z","etag":null,"topics":["cron-jobs","ruby","ruby-gem","ruby-on-rails","scheduled-jobs","scheduler","sidekiq","sidekiq-cron","sidekiq-jobs","sidekiq-workers"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/sidekiq-cron.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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":"2013-08-25T09:43:05.000Z","updated_at":"2025-05-20T13:01:47.000Z","dependencies_parsed_at":"2024-04-09T10:29:34.882Z","dependency_job_id":"818d374f-8c05-4780-9bd0-de797b2971dc","html_url":"https://github.com/sidekiq-cron/sidekiq-cron","commit_stats":{"total_commits":457,"total_committers":113,"mean_commits":4.04424778761062,"dds":0.6345733041575492,"last_synced_commit":"8d0cf5ea18aa36957e45ca34fe1161fa6882d731"},"previous_names":["ondrejbartas/sidekiq-cron"],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sidekiq-cron","download_url":"https://codeload.github.com/sidekiq-cron/sidekiq-cron/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":256143851,"owners_count":22343451,"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"}},"repo_metadata_updated_at":"2025-05-27T08:37:45.404Z","dependent_packages_count":0,"downloads":null,"downloads_period":null,"dependent_repos_count":0,"rankings":{"downloads":null,"dependent_repos_count":5.807004531283771,"dependent_packages_count":5.441509219438237,"stargazers_count":null,"forks_count":null,"docker_downloads_count":null,"average":5.624256875361004},"purl":"pkg:golang/github.com/sidekiq-cron/sidekiq-cron","advisories":[],"docker_usage_url":"https://docker.ecosyste.ms/usage/go/github.com/sidekiq-cron/sidekiq-cron","docker_dependents_count":null,"docker_downloads_count":null,"usage_url":"https://repos.ecosyste.ms/usage/go/github.com/sidekiq-cron/sidekiq-cron","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/go/github.com/sidekiq-cron/sidekiq-cron/dependencies","status":null,"funding_links":[],"critical":null,"issue_metadata":{"last_synced_at":"2025-05-26T20:33:47.406Z","issues_count":106,"pull_requests_count":142,"avg_time_to_close_issue":7841345.475728155,"avg_time_to_close_pull_request":2181181.503546099,"issues_closed_count":103,"pull_requests_closed_count":141,"pull_request_authors_count":55,"issue_authors_count":84,"avg_comments_per_issue":4.6415094339622645,"avg_comments_per_pull_request":3.26056338028169,"merged_pull_requests_count":128,"bot_issues_count":0,"bot_pull_requests_count":0,"past_year_issues_count":33,"past_year_pull_requests_count":55,"past_year_avg_time_to_close_issue":1976937.9677419355,"past_year_avg_time_to_close_pull_request":179058.0,"past_year_issues_closed_count":31,"past_year_pull_requests_closed_count":54,"past_year_pull_request_authors_count":18,"past_year_issue_authors_count":22,"past_year_avg_comments_per_issue":5.363636363636363,"past_year_avg_comments_per_pull_request":2.6545454545454543,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":49,"issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/issues","maintainers":[{"login":"markets","count":48,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/markets"},{"login":"Linell","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/Linell"}],"active_maintainers":[{"login":"markets","count":18,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/markets"}]},"versions_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fsidekiq-cron%2Fsidekiq-cron/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fsidekiq-cron%2Fsidekiq-cron/version_numbers","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fsidekiq-cron%2Fsidekiq-cron/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fsidekiq-cron%2Fsidekiq-cron/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fsidekiq-cron%2Fsidekiq-cron/codemeta","maintainers":[],"registry":{"name":"proxy.golang.org","url":"https://proxy.golang.org","ecosystem":"go","default":true,"packages_count":2108863,"maintainers_count":0,"namespaces_count":782439,"keywords_count":112823,"github":"golang","metadata":{"funded_packages_count":53495},"icon_url":"https://github.com/golang.png","created_at":"2022-04-04T15:19:22.939Z","updated_at":"2026-04-19T05:14:45.920Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages","maintainers_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/maintainers","namespaces_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/namespaces"}},{"id":13467293,"name":"ruby-sidekiq-cron","ecosystem":"ubuntu","description":null,"homepage":"https://github.com/sidekiq-cron/sidekiq-cron","licenses":null,"normalized_licenses":[],"repository_url":"https://github.com/sidekiq-cron/sidekiq-cron","keywords_array":["universe/misc"],"namespace":"universe","versions_count":1,"first_release_published_at":"2026-02-09T17:18:24.465Z","latest_release_published_at":"2026-02-09T17:18:24.465Z","latest_release_number":"1.12.0-1","last_synced_at":"2026-03-09T18:22:57.748Z","created_at":"2026-02-09T17:18:24.203Z","updated_at":"2026-03-09T18:32:55.604Z","registry_url":"https://launchpad.net/ubuntu/+source/ruby-sidekiq-cron","install_command":"apt-get install ruby-sidekiq-cron","documentation_url":null,"metadata":{"component":"universe","architecture":"all","priority":"optional","binary":"ruby-sidekiq-cron","standards_version":"4.6.2","maintainer":"Debian Ruby Team \u003cpkg-ruby-extras-maintainers@lists.alioth.debian.org\u003e","build_depends":"debhelper-compat (= 13), gem2deb, rake, ruby-fugit, redis-server, ruby-mocha, ruby-rack-test, ruby-redis-namespace, ruby-shoulda-context, ruby-sidekiq, ruby-sinatra, ruby-simplecov, ruby-globalid (\u003e= 1.0.1~)","build_depends_indep":null,"build_depends_arch":null},"repo_metadata":{},"repo_metadata_updated_at":null,"dependent_packages_count":0,"downloads":null,"downloads_period":null,"dependent_repos_count":0,"rankings":{"downloads":null,"dependent_repos_count":0.0,"dependent_packages_count":0.0,"stargazers_count":null,"forks_count":null,"docker_downloads_count":null,"average":100},"purl":"pkg:deb/ubuntu/ruby-sidekiq-cron?arch=source\u0026distro=ubuntu-24.10\u0026repository_url=https://launchpad.net/ubuntu/oracular","advisories":[],"docker_usage_url":"https://docker.ecosyste.ms/usage/ubuntu/ruby-sidekiq-cron","docker_dependents_count":null,"docker_downloads_count":null,"usage_url":"https://repos.ecosyste.ms/usage/ubuntu/ruby-sidekiq-cron","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/ubuntu/ruby-sidekiq-cron/dependencies","status":null,"funding_links":[],"critical":null,"issue_metadata":null,"versions_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/packages/ruby-sidekiq-cron/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/packages/ruby-sidekiq-cron/version_numbers","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/packages/ruby-sidekiq-cron/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/packages/ruby-sidekiq-cron/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/packages/ruby-sidekiq-cron/codemeta","maintainers":[],"registry":{"name":"ubuntu-24.10","url":"https://launchpad.net/ubuntu/oracular","ecosystem":"ubuntu","default":false,"packages_count":38437,"maintainers_count":0,"namespaces_count":4,"keywords_count":0,"github":"ubuntu","metadata":{"codename":"oracular","mirror":"http://old-releases.ubuntu.com/ubuntu"},"icon_url":"https://github.com/ubuntu.png","created_at":"2026-02-04T11:01:48.028Z","updated_at":"2026-04-27T18:20:37.303Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/packages","maintainers_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/maintainers","namespaces_url":"https://packages.ecosyste.ms/api/v1/registries/ubuntu-24.10/namespaces"}}],"commits":{"id":3399,"full_name":"sidekiq-cron/sidekiq-cron","default_branch":"master","total_commits":487,"total_committers":121,"total_bot_commits":0,"total_bot_committers":0,"mean_commits":4.024793388429752,"dds":0.6570841889117043,"past_year_total_commits":10,"past_year_total_committers":7,"past_year_total_bot_commits":0,"past_year_total_bot_committers":0,"past_year_mean_commits":1.4285714285714286,"past_year_dds":0.8,"last_synced_at":"2026-04-29T21:44:44.561Z","last_synced_commit":"44c12804b3c6377cafab1a07a02a3a79db2de7b2","created_at":"2023-03-07T09:17:33.200Z","updated_at":"2026-04-29T21:44:34.091Z","committers":[{"name":"Ondrej Bartas","email":"ondrej@bartas.cz","login":"ondrejbartas","count":167},{"name":"Marc Anguera","email":"srmarc.ai@gmail.com","login":"markets","count":66},{"name":"josh.c","email":"junyu.live@gmail.com","login":"Ox0rigin","count":20},{"name":"Girish Gopaul","email":"ggopaul0510@gmail.com","login":"giriss","count":15},{"name":"Mike Rogers","email":"me@mikerogers.io","login":"MikeRogers0","count":9},{"name":"Satyakam Pandya","email":"satyakampandya@gmail.com","login":"satyakampandya","count":9},{"name":"Yaroslav","email":"39729785+viralpraxis","login":"viralpraxis","count":8},{"name":"John Mettraux","email":"jmettraux@gmail.com","login":"jmettraux","count":8},{"name":"sue445","email":"sue445@sue445.net","login":"sue445","count":7},{"name":"Ralph Churchill","email":"ralph.churchill@vitals.com","login":"mrchucho","count":6},{"name":"tfluehmann","email":"t.fluehmann94@hotmail.com","login":"tfluehmann","count":5},{"name":"Sandip Mane","email":"sandip2490@gmail.com","login":"sandip-mane","count":5},{"name":"Kevin Robell","email":"kevin.robell@sensortower.com","login":"kevinrobell-st","count":5},{"name":"Danilo Cabello","email":"cabello","login":"cabello","count":5},{"name":"David Warburton","email":"david.warburton@gmail.com","login":"dwarburt","count":4},{"name":"Heinrich Lee Yu","email":"hleeyu@gmail.com","login":"engwan","count":4},{"name":"tttffff","email":"tristanfellows@icloud.com","login":"tttffff","count":4},{"name":"284km","email":"k.furuhashi10@gmail.com","login":"284km","count":3},{"name":"Felix Bünemann","email":"buenemann@louis.info","login":"felixbuenemann","count":3},{"name":"Leo Arnold","email":"leoarnold","login":"leoarnold","count":3},{"name":"Richard Wu","email":"rich@tablexi.com","login":"n00dle","count":3},{"name":"Stephan Kaag","email":"stephan@ka.ag","login":"stephankaag","count":3},{"name":"Adriano Rob","email":"wiermann@broou.com","login":"adrianobarroso","count":3},{"name":"Tobias Fluehmann","email":"tobias.fluehmann@swisscom.com","login":null,"count":3},{"name":"fatkodima","email":"fatkodima123@gmail.com","login":"fatkodima","count":2},{"name":"Vasiliy Sukhachev","email":"vsuhachev@yandex.ru","login":"vsuhachev","count":2},{"name":"Tony Ciou","email":"cioutonyhao@gmail.com","login":"tonyciou","count":2},{"name":"Fabrizio Monti","email":"f.monti@datocms.com","login":"delphaber","count":2},{"name":"Stan Hu","email":"stanhu@gmail.com","login":"stanhu","count":2},{"name":"Salvatore Ferrucci","email":"salvatore@algonauti.com","login":"safeforge","count":2},{"name":"Ricky Nguyen","email":"ricky.nguyen@gmail.com","login":"lepfhty","count":2},{"name":"Philip Dubé","email":"serprex","login":"serprex","count":2},{"name":"Peter Goldstein","email":"peter.m.goldstein@gmail.com","login":"petergoldstein","count":2},{"name":"Masafumi Koba","email":"473530+ybiquitous","login":"ybiquitous","count":2},{"name":"MMartyn","email":"MMartyn@weblinc.com","login":"MMartyn","count":2},{"name":"Kryštof Korb","email":"krystof@korb.cz","login":"krystof-k","count":2},{"name":"Johnathan Ludwig","email":"john@johnathanludwig.com","login":"johnathanludwig","count":2},{"name":"Guillaume Hain","email":"zedtux@zedroot.org","login":"zedtux","count":2},{"name":"Garrett Thornburg","email":"film42@gmail.com","login":"film42","count":2},{"name":"Franck TROUILLEZ","email":"57403591+francktrouillez","login":"francktrouillez","count":2},{"name":"Florian Wininger","email":"fw.centrale@gmail.com","login":"fwininger","count":2},{"name":"Danilo Carolino","email":"danilogcarolino@gmail.com","login":"danilogco","count":2},{"name":"Cuong Lam","email":"thanhcuong1990@gmail.com","login":"thanhcuong1990","count":2},{"name":"Chris Gunther","email":"chris@room118solutions.com","login":"cgunther","count":2},{"name":"Alexey Vasiliev","email":"leopard.not.a@gmail.com","login":"le0pard","count":2},{"name":"ngouy","email":"nathangouy@free.fr","login":"ngouy","count":2},{"name":"Alexander Logvinov","email":"avl@logvinov.com","login":"incubus","count":1},{"name":"Alexandr Korsak","email":"alex.korsak@gmail.com","login":"oivoodoo","count":1},{"name":"Andrew Kodkod","email":"678665+akodkod","login":"akodkod","count":1},{"name":"Andrey Novikov","email":"envek@envek.name","login":"Envek","count":1},{"name":"Arnas Dundulis","email":"arnas@vinted.com","login":"arrrnas","count":1},{"name":"Asahi Iwase","email":"asahi.iwase.engineer@gmail.com","login":"iwaseasahi","count":1},{"name":"Atrox","email":"hello@atrox.dev","login":"Atrox","count":1},{"name":"Pavel Chuchuva","email":"Pavel.Chuchuva@quest.com","login":null,"count":1},{"name":"Cameron Kidman","email":"cameron.kidman@mx.com","login":null,"count":1},{"name":"Christopher Chow","email":"christopher.chow@kinesis.org","login":null,"count":1},{"name":"Alex Beeck","email":"alex@xlsol.com","login":null,"count":1},{"name":"Dave Rogers","email":"dave.rogers@hellolabs.com","login":null,"count":1},{"name":"Jack Pan","email":"panjie@xdstar.net","login":null,"count":1},{"name":"Nikolai Berkoff","email":"nikolai.berkoff@blacksquaremedia.com","login":null,"count":1},{"name":"Danillo Souza","email":"dsouza@tractionguest.com","login":null,"count":1},{"name":"Peter Lampesberger","email":"office@lampesberger.net","login":"h0jeZvgoxFepBQ2C","count":1},{"name":"Raj","email":"raj_abc38@yahoo.com","login":"RajRoR","count":1},{"name":"Robert Beekman","email":"robert@matsimitsu.nl","login":"matsimitsu","count":1},{"name":"Robert Steuck","email":"robert.steuck@gmail.com","login":"hqm42","count":1},{"name":"Rocela Durazo","email":"3598290+roseliux","login":"roseliux","count":1},{"name":"Romeu Fonseca","email":"romeu.hcf@gmail.com","login":"romeuhcf","count":1},{"name":"Ryan McGeary","email":"ryan@mcgeary.org","login":"rmm5t","count":1},{"name":"Ryan Winograd","email":"ryan@thewinograds.com","login":"rylwin","count":1},{"name":"Ryo","email":"ryohashimoto@gmail.com","login":"ryohashimoto","count":1},{"name":"Ryota Arai","email":"ryota.arai@gmail.com","login":"ryotarai","count":1},{"name":"Sam Schenkman-Moore","email":"samsm@samsm.com","login":"samsm","count":1},{"name":"Sameer Siruguri","email":"siruguri@gmail.com","login":"siruguri","count":1},{"name":"Sebastian Cohnen","email":"tisba","login":"tisba","count":1},{"name":"Tekin Suleyman","email":"tekin@tekin.co.uk","login":"tekin","count":1},{"name":"The Gitter Badger","email":"badger@gitter.im","login":"gitter-badger","count":1},{"name":"Tim Minkov","email":"timothyminkov@gmail.com","login":"timminkov","count":1},{"name":"Tom Meinlschmidt","email":"tomas@meinlschmidt.com","login":"tmeinlschmidt","count":1},{"name":"Tom Prats","email":"tprats108@gmail.com","login":"tomprats","count":1},{"name":"Uzzal Devkota","email":"theoozzal@gmail.com","login":"oozzal","count":1},{"name":"Víctor","email":"bellzebu@hotmail.com","login":"vzamanillo","count":1},{"name":"Yuri Zubov","email":"yury.zubau@gmail.com","login":"yuri-zubov","count":1},{"name":"Yuta Nishimori","email":"nyuta2048@gmail.com","login":"nyuta01","count":1},{"name":"arathunku","email":"arathunku","login":"arathunku","count":1},{"name":"arthurbryant","email":"cst.feng@gmail.com","login":"arthurbryant","count":1},{"name":"kakikubo","email":"kakikubo@gmail.com","login":"kakikubo","count":1},{"name":"masayuki oguni","email":"masayuki-oguni@mgnt-inc.jp","login":"masayukioguni","count":1},{"name":"mkusaka","email":"hinoshita1992@gmail.com","login":"mkusaka","count":1},{"name":"sylg","email":"sgiuliani@gmail.com","login":"sylg","count":1},{"name":"tai2","email":"hello@tai2.net","login":"tai2","count":1},{"name":"ななころび","email":"7korobi@gmail.com","login":"7korobi","count":1},{"name":"Atsuo Fukaya","email":"fukayatsu@gmail.com","login":"fukayatsu","count":1},{"name":"Carl Eqladios","email":"eqladios@gmail.com","login":"eqladios","count":1},{"name":"Chris Maximin","email":"chris@chrismaximin.com","login":"chrismaximin","count":1},{"name":"DM","email":"deemox@gmail.com","login":"dmeremyanin","count":1},{"name":"Daisuke Harada","email":"d.backford1231@gmail.com","login":"machisuke","count":1},{"name":"David Bradford","email":"david@zerobearing.com","login":"zerobearing2","count":1},{"name":"Denis","email":"denis.peplin@gmail.com","login":"denispeplin","count":1},{"name":"Eric Hankins","email":"ehankins@rednovalabs.com","login":"stormsilver","count":1},{"name":"Eumir Gaspar","email":"corroded","login":"corroded","count":1},{"name":"Evgeny Pavlov","email":"evgeny@pavlov.name","login":"Eunix","count":1},{"name":"Fabien LEFEBVRE","email":"d1ceward@gmail.com","login":"d1ceward","count":1},{"name":"Gavin Stark","email":"gavin@gstark.com","login":"gstark","count":1},{"name":"Hans Lemuet","email":"Spone","login":"Spone","count":1},{"name":"Irvan Fauziansyah","email":"ervhan@gmail.com","login":"IrvanFza","count":1},{"name":"Jakob Pupke","email":"jakob.pupke@gmail.com","login":"haffla","count":1},{"name":"Jorge Hernandez","email":"jdaviderb@gmail.com","login":"jdaviderb","count":1},{"name":"Josh Cronemeyer","email":"joshuacronemeyer@gmail.com","login":"joshuacronemeyer","count":1},{"name":"Joshua Van Deren","email":"22926257+jvanderen1","login":"jvanderen1","count":1},{"name":"João Serra","email":"cybernabojr@gmail.com","login":"jpserra","count":1},{"name":"Kian-Meng Ang","email":"kianmeng.ang@gmail.com","login":"kianmeng","count":1},{"name":"Laurent Arnoud","email":"laurent@spkdev.net","login":"spk","count":1},{"name":"Linell Bonnette","email":"tlbonnette@gmail.com","login":"Linell","count":1},{"name":"Lutz Lengemann","email":"mobilutz","login":"mobilutz","count":1},{"name":"Masato Nakamura","email":"masato.nakamura145@gmail.com","login":"m-nakamura145","count":1},{"name":"Mike Errington","email":"mike.errington@gmail.com","login":"merrington","count":1},{"name":"Muz Muz","email":"mudassarhassan135@gmail.com","login":"themudassarhassan","count":1},{"name":"Nicolas Leger","email":"nicolasleger","login":"nicolasleger","count":1},{"name":"Niels Hoffmann","email":"niels@zentralmaschine.net","login":"nhoffmann","count":1},{"name":"Noah Harrison","email":"noah@frontporchforum.com","login":"noahfpf","count":1},{"name":"Oleg Yakovenko","email":"olegykz@gmail.com","login":"olegykz","count":1}],"past_year_committers":[{"name":"Marc Anguera","email":"srmarc.ai@gmail.com","login":"markets","count":2},{"name":"Kevin Robell","email":"kevin.robell@sensortower.com","login":"kevinrobell-st","count":2},{"name":"Florian Wininger","email":"fw.centrale@gmail.com","login":"fwininger","count":2},{"name":"Yaroslav","email":"iaroslav2k@gmail.com","login":"viralpraxis","count":1},{"name":"Tony Ciou","email":"cioutonyhao@gmail.com","login":"tonyciou","count":1},{"name":"Rocela Durazo","email":"3598290+roseliux","login":"roseliux","count":1},{"name":"Andrew Kodkod","email":"678665+akodkod","login":"akodkod","count":1}],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-30T00:00:07.427Z","repositories_count":6223397,"commits_count":900024277,"contributors_count":34899964,"owners_count":1147576,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"sidekiq-cron/sidekiq-cron","html_url":"https://github.com/sidekiq-cron/sidekiq-cron","last_synced_at":"2026-04-28T04:01:37.461Z","status":"active","issues_count":110,"pull_requests_count":204,"avg_time_to_close_issue":8881035.666666666,"avg_time_to_close_pull_request":2327176.207070707,"issues_closed_count":102,"pull_requests_closed_count":198,"pull_request_authors_count":58,"issue_authors_count":89,"avg_comments_per_issue":3.8454545454545457,"avg_comments_per_pull_request":3.303921568627451,"merged_pull_requests_count":180,"bot_issues_count":0,"bot_pull_requests_count":0,"past_year_issues_count":7,"past_year_pull_requests_count":10,"past_year_avg_time_to_close_issue":5250439.285714285,"past_year_avg_time_to_close_pull_request":250014.6,"past_year_issues_closed_count":7,"past_year_pull_requests_closed_count":10,"past_year_pull_request_authors_count":7,"past_year_issue_authors_count":7,"past_year_avg_comments_per_issue":2.4285714285714284,"past_year_avg_comments_per_pull_request":2.7,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":10,"created_at":"2023-05-12T17:15:36.460Z","updated_at":"2026-04-28T04:01:37.461Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidekiq-cron%2Fsidekiq-cron/issues","issue_labels_count":{"wontfix":30,"feature":8,"enhancement":7,"web_ui":5,"question":4,"bug":2,"engineering":2,"discussion":2},"pull_request_labels_count":{"feature":6,"wontfix":2},"issue_author_associations_count":{"NONE":79,"CONTRIBUTOR":26,"MEMBER":5},"pull_request_author_associations_count":{"CONTRIBUTOR":125,"MEMBER":54,"NONE":24,"COLLABORATOR":1},"issue_authors":{"markets":5,"krystof-k":4,"satyakampandya":3,"kevinrobell-st":3,"sandip-mane":3,"collimarco":2,"francktrouillez":2,"engwan":2,"phyzalis":2,"iwaseasahi":2,"lloydwatkin":2,"freemanoid":2,"konalegi":2,"rocketedaway":1,"joevandyk":1,"JerrodCarpenter":1,"limjinsun":1,"knightq":1,"eileen-jiang":1,"michael-ciocca":1,"rafal-brize":1,"nickgal":1,"addam128":1,"eddygarcas":1,"Chrisgo-75":1,"vitobotta":1,"jchan172":1,"mperham":1,"szpasztor":1,"optikalefx":1,"thisIsLoading":1,"leoarnold":1,"f-ewald":1,"phlegx":1,"jsantos":1,"viralpraxis":1,"denisj":1,"maxfurman":1,"marcogregorius":1,"vanboom":1,"fwininger":1,"shota-yamashita":1,"rslhdyt":1,"delphaber":1,"fcy-nienan":1,"benkruger":1,"fatkodima":1,"mohsintahir":1,"pboling":1,"kieetnvt":1,"surbhig213":1,"v-kumar":1,"agramichael":1,"arent-groebner":1,"farooqch11":1,"byungjikroh":1,"eis-ioki":1,"djpremier":1,"erick-c-mc":1,"hectorakemp":1,"morus":1,"matthewmcgarvey":1,"javinto":1,"noahfpf":1,"axos88":1,"ybiquitous":1,"cmalpeli":1,"galievruslan":1,"Toucouleur66":1,"arathunku":1,"Azdaroth":1,"sampenguin":1,"pyromaniac":1,"thilonel":1,"jcostello":1,"louman":1,"LaurelOlson":1,"KieranP":1,"lonhtm":1,"Ramkumar0508":1,"gregorbg":1,"Emanuelmoves":1,"kaiomagalhaes":1,"debow77":1,"twnaing":1,"stanhu":1,"dsusviela":1,"jvanderen1":1,"romamur":1},"pull_request_authors":{"markets":54,"satyakampandya":20,"viralpraxis":15,"leoarnold":8,"tttffff":8,"kevinrobell-st":8,"francktrouillez":5,"sandip-mane":5,"fatkodima":4,"engwan":4,"krystof-k":4,"nyuta01":3,"delphaber":3,"eqladios":2,"iwaseasahi":2,"danilogco":2,"freemanoid":2,"tonyciou":2,"jmettraux":2,"m-nakamura145":2,"serprex":2,"kakikubo":2,"noahfpf":2,"ryotarai":2,"thanhcuong1990":2,"fwininger":2,"themudassarhassan":2,"jvanderen1":2,"stanhu":2,"arathunku":2,"zedtux":2,"roseliux":1,"dmeremyanin":1,"collimarco":1,"IrvanFza":1,"haffla":1,"vsuhachev":1,"Linell":1,"dalpo":1,"oozzal":1,"olegykz":1,"hqm42":1,"petergoldstein":1,"akodkod":1,"machisuke":1,"ybiquitous":1,"dapi":1,"chrismaximin":1,"kianmeng":1,"gogainda":1,"rromanchuk":1,"jdaviderb":1,"mkusaka":1,"Spone":1,"samsm":1,"cgunther":1,"vzamanillo":1,"yuri-zubov":1},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-29T00:00:10.439Z","repositories_count":14445217,"issues_count":34169336,"pull_requests_count":112178252,"authors_count":11248977,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{"wontfix":5,"feature":2,"bug":1,"enhancement":1,"question":1},"past_year_pull_request_labels_count":{},"past_year_issue_author_associations_count":{"NONE":5,"CONTRIBUTOR":2},"past_year_pull_request_author_associations_count":{"CONTRIBUTOR":8,"MEMBER":2},"past_year_issue_authors":{"addam128":1,"fwininger":1,"JerrodCarpenter":1,"kevinrobell-st":1,"optikalefx":1,"romamur":1,"vanboom":1},"past_year_pull_request_authors":{"fwininger":2,"kevinrobell-st":2,"markets":2,"akodkod":1,"roseliux":1,"tonyciou":1,"viralpraxis":1},"maintainers":[{"login":"markets","count":59,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/markets"},{"login":"Linell","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/Linell"}],"active_maintainers":[{"login":"markets","count":2,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/markets"}]},"events":{"total":{"ReleaseEvent":5,"DeleteEvent":9,"PullRequestEvent":82,"ForkEvent":22,"IssuesEvent":48,"WatchEvent":72,"IssueCommentEvent":189,"PushEvent":46,"PullRequestReviewCommentEvent":20,"PullRequestReviewEvent":53,"CreateEvent":17},"last_year":{"ReleaseEvent":1,"PullRequestEvent":8,"ForkEvent":4,"IssuesEvent":7,"WatchEvent":21,"IssueCommentEvent":16,"PushEvent":6,"PullRequestReviewEvent":2,"PullRequestReviewCommentEvent":2,"CreateEvent":3}},"keywords":["cron-jobs","ruby","ruby-gem","ruby-on-rails","scheduled-jobs","scheduler","sidekiq","sidekiq-cron","sidekiq-jobs","sidekiq-workers"],"dependencies":[{"ecosystem":"rubygems","filepath":"sidekiq-cron.gemspec","sha":null,"kind":"manifest","created_at":"2022-08-07T05:15:36.819Z","updated_at":"2022-08-07T05:15:36.819Z","repository_link":"https://github.com/sidekiq-cron/sidekiq-cron/blob/master/sidekiq-cron.gemspec","dependencies":[{"id":587837736,"package_name":"fugit","ecosystem":"rubygems","requirements":"~\u003e 1","direct":true,"kind":"runtime","optional":false},{"id":587837737,"package_name":"sidekiq","ecosystem":"rubygems","requirements":"\u003e= 4.2.1","direct":true,"kind":"runtime","optional":false},{"id":587837738,"package_name":"minitest","ecosystem":"rubygems","requirements":"~\u003e 5.15","direct":true,"kind":"development","optional":false},{"id":587837739,"package_name":"mocha","ecosystem":"rubygems","requirements":"~\u003e 1.14","direct":true,"kind":"development","optional":false},{"id":587837740,"package_name":"redis-namespace","ecosystem":"rubygems","requirements":"~\u003e 1.8","direct":true,"kind":"development","optional":false},{"id":587837741,"package_name":"rack","ecosystem":"rubygems","requirements":"~\u003e 2.2","direct":true,"kind":"development","optional":false},{"id":587837742,"package_name":"rack-test","ecosystem":"rubygems","requirements":"~\u003e 1.1","direct":true,"kind":"development","optional":false},{"id":587837743,"package_name":"rake","ecosystem":"rubygems","requirements":"~\u003e 13.0","direct":true,"kind":"development","optional":false},{"id":587837744,"package_name":"simplecov","ecosystem":"rubygems","requirements":"~\u003e 0.21","direct":true,"kind":"development","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/ci.yml","sha":null,"kind":"manifest","created_at":"2023-01-13T15:49:50.481Z","updated_at":"2023-01-13T15:49:50.481Z","repository_link":"https://github.com/sidekiq-cron/sidekiq-cron/blob/master/.github/workflows/ci.yml","dependencies":[{"id":6888378079,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":6888378080,"package_name":"ruby/setup-ruby","ecosystem":"actions","requirements":"v1","direct":true,"kind":"composite","optional":false},{"id":6888378081,"package_name":"redis","ecosystem":"actions","requirements":"*","direct":true,"kind":"docker","optional":false}]},{"ecosystem":"docker","filepath":"docker/Dockerfile","sha":null,"kind":"manifest","created_at":"2024-01-05T22:00:07.911Z","updated_at":"2024-01-05T22:00:07.911Z","repository_link":"https://github.com/sidekiq-cron/sidekiq-cron/blob/master/docker/Dockerfile","dependencies":[{"id":15452723666,"package_name":"ruby","ecosystem":"docker","requirements":"3.2","direct":true,"kind":"build","optional":false}]},{"ecosystem":"docker","filepath":"docker/docker-compose.yml","sha":null,"kind":"manifest","created_at":"2024-01-05T22:00:07.917Z","updated_at":"2024-01-05T22:00:07.917Z","repository_link":"https://github.com/sidekiq-cron/sidekiq-cron/blob/master/docker/docker-compose.yml","dependencies":[{"id":15452723667,"package_name":"redis","ecosystem":"docker","requirements":"latest","direct":true,"kind":"runtime","optional":false},{"id":15452723668,"package_name":"sidekiq-cron-test","ecosystem":"docker","requirements":"latest","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"rubygems","filepath":"Gemfile","sha":null,"kind":"manifest","created_at":"2024-01-05T22:00:09.245Z","updated_at":"2024-01-05T22:00:09.245Z","repository_link":"https://github.com/sidekiq-cron/sidekiq-cron/blob/master/Gemfile","dependencies":[]}],"score":null,"created_at":"2024-12-15T21:38:07.291Z","updated_at":"2026-04-30T05:00:59.213Z","avatar_url":"https://github.com/sidekiq-cron.png","language":"Ruby","monthly_downloads":0,"readme":"![Sidekiq-Cron](logos/cover.png)\n\n[![Gem Version](https://badge.fury.io/rb/sidekiq-cron.svg)](https://badge.fury.io/rb/sidekiq-cron)\n[![CI](https://github.com/sidekiq-cron/sidekiq-cron/actions/workflows/ci.yml/badge.svg)](https://github.com/sidekiq-cron/sidekiq-cron/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/sidekiq-cron/sidekiq-cron/branch/master/graph/badge.svg?token=VK9IVLIaY8)](https://codecov.io/gh/sidekiq-cron/sidekiq-cron)\n\n\u003e A scheduling add-on for [Sidekiq](https://sidekiq.org/)\n\n🎬 [Introduction video about Sidekiq-Cron by Drifting Ruby](https://www.driftingruby.com/episodes/periodic-tasks-with-sidekiq-cron)\n\nSidekiq-Cron runs a thread alongside Sidekiq workers to schedule jobs at specified times (using cron notation `* * * * *` or natural language, powered by [Fugit](https://github.com/floraison/fugit)).\n\nChecks for new jobs to schedule every 30 seconds and doesn't schedule the same job multiple times when more than one Sidekiq process is running.\n\nScheduling jobs are added only when at least one Sidekiq process is running, but it is safe to use Sidekiq-Cron in environments where multiple Sidekiq processes or nodes are running.\n\nIf you want to know how scheduling work, check out [under the hood](#under-the-hood).\n\n## Changelog\n\nBefore upgrading to a new version, please read our [Changelog](CHANGELOG.md).\n\n## Installation\n\nInstall the gem:\n\n```\n$ gem install sidekiq-cron\n```\n\nOr add to your `Gemfile` and run `bundle install`:\n\n```ruby\ngem \"sidekiq-cron\"\n```\n\n**NOTE** If you are not using Rails, you need to add `require 'sidekiq-cron'` somewhere after `require 'sidekiq'`.\n\n## Getting Started\n\n### Job properties\n\n```ruby\n{\n  # MANDATORY\n  'name' =\u003e 'name_of_job', # must be uniq!\n  'cron' =\u003e '1 * * * *',  # execute at 1 minute of every hour, ex: 12:01, 13:01, 14:01, ...\n  'class' =\u003e 'MyClass',\n  # OPTIONAL\n  'namespace' =\u003e 'YourNamespace', # groups jobs together in a namespace (Default value is 'default'),\n  'source' =\u003e 'dynamic', # source of the job, `schedule`/`dynamic` (default: `dynamic`)\n  'queue' =\u003e 'name of queue',\n  'retry' =\u003e '5', # Sidekiq (not supported by ActiveJob) number of retries, or false to discard on first failure\n  'args' =\u003e '[Array or Hash] of arguments which will be passed to perform method',\n  'date_as_argument' =\u003e true, # add the time of execution as last argument of the perform method\n  'active_job' =\u003e true,  # enqueue job through Active Job interface\n  'queue_name_prefix' =\u003e 'prefix', # Active Job queue with prefix\n  'queue_name_delimiter' =\u003e '.', # Active Job queue with custom delimiter (default: '_')\n  'description' =\u003e 'A sentence describing what work this job performs',\n  'status' =\u003e 'disabled' # default: enabled\n}\n```\n\n**NOTE** The `status` of a job does not get changed in Redis when a job gets reloaded unless the `status` property is explicitly set.\n\n### Configuration\n\nAll configuration options:\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.cron_poll_interval = 10 # Default is 30\n  config.cron_schedule_file = 'config/my_schedule.yml' # Default is 'config/schedule.yml'\n  config.cron_history_size = 20 # Default is 10\n  config.default_namespace = 'statistics' # Default is 'default'\n  config.available_namespaces = %w[statistics maintenance billing] # Default is `[config.default_namespace]`\n  config.natural_cron_parsing_mode = :strict # Default is :single\n  config.reschedule_grace_period = 300 # Default is 60\nend\n```\n\nIf you are using Rails, you should add the above block inside an initializer (`config/initializers/sidekiq-cron.rb`).\n\n### Time, cron and Sidekiq-Cron\n\nFor testing your cron notation you can use [crontab.guru](https://crontab.guru).\n\nSidekiq-Cron uses [Fugit](https://github.com/floraison/fugit) to parse the cronline. So please, check Fugit documentation for further information about allowed formats.\n\nIf using Rails, this is evaluated against the timezone configured in Rails, otherwise the default is UTC.\n\nIf you want to have your jobs enqueued based on a different time zone you can specify a timezone in the cronline,\nlike this `'0 22 * * 1-5 America/Chicago'`.\n\n#### Natural-language formats\n\nSince Sidekiq-Cron `v1.7.0`, you can use the natural-language formats supported by Fugit, such as:\n\n```ruby\n\"every day at five\" # =\u003e '0 5 * * *'\n\"every 3 hours\"     # =\u003e '0 */3 * * *'\n```\n\nSee [the relevant part of Fugit documentation](https://github.com/floraison/fugit#fugitnat) for details.\n\nThere are multiple modes that determine how natural-language cron strings will be parsed.\n\n1. `:single` (default)\n\n```ruby\nSidekiq::Cron.configure do |config|\n  # Note: This doesn't need to be specified since it's the default.\n  config.natural_cron_parsing_mode = :single\nend\n```\n\nThis parses the first possible cron line from the given string and then ignores any additional cron lines.\n\nEx. `every day at 3:15 and 4:30`\n\n- Equivalent to `15 3 * * *`.\n- `30 4 * * *` gets ignored.\n\n2. `:strict`\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.natural_cron_parsing_mode = :strict\nend\n```\n\nThis throws an error if the given string would be parsed into multiple cron lines.\n\nEx. `every day at 3:15 and 4:30`\n\n- Would throw an error and the associated cron job would be invalid\n\n#### Second-precision (sub-minute) cronlines\n\nIn addition to the standard 5-parameter cronline format, Sidekiq-Cron supports scheduling jobs with second-precision using a modified 6-parameter cronline format:\n\n`Seconds Minutes Hours Days Months DayOfWeek`\n\nFor example: `\"*/30 * * * * *\"` would schedule a job to run every 30 seconds.\n\nNote that if you plan to schedule jobs with second precision you may need to override the default schedule poll interval so it is lower than the interval of your jobs:\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.cron_poll_interval = 10\nend\n```\n\nThe default value at time of writing is 30 seconds. See [under the hood](#under-the-hood) for more details.\n\n### Namespacing\n\n#### Default namespace\n\nWhen not giving a namespace, the `default` one will be used.\n\nIn the case you'd like to change this value, you can change it via the following configuration flag:\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.default_namespace = 'statistics'\nend\n```\n\n#### Renaming namespace\n\nIf you rename the namespace of a job that is already running, the gem will not automatically delete the cron job associated with the old namespace. This means you could end up with two cron jobs running simultaneously.\n\nTo avoid this, it is recommended to delete all existing cron jobs associated with the old namespace before making the change. You can achieve this with the following code:\n\n```ruby\nSidekiq::Cron::Job.all('YOUR_OLD_NAMESPACE_NAME').each { |job| job.destroy }\n```\n\n#### Available namespaces\n\nBy default, Sidekiq Cron uses the available_namespaces configuration option to determine which namespaces your application utilizes. The default namespace (`\"default\"`, by default) is always included in the list of available namespaces.\n\nIf you want Sidekiq Cron to automatically detect existing namespaces from the Redis database, you can set `available_namespaces` to the special option `:auto`.\n\nIf available_namespaces is explicitly set and a job is created with an unexpected namespace, a warning will be printed, and the job will be assigned to the default namespace.\n\n#### Migrating to 2.3\n\nAs discussed in [this issue](https://github.com/sidekiq-cron/sidekiq-cron/issues/516), the approach introduced in Sidekiq Cron 2.0 for determining available namespaces using the `KEYS` command is not acceptable. Therefore, starting from version 2.3, namespacing has been reworked:\n\n- If you were not using the namespacing feature, no action is required. You can even remove `available_namespaces = %w[default]`, as it is now the default.\n\n- If you were using the namespacing feature and explicitly specified available namespaces as a list, no changes are needed.\n\n- If you were using the namespacing feature and relied on automatic namespace inference, you should either specify all used namespaces explicitly or set `available_namespaces` to `:auto` to maintain automatic detection. However, note that this approach does not scale well (see the referenced issue for details).\n\n#### Usage\n\nWhen creating a new job, you can optionally give a `namespace` attribute, and then you can pass it too in the `find` or `destroy` methods.\n\n```ruby\nSidekiq::Cron::Job.create(\n  name: 'Hard worker - every 5min',\n  namespace: 'Foo',\n  cron: '*/5 * * * *',\n  class: 'HardWorker'\n)\n# INFO: Cron Jobs - add job with name Hard worker - every 5min in the namespace Foo\n\n# Without specifying the namespace, Sidekiq::Cron use the `default` one, therefore `count` return 0.\nSidekiq::Cron::Job.count\n#=\u003e 0\n\n# Searching in the job's namespace returns 1.\nSidekiq::Cron::Job.count 'Foo'\n#=\u003e 1\n\n# Same applies to `all`. Without a namespace, no jobs found.\nSidekiq::Cron::Job.all\n\n# But giving the job's namespace returns it.\nSidekiq::Cron::Job.all 'Foo'\n#=\u003e [#\u003cSidekiq::Cron::Job:0x00007f7848a326a0 ... @name=\"Hard worker - every 5min\", @namespace=\"Foo\", @cron=\"*/5 * * * *\", @klass=\"HardWorker\", @status=\"enabled\" ... \u003e]\n\n# If you'd like to get all the jobs across all the namespaces then pass an asterisk:\nSidekiq::Cron::Job.all '*'\n#=\u003e [#\u003cSidekiq::Cron::Job ...\u003e]\n\njob = Sidekiq::Cron::Job.find('Hard worker - every 5min', 'Foo').first\njob.destroy\n# INFO: Cron Jobs - deleted job with name Hard worker - every 5min from namespace Foo\n#=\u003e true\n```\n\n### What objects/classes can be scheduled\n\n#### Sidekiq Worker\n\nIn this example, we are using `HardWorker` which looks like:\n\n```ruby\nclass HardWorker\n  include Sidekiq::Worker\n\n  def perform(*args)\n    # do something\n  end\nend\n```\n\nFor Sidekiq workers, `symbolize_args: true` in `Sidekiq::Cron::Job.create` or in Hash configuration is gonna be ignored as Sidekiq currently only allows for [simple JSON datatypes](https://github.com/sidekiq/sidekiq/wiki/The-Basics#:~:text=These%20two%20methods,not%20serialize%20properly.).\n\n#### Active Job\n\nYou can schedule `ExampleJob` which looks like:\n\n```ruby\nclass ExampleJob \u003c ActiveJob::Base\n  queue_as :default\n\n  def perform(*args)\n    # Do something\n  end\nend\n```\n\nFor Active Job you can use `symbolize_args: true` in `Sidekiq::Cron::Job.create` or in Hash configuration,\nwhich will ensure that arguments you are passing to it will be symbolized when passed back to `perform` method in worker.\n\n### Adding Cron jobs\n\nRefer to [Schedule vs Dynamic jobs](#schedule-vs-dynamic-jobs) to understand the difference.\n\n```ruby\nclass HardWorker\n  include Sidekiq::Worker\n\n  def perform(name, count)\n    # do something\n  end\nend\n\nSidekiq::Cron::Job.create(name: 'Hard worker - every 5min', cron: '*/5 * * * *', class: 'HardWorker') # execute at every 5 minutes\n# =\u003e true\n```\n\n`create` method will return only true/false if job was saved or not.\n\n```ruby\njob = Sidekiq::Cron::Job.new(name: 'Hard worker - every 5min', cron: '*/5 * * * *', class: 'HardWorker')\n\nif job.valid?\n  job.save\nelse\n  puts job.errors\nend\n\n# or simple\nunless job.save\n  puts job.errors # will return array of errors\nend\n```\n\nUse ActiveRecord models as arguments:\n\n```ruby\nclass Person \u003c ApplicationRecord\nend\n\nclass HardWorker \u003c ActiveJob::Base\n  queue_as :default\n\n  def perform(person)\n    puts \"person: #{person}\"\n  end\nend\n\nperson = Person.create(id: 1)\nSidekiq::Cron::Job.create(name: 'Hard worker - every 5min', cron: '*/5 * * * *', class: 'HardWorker', args: person)\n# =\u003e true\n```\n\nLoad more jobs from hash:\n\n```ruby\nhash = {\n  'name_of_job' =\u003e {\n    'class' =\u003e 'MyClass',\n    'cron'  =\u003e '1 * * * *',\n    'args'  =\u003e '(OPTIONAL) [Array or Hash]'\n  },\n  'My super iber cool job' =\u003e {\n    'class' =\u003e 'SecondClass',\n    'cron'  =\u003e '*/5 * * * *'\n  }\n}\n\nSidekiq::Cron::Job.load_from_hash hash\n```\n\nLoad more jobs from array:\n\n```ruby\narray = [\n  {\n    'name'  =\u003e 'name_of_job',\n    'class' =\u003e 'MyClass',\n    'cron'  =\u003e '1 * * * *',\n    'args'  =\u003e '(OPTIONAL) [Array or Hash]'\n  },\n  {\n    'name'  =\u003e 'Cool Job for Second Class',\n    'class' =\u003e 'SecondClass',\n    'cron'  =\u003e '*/5 * * * *'\n  }\n]\n\nSidekiq::Cron::Job.load_from_array array\n```\n\nBang-suffixed methods will remove jobs where source is `schedule` and are not present in the given hash/array, update jobs that have the same names, and create new ones when the names are previously unknown.\n\n```ruby\nSidekiq::Cron::Job.load_from_hash! hash\nSidekiq::Cron::Job.load_from_array! array\n```\n\n### Loading jobs from schedule file\n\nYou can also load multiple jobs from a YAML file:\n\n```yaml\n# config/schedule.yml\n\nmy_first_job:\n  cron: \"*/5 * * * *\"\n  class: \"HardWorker\"\n  queue: hard_worker\n\nsecond_job:\n  cron: \"*/30 * * * *\" # execute at every 30 minutes\n  class: \"HardWorker\"\n  queue: hard_worker_long\n  args:\n    hard: \"stuff\"\n```\n\nThere are multiple ways to load the jobs from a YAML file\n\n1. The gem will automatically load the jobs mentioned in `config/schedule.yml` file (it supports ERB)\n2. When you want to load jobs from a different filename, mention the filename in Sidekiq configuration as follows:\n\n    ```ruby\n    Sidekiq::Cron.configure do |config|\n      config.cron_schedule_file = \"config/users_schedule.yml\"\n    end\n    ```\n\n3. Load the file manually as follows:\n\n    ```ruby\n    # config/initializers/sidekiq.rb\n\n    Sidekiq.configure_server do |config|\n      config.on(:startup) do\n        schedule_file = \"config/users_schedule.yml\"\n\n        if File.exist?(schedule_file)\n          schedule = YAML.load_file(schedule_file)\n\n          Sidekiq::Cron::Job.load_from_hash!(schedule, source: \"schedule\")\n        end\n      end\n    end\n    ```\n\n### Finding jobs\n\n```ruby\n# return array of all jobs\nSidekiq::Cron::Job.all\n\n# return one job by its unique name - case sensitive\nSidekiq::Cron::Job.find \"Job Name\"\n\n# return one job by its unique name - you can use hash with 'name' key\nSidekiq::Cron::Job.find name: \"Job Name\"\n\n# if job can't be found nil is returned\n```\n\n### Destroy jobs\n\n```ruby\n# destroy all jobs\nSidekiq::Cron::Job.destroy_all!\n\n# destroy job by its name\nSidekiq::Cron::Job.destroy \"Job Name\"\n\n# destroy found job\nSidekiq::Cron::Job.find('Job name').destroy\n```\n\n### Work with job\n\n```ruby\njob = Sidekiq::Cron::Job.find('Job name')\n\n# disable cron scheduling\njob.disable!\n\n# enable cron scheduling\njob.enable!\n\n# get status of job:\njob.status\n# =\u003e enabled/disabled\n\n# enqueue job right now!\njob.enqueue!\n```\n\n### Schedule vs Dynamic jobs\n\nThere are two potential job sources: `schedule` and `dynamic`.\nJobs associated with schedule files are labeled as `schedule` as their source,\nwhereas jobs created at runtime without the `source=schedule` argument are classified as `dynamic`.\n\nThe key distinction lies in how these jobs are managed.\nWhen a schedule is loaded, any stale `schedule` jobs are automatically removed to ensure synchronization within the schedule.\nThe `dynamic` jobs remain unaffected by this process.\n\n### How to start scheduling?\n\nJust start Sidekiq workers by running:\n\n```\n$ bundle exec sidekiq\n```\n\n### Web UI for Cron Jobs\n\nIf you are using Sidekiq's web UI and you would like to add cron jobs too to this web UI,\nadd `require 'sidekiq/cron/web'` after `require 'sidekiq/web'`.\n\nWith this, you will get:\n\n![Web UI](docs/images/web-cron-ui.jpeg)\n\n## Under the hood\n\nWhen you start the Sidekiq process, it starts one thread with `Sidekiq::Poller` instance, which perform the adding of scheduled jobs to queues, retries etc.\n\nSidekiq-Cron adds itself into this start procedure and starts another thread with `Sidekiq::Cron::Poller` which checks all enabled Sidekiq cron jobs every 30 seconds, if they should be added to queue (their cronline matches time of check).\n\nSidekiq-Cron is checking jobs to be enqueued every 30s by default, you can change it by setting:\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.cron_poll_interval = 10\nend\n```\n\nWhen Sidekiq (and Sidekiq-Cron) is not used in zero-downtime deployments, after the deployment is done Sidekiq-Cron starts to catch up. It will consider older jobs that missed their schedules during that time. By default, only jobs that should have started less than 1 minute ago are considered. This is problematic for some jobs, e.g., jobs that run once a day. If on average Sidekiq is shut down for 10 minutes during deployments, you can configure Sidekiq-Cron to consider jobs that were about to be scheduled during that time:\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.reschedule_grace_period = 600 # 10 minutes in seconds\nend\n```\n\nSidekiq-Cron is safe to use with multiple Sidekiq processes or nodes. It uses a Redis sorted set to determine that only the first process who asks can enqueue scheduled jobs into the queue.\n\nWhen running with many Sidekiq processes, the polling can add significant load to Redis. You can disable polling on some processes by setting:\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.cron_poll_interval = 0\nend\n```\n\nSidekiq will internally determine the process count by checking Redis but if polling has been disabled from some Sidekiq processes by setting the cron poll interval to zero, as explained above, that count might be incorrect. In that case, it is possible to override the default process count for Sidekiq Cron. This affects the way the random poll interval is calculated internally.\n\n```ruby\nSidekiq::Cron.configure do |config|\n  config.cron_poll_process_count = 2\nend\n```\n\n## Testing your configuration\n\nYou can test your application's configuration by loading the schedule in your test suite. Below is an example using RSpec in a Rails project:\n\n```ruby\n# spec/cron_schedule_spec.rb\nrequire \"rails_helper\"\n\nRSpec.describe \"Cron Schedule\" do\n  let(:schedule_loader) { Sidekiq::Cron::ScheduleLoader.new }\n  let(:all_jobs) { Sidekiq::Cron::Job.all }\n\n  # Confirms that `config.cron_schedule_file` points to a real file.\n  it \"has a schedule file\" do\n    expect(schedule_loader).to have_schedule_file\n  end\n\n  # Confirms that no jobs in the schedule have an invalid cron string.\n  it \"does not return any errors\" do\n    expect(schedule_loader.load_schedule).to be_empty\n  end\n\n  # May be subject to churn, but adds confidence.\n  it \"adds the expected number of jobs\" do\n    schedule_loader.load_schedule\n    expect(all_jobs.size).to eq 5\n  end\n\n  # Confirms that all job classes exist.\n  it \"has a valid class for each added job\" do\n    schedule_loader.load_schedule\n    # Shows that all classes exist (as we can constantize the names without raising).\n    job_classes = all_jobs.map { |job| job.klass.constantize }\n    # Naive check that classes are sidekiq jobs (as they all have `.perfrom_async`).\n    expect(job_classes).to all(respond_to(:perform_async))\n  end\nend\n```\n\n## Contributing\n\n**Thanks to all [contributors](https://github.com/sidekiq-cron/sidekiq-cron/graphs/contributors), you’re awesome and this wouldn’t be possible without you!**\n\n* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.\n* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.\n* Fork the project.\n* Start a feature/bugfix branch.\n* Commit and push until you are happy with your contribution.\n* Make sure to add tests for it. This is important so we don't break it in a future version unintentionally.\n* Open a pull request!\n\n### Testing\n\nYou can execute the test suite by running:\n\n```\n$ bundle exec rake test\n```\n\n### Using Docker\n\nThis project uses [Docker Compose](https://docs.docker.com/compose/) in order to orchestrate containers and get the test suite running on you local machine, and here you find the commands to run in order to get a complete environment to build and test this gem:\n\n1. Build the Docker image (only the first time):\n```\ndocker compose -f docker/docker-compose.yml build\n```\n\n2. Run the test suite:\n```\ndocker compose -f docker/docker-compose.yml run --rm tests\n```\n\n_This command will download the first time the project's dependencies (Redis so far), create the containers and run the default command to run the tests._\n\n**Running other commands**\n\nIn the case you need to run a command in the gem's container, you would do it like so:\n\n```\ndocker compose -f docker/docker-compose.yml run --rm tests \u003cHERE IS YOUR COMMAND\u003e\n```\n_Note that `tests` is the Docker Compose service name defined in the `docker/docker-compose.yml` file._\n\n**Running a single test file**\n\nGiven you only want to run the tests from the `test/unit/web_extension_test.rb` file, you need to pass its path with the `TEST` env variable, so here is the command:\n\n```\ndocker compose -f docker/docker-compose.yml run --rm --env TEST=test/unit/web_extension_test.rb tests\n```\n\n## License\n\nCopyright (c) 2013 Ondrej Bartas. See [LICENSE](LICENSE.txt) for further details.\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":["activerecord","activejob","mvc","background-jobs","jobs","rubygems","rack","crash-reporting","rubocop","sinatra"],"project_url":"https://ruby.ecosyste.ms/api/v1/projects/206","html_url":"https://ruby.ecosyste.ms/projects/206"}