【Ruby】Timers を使って定期実行する
2022/07/28
スクリプト内でとある処理を一定の間隔で繰り返し実行したい時、すぐ思いつくのは loop と sleep を使う方法
しかし、これだと処理の実行時間分ズレが発生する
sleep.rb
loop do
puts Time.now
# 少し時間が掛かる処理
[*1..5000000].map(&:to_s).count
sleep 60
end
$ ruby sleep.rb
2022-07-25 22:12:22 +0900
2022-07-25 22:13:26 +0900
2022-07-25 22:14:28 +0900
2022-07-25 22:15:29 +0900
2022-07-25 22:16:31 +0900
2022-07-25 22:17:33 +0900
2022-07-25 22:18:35 +0900
2022-07-25 22:19:36 +0900
2022-07-25 22:20:38 +0900
2022-07-25 22:21:40 +0900
どうにかならないかと探してみたら、それを解決する timers という Gem を見つけた
timers.rb
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'timers'
end
timers = Timers::Group.new
timers.every(60) do
puts Time.now
# 少し時間が掛かる処理
[*1..5000000].map(&:to_s).count
end
loop { timers.wait }
$ ruby timers.rb
2022-07-25 22:13:20 +0900
2022-07-25 22:14:20 +0900
2022-07-25 22:15:20 +0900
2022-07-25 22:16:20 +0900
2022-07-25 22:17:20 +0900
2022-07-25 22:18:20 +0900
2022-07-25 22:19:20 +0900
2022-07-25 22:20:20 +0900
2022-07-25 22:21:20 +0900
2022-07-25 22:22:20 +0900
しっかり60秒ごと実行されている
サンプルコードとしてわかりやすいように今回は every メソッドを使ったが、これは1回目の処理も60秒後に実行される
1回目の処理はすぐに実行して欲しい場合は now_and_every メソッドを使うと良い