画面に一件しか見えない二重処理
ブラウザーが10秒で待機を諦めても、WordPressのREST処理が11秒目以降にプロバイダーから回答を受け取る場合があります。JavaScriptが同じ入力を再送すると、利用者には後から返った一つの回答だけが見えますが、外部では二つの生成が完了します。
20件の比率から利用者の意図を定義する
確認すべき比率は画面表示数ではありません。ブラウザー送信数、WordPress受領数、プロバイダー要求数、完了結果数、課金対象数を別々に数えます。20回の操作が20:40:40になったら、費用増は利用者数ではなく再試行設計が作っています。
冪等キーはHTTP要求ごとではなく、『同じAI処理を一度だけ行う』という利用者の意図ごとに一つ発行します。ボタン押下時に安全な乱数で生成し、通信の再送では同じ値を再利用し、利用者が内容を変更して新しい処理を始めたときだけ新しい値にします。
内容を保存せず冪等キーを持つ
キーへプロンプト本文やメールアドレスを埋め込む必要はありません。十分なランダム性を持つ識別子と、サーバー側に保存する処理状態、入力の一方向要約、結果の参照を組み合わせれば、内容を露出せず同一処理かを確認できます。
WordPressを重複排除の責任層にする
JavaScriptだけでボタンを無効化しても、回線切断、別タブ、モバイル再送は防げません。プロバイダーだけへ冪等性を期待すると、使用するAPIやモデルごとに挙動が変わります。この構成ではWordPressのREST入口を責任層とし、同じキーの二件目へ既存状態または既存結果を返します。
状態は少なくともreceived、running、completed、failed_retryable、failed_finalに分けます。running中の同じキーへ新しい外部呼び出しを作らず、completedなら保存方針に従って結果参照を返し、再試行可能な失敗だけ明示的な規則で次の実行を許可します。
| 試験 | ブラウザー送信 | REST受領 | 外部要求 | 期待結果 |
|---|---|---|---|---|
| 通常 | 20 | 20 | 20 | 20件完了 |
| 応答遅延で各1回再送 | 40 | 40 | 20 | 同じ20件へ合流 |
| 同じキーで同時送信 | 40 | 40 | 20 | 二件目はrunningを返す |
| 完了後に同じキーを再送 | 40 | 40 | 20 | 既存結果を参照 |
| 入力変更後に新しいキー | 20 | 20 | 20 | 別処理として完了 |
タイムアウトと失敗状態を別々に試す
導入時にブラウザーのタイムアウトを延ばし、同時に再試行を減らすと、二重送信が何で解消したか分かりません。まず現行タイムアウトのまま冪等化だけを入れ、遅延を注入して外部要求数が増えないことを確認し、その後に待ち時間と利用者向け表示を調整します。
失敗時に同じキーを永久に固定すると正当な再実行まで止まります。外部へ送る前の失敗、送信後に結果不明の失敗、明示的な拒否、完了後の応答消失を区別し、それぞれ再実行、照会、既存結果返却のどれにするか決めます。
20対20対20を本番の受入条件にする
受入試験の合格条件は、20の利用者意図に対してWordPressが20の処理所有権を作り、外部要求と課金対象完了も20になることです。ブラウザー送信だけは再送により40でも構いませんが、その増加が下流へ伝播しないことを要求します。
本番では生の入力を保存せず、冪等キー、状態遷移、要求ID、費用推定、保持期限だけを監査できる形にします。ガイドに沿ってMonitoringで通常の再送率を確認してから、異常な再試行の制御を重ねると、アプリの欠陥と保護機能の効果を取り違えません。
「RESTプロキシとJavaScript再試行による二重送信を、20件の受入試験で止める」の「二重送信の受入判定表」を、最初の実環境導入に使ってください。AI Cost Circuit Breakerを無料でダウンロードし、Monitoringから始め、期待するシグナルと戻し方を確認してから制御を有効にしましょう。