Search code examples
ruby-on-railsrubyherokuclockwork

Dynamically generating a clock file (or any file) during Rails deployment on Heroku


I use the Clockwork gem to schedule jobs on my Rails app deployed with Heroku.

For the unfamiliar, it basically reads from a clock.rb file in your app root..

# config.rb

# Schedule every Monday @ 13:00 UTC
every(1.week, "some description", at: "Monday 13:00", tz: "UTC"){
  `rake clock_tasks:my_task`
}

... and there's a dedicated Dyno that runs the clock process.

# Procfile
...
clock: bundle exec clockwork clock.rb
...

Well what if I didn't want to hard-code the clock file? I'd love to be able to generate the clock.rb dynamically using ERB at app startup. This gives me the flexibility to schedule or not schedule certain tasks based of Environment configurations, etc...

  1. Does Heroku allow you to "write" a file at any point to your local filesystem so I can generated and write the clock.rb file during an initializer step?

  2. Is there a way to delay the execution of starting the dyno with the bundle exec command until AFTER I've created the clock.rb file? I could start off with a fake/empty file and then populate a new one during initializer, but I'd still need a way for clock to pick it up again by restarting the bundle exec clockwork... command.

Any other creative solutions appreciated.

Thanks!


Solution

  • You config.rb is just Ruby. There is no need for ERB, plain Ruby in combination with ENV variables should be enough to solve you problem:

    # Schedule every `ENV['schedule_time']` (with fallback if empty)
    schedule_time = ENV['schedule_time'].presence || 'Monday 13:00'
    every(1.week, "some description", at: schedule_time, tz: "UTC") {
      `rake clock_tasks:my_task`
    }
    

    Or you can write something like this:

    if ENV[`foo`]
      # config bar
    else
      # config baz
    end
    

    You may want to read Configuration and Config Vars about how to set and read environment variables on Heroku.