Playwright Worker Queueにおけるルーティングキーとプロファイルリースの活用

TimeoutError: page.click failed のような Playwright のエラーは、しばしば「嘘」をついています。

そのエラーは、スクリプトが何を見たかを伝えているに過ぎません。そもそも、なぜスクリプトが間違った場所にいたのかという理由は教えてくれないのです。

かつて、2つのワーカーが同じアカウントのジョブを同時に取得してしまうケースを目にしたことがあります。両方のワーカーが、全く同じブラウザプロファイルを同時に開いてしまったのです。一方のワーカーは読み込みの遅いページで待機しており、もう一方のワーカーはリトライを行い、セッション状態を変更したことで、結果として失敗を引き起こしました。

問題はコードではありませんでした。問題はキューにありました。

ほとんどのワーカーキューは、ステートレスなジョブ向けに設計されています。

  • ジョブを取得する
  • 空いているワーカーを見つける
  • タスクを実行する
  • 完了としてマークする

これはスクリーンショットの撮影や API コールの実行には適していますが、ブラウザ自動化においては失敗します。

ブラウザプロファイルはステートレスではありません。それは一つのアカウント、一つのプロキシ、そして一つのセッション状態に紐付いています。最も速いワーカーが、常に最適なワーカーであるとは限らないのです。

安全にスケールさせるには、ロジックを転換する必要があります。

「どのワーカーが空いているか?」と問うのではなく、

「今、どののアカウント環境を使用するのが安全か?」と問うべきです。

これには、以下の3つのレイヤーで対処できます。

  1. Routing Keys どのワーカーにも、あらゆるジョブを勝手に取得させないでください。プロファイルIDまたはアカウントIDに基づいたルーティングキーを使用します。これにより、特定のプロファイルに同時に触れるワーカーを常に1つだけに制限できます。

  2. Profile Leases キューの「クレーム(取得)」は、ワーカーがジョブを所有することを意味します。プロファイルの「リース」は、ワーカーが特定のブラウザプロファイルを一定時間使用することを許可されることを意味します。ハートビート(生存確認)付きのリースを使用してください。タスクが予想以上に長引く場合、ワーカーはリースを更新する必要があります。

  3. Fencing Tokens 古い(Stale)ワーカーは危険です。ネットワークの遅延によってリースを失ったワーカーが、そのまま実行を続けてデータを書き込もうとする可能性があるからです。フェンシングトークンを使用してください。ストレージ層は、古いトークンからの書き込みをすべて拒否するように設計すべきです。

また、「レディネス・ゲート(readiness gate)」も追加する必要があります。Playwright を起動する前に、以下を確認してください。

  • アカウントは一時停止されていないか?
  • プロファイルに人間による確認が必要ではないか?
  • プロキシのリージョンはジョブの要件と一致しているか?

ブロックされたジョブが、必ずしも失敗したジョブとは限りません。それは単に、適切なコンテキストを待っているだけのジョブであることが多いのです。

スピードだけを優先するキューを作るのはやめましょう。アカウントの状態を優先するキューを構築してください。

Source: https://dev.to/web4browser/using-routing-keys-and-profile-leases-in-playwright-worker-queues-a53