FreeCamp

wheneverを用いてバッチ処理の実装

バッチ処理という言葉は聞いたことありますか?
バッチ処理とは一定の時間感覚で行う処理のことです。
1分起きや1時間起き、1日起きに何かしらの処理を行いたい時等に利用します。
データを収集したり削除したり、投稿したりアナウンスしたりと用途は様々です。
今回はRailsのGem wheneverを用いてバッチ処理を実装します。

目次

  1. cronとは
  2. Gem wheneverとは
  3. 実装

1. cronとは

まず始めにバッチ処理をする上で避けては通れないのがcronです。
バッチ処理と調べると必ずcronという言葉が検索結果に出てきます。
cronはUNIX系(LINUXやOS X)に備わっている常駐プログラム(デーモン)の一種で、定期的に処理を実行してくれるというプログラムです。
cronが定期実行を行ってくれるものという認識で良いです。

さて、cronがUNIXのマシンに備わっているというのはわかりましたが、
そのcronをどうやって動かすのかが重要です。
cronを実行するために必要なコマンドが「crontab」です。
crontabを利用すればターミナル上で定期実行することが可能です。

では試しにcrontabを利用してみましょう。

$ crontab -e // cronの設定

上記コマンドを実行するとエディターが開かれます。
そのエディターにスケジュールと実行したいコマンドを書いていきます。

* * * * * <実行したいコマンド> // 分 時 日 月 曜日 <コマンド>

毎週土曜の朝8時20分にlsコマンドを実行したい場合は以下のようになります。

20 8 * * 6 ls

また、一分おきにlsコマンドを実行したい場合は以下のようになります。

*/1 * * * * ls

エディターを保存して抜けて「crontab: installing new crontab」と表示されたら定期実行の処理が走ります。
1分過ぎた頃に何かしらキーを打つと「You have new mail in /var/mail/ユーザー名」が表示されると思います。
このパスの中身を見てみましょう

$ cat /var/mail/ユーザー名

定期実行がされているのが確認できたでしょうか?
設定したcronを削除しましょう。

$ crontab -r // 設定したcronを削除します

また、cronでよく使われるコマンドをまとめておきます。

$ crontab -e // cronの設定
$ crontab -l // 設定したcronの閲覧
$ crontab -r // 設定したcronの削除

2. Gem wheneverとは

次にGem wheneverについて説明していきます。
Gem wheneverは一言で言うと「crontabを管理するGem」です。
Railsアプリケーション内で、処理とスケジュールを管理してくれます。
それでは実際にRailsアプリケーションに導入してみましょう。

3. 実装

アプリケーションの基盤を作成するまではコマンドやエディタの記述のみで、説明は省きます。

$ rails new rails_whenever
$ cd rails_whenever
$ rails g model Post title:string body:text
$ rails db:migrate

Postモデルのみ作成しました。
投稿という処理を定期的に行っていきたいと思います。
それでは早速Gem wheneverを導入していきます。

...追記
gem 'whenever', require: false // require: falseとするのは
このGem自体がRailsアプリケーションに反映するものではなく、
ターミナル(言わばOS)に反映させるものだからです。
$ bundle // bundle installコマンドは省略できます。
$ bundle exec wheneverize . // config/schedule.rbを作成します。
このファイルにスケジュールとタスクを記述します。

wheneverはcommand, rake, runner, scriptなどスケジュール可能ですが、
今回はよく使われる手軽なrunnerを利用します。

...追記
env :PATH, ENV['PATH'] # 絶対パスから相対パス指定
set :output, 'log/cron.log' # ログの出力先ファイルを設定
set :environment, :development # 環境を設定


every 1.minute do // 1分おきに実行
  runner "Post.create_test" // Postモデルのcreate_testアクションを実行
end
def self.create_test // レシーバ指定なし
  Post.create(title: "test", body: "testtest")
end

ここまで記述したら残りはcronの設定のみです。

$ bundle exec whenever --update-crontab // 実行

実際に動いているかどうか、rails consoleで確認しましょう。

$ rails c // rails consoleは省略できる
irb(main):001:0> Post.all

どうですか?1分おきに投稿が増えているのが確認できましたか?
最後に設定したcronを削除します。

$ bundle exec whenever --clear-crontab
もしくは
$ crontab -r

4. 最後に

バッチ処理はどうでしたか?
内容を理解するのは大変だと思いますが、記述も実行コマンドも多くなく、
手軽に組み込める処理だと思います。
ぜひ皆さんのRailsアプリケーションに導入してみてください。

ps.
運用しないのであればcron消すのを忘れずに。。
crontab -r もしくは bundle exec whenever –clear-crontab