Gearman::Clientのdispatch_backgroundで非同期Job実行

JobQueueを使うと、時間のかかる処理でブロックせずにクライアントに応答を返せるというのと、メモリの食うモジュールを別プロセスに分離できて、アプリケーションサーバー側の1プロセスのサイズが小さくできるために、アプリケーションサーバーでリクエストを多く捌けるようになります。

Gearman::Clientのdispatch_backgroundでTaskをdispatchすれば、そのTaskはバックグラウンドで実行されます。ただ、Gearman::Clientを使う場合、Jobが刺さった場合に、そのJobがtimeoutせずにJobServerにJobが残ってしまいます。

Gearman::WorkerとGearman::Clientの両方でtimeoutが設定できるように書いてあるのですが、Gearman::Clientのほうはソースに明示的にtimeoutをサポートしていない旨、書かれています。Gearman::Workerのほうは明示的には書いていませんがtimeoutがききません。

Jobのサイズが小さい事を想定すれば、仮にJobが残ってしまっても、実際の運用上は、大した問題にはならないかもしれない。といっても、Jobが頻繁に刺さるようであれば、それはそれで問題だけれど。

timeoutをサポートするには、Gearman::Client::Asyncを使えば大丈夫なようです。実際にstatusコマンドで確認すると、こちらのほうはGearman::Client::AsyncにGearman::Taskのtaskを登録する際にそのタスクにtimeoutを設定しておけば、ちゃんとtimeout処理が実行され、on_failのcallback関数がcallされて、jobはqueueに残らないようになっていました。

少し触ってみた感じでは、実用上はGearman::Clientのdisptach_backgroundだけでもいいのかなぁという気はしました。今のところ、Gearman::Client::Asyncが適しているというケースが殆ど思いつきませんでした。Gearman::Client::Asyncが必要なケースが思いつかないのは、まだ理解が足りないからかもしれませんが...