Painless Cron jobs in Crystal using Schedule

whenever gem for scheduling tasks in their projects, so do we and with ‘whenever’  scheduling tasks become so effortless that we absolutely loved it. Recently we have been deploying Crytal apps to production and Kemal is our framework of choice. During the process, we felt the urge to have something similar to whenever in Crystal for cron jobs and that’s when we discovered Schedule – a Crystal shard that provides a clear DSL to write periodic or scheduled tasks and there was no turning back.

Getting started

Add Schedule to your `shard.yml` file
dependencies:
  schedule:
    github: hugoabonizio/schedule.cr
you are all set to schedule your tasks, all you gotta do is require the schedule module as require "schedule"

Examples

Schedul’s API defines 2 important methods, .every and .after for periodic and scheduled execution of tasks respectively.
Periodic execution
For running a task periodically we have to pass in a valid interval as well as a block to the .every method. For example,
require "schedule"
Schedule.every(3.seconds) do
  puts "I run every 3 seconds"
end
will print the message on every 3 seconds. Similarly
require "schedule"
Schedule.every(1.hour) do
  ClassName.hourly_job
end
will call the class method hourly_job every 1 hour
Scheduled execution
For scheduling tasks to run sometime in the future we can make use of the after method.
require "schedule"
# Execute a task after X interval
Schedule.after(10.seconds) do
  puts "I am going to run after 10 seconds"
end
Stop and Retry jobs
Call Schedule.retry to retry a task and Schedule.stop to stop the executing a task
MAX_COUNT = 3
Schedule.every(10.seconds) do
  count = get_count
  Schedule.retry if count == 0
  Schedule.stop if count >= MAX_COUNT
end
 Exception handlers
We can use Schedule.exception_handler to set an exception handler in our tasks
require "schedule"
Schedule.exception_handler do |ex|
  puts "Exception recued! #{ex.message}"
end
Schedule.every(100.milliseconds) do
  raise "I'm an Exception"
end
it is also possible to pass a proc to `Schedule.exception_handler` directly to set the exception handler
handler = ->(ex : Exception) { puts "Exception recued! #{ex.message}" }
Schedule.exception_handler = handler
schedule.cr is still in the early stages of development and many options that we are familiar with using whenever – like running tasks on a specific day of the week are not available yet but are coming soon.  Happy Hacking <3]]>