Pular para o conteúdo

Introdução

Queuety é um plugin WordPress que oferece uma fila rápida de jobs, um mecanismo durável de fluxos de trabalho e um runtime durável de máquina de estado. Os workers reivindicam jobs diretamente de MySQL e os processam em um processo WP-CLI de longa duração. O runtime PHP que carrega WordPress e WP-CLI precisa de mysqli ou pdo_mysql.

Por que Queuety?

WordPress não tem um sistema real de jobs em segundo plano. wp_cron só é acionado em visitas a páginas. O executor padrão de Action Scheduler usa WP-Cron e requisições HTTP de loopback, processando lotes por no máximo 30 segundos. Uma chamada API de LLM que leva 60 segundos é encerrada pelo tempo limite de 30 segundos de PHP. Não há como executar processos com várias etapas que sobrevivam a falhas e retomem de onde pararam.

Queuety resolve isso com três recursos básicos:

  1. Jobs para tarefas em segundo plano sem acompanhamento
  2. Fluxos de trabalho para processos duráveis com várias etapas e estado persistente
  3. Máquinas de estado para estados de ciclo de vida duradouros e orientados a eventos

Exemplo rápido

Envie um job usando o moderno 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!' );

Ou use a abordagem clássica com o nome do manipulador:

PHP
use Queuety\Queuety;

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

Execute um fluxo de trabalho durável:

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

Modele uma sessão duradoura com uma máquina de estado:

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

Inicie um worker:

Shell
wp queuety work

Se você estiver criando um sistema baseado em agentes, comece por Orquestração de agentes. O guia mostra como fluxos de planejador e executor, etapas de revisão humana e esperas entre fluxos de trabalho se integram.

Se o sistema for duradouro e orientado a eventos, comece por Máquinas de estado junto com os fluxos de trabalho.

Se você quiser exemplos de integração de ponta a ponta, consulte Exemplos, que agora inclui padrões baseados em Neuron para alternar provedores, transmitir dados, repetir revisões com suporte de memória e lidar com fluxos de trabalho dependentes.

Se você quiser iniciar fluxos de trabalho a partir de eventos de domínio WordPress, como save_post, consulte Gatilhos de ação.

Se você quiser usar o runtime com suporte a DB fora de WordPress, consulte Uso independente.

Principais diferenciais

  • Execução rápida. Os workers acessam a fila MySQL diretamente e evitam o padrão cron por solicitação, que torna o processamento em segundo plano mais lento em WordPress.
  • Fluxos de trabalho duráveis. Processos de várias etapas com estado persistente que sobrevivem a tempos limite PHP, falhas e novas tentativas. Cada limite entre etapas é uma transação MySQL atômica.
  • Máquinas de estado explícitas. Modele sessões de chat, aprovações e outros ciclos de vida longos com estados nomeados, transições protegidas, ações de entrada em estado enfileiradas e cronologias de eventos duráveis.
  • Despacho API moderno. Classes de tarefas autocontidas com a trait Dispatchable, propriedades tipadas do construtor como carga útil e $tries/$timeout/$backoff declarados na classe. Uma classe readonly não pode definir valores padrão para essas propriedades; portanto, declare-as em uma classe comum com propriedades promovidas readonly no construtor.
  • Pipeline de middleware. Middleware no estilo onion para limitação de taxa, controle de exceções, tarefas únicas e lógica personalizada. Declarado por tarefa por meio de um método middleware().
  • Etapas em streaming. A interface StreamingStep produz blocos que são persistidos imediatamente no banco de dados. Em uma nova tentativa, os blocos salvos anteriormente são fornecidos para que o fluxo possa continuar de onde parou. Ideal para respostas de LLM e downloads grandes.
  • Camada de cache conectável. CacheFactory detecta automaticamente o APCu ou usa um cache em memória como alternativa. Backends personalizados implementam Contracts\Cache. Usado internamente para consultas do limitador de taxa e estado da fila.
  • Agrupamento e encadeamento. Despache grupos de tarefas com callbacks then/catch/finally e acompanhamento do progresso, ou encadeie tarefas sequencialmente, cada uma dependendo da conclusão da anterior.
  • Atrasos e esperas duráveis. delay() adiciona atrasos seguros a reinicializações do processo. wait_for_signal(), wait_for_signals(), wait_for_approval(), wait_for_input() e wait_for_workflow() permitem que os fluxos de trabalho aguardem eventos externos ou outros fluxos sem manter PHP ativo.
  • For-each dinâmico. for_each() expande ramificações de tarefas descobertas em tempo de execução a partir do estado do fluxo de trabalho e oferece modos de conclusão por sucesso de todos, primeiro sucesso ou quórum.
  • Transferências assíncronas de fluxo de trabalho. start_workflows() transforma itens descobertos em tempo de execução em fluxos de trabalho independentes de nível superior que podem ser aguardados posteriormente.
  • Gatilhos de ações WordPress. on_action() mapeia hooks de ações do core ou de plugins para despachos duráveis de fluxos de trabalho, com controle de condições e idempotência.
  • Artefatos duráveis. Armazene saídas nomeadas do fluxo de trabalho fora do conjunto principal de estados e mantenha-as durante a inspeção de status, CLI, exportação e reprodução.
  • Proteções de fluxo de trabalho. version(), um hash de definição determinístico, chaves de despacho idempotentes e orçamentos de fluxo de trabalho facilitam a inspeção de execuções no estilo agente e dificultam duplicá-las ou deixá-las continuar indefinidamente sem perceber.
  • Gerenciamento de recursos. Grupos de concorrência, unidades de custo, orçamentos de fluxo de trabalho e admissão de workers ajudam a manter trabalhos caros no estilo agente dentro de limites definidos.
  • Compensação de etapas. compensate_with() e compensate_on_failure() fornecem hooks de reversão para etapas concluídas quando os fluxos de trabalho são cancelados ou falham.
  • Sinais de atividade. Etapas de longa duração enviam sinais de atividade para impedir que o sistema de recuperação de tarefas obsoletas retome trabalhos ativos.
  • Rastreamento de fluxo de trabalho. Cada transição de etapa é registrada com entrada, saída, estado antes/depois, contexto, artefatos, blocos, erros e depuração temporal por meio de workflow_state_at().
  • Etapas paralelas. Execute etapas simultaneamente e aguarde a conclusão de todas antes de avançar.
  • Ramificação condicional. Pule para etapas nomeadas com base no estado anterior usando _next_step.
  • Executar fluxos de trabalho. Inicie fluxos de trabalho filhos que devolvem resultados ao fluxo pai.
  • Filas prioritárias. Quatro níveis (Baixa, Normal, Alta, Urgente) por meio de enums PHP com segurança de tipos.
  • Workers com várias filas. Processe várias filas com ordenação estrita por prioridade em um único worker.
  • Limitação de taxa. Limites de execução por manipulador com janela deslizante.
  • Tarefas recorrentes. Agendamento baseado em intervalos e em cron, com políticas configuráveis para sobreposição (Permitir, Ignorar, Armazenar em buffer).
  • Cancelamento de fluxo de trabalho. Cancele fluxos de trabalho em execução e acione manipuladores de limpeza registrados.
  • Poda de estado. Remova automaticamente saídas antigas de etapas para manter gerenciável o estado de fluxos de trabalho grandes.
  • Concorrência de workers. --workers=N cria vários processos com reinicialização automática após falhas.
  • Observabilidade completa. Registro em banco de dados, métricas por manipulador e webhooks de eventos.
  • Utilitários de teste. QueueFake registra tarefas e lotes despachados para asserções em testes unitários.
  • Atributos PHP. #[QueuetyHandler('name')] para registro de manipuladores sem configuração.

Como funciona

Os workers são executados em um processo WP-CLI de longa duração e obtêm tarefas diretamente de MySQL. As linhas da fila, o estado dos fluxos de trabalho, os registros, os lotes, os sinais e os blocos em streaming ficam todos em MySQL, portanto, a reinicialização dos workers não faz perder o estado da orquestração.

Os fluxos de trabalho dividem tarefas de longa duração em etapas. Cada etapa persiste sua saída em um conjunto de estados compartilhado no banco de dados. Se PHP parar no meio de uma etapa, o worker tenta executar essa etapa novamente com todo o estado anterior intacto. O limite da etapa é uma única transação MySQL: a atualização do estado, a conclusão da tarefa e o enfileiramento da próxima etapa acontecem de forma atômica.

Código
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

Requisitos

  • PHP 8.2 ou posterior
  • WordPress 6.4 ou posterior
  • MySQL 8.0+ ou MariaDB 10.6+, porque os workers obtêm tarefas usando SELECT ... FOR UPDATE SKIP LOCKED
  • mysqli ou pdo_mysql no ambiente de execução PHP que carrega WordPress e WP-CLI
  • WP-CLI para executar workers dedicados com wp queuety work
  • As extensões pcntl e posix PHP para pools de workers (--workers, --min-workers, --max-workers)

Veja Primeiros passos para instruções de instalação.