コンテンツへスキップ

ワークフローの期限

ワークフローには期限を設定できます。実行中のワークフローが指定された時間内に完了しない場合、Queuetyはそれを失敗としてマークし、任意でハンドラーを呼び出します。一時停止中、シグナル待ち、または他のワークフロー待ちのワークフローは、待機中に期限切れになりません。期限は、長時間稼働するwp queuety workプロセスによって約1分ごとに確認されます。--onceワーカーやWP-Cronの代替処理では確認されません。これは、無期限に実行されるべきでない長時間稼働のワークフローに対するデッドマンスイッチとして機能します。

期限の設定

ワークフロービルダーでmust_complete_within()を使い、許容する最大実行時間を設定します。期限を超過したときに実行するハンドラーを登録するには、on_deadline()を使います。

PHP
use Queuety\Queuety;

Queuety::workflow( 'data_import' )
    ->then( FetchDataHandler::class )
    ->then( TransformDataHandler::class )
    ->then( LoadDataHandler::class )
    ->must_complete_within( hours: 24 )
    ->on_deadline( ImportTimeoutHandler::class )
    ->dispatch( [ 'source' => $url ] );

must_complete_within()メソッドは、合計される名前付きパラメーターを受け取ります。

PHP
->must_complete_within( hours: 2, minutes: 30 )  // 2.5 hours
->must_complete_within( days: 1 )                 // 24 hours
->must_complete_within( seconds: 3600 )           // 1 hour
->must_complete_within( days: 1, hours: 12 )      // 36 hours

期限ハンドラー

on_deadline()ハンドラークラスはhandle( array $state ): voidメソッドを実装する必要があります。ワークフローの公開状態(_で始まらないすべてのキー)が渡されます。

PHP
class ImportTimeoutHandler {

    public function handle( array $state ): void {
        // Alert the team.
        wp_mail(
            'ops@example.com',
            'Import workflow timed out',
            'Workflow for source ' . ( $state['source'] ?? 'unknown' ) . ' exceeded its deadline.'
        );

        // Clean up partial work.
        if ( isset( $state['temp_file'] ) ) {
            unlink( $state['temp_file'] );
        }
    }
}

期限ハンドラーは任意です。独自のロジックを実行せずにワークフローを失敗させるだけの場合は、on_deadline()を指定せずにmust_complete_within()を使います。

期限の確認方法

ワーカーは処理ループの一環として、60秒ごとに期限切れを確認します。statusがまだrunningで、deadline_atが過去になっているワークフローが見つかると、登録済みの場合はon_deadlineハンドラーを呼び出し、エラーメッセージDeadline exceededを付けてワークフローを失敗としてマークし、workflow_deadline_exceededログイベントを記録します。期限はワークフロー行のdeadline_atタイムスタンプとして保存され、設定された期間を基にディスパッチ時に計算されます。

期限切れ時の動作

ワークフローが期限を超過すると、ステータスがfailedに変わり、エラーメッセージにDeadline exceededが設定され、登録されている場合は期限切れハンドラーが同期的に実行され、workflow_deadline_exceededログエントリーが記録されます。実行中のジョブが途中で中断されることはありませんが、ワークフローは期限切れのステップ境界を越えて進みません。期限切れハンドラー自体が例外をスローした場合、その例外は黙って捕捉され、ワークフローは失敗状態になります。

WorkflowBuilderのメソッド

メソッド 説明
must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 ) 許可する最大時間を設定します。すべてのパラメーターが合算されます。
on_deadline( string $handler_class ) 期限を超過したときに呼び出すハンドラーを登録します。

例: 再試行を伴う期限設定

期限切れで失敗したワークフローを再試行しても、ほとんど役に立ちません。retry_workflow()は状態をrunningにリセットし、失敗したステップを再キューイングしますが、期限を解除も延長もしないため、約1分以内の次の期限チェックで再び失敗します。代わりに新しいワークフローをディスパッチしてください。

PHP
$status = Queuety::workflow_status( $workflow_id );

if ( 'failed' === $status->status->value ) {
    // Check if it was a deadline failure.
    // You may want to dispatch a new workflow instead of retrying.
    Queuety::retry_workflow( $workflow_id );
}

期限とスリープ遅延の違い

期限はワークフロー全体の実行時間に適用されます。スリープ遅延(->delay())は、ステップ列の一部としてワークフローを一定時間停止します。1時間のスリープ遅延と2時間の期限を設定したワークフローでは、スリープ以外のステップにかかる合計時間が1時間を超えると失敗します。