rails (ruby) で forever 的なことがやりたい際のベストプラクティス


バックグラウンドのバッチ処理を rails (のサブセット: ActiveRecord などのみ使う) で記述しています。結果、
`Application#load_tasks` により `bundle exec rake`
コマンドでバッチをコマンドで実行できる状態になっていたとします。

この時に、バッチのメインループを、失敗しようが成功しようが、ある一定のインターバルを挟んだ上で、ひたすらループしたいと考えています。これは、どう実現するのがベストでしょうか?

似たようなことを実現する上で、有名なツールとして `whenever` がありますが、これは cron
による定期実行をサポートするツールであって、「秒単位でインターバルを指定しながらひたすらループしたい」という今回やりたいことは満たせないと思っています。

また、同じ系統のツールたちに、 もろもろの job queue (active_job でサポートされるような) がありますが、 redis
を前提としているものが大半であったりして、わりと、オーバーキルな気がしています。

運用でどうにかするという観点では、現在では以下のように tmux session と shell script を組み合わせています。

[code]

    tmux new-session -s セッション名 -d 'while true; do 実行したいコマンド; sleep インターバル; done'
    
[/code]

ただ、この方法は、なんというかあまり rail
にのっかっていないというか、ちょっと気をつかわないと上手く動かなかったりするので、これをよろしくやってくれるライブラリなどがあれば知りたいな、と思っています。




  * 対象のバッチ処理を Sidekiq のジョブとして定義したのちに、 sidekiq-scheduler で定期実行
  * sidekiq 自体は foreman export で、対象サーバーのサービスとして登録

に最終的に落ち着きました。




> バッチのメインループを、(中略)ひたすらループしたいと考えています。

この部分がよくわからなかったので見当違いの回答だったらすみません。

単純に無限ループするrake taskを作ってはだめでしょうか?

run_forever.rake

[code]

    namespace :my_task do
      desc "run forever"
      task 'run_forever' do
        loop do
          Rake::Task["main"].invoke
          sleep 10
        end
      end
    end
    
[/code]

実行

[code]

    $ bundle exec rake my_task:run_forever &
    
[/code]

> 失敗しようが成功しようが

というのは例外を吐くかどうか、ということでしょうか?  
それならmain rake taskで例外をキャッチしてしまえば良いと思います。

