简体   繁体   中英

How do I use Rails clockwork gem to run rake tasks?

What is the syntax for calling rake tasks from clockwork? I've tried all kinds of syntax, and nothing seems to work. (I'm specifically interested in clockwork because Heroku's supporting it.)

Here's my clock.rb, using the same syntax that the whenever gem uses:

module Clockwork
  puts "testing clockwork!"
  every(30.seconds, 'Send Messages') {
    rake 'scheduler:send_messages'
    }
end

And here's my rake task in scheduler.rake:

task :send_messages => :environment do
  puts "rake task run successfully!"
end

And here's what happens when I start a clockwork process:

$ clockwork lib/clock.rb
testing clockwork!
I, [2012-07-16T14:42:58.107245 #46427]  INFO -- : Starting clock for 1 events: [ Send Messages ]
I, [2012-07-16T14:42:58.107364 #46427]  INFO -- : Triggering 'Send Messages'
attempting to run rake task!
E, [2012-07-16T14:42:58.107437 #46427] ERROR -- : undefined method `rake' for Clockwork:Module (NoMethodError)

This runs every 30 seconds. As you can see, the clock.rb is executed successfully. But I can't for the life of me figure out the syntax to run a rake task. The clockwork readme is no help, unfortunately:

https://github.com/tomykaira/clockwork

rake is not a method, so you can't invoke it like that here.

You can either shell out and invoke it, something like

every(30.seconds, 'Send Messages') {
  `rake scheduler:send_messages`
}

or rather invoke a new detached process using the heroku API. This is my preferred method right now:

Heroku::API.new.post_ps('your-app', 'rake scheduler:send_messages')

Heroku::API is available from heroku.rb: https://github.com/heroku/heroku.rb

You can pass in a block to every that executes your rake task:

every(1.day, "namespace:task") do
  ApplicationName::Application.load_tasks
  Rake::Task['namespace:task'].invoke
end

You can add the following method to your clock.rb file:

def execute_rake(file,task)
require 'rake'
rake = Rake::Application.new
Rake.application = rake
Rake::Task.define_task(:environment)
load "#{Rails.root}/lib/tasks/#{file}"
rake[task].invoke
end

and then call

execute_rake("your_rake_file.rake","your:rake:task")

in your handler

Invoking the task using Rake::Task['...'].invoke works well the first time, but the task need to be reenabled to be invoked again later.

    ApplicationName::Application.load_tasks

    module Clockwork do
        every(10.minutes, "namespace:task") do
          Rake::Task['namespace:task'].invoke
          Rake::Task['namespace:task'].reenable
        end
    end

Otherwise the task will be invoked the first time, but no more after that until the clockwork process is restarted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM