
# Введение

Queuety — это плагин WordPress, предоставляющий быструю очередь заданий, надежный движок рабочих процессов и среду выполнения конечных автоматов с сохранением состояния. Обработчики получают задания напрямую из MySQL и выполняют их в длительно работающем процессе WP-CLI. Среде выполнения PHP, которая загружает WordPress и WP-CLI, требуется либо `mysqli`, либо `pdo_mysql`.

## Почему Queuety?

В WordPress нет полноценной системы фоновых заданий. `wp_cron` запускается только при посещении страниц. Стандартный обработчик Action Scheduler работает через WP-Cron и запросы к локальному серверу HTTP, обрабатывая пакеты заданий не более 30 секунд каждый. Вызов LLM API, занимающий 60 секунд, будет прерван из-за 30-секундного тайм-аута PHP. Нельзя запускать многоэтапные процессы, которые переживают сбои и возобновляются с места остановки.

Queuety решает эту проблему с помощью трех примитивов:

1. **Задания** для фоновой работы в режиме отправки без ожидания результата
2. **Рабочие процессы** для надежных многоэтапных процессов с сохранением состояния
3. **Конечные автоматы** для долговременного состояния жизненного цикла, управляемого событиями

## Быстрый пример

Отправьте задание с помощью современного API:

```php
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

readonly class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

SendEmailJob::dispatch( 'user@example.com', 'Welcome', 'Hello from Queuety!' );
```

Или используйте классический подход с именем обработчика:

```php
use Queuety\Queuety;

Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );
```

Запустите надежный рабочий процесс:

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

Представьте длительную сессию в виде конечного автомата:

```php
use Queuety\Enums\StateMachineStatus;

Queuety::machine( 'agent_session' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'completed' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );
```

Запустите обработчик:

```bash
wp queuety work
```

Если вы разрабатываете систему с агентами, начните с раздела [Оркестрация агентов](https://queuety.inline0.dev/ru/docs/workflows/agent-orchestration). В нем показано, как связать потоки планирования и выполнения, этапы проверки человеком и ожидание между рабочими процессами.

Если система работает долго и управляется событиями, начните с раздела [Конечные автоматы](https://queuety.inline0.dev/ru/docs/state-machines) в дополнение к рабочим процессам.

Примеры интеграции от начала до конца см. в разделе [Примеры](https://queuety.inline0.dev/ru/docs/examples): теперь в нем представлены шаблоны на основе Neuron для переключения поставщиков, потоковой передачи, повторных проверок с сохранением состояния и зависимых рабочих процессов.

Если нужно запускать рабочие процессы по событиям предметной области WordPress, например `save_post`, см. раздел [Триггеры действий](https://queuety.inline0.dev/ru/docs/features/action-triggers).

Если вы хотите использовать среду выполнения с поддержкой базы данных вне WordPress, см. раздел [Автономное использование](https://queuety.inline0.dev/ru/docs/features/standalone-use).

## Ключевые отличия

- **Быстрое выполнение.** Воркеры напрямую получают доступ к очереди MySQL и избегают шаблона cron для каждого запроса, который замедляет фоновую работу в WordPress.
- **Надёжные рабочие процессы.** Многоэтапные процессы с постоянным состоянием, которые переживают тайм-ауты PHP, сбои и повторные попытки. Граница каждого шага — атомарная транзакция MySQL.
- **Явные конечные автоматы.** Моделируйте чаты, согласования и другие длительные жизненные циклы с именованными состояниями, защищёнными переходами, действиями при входе в состояние, помещаемыми в очередь, и надёжными временными шкалами событий.
- **Современный механизм диспетчеризации API.** Автономные классы задач с трейтом `Dispatchable`, типизированными свойствами конструктора в качестве данных и `$tries`/`$timeout`/`$backoff`, объявленными в классе. Класс `readonly` не позволяет задавать значения по умолчанию для этих свойств, поэтому объявляйте их в обычном классе с readonly promoted-свойствами конструктора.
- **Конвейер промежуточного ПО.** Промежуточное ПО в стиле «луковицы» для ограничения частоты запросов, ограничения исключений, уникальных задач и пользовательской логики. Объявляется для каждой задачи с помощью метода `middleware()`.
- **Потоковые шаги.** Интерфейс `StreamingStep` выдаёт фрагменты, которые сразу сохраняются в базе данных. При повторной попытке передаются ранее сохранённые фрагменты, чтобы поток продолжился с места остановки. Подходит для ответов LLM и больших загрузок.
- **Подключаемый слой кэша.** `CacheFactory` автоматически обнаруживает APCu или использует кэш в памяти. Пользовательские серверные части реализуют `Contracts\Cache`. Используется внутри системы для поиска ограничителей частоты запросов и состояния очереди.
- **Пакетная обработка и цепочки.** Группируйте задачи с помощью обратных вызовов `then`/`catch`/`finally` и отслеживания выполнения либо выстраивайте задачи последовательно, чтобы каждая зависела от завершения предыдущей.
- **Надёжные задержки и ожидания.** `delay()` добавляет задержки, безопасные при перезапуске процесса. `wait_for_signal()`, `wait_for_signals()`, `wait_for_approval()`, `wait_for_input()` и `wait_for_workflow()` позволяют рабочим процессам ожидать внешних событий или других процессов, не поддерживая PHP в активном состоянии.
- **Динамический цикл for-each.** `for_each()` добавляет ветви задач, обнаруженные во время выполнения на основе состояния рабочего процесса, и поддерживает режимы завершения при успехе всех задач, при первом успехе и при достижении кворума.
- **Асинхронная передача управления рабочим процессам.** `start_workflows()` превращает элементы, обнаруженные во время выполнения, в независимые рабочие процессы верхнего уровня, которые можно ожидать позднее.
- **Триггеры действий WordPress.** `on_action()` связывает хуки действий ядра или плагинов с надёжным запуском рабочих процессов, обеспечивая условия запуска и идемпотентность.
- **Надёжные артефакты.** Храните именованные результаты рабочего процесса отдельно от основного хранилища состояния и включайте их в просмотр состояния, CLI, экспорт и воспроизведение.
- **Защитные механизмы рабочих процессов.** `version()`, детерминированный хеш определения, ключи идемпотентного запуска и бюджеты рабочего процесса упрощают проверку запусков в стиле агентских систем и помогают предотвратить дублирование или незаметное превышение допустимого времени выполнения.
- **Управление ресурсами.** Группы параллелизма, единицы стоимости, бюджеты рабочего процесса и допуск задач в воркер помогают удерживать ресурсоёмкую работу в стиле агентских систем в заданных пределах.
- **Компенсация шагов.** `compensate_with()` и `compensate_on_failure()` предоставляют хуки для отката завершённых шагов при отмене или сбое рабочего процесса.
- **Сигналы активности.** Длительные шаги отправляют сигналы активности, чтобы система восстановления устаревших задач не перехватывала выполняемую работу.
- **Трассировка рабочих процессов.** Каждый переход шага записывается вместе с входными и выходными данными, состоянием до и после, контекстом, артефактами, фрагментами, ошибками и временной отладкой с помощью `workflow_state_at()`.
- **Параллельные шаги.** Выполняйте шаги одновременно и ждите завершения всех, прежде чем продолжать.
- **Условное ветвление.** Переходите к именованным шагам на основе предыдущего состояния с помощью `_next_step`.
- **Запуск рабочих процессов.** Запускайте дочерние рабочие процессы, передающие результаты родительскому.
- **Очереди с приоритетами.** Четыре уровня (Low, Normal, High, Urgent) с помощью типобезопасных перечислений PHP.
- **Воркеры с несколькими очередями.** Обрабатывайте несколько очередей с чётким порядком приоритета в одном воркере.
- **Ограничение частоты запросов.** Ограничивайте число запусков каждого обработчика с помощью скользящего окна.
- **Повторяющиеся задачи.** Планирование через заданные интервалы и по расписанию cron с настраиваемыми правилами пересечения запусков (Allow, Skip, Buffer).
- **Отмена рабочего процесса.** Отменяйте выполняющиеся рабочие процессы и запускайте зарегистрированные обработчики очистки.
- **Очистка состояния.** Автоматически удаляйте старые выходные данные шагов, чтобы управлять размером состояния больших рабочих процессов.
- **Параллелизм воркеров.** `--workers=N` запускает несколько процессов с автоматическим перезапуском после сбоя.
- **Полная наблюдаемость.** Журналирование в базе данных, метрики для каждого обработчика и вебхуки событий.
- **Средства тестирования.** `QueueFake` записывает отправленные задачи и пакеты для проверок в модульных тестах.
- **Атрибуты PHP.** `#[QueuetyHandler('name')]` для регистрации обработчиков без настройки.

## Как это работает

Воркеры работают в долгоживущем процессе WP-CLI и напрямую получают задачи из MySQL. Строки очередей, состояние рабочих процессов, журналы, пакеты, сигналы и потоковые фрагменты хранятся в MySQL, поэтому перезапуск воркеров не приводит к потере состояния оркестрации.

Рабочие процессы разбивают длительную работу на шаги. Каждый шаг сохраняет результат в общее хранилище состояния в базе данных. Если PHP завершает работу посреди шага, воркер повторяет этот шаг, сохраняя всё предыдущее состояние. Граница шага — единая транзакция MySQL: обновление состояния, завершение задачи и добавление следующего шага в очередь происходят атомарно.

```
Workflow: generate_report (3 steps)

Step 0: fetch_data     -> state: {user_data: {...}}
Step 1: call_llm       -> PHP dies -> retry -> state: {user_data: {...}, llm_response: "..."}
Step 2: format_output  -> state: {user_data: {...}, llm_response: "...", report_url: "/reports/42.pdf"}

Workflow: completed
```

## Требования

- PHP версии 8.2 или новее
- WordPress версии 6.4 или новее
- MySQL версии 8.0+ или MariaDB версии 10.6+, поскольку воркеры получают задачи с помощью `SELECT ... FOR UPDATE SKIP LOCKED`
- `mysqli` или `pdo_mysql` в среде выполнения PHP, загружающей WordPress и WP-CLI
- WP-CLI для запуска выделенных воркеров с `wp queuety work`
- Расширения `pcntl` и `posix` PHP для пулов воркеров (`--workers`, `--min-workers`, `--max-workers`)

См. [Начало работы](https://queuety.inline0.dev/ru/docs/getting-started) для установки.
