How do I use Rails clockwork gem to run rake tasks

2019-02-08 20:53发布

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

3条回答
Emotional °昔
2楼-- · 2019-02-08 21:23

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
查看更多
走好不送
3楼-- · 2019-02-08 21:35

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

查看更多
Root(大扎)
4楼-- · 2019-02-08 21:43

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

查看更多
登录 后发表回答