Как использовать Rails clockwork gem для запуска задач рейка?

Каков синтаксис для вызова задач рейка из часового механизма? Я пробовал все виды синтаксиса, и ничего не работает. (Меня особенно интересует часовой механизм, потому что Heroku поддерживает его.)

Здесь мой clock.rb, используя тот же синтаксис, что и всякий раз, когда используется камень:

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

И вот моя задача rake в scheduler.rake:

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

И вот что происходит, когда я запускаю часовой механизм:

$ 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)

Это выполняется каждые 30 секунд. Как вы можете видеть, clock.rb выполняется успешно. Но я не могу, чтобы жизнь меня определяла синтаксис для запуска грабли. К сожалению, часовая версия readme не помогает:

https://github.com/tomykaira/clockwork

Ответ 1

rake не является методом, поэтому вы не можете его вызывать здесь.

Вы можете либо выложить и вызвать его, что-то вроде

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

или, скорее, вызвать новый отсоединенный процесс, используя API-интерфейс heroku. Это мой предпочтительный метод прямо сейчас:

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

Heroku:: API доступен от heroku.rb: https://github.com/heroku/heroku.rb

Ответ 2

В файл clock.rb можно добавить следующий метод:

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

а затем вызовите

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

в вашем обработчике

Ответ 3

Вы можете пройти в блок до every, который выполняет вашу команду rake:

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