Перейти до вмісту

Кінцеві терміни робочих процесів

Для робочих процесів можна задати кінцевий термін. Якщо запущений робочий процес не завершиться протягом указаного часу, Queuety позначить його як невдалий і за потреби викличе обробник. Робочі процеси на паузі або в очікуванні сигналу чи інших робочих процесів не вважаються такими, що перевищили термін, поки очікують. Довготривалий процес wp queuety work перевіряє кінцеві терміни приблизно раз на хвилину, а не воркери --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'] );
        }
    }
}

Обробник кінцевого терміну необов’язковий. Якщо потрібно лише позначити робочий процес як невдалий без виконання власної логіки, використовуйте must_complete_within() без on_deadline().

Як працює перевірка кінцевого терміну

Воркер перевіряє кінцеві терміни, що минули, кожні 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 і повторно додає крок із помилкою до черги, але не скидає і не продовжує кінцевий термін, тож наступна перевірка протягом приблизно хвилини знову завершить його помилкою. Натомість запустіть новий робочий процес.

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()) призупиняють робочий процес на визначений час як частину послідовності кроків. Якщо робочий процес має годинну затримку сну та кінцевий термін у 2 години, він завершиться помилкою, якщо кроки поза сном триватимуть загалом понад 1 годину.