← Laravel: pedidos, dados e decisões de aplicação
09 / 10 · 65 MIN

Filas, repetições e agendamento

Relacionar ligação, fila, commit e ciclo de vida do worker com a entrega de trabalho. Distinguir unicidade, exclusão de sobreposição e idempotência dos efeitos, incluindo limites do agendamento distribuído.

Ligação, fila e consumidor

A ligação de filas escolhe o backend configurado; a fila identifica um conjunto de jobs dentro dessa ligação. onQueue("receipts") não muda por si o backend nem a ligação SQL usada por queries no job. Confirma onde o produtor submete e quais filas os workers consomem, incluindo prioridade.

Um job aceite para submissão pode continuar por processar se nenhum consumidor observar essa fila. A análise operacional deve ligar estes três elementos antes de concluir que o código do job falhou.

Submeter depois da confirmação dos dados

Um worker pode receber um job antes de a transação do pedido confirmar a encomenda que ele precisa de ler. after_commit na ligação de filas ou afterCommit no job adia a submissão até às transações abertas abrangidas confirmarem. Se a transação for revertida, os jobs pendentes desse contexto são descartados.

Um atraso fixo não observa commit. Esta ordem resolve a corrida de visibilidade descrita; não constitui uma transação distribuída com o fornecedor externo nem uma garantia de que todo o efeito será produzido uma única vez.

Sequência, falha e efeito já aceite

Uma chain executa jobs por ordem de sucesso; se B falha definitivamente depois de A, C não avança. Isso não desfaz automaticamente o efeito de A. Distingue também submissões únicas e tentativas: ShouldBeUnique usa um lock para limitar submissões, mas o mesmo job pode repetir depois de uma aceitação externa e falha local.

Define identidade estável e reconciliação com o fornecedor. As restrições de jobs únicos não se aplicam a jobs dentro de batches, pelo que esse âmbito requer análise própria.

Tentativas, timeouts e sobreposição

Nos drivers que usam retry_after, o timeout efetivo do worker deve ser vários segundos inferior a esse intervalo. Se o job ficar novamente disponível antes de o primeiro worker terminar, outro pode processá-lo em paralelo. Confirma overrides do job e o funcionamento do timeout.

WithoutOverlapping controla concorrência por chave, mas devolver um job por sobreposição também consome uma tentativa. releaseAfter define atraso, dontRelease elimina o job sobreposto e expireAfter limita a duração do lock. Nenhuma destas opções deve ser confundida com um registo durável de efeitos únicos.

Workers ativos e código publicado

queue:work mantém um processo de longa duração que não absorve automaticamente as alterações publicadas. queue:restart usa a cache para sinalizar uma saída graciosa depois do job atual; um monitor de processos deve voltar a iniciar os consumidores.

Confirma configuração da cache, saída, novo arranque e revisão efetiva em trabalho posterior. O sucesso da publicação web não prova que os workers mudaram. Repetir todos os jobs antes de resolver a versão pode duplicar efeitos com o mesmo código antigo.

Um servidor e ausência de sobreposição

onOneServer coordena a mesma tarefa entre schedulers usando um lock num serviço de cache central partilhado e suportado. withoutOverlapping evita iniciar a tarefa enquanto a instância anterior ainda mantém o respetivo lock. Define uma duração adequada e distingue o comando de trabalho que ele apenas submete: se um comando termina logo após colocar um job na fila, o lock do scheduler não cobre automaticamente a execução desse job.

Caches locais independentes e chaves iguais não criam coordenação distribuída.

Período de negócio e mudança de versão

Uma hora local pode repetir-se ou não existir numa mudança de horário de verão. A documentação alerta para tarefas repetidas ou ausentes; define o período de negócio a processar e reconcilia o seu estado. UTC pode simplificar o calendário técnico, mas a regra de negócio continua explícita.

Para tarefas sub-minute, schedule:run pode manter o código anterior até ao fim do minuto; schedule:interrupt, após a publicação, interrompe essas invocações. Não confundas isso com interromper todos os jobs já submetidos ou demonstrar que o relatório diário terminou.

<?php
// Application excerpts for reading: imports and domain classes omitted.
DB::transaction(function () use ($invoice) {
    $invoice->status = 'approved';
    $invoice->save();
    DeliverReceipt::dispatch($invoice->id)
        ->onQueue('receipts')
        ->afterCommit();
});

// Separate schedule definition; report:build performs its work synchronously.
Schedule::command('report:build')
    ->dailyAt('03:00')
    ->timezone('UTC')
    ->onOneServer()
    ->withoutOverlapping(15);
// Shared supported central cache and completion before lock expiry assumed.
NA PRÁTICA

O primeiro fragmento pressupõe que o modelo usa a mesma ligação transacional e que o job recebe uma identidade estável. afterCommit trata a visibilidade da aprovação para o worker; não prova entrega única do recibo. O segundo fragmento agenda um comando síncrono em UTC e coordena servidores e sobreposição por cache partilhada.

Os 15 minutos são uma premissa do exemplo, não um valor universal. Classes, imports, configuração e tratamento de falhas não estão fornecidos. A atividade consiste em interpretar os limites, sem executar código.

Armadilhas comuns

Tratar onQueue como ligação de backend; substituir commit por atraso fixo; esperar rollback global de uma chain; ignorar tentativas consumidas pelo middleware; atribuir execução única a ShouldBeUnique; presumir que publicar ficheiros atualiza workers ativos.

Tópicos relacionados: Transações, concorrência e migrações · Container, providers e duração das instâncias · Testes, cache e diagnóstico de releases

Leva esta ideia contigo

Fila, transação, lock e efeito externo têm fronteiras próprias. Define a identidade do trabalho, observa quando se torna executável, controla o intervalo de concorrência e reconcilia a aceitação final. O agendamento e os comandos de reinício precisam de evidência da execução que realmente ocorreu.

Criar conta

Referência: Queue connection and queue name · Laravel 13.x; PHP 8.3+