わたしの理解しているように、Gearmanは非常に「自分のビジネスではない」アプローチを採用しています。たとえば、労働者がクラッシュしない限り、実行された仕事には介入しません。すべての成功/失敗メッセージは、Gearmanサーバー自体ではなく、クライアントによって処理されるはずです。フォアグラウンド求人
、これはすべてのsendFail()
/sendException()
およびその他のsend*()
がクライアントに送られ、それがジョブを再試行するか否かを決定するために、クライアント次第だということを意味します。再試行する必要がない場合があるため、これは意味があります。
バックグラウンドジョブでは、コールバックをリッスンするクライアントがないため、すべてのsend*()
関数が意味を失います。その結果、送信されたメッセージはGearmanによって無視されます。ジョブが再試行される唯一の条件は、ワーカーがクラッシュしたときです(exit(XX)
コマンドでエミュレートすることができます。XX
はゼロ以外の値です)。これはもちろん、あなたがやりたいことではありません。なぜなら、従業員は通常、長時間実行されているプロセスであり、失敗した各ジョブの後に再起動する必要があるプロセスではないからです。
個人的に、私はsend*()
関数への呼び出しを傍受してから、再試行のメカニズムを自分で実装する、デフォルトのGearmanJobクラスを拡張することでこの問題を解決しました。基本的には、すべての再試行関連データ(最大再試行回数、既に再試行された回数)をワークロードと共に渡し、すべてを自分で処理します。ちょっと面倒ですが、なぜGearmanがこのように動作するのか理解しています。すべてのアプリケーションロジックを処理できるだけです。
最後に、指数関数タイムアウト(またはそのタイムアウトのタイムアウト)を指定してジョブを再試行する機能に関すること。 Gearmanには遅延ジョブを追加する機能があります(protocol documentationにはSUBMIT_JOB_EPOCH
があります)。しかし、PHPの拡張機能についてはわかりませんが、Pythonモジュールはサポートしていないと思います。未来。しかし、現時点では機能していると分かっています。Gearmanに未処理のソケットリクエストを送信するだけで済みます(また指数部も実装する必要があります)。
ただし、this blog postは、SUBMIT_JOB_EPOCHの実装が拡張されないと主張しています。彼はnode.jsとsetTimeout()
を使って動作させていますが、私は他の人がunixユーティリティat
を使って同じことをするのを見てきました。いずれにせよ、Gearmanはあなたのためにそれをしません。信頼性に重点を置いていますが、すべてのロジックに集中できます。
sys.exit()はGearmanの悪い考えです。通常は、このようなジョブは永久に再試行されます(デーモンの起動時にジョブリトライを設定しない限り)。ジョブからのステータス/結果を返すだけで 'return stringvar'を実行してください。(例えば、DB行や実際の情報をキャッシュするなど) – RichVel