BackgrounDRbのWorkerオブジェクト削除タイミングについての悩み
BackgrounDRbのサンプルでよく見かけるのが以下のようなソース。
def start_background_task session[:KEY] = MiddleMan.new_worker(:class => :foo_worker, :args => "hoge") end #start_background_task.rhtmlから非同期で呼ばれるアクション def update_progress if request.xhr? worker = MiddleMan.worker(session[:KEY]) progress_percent = worker.progress_percent render :update do |page| page.call('progressPercent', 'progressbar', progress_percent) page.redirect_to(:action => 'done') if progress_percent >= 100 end end end def done MiddleMan.delete_worker(session[:KEY]) end
分かりやすい例なのだけれど、肝心な点が抜けている。
それは、「処理中にブラウザを閉じたらどうなるのか?」と言う事。
このソースだと、処理の完了後に表示されるアクションでワーカーオブジェクトの削除処理を実装している為、途中でブラウザを閉じたりするとワーカーオブジェクトが削除されなくなってしまう。
じゃあどうしよう、という事で悩んでいたのだが、タイミングよくWEB+DB PRESS 40号のRails連載記事でBackgrounDRbが紹介されていた。
記事では、ワーカーの作成時のオプションにttlとexpire_typeと言う値を指定できるとの事。
例えば以下のように書くと、最後にアクセスした時刻から300秒経過するとワーカーオブジェクトが削除されるらしい。
MiddleMan.new_worker(:class => :foo_worker, :args => "foo", :ttl => 300, :expire_type => :accessed)
キタコレと思ったものの、BackgrounDRbのソースを読んだ時にはttlとexpire_typeオプションを処理している箇所が見当たらなかった。
再度見なおしても、やっぱりない…。
記事内ではBackgrounDRbのバージョンについて何も言及されていなかったのだけれど、WEB+DB PRESSのサポートページにソースがアップされていた。このソースだと、BackgrounDRb起動時に削除用のスレッドが生成され、それがttlとexpire_typeオプションを見てワーカーオブジェクトを削除するように実装されていた。
今のBackgrounDRbの最新版は0.21だが、過去のバージョンは0.20までしかない。
どちらのバージョンにも上記の処理がなかったところを見ると、WEB+DB PRESSで使用したBackgrounDRbのバージョンはかなり古いものなのだと思う。
うーんどうしよう…。
古いバージョンに戻すのも怖いし、かと言ってそれなりに巨大化した今のBackgrounDRbを勝手に拡張して問題が起こらない自信もなし。
そもそもあって然るべきの削除用のスレッド周りの処理が何故削除されたのか、という事情も分からないからなあ。
もうちょっと調べてみよう。