Herokuでcron?もう古いかも、それ

結論から言いますと、今日現在ではまだ古くありません。まだアドオンもありますし。日時cron、無料です。

でもCedar Stackがデフォルトになる頃には過去の遺物扱いになるかもしれません。なぜならば、Cedar StackからProcess modelが導入されました。
ProcfileでClockwork gemをつかったclockプロセスを指定してやることにより、cronを使わずともタスクスケジューリングできてしまうのです。

すでにherokuを使ったことがある人でしたら「clockプロセス動かすって、dyno増やすの?料金かからないの?」と思うかもしれません。実は2011年6月1日からherokuの料金体系が変わっていて750 dyno-hoursまで無料で使えるようになっています。1dyno(=1プロセス)が1ヶ月で672-744 dyno-hoursとなるので、1dyno/月までならば無料でさらに少し余裕があります。
というわけで、通常rackアプリに使われるwebプロセスを動作させず、clockプロセスだけを動作させれば無料ですね。

ローカルでためす

clockwork を使ってみる

READMEを参照しながら、clock.rbを作成します。
とりあえず10秒毎のジョブだけ

#clock.rb
require 'clockwork'
include Clockwork

handler do |job|
  puts "Running #{job}"
end

every(10.seconds, 'frequent.job')

$ clockwork clock.rb とコマンドを実行する*1ことで、10秒毎にジョブが実行されているのが確認できると思います。

foreman から動かしてみる

Procfileを作成します。

clock: bundle exec clockwork clock.rb

$ foreman start とコマンドを実行する*2ことで、先ほどと同様のジョブがclockプロセスとして実行されるのが確認できると思います。

herokuで動かしてみる

git

gitリポジトリを作成してコミットしておきます。書くまでもないかもしれませんが、次のように。

$ git init
$ git add .
$ git commit -m 'first commit'
heroku

cedarスタックを指定してheroku-createします。そしてデプロイ。

$ heroku create --stack cedar
$ git push heroku master
$ heroku scale web=0 clock=1 # webプロセスをなくし、clockをひとつ起動する

$ heroku psで、clockプロセスが一つであることを確認。
つづいて、$ heroku logs --tailでログを確認。ローカルで動作させたときと同様、10秒毎にジョブが動作しているはず。

まとめ

cedar stackから導入されたProcess modelを利用、さらにclockプロセスでclockworkを動作させることによってherokuでdaily以外のタスクスケジューリングを無料で使えちゃいます。ただし、その場合webプロセスは止めないとお金かかりますけど。
Clockwork can be run as a singleton process for a very flexible cron replacement らしいので、いずれアドオンとしてのcronからclockプロセスを動作させる方針へとシフトしていきそうな気がします。たしかにPaaSでアプリをホスティングしてもらうことを考えると、そのほうが望ましいですね。
タスクスケジューリングができるとなにが嬉しいのかというと、毎朝前日の Rails のコミットログを自分にメールするようにできちゃうかもしれないわけです。というか、ほんとはそこまでやりたかったんですが、コミットログをまとめること、メールを送ることをどうしようか考え中。いずれそこまでを、できるだけシンプルにやりたい。

Gemfileなど説明していないものは、ソースをご参照ください。
https://github.com/marutanm/heroku-cedar-clock

*1:要、clockwork gem

*2:要、foreman gem