Перейти к содержимому

Крайние сроки workflow

Для workflow можно задать крайний срок. Если выполняющийся workflow не завершится за указанное время, Queuety отметит его как завершившийся сбоем и при необходимости вызовет обработчик. Срок не истекает, пока workflow приостановлен или ожидает сигнал либо другие workflow. Длительно работающий процесс wp queuety work проверяет крайние сроки примерно раз в минуту, а --once workers и резервный механизм WP-Cron этого не делают. Это служит аварийным выключателем для длительных workflow, которым нельзя работать бесконечно.

Установка крайнего срока

Используйте must_complete_within() в конструкторе workflow, чтобы задать максимально допустимую длительность. Используйте 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. Он получает публичное состояние workflow (все ключи, не начинающиеся с _).

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'] );
        }
    }
}

Обработчик крайнего срока необязателен. Если нужно только отметить workflow как завершившийся сбоем без запуска пользовательской логики, используйте must_complete_within() без on_deadline().

Как работает проверка крайнего срока

Worker проверяет истекшие крайние сроки каждые 60 секунд в рамках цикла обработки. Когда он обнаруживает workflow, для которого status по-прежнему имеет значение running, а deadline_at находится в прошлом, он вызывает зарегистрированный обработчик on_deadline, отмечает workflow как завершившийся сбоем с сообщением об ошибке Deadline exceeded и записывает в журнал событие workflow_deadline_exceeded. Крайний срок хранится как метка времени deadline_at в строке workflow и рассчитывается во время запуска на основе заданной длительности.

Что происходит по истечении срока

Когда workflow превышает крайний срок, его статус меняется на failed, в качестве сообщения об ошибке указывается Deadline exceeded, зарегистрированный обработчик крайнего срока запускается синхронно, а в журнал добавляется запись workflow_deadline_exceeded. Выполняющиеся задания не прерываются в процессе работы, но workflow не перейдет за границу просроченного шага. Если обработчик крайнего срока выбрасывает исключение, оно незаметно перехватывается, а workflow все равно завершается сбоем.

Методы WorkflowBuilder

Метод Описание
must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 ) Задает максимально допустимую длительность. Значения всех параметров суммируются.
on_deadline( string $handler_class ) Регистрирует обработчик, который вызывается при превышении крайнего срока.

Пример: крайний срок с повторной попыткой

Повторять workflow, завершившийся сбоем из-за крайнего срока, обычно бессмысленно. retry_workflow() сбрасывает его в running и повторно ставит неудачный шаг в очередь, но не очищает крайний срок и не продлевает его, поэтому при следующей проверке примерно через минуту workflow снова завершится сбоем. Вместо этого запустите новый workflow.

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 );
}

Крайний срок и задержки сна

Крайний срок распространяется на всю длительность workflow. Задержки сна (->delay()) приостанавливают workflow на заданное время в рамках последовательности шагов. Workflow с часовой задержкой сна и крайним сроком в 2 часа завершится сбоем, если шаги вне сна в сумме займут больше 1 часа.