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

Робочі процеси

Робочі процеси розбивають тривалу роботу на окремі кроки. Результат кожного кроку зберігається в спільному сховищі стану в базі даних. Якщо PHP завершує роботу посеред кроку, виконавець повторює цей крок, зберігаючи весь попередній стан.

Що таке робочі процеси?

Робочий процес — це впорядкована послідовність кроків. Кожен крок — це клас PHP, який отримує накопичений стан усіх попередніх кроків і повертає нові дані для об’єднання зі станом. Робочий процес просувається по одному кроку за раз, а кожен перехід виконується в атомарній транзакції MySQL.

PHP
use Queuety\Queuety;

$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );

Накопичення стану

Початкові дані, передані в dispatch(), стають початковим станом. Ключі, повернуті кожним кроком, об’єднуються зі станом. Ключі, що починаються з _, зарезервовані для керувальних значень, як-от _next_step, і не об’єднуються з публічним станом:

Код
dispatch(['user_id' => 42])

Step 0: FetchDataHandler   -> returns ['user_name' => 'Alice']
  state: {user_id: 42, user_name: 'Alice'}

Step 1: CallLLMHandler     -> returns ['llm_response' => '...']
  state: {user_id: 42, user_name: 'Alice', llm_response: '...'}

Step 2: FormatOutputHandler -> returns ['report_url' => '/reports/42.pdf']
  state: {user_id: 42, user_name: 'Alice', llm_response: '...', report_url: '/reports/42.pdf'}

Кожен крок отримує весь накопичений стан. Завдяки цьому можна легко передавати дані між кроками без зовнішнього сховища.

Можливість відновлення

Робочі процеси надійні, оскільки стан зберігається в базі даних після кожного кроку. Якщо виконавець аварійно завершує роботу під час кроку 1, робочий процес запускається знову з кроку 1, а результат кроку 0 вже міститься в стані.

Межа кроку — це одна транзакція MySQL, яка атомарно:

  1. Оновлює стан робочого процесу результатом кроку
  2. Позначає завдання поточного кроку як виконане
  3. Ставить у чергу завдання наступного кроку

Це гарантує, що стан ніколи не буде втрачено, навіть у разі аварій, перевищення часу очікування або фатальних помилок PHP.

Життєвий цикл робочого процесу

Код
dispatch() -> running -> step 0 -> step 1 -> ... -> step N -> completed
                  |                   |
                  |                   +-> failed -> retry -> running (from failed step)
                  |
                  +-> paused -> resumed -> running
                  |
                  +-> waiting_for_signal -> signal received -> running
                  |
                  +-> waiting_for_workflows -> dependency settles -> running
                  |
                  +-> cancelled (via cancel_workflow)
Статус Опис
running Активно виконує кроки
completed Усі кроки успішно завершено
failed Крок завершився помилкою після вичерпання повторних спроб
paused Призупинено вручну. Поточна робота може завершитися, але наступні кроки не ставляться в чергу до відновлення
waiting_for_signal Очікує зовнішній сигнал через Queuety::signal()
waiting_for_workflows Очікує завершення одного або кількох інших робочих процесів через wait_for_workflow() або wait_for_workflows()
cancelled Явно скасовано через Queuety::cancel_workflow(). Очікувані завдання приховуються, а необов’язковий обробник очищення виконується.

Керування робочими процесами

Перевірка статусу:

PHP
$state = Queuety::workflow_status( $workflow_id );
echo $state->status->value;   // 'running'
echo $state->current_step;    // 1
echo $state->total_steps;     // 3
print_r( $state->waiting_for ); // ['42'] while waiting on another workflow
print_r( $state->wait_details ); // matched/remaining blockers, result key, correlation info

Призупинення та відновлення:

PHP
Queuety::pause_workflow( $workflow_id );
Queuety::resume_workflow( $workflow_id );

Повторний запуск робочого процесу з помилкою, починаючи з кроку, що завершився помилкою:

PHP
Queuety::retry_workflow( $workflow_id );

Скасування робочого процесу та запуск обробників очищення:

PHP
Queuety::cancel_workflow( $workflow_id );

Докладніше про обробники очищення та наслідки скасування робочого процесу див. в розділі Скасування.

Параметри робочого процесу

Налаштуйте чергу, пріоритет і поведінку повторних спроб для всіх кроків робочого процесу:

PHP
use Queuety\Enums\Priority;

Queuety::workflow( 'important_pipeline' )
    ->on_queue( 'pipelines' )
    ->with_priority( Priority::High )
    ->max_attempts( 5 )
    ->on_cancel( PipelineCleanupHandler::class )
    ->prune_state_after( 3 )
    ->then( StepA::class )
    ->then( StepB::class )
    ->dispatch( $payload );

Метод on_cancel() реєструє обробник очищення, який запускається під час скасування робочого процесу. Див. розділ Скасування.

Метод prune_state_after() вмикає автоматичне видалення старих результатів кроків, щоб обмежити розмір стану робочого процесу. Див. розділ Очищення стану.

Використовуйте compensate_with(), щоб додати обробник компенсації для окремого кроку. Використовуйте compensate_on_failure(), щоб автоматично виконувати компенсацію завершених кроків після збою робочого процесу, а не лише в разі явного скасування. Див. розділ Компенсація.

Використовуйте обмеження робочого процесу для безпечнішої тривалої оркестрації: version() додає до визначення тег із версією на рівні застосунку, Queuety також зберігає детермінований хеш визначення для кожного запуску, idempotency_key() забезпечує надійну диспетчеризацію під час повторних спроб або дублікатів запитів, а max_transitions(), max_for_each_items() і max_state_bytes() зупиняють неконтрольовані запуски до того, як ситуація вийде з-під контролю. Див. розділ Обмеження.

Типи кроків

Queuety підтримує одинадцять типів кроків у робочому процесі:

Типові сценарії

Якщо ви створюєте автономні або напівавтономні системи, почніть із розділу Оркестрація агентів. У ньому показано, як for_each(), start_agents(), wait_for_agents(), wait_for_workflow() і wait_for_decision() працюють разом у реальних сценаріях із планувальником, виконавцем і перевіркою людиною.