【Ruby on Rails】決まった時間に自動で処理してくれる`whenever`の使い方!
こんばんは。早くエンジニアになりたいopiyoです。
以前rssを取得する方法について、まとめて見たのですが今日はそれの発展させたいと思います。 opiyotan.hatenablog.com
時代は変わる。そして情報も常に変わる。
だから、rss情報も常に最新の情報を自動で取得したいですよね。
そんな時に便利なのが自動で決まった時間に処理をしてくれるwhenever
というgemです。
- 毎日2時間毎にrss情報を取得する!
- 毎日朝3時にDBのバックアップを取得する!
みたいな事が出来ちゃう訳ですね。
wheneverの導入
先ずは、whenever
という定期実行するためのgem
をインストールします。
# Gemfile gem 'whenever', :require => false
そして、魔法のbundle install
$ bundle install
次にやるのが、whenever
の設定を記述するファイルを作成します。
これはコマンドが用意されています。
$ bundle exec wheneverize . [add] writing `./config/schedule.rb' [done] wheneverized!
すると、schedule.rb
というファイルが出来上がります!
# config/schedule.rb # Use this file to easily define all of your cron jobs. # # It's helpful, but not entirely necessary to understand cron before proceeding. # http://en.wikipedia.org/wiki/Cron # # Example: # # set :output, "/path/to/my/cron_log.log" # # every 2.hours do # command "/usr/bin/some_great_command" # runner "MyModel.some_method" # rake "some:great:rake:task" # end # # every 4.days do # runner "AnotherModel.prune_old_records" # end # # Learn more: http://github.com/javan/whenever
ここに定期実行する為の処理を書いていきますよー
schedule.rbの書き方
今回は、動作確認までしたいので1分毎にHelloWorld
を出力するrake
タスクを呼び出す処理を設定します。
# config/schedule.rb # cronログを吐き出す場所 set :output, File.join(Whenever.path, "log", "cron.log") # ジョブの実行環境の指定 set :environment, :development # 1分毎に`HelloWorld`を出力する every 1.minutes do begin rake "rss:hello" rescue => e raise e end end
# lib/tasks/rss.rake namespace :rss do task :hello => :environment do rss_hello = RssImport.new rss_hello.hello end end
# lib/rss_import.rb class RssImport def hello puts "HelloWorld" end end
これで準備は完了です!
wheneverを実行する
先ずは、設定ファイルの記述にミスが無いかどうかチェック!
エラーになる
$ bundle exec whenever bundler: failed to load command: whenever (/Users/taku/.rbenv/versions/2.4.1/bin/whenever) NameError: undefined local variable or method `import' for #<Whenever::JobList:0x007fb7fba35330>
こんなエラーが出た時は、設定ファイルをもう一度見直してください。
私はrake
タスクを定義する場所を""
で囲っていなかったので最初ずっとエラーになってました。
他の問題としては、rake
タスクを設定しているファイルが読めていない可能性があるのでschedule.rb
の最初にrequire "/path/to/config/environment.rb"
を定義してみてください。
成功する
成功すると、こんなメッセージが表示されます。
$ bundle exec whenever * * * * * /bin/bash -l -c 'cd /Users/taku/rails/mapachannel && RAILS_ENV=development bundle exec rake rss:hello --silent >> /Users/taku/rails/mapachannel/log/cron.log 2>&1’ ## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated. ## [message] Run `whenever --help' for more options.
ここまで来たら実際に、これをcrontab
というXXに登録してあげます!
$ bundle exec whenever --update-crontab [write] crontab file updated
正しく設定されているかどうかは、crontab -l
コマンドでチェック出来ます!
$ crontab -l # Begin Whenever generated tasks for: /Users/taku/rails/mapachannel/config/schedule.rb at: 2018-01-18 14:21:42 +0900 * * * * * /bin/bash -l -c 'cd /Users/taku/rails/mapachannel && RAILS_ENV=development bundle exec rake rss:hello --silent >> /Users/taku/rails/mapachannel/log/cron.log 2>&1' # End Whenever generated tasks for: /Users/taku/rails/mapachannel/config/schedule.rb at: 2018-01-18 14:21:42 +0900
なんかどのサイトを確認方法はcrontab -e
って書かれてるのだけど、-e
にするとvi
が開くから良くないと思うのだけど。
間違えて-e
してしまった場合は慌てずに、esc + :q!
で閉じれます!
間違えて設定してしまった場合は、これで
$ bundle exec whenever --clear-crontab
定期実行されているかチェック
最後に1分間毎にHelloWorld
が呼ばれているかチェックします。
logを見て見ましょう!
$ tail -f log/cron.log HelloWorld ・ ・ ・
tail -f
とするとリアルタイムにログを見る事が出来ます。
1分間毎にHelloWorld
が増えて表示されれば成功してますね。