クローラーをRailsで作っているものです
アプリの具体的な機能としては
- クローラーの実行(データの収集)
- クローラーで集めてきた情報をDBに格納
- DBに格納したデータのソート、フィルタリング表示
といったシンプルなものです
このうちクローラーをActiveJobとSidekiqで実行しているのですが、二重で実行されるのを防ぐため、Jobの実行時にtmp/pids/LOCK.pidファイルを作り、そのファイルがすでにあるかどうかを見てからJobを走らせるようにしています
ruby
1# crawl_controller.rb 2 3before_action :check_lockfile_before_crawl 4 5def check_lockfile_before_crawl 6 if File.exists?(LOCKFILE) 7 pid = 0 8 File.open(LOCKFILE, "r") do |f| 9 pid = f.read.chomp!.to_i 10 end 11 if exist_process(pid) 12 flash[:danger] = "現在クローリング中です。クローリングを実行する場合は現在のクローリングが終了した後にやり直してください" 13 else 14 flash[:danger] = "プロセス途中で死んだタスクがあります" 15 end 16 redirect_to root_path 17 return 18 end 19 end 20 21def exist_process(pid) 22 begin 23 gid = Process.getpgid(pid) 24 true 25 rescue => e 26 logger e 27 false 28 end 29 end
これがローカルの環境なら良いのですが、herokuだとredis系の処理がWebとは別のDyno内で走ってしまうので、自ずとpidファイルもworker-dynoの上で作成されてしまうようなのです
なので上のようなメソッドを作っても、Web-Dyno内のサーバ上にpidファイルが作成されないがゆえに意味をなさないのです........
長くなりましたが、要は
- herokuないで二重で走らないようなバックグラウンドのロジックはどのように書いたら良いでしょうか?
ということです
よろしくお願いいたします
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/19 13:05