2014年10月1日 星期三

在Rails利用Delayed Job與Clockwork定時執行action

話說我想要的功能是10秒鐘去檢查一次某項欄位的值,一開始把事情想的太簡單了,以為可以用什麼countdown或是timer的功能,後來才發現是和排程有關係的,雖然這兩個gem功能簡單好用,但是Delayed_JobClockwork在github的Readme也沒有很清楚,不過還是值得一看,所以特別寫這一篇來說明一下。


安裝Delayed job與Clockwork

在gemfile中加入這兩個gem

gem 'delayed_job_active_record'

gem 'clockwork'

執行bundle install,把他們安裝起來

delayed_job在排程上需要有一個jobs table來記錄排程,接著我們來產生這個table

rails generate delayed_job:active_record
rake db:migrate

為Clockwork指派任務

為什麼會需要兩個gem而不是一個呢?因為clockwork負責的是時間到的時候把任務再放入排程,他自己是沒辦法執行排程的工作的,排程的工作是由delayed job來負責的,現在在你的專案下新增一個clock.rb(也有人是放在lib裡面)。

require 'clockwork'
module Clockwork
  handler do |job|
    puts "Running #{job}"
  end

  # handler receives the time when job is prepared to run in the 2nd argument
  # handler do |job, time|
  #   puts "Running #{job}, at #{time}"
  # end
  every(10.seconds, "check_auction_times加入排程" ) { 
    ActionController::Base::ApplicationController.new.delay.check_times }
end

直接看到every那一行,10.seconds代表每10秒執行一次,後面接著是這項任務的名稱,自己可以隨意給你想要的名字,大括號內的東西是你要執行的action的位置,指定的方式是Module::Class.new.method_to_call,加上delay就是要放在排程的意思,以我的例子來看就是執行ApplicationController下面check_times這個action。


啟動Clockwork與Delayed job

打開你的console,執行下面指令


$ clockwork clock.rb
I, [2014-10-02T10:30:23.272561 #595]  INFO -- : Starting clock for 1 events: [ check_auction_times加入排程 ]
I, [2014-10-02T10:30:23.272684 #595]  INFO -- : Triggering 'check_auction_times加入排程'

還沒結束,你還要再開一個console把Delayed job也同時啟動


$ rake jobs:work
[Worker(host:nagamines-Mac-mini.local pid:606)] Starting job worker
[Worker(host:nagamines-Mac-mini.local pid:606)] Job ApplicationController#check_auction_times_without_delay (id=1230) RUNNING

這樣就搞定了,去試試你自己要的功能吧

沒有留言:

張貼留言