自動化フローが、判断やデータ、確認がなければ先に進めない段階に達することがあります。たとえば、重要な操作を確定する前に承認が必要な場合や、人だけが提供できる情報を待つ場合です。そのようなとき、システムは現在の実行を止めるだけでなく、復旧可能な状態を保持し、何が不足しているのかを明確にする必要があります。
PHPの自動化フローを一時停止・再開する設計では、プロセスの状態と処理の実行を切り分けます。一時停止は意図的かつ永続的で、監査可能でなければなりません。再開時には、プロセスが引き続き有効であることと、適用済みの副作用が繰り返されないことを確認します。これはレビューキューの設計とは異なります。ここで重視するのは、フローのライフサイクルと安全な継続です。
一時停止・待機・失敗を区別する

処理が進まないからといって、すべてが一時停止中とは限りません。APIの応答がまだない状態は外部応答待ちです。ネットワークエラーなら再試行が妥当な場合があります。回復不能な例外が発生した場合は、プロセスを失敗として終了できます。一方、意図的な一時停止とは、フローが既知の境界に達し、続行または終了のために明示的な条件を必要としている状態です。
状況ごとに異なる状態を使うことで、運用上の誤った判断を防げます。承認待ちのアクションを再試行すると、不要なリクエストを繰り返す可能性があります。正当な一時停止を失敗として扱うと、不適切なアラートや復旧ポリシーが発動するおそれがあります。少なくとも、実行中、外部応答待ち、介入が必要、完了、キャンセル済み、失敗の状態を個別に定義してください。業務上、一時停止を一定期間後に無効にする必要がある場合は、有効期限も設定します。
一時停止を導入する前に、何がきっかけとなり、誰が解決できるのかを具体化してください。応答が届けば自動的に完了する保留タスクなら、必ずしも人の介入は必要ありません。一方、金銭、法務、アクセス権、セキュリティに影響する判断には、人の介入が必要な場合があります。この区別によって、誰が操作できるか、どの証跡を保存するか、誰も応答しなかった場合にどうするかが決まります。
状態と再開位置を永続化する
プロセスは、PHPのリクエスト終了後、ワーカーの再起動後、サービスの新バージョンへの更新後も存続できなければなりません。安定した識別子、現在の状態、到達したステップ、一時停止の理由、必要なデータへの参照、関連するタイムスタンプを永続ストレージに保存します。必要に応じて、誰がプロセスを一時停止または解決したか、どの判断が下されたかも記録します。
「承認待ち」のようなメッセージだけを保存するのは避けてください。それだけでは、どの実行が停止しているのか、どのステップを続行すべきか、データが変更されたかどうかが分かりません。代わりに、再開の妥当性を検証するのに十分なコンテキストを持たせ、一時停止をプロセスモデルの一部として表現します。可能な限り、機密情報を不必要に複製せず、その情報への参照を保持してください。情報の性質に応じたアクセス制御と保持期間も適用します。
許可される状態遷移を定義し、サーバー側で検証します。たとえば、介入が必要なプロセスは実行中、キャンセル済み、または期限切れに移行できますが、完了したプロセスを通常のリクエストで再び実行中に戻すべきではありません。PHP関数で遷移を検証できますが、そのルールはインターフェースだけでなく、データベース上でも並行処理に対して保護する必要があります。
プロセスの記録と実行を分離する
プロセスを続行すべきだと記録することと、そのステップを実行することは関連していますが、同じ操作ではありません。状態を更新した後、処理を開始する前にプロセスが終了すると、フローが停止したままになる可能性があります。状態遷移を保存する前に処理を開始すると、再実行によって同じステップが重複するおそれがあります。永続化された状態から未処理の作業を復旧できるよう、両者の連携を設計してください。
一般的な方法の一つは、トランザクショナル・アウトボックスパターンなどを使い、状態遷移と続行指示を同じデータベーストランザクションで保存することです。別のワーカーがその指示を読み取り、次のステップを実行します。具体的な選択はアーキテクチャによって異なります。重要なのは、Webリクエストが稼働し続けることに頼らず、未処理の作業を検出して復旧できるようにすることです。
外部への副作用には、さらに注意が必要です。ローカルトランザクションだけでは、送信済みのメール、確定済みの請求、または別サービスが受け付けたリクエストを取り消せません。送信先が対応している場合は各ステップに冪等性キーを用い、次へ進む前に結果を記録します。また、安全に再実行できない操作については、照合や補償処理を検討してください。結果が分かる前にステップを完了扱いにしてはいけません。
再開・キャンセル・期限切れを制御する
再開操作では、現在の状態、リクエストした人の本人確認と権限、必要な条件が満たされていることを検証します。権限のある人にボタンを表示するだけでは不十分です。リクエストを受け取った際に、サーバー側ですべてを再検証する必要があります。判断に理由や追加データが必要な場合は、それらを検証し、解決内容の一部として保存します。
キャンセルと期限切れも、記録を削除するのではなく、明示的な状態遷移として扱います。キャンセル時には、新たなステップを実行できないようにし、すでに発生した副作用のうち取り消せないものがあるかを明確にします。期限切れ後の動作も定義してください。プロセスを終了するのか、再度介入を求めるのか、別のアクションへ引き継ぐのかを決めます。動作は業務ルールに応じて定め、運用担当者が把握できるようにする必要があります。
リクエストの重複や競合は日常的に起こります。ユーザーが二度クリックしたり、二人の担当者がほぼ同時に操作したりすることがあります。条件付き更新、ロック、またはバージョン管理を使い、有効な遷移が一つだけ適用されるようにしてください。二度目のリクエストには、現在の状態に沿った結果を返し、副作用を再実行してはいけません。重複を識別できるよう、操作IDまたは冪等性キーを保存します。
一時停止の理由を明確にし、検証可能にする
運用画面では、プロセスが停止している理由、保留中のステップ、不足している情報、操作可能な担当者、各選択肢の結果を説明します。曖昧なボタンや、承認・データ修正・続行を一つにまとめた操作は避けてください。判断に必要な情報だけを、役割に応じて制限されたアクセスで提示します。状態遷移の履歴があれば、正当な待機と、停止したままのプロセスや設定ミスを見分けられます。
外部への副作用の前後で中断が発生するケースを含めて、フローをテストしてください。再起動しても一時停止状態が失われないこと、再開を繰り返してもアクションが重複しないこと、キャンセルによって後続のステップが実行されないことを確認します。停止中のデータ変更、権限の取り消し、期限切れ、遅延した応答、同時に届く二つのリクエストもテスト対象に含めてください。ログとアラートも確認します。シークレットを漏らすことなく、プロセスを特定して次のステップを理解できる内容にしてください。
動作を決めるためのチェックリスト

- 待機:外部からの応答を待っており、時間制限と復旧方法が定義されていて、応答が届けばシステムが自動的に続行できる。
- 介入のため一時停止:後続のステップを実行する前に、人による明示的な判断またはデータが必要である。
- 再試行:一時的な障害が発生し、ステップを安全に繰り返せるか、冪等性によって保護されている。
- 終了:有効な続行方法がない、またはプロセスが完了、キャンセル、期限切れ、もしくは回復不能な失敗に至った。
フローをデプロイする前に、各状態遷移が許可されていること、状態が永続化されること、実行済みの副作用が繰り返されないこと、チームが一時停止を解決する方法を把握していることを確認してください。何を、どのデータを使い、どの条件で再開するのか答えられないなら、そのプロセスにはまだ安全な再開位置がありません。



