LoginSignup
63
58

More than 5 years have passed since last update.

Clockwork Cheat Sheet

Last updated at Posted at 2013-04-27

=====================

Clockworkは定期的な処理が簡単に実装できるライブラリです。
使い方も簡単ですが、せっかくなのでチートシートを作りました。

Clockworkはcronの代替に使えます。RubyなのでDSL記法や便利な関数が使えます。
(Railsで利用するとActionPackなど更に便利なライブラリが使えます。)

Register

定期的に処理する内容をeveryに記述します。
everyは期間、処理(ジョブ)、条件を指定します。

every([period], [job name], [options]) [{job block}]

Period

ジョブを実行する期間(間隔)を指定します。
期間の単位はです。

[数字].[単位のキーワード]で設定します。

キーワードの単数形と複数形はエイリアスです。
(数字が1なら単数形、2以上なら複数形を使うとよいです。)

List

単位 単数形 複数形 Source
second seconds period * 1
minute minutes period * 60
hour hours period * 3600
day days period * 86400
week weeks period * 604800

Example

every(4.seconds, '4.seconds.job')  # 4秒間隔
every(2.hours, '2.hours.job')      # 2時間間隔
every(1.day, '1.day.job')          # 1日間隔

Options

ジョブを実行する条件を指定します。
条件にはatifがあります。

at

何時にジョブを実行するか指定します。

'[時]:[分]' で設定します。

(時間は複数の指定ができます。また、曜日を指定できます。)

List

指定 period at 処理される時間
時分 1.day '01:30' 1時30分
0省略 1.day '1:30' 1時30分
毎時 1.hour '**:30' 毎時30分
複数 1.hour ['12:00', '18:00'] 12時と18時
曜日 1.week 'Saturday 12:00' 土曜日の12時
Week day list

曜日は省略を合わせると4パターンあります。
エイリアスなので好きなキーワードを使えます。

曜日 指定1 指定2 指定3 指定4
sunday Sunday sun Sun
monday Monday mon Mon
tuesday Tuesday tue Tue
wednesday Wednesday wed Wed
thursday Thursday thu Thu
friday Friday fri Fri
saturday Saturday sat Sat

Example

every(1.day, 'job', at: '01:30')             # 1時30分
every(1.day, 'job', at: '1:30')              # 1時30分
every(1.hour, 'job', at: '**:30')            # 毎時30分
every(1.hour, 'job', at: ['12:00', '18:00']) # 12時と18時
every(1.week, 'job', at: 'Saturday 12:00')   # 土曜日の12時
Anti-pattern

periodatの組合せに注意が必要です。

例では毎時30分の指定ですが期間が1日間隔なので、Clockworkが12時にスタートすると
初回は12時30分に実行されて、次回は翌日の12時30分に実行されます。

every(1.day, 'job', at: '**:30') # 毎時30分では実行しない!

if

ジョブを実行する条件を指定します。

lambda { |t| [式] } で設定します。

(式に時間が不要なら`|t|`を`|_|`に変更します。)

Example

月初や月末で指定できます。

every(1.day, 'job', at: '9:00', if: lambda { |t| t.day == 1 }) # 月初の9時
every(1.day, 'job', at: '21:00', if: lambda { |t| t.day == Date.new(t.year, t.month, -1).day }) # 月末の21時
Practical

処理の失敗をモニタリングしてアラートを通知することが簡単に実装できます。
(Sidekiqを利用すると非同期処理の実装が簡単です。)

every(1.minute, 'Failure::Worker', if: lambda { |_| Failure.all.count > 0 }) do 
  Failure::Worker.perform_async
end

Job

実行するジョブを指定します。
(ジョブはSidekiqなどを利用が必要です。)

every(period, [job name], options) [{job block}] で設定します。

{job block}に記述する方法と[job name]を利用してhandlerに記述する方法があります。

Job block

期間、条件、ジョブをまとめて記述できます。

every(1.second, '1.second.job') do
  puts "Running job"
end

handler

期間、条件とジョブを分けて記述できます。

handler do |job|
  case job
  when '1.second.job'
    "Running job"
  end 
end

every(1.second, '1.second.job')

Example

Practical

Railsの例ですが、環境(開発や本番)に合わせて制御できます。

clock.rb
require_relative '../config/boot'
require_relative '../config/environment'

require 'clockwork'
include Clockwork

case Rails.env
when 'development'
  every(1.second, 'seconds.job') do
    puts "Running development job"
  end
when 'staging'
  every(1.minute, 'minutes.job') do
    puts "Running staging job"
  end
when 'production'
  every(1.hour, 'hours.job') do
    puts "Running staging job"
  end
else # Unknown
  every(1.day, 'days.job') do
    puts "Running production job"
  end  
end

# Shared jobs
every(1.week, 'weeks.job') do
  puts "Running common job"
end

Anti-pattern

Rubyはマルチスレッドの処理をしないとジョブが期待した時間に実行されません。

例では1秒間隔と10秒間隔のジョブを実行します。しかし、10秒間隔のジョブで
20秒の待ちが発生するので1秒間隔のジョブも20秒待たされます。

every(1.second, '1.second.job') {sleep 0}
every(10.seconds, '10.seconds.job') {sleep 20}

Tips

cronとは違いworkerの引数にオブジェクトを指定できるところがとても便利です。
(もちろんハッシュも使えます。)

every(1.minute, 'Time::Worker') do 
  Time::Worker.perform_async(Time.now, {foo: :bar})
end
63
58
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
63
58