{"id":13879568,"url":"https://github.com/bibendi/schked","last_synced_at":"2025-04-06T03:07:29.702Z","repository":{"id":48835018,"uuid":"163503258","full_name":"bibendi/schked","owner":"bibendi","description":"Framework agnostic scheduler to run recurring jobs.","archived":false,"fork":false,"pushed_at":"2023-09-06T14:46:17.000Z","size":93,"stargazers_count":129,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T01:13:12.841Z","etag":null,"topics":["gem","rails","recurring-jobs","ruby","rufus","schedule","scheduler"],"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/bibendi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2018-12-29T10:48:40.000Z","updated_at":"2025-03-22T14:18:46.000Z","dependencies_parsed_at":"2024-10-13T00:21:03.053Z","dependency_job_id":"a1157436-9369-4114-8e21-d2e65e1461c9","html_url":"https://github.com/bibendi/schked","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fschked","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fschked/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fschked/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fschked/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bibendi","download_url":"https://codeload.github.com/bibendi/schked/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247427006,"owners_count":20937201,"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":["gem","rails","recurring-jobs","ruby","rufus","schedule","scheduler"],"created_at":"2024-08-06T08:02:25.474Z","updated_at":"2025-04-06T03:07:29.674Z","avatar_url":"https://github.com/bibendi.png","language":"Ruby","readme":"[![Gem Version](https://badge.fury.io/rb/schked.svg)](https://badge.fury.io/rb/schked)\n[![Build Status](https://travis-ci.org/bibendi/schked.svg?branch=master)](https://travis-ci.org/bibendi/schked)\n\n# Schked\n\nFramework agnostic [Rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) wrapper to run recurring jobs.\n\n\u003ca href=\"https://evilmartians.com/?utm_source=schked\"\u003e\n\u003cimg src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\" alt=\"Sponsored by Evil Martians\" width=\"236\" height=\"54\"\u003e\u003c/a\u003e\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem \"schked\"\n```\n\nAnd then execute:\n\n```sh\nbundle\n```\n\nOr install it yourself as:\n\n```sh\ngem install schked\n```\n\n## Usage\n\n### Ruby on Rails\n\n.schked\n\n```\n--require config/environment.rb\n```\n\nconfig/schedule.rb\n\n```ruby\ncron \"*/30 * * * *\", as: \"CleanOrphanAttachmentsJob\", timeout: \"60s\", overlap: false do\n  CleanOrphanAttachmentsJob.perform_later\nend\n```\n\nIf you have a Rails engine with own schedule:\n\nengine-path/lib/foo/engine.rb\n\n```ruby\nmodule Foo\n  class Engine \u003c ::Rails::Engine\n    initializer \"foo\" do |app|\n      Schked.config.paths \u003c\u003c root.join(\"config\", \"schedule.rb\")\n    end\n  end\nend\n```\n\nAnd run Schked:\n\n```sh\nbundle exec schked start\n```\n\nTo show schedule:\n\n```sh\nbundle exec schked show\n```\n\n### Duplicate scheduling\n\nWhen you deploy your schedule to production, you want to start new instance before you shut down the current. And you don't want simultaneous working of both. To achieve a seamless transition, Schked is using Redis for locks.\n\nYou can configure Redis client as the following:\n\n```ruby\nSchked.config.redis = {url: ENV.fetch(\"REDIS_URL\") }\n```\n\n### Callbacks\n\nAlso, you can define callbacks for errors handling:\n\nconfig/initializers/schked.rb\n\n```ruby\nSchked.config.register_callback(:on_error) do |job, error|\n  Raven.capture_exception(error) if defined?(Raven)\nend\n```\n\nThere are `:before_start`, `:after_finish` and `:around_job` callbacks as well.\n\nWarning: `:before_start` and `:after_finish` callbacks are executed in the scheduler thread, not in the work threads (the threads where the job execution really happens).\n\n`:around_job` callback is executed in the job's thread.\n\n```ruby\nSchked.config.register_callback(:around_job) do |job, \u0026block|\n  ...\n  block.call\n  ...\nend\n```\n\n### Logging\n\nBy default Schked writes logs into stdout. In Rails environment Schked is using application logger. You can change it like this:\n\nconfig/initializers/schked.rb\n\n```ruby\nSchked.config.logger = Logger.new(Rails.root.join(\"log\", \"schked.log\"))\n```\n\n### Monitoring\n\n[Yabeda::Schked](https://github.com/yabeda-rb/yabeda-schked) - built-in metrics for monitoring Schked recurring jobs out of the box! Part of the [yabeda](https://github.com/yabeda-rb/yabeda) suite.\n\n### Testing\n\n```ruby\ndescribe Schked do\n  let(:worker) { described_class.worker.tap(\u0026:pause) }\n\n  around do |ex|\n    Time.use_zone(\"UTC\") { Timecop.travel(start_time, \u0026ex) }\n  end\n\n  describe \"CleanOrphanAttachmentsJob\" do\n    let(:start_time) { Time.zone.local(2008, 9, 1, 10, 42, 21) }\n    let(:job) { worker.job(\"CleanOrphanAttachmentsJob\") }\n\n    specify do\n      expect(job.next_time.to_local_time)\n        .to eq Time.zone.local(2008, 9, 1, 11, 0, 0)\n    end\n\n    it \"enqueues job\" do\n      expect { job.call(false) }\n        .to have_enqueued_job(CleanOrphanAttachmentsJob)\n    end\n  end\nend\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/bibendi/schked. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the Schked project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/schked/blob/master/CODE_OF_CONDUCT.md).\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbibendi%2Fschked","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbibendi%2Fschked","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbibendi%2Fschked/lists"}