Filas
Sistema de queues e workers.
Filas (Queue)
Sistema de filas 100% nativo do illuminate/queue — driver de banco de dados (tabela jobs
na conexão iam). Use para tirar trabalho pesado (e-mails, relatórios, integrações) do
caminho síncrono da request, sem travar o usuário.
Como funciona
Requisição web
└── MeuJob::dispatch($dados)
└── insere registro na tabela jobs (conexão iam)
php artisan queue:work (processo separado, em background)
└── lê jobs da tabela jobs
└── instancia MeuJob e chama handle()
├── sucesso → remove da tabela jobs
└── falha → tenta novamente (até $tries vezes)
após esgotar → move para failed_jobs
Criando um Job
Gere com php artisan make:job e implemente ShouldQueue — não há classe base própria do
MAD, é o Job padrão do Laravel:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessarPedidoJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3; // tentativas antes de ir para failed_jobs
public int $timeout = 120; // segundos máximos de execução
public function __construct(public int $pedidoId) {}
public function handle(): void
{
$pedido = Pedido::findOrFail($this->pedidoId);
$pedido->processar();
}
}
Propriedades comuns do Job
| Propriedade | Padrão | Descrição |
|---|---|---|
$tries |
1 (sobrescrito por --tries do worker) |
Tentativas antes de ir para failed_jobs |
$timeout |
60 |
Segundos máximos — worker mata o processo se ultrapassar |
$backoff |
— | Array de segundos de espera entre tentativas ([10, 30, 90]) ou um int fixo |
$queue |
default |
Fila onde o job é colocado (também via ->onQueue('nome') no dispatch) |
Disparando Jobs
// Dispatch simples — fila default
ProcessarPedidoJob::dispatch($pedido->id);
// Dispatch em fila específica
EnviarRelatorioJob::dispatch($dados)->onQueue('reports');
// Dispatch com atraso
NotificarClienteJob::dispatch($clienteId)->delay(now()->addMinutes(5));
// Síncrono (ignora a fila, roda na hora — útil em testes com QUEUE_CONNECTION=sync)
ProcessarPedidoJob::dispatchSync($pedido->id);
Dispatch de dentro de um MadComponent
use Mad\Component\MadComponent;
use Mad\Http\MadResponse;
use Mad\Ui\MadToast;
class PedidoForm extends MadComponent
{
public MadForm $form;
public function onSave(): MadResponse
{
$pedido = Pedido::create($this->form->getData());
// Dispara em background — não bloqueia o usuário
ProcessarPedidoJob::dispatch($pedido->id);
return (new MadResponse())
->toast(MadToast::success('Pedido salvo! O processamento ocorrerá em instantes.'))
->closeDrawer();
}
}
Filas múltiplas
Organize prioridades com filas nomeadas:
JobUrgente::dispatch($dados)->onQueue('critical');
EnviarEmailJob::dispatch($dados)->onQueue('emails');
GerarRelatorioJob::dispatch($dados)->onQueue('reports');
JobNormal::dispatch($dados); // fila default
Para processar com prioridade, rode workers dedicados — o primeiro nome da lista é esvaziado primeiro:
# Worker de alta prioridade (drena 'critical' antes de 'default')
php artisan queue:work --queue=critical,default
# Worker dedicado a e-mails
php artisan queue:work --queue=emails
Rodando o Worker
Desenvolvimento
php artisan queue:work
php artisan queue:work --queue=emails
cPanel / Shared hosting (via cron)
# Processa jobs por 55s e sai — cron reinicia no próximo minuto
php artisan queue:work --max-time=55
# Ou: processa apenas 1 job por invocação
php artisan queue:work --once
Produção — systemd ou Supervisor
O repositório já traz as units prontas em deploy/ (mesmo worker usado pelo
MailService para entregar e-mails transacionais):
# systemd
sudo cp deploy/mad-queue-worker.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now mad-queue-worker
# Supervisor (alternativa)
sudo cp deploy/mad-queue-worker.conf /etc/supervisor/conf.d/
sudo supervisorctl reread && sudo supervisorctl update
Ambas rodam o mesmo comando:
php artisan queue:work --tries=3 --max-time=3600 --backoff=10 --sleep=3
Reinicie a cada deploy para o worker carregar o código novo —
php artisan queue:restart(ousudo systemctl restart mad-queue-worker).
Principais opções do queue:work
| Opção | Padrão | Descrição |
|---|---|---|
--queue=nome |
default |
Fila(s) a processar (vírgula define prioridade) |
--once |
— | Processa 1 job e sai |
--max-time=N |
— | Recicla o processo após N segundos (espera o job atual terminar — graceful) |
--max-jobs=N |
— | Para após processar N jobs |
--sleep=N |
3 |
Segundos de espera quando não há jobs |
--tries=N |
1 |
Tentativas por job (sobrescrito por $tries do próprio Job) |
--backoff=N |
0 |
Segundos entre tentativas quando o Job não define $backoff/backoff() |
--timeout=N |
60 |
Segundos máximos por job (mata o processo se ultrapassar) |
--memory=N |
128 |
Limite de memória (MB) antes de reciclar o worker |
Importante:
--max-time/--max-jobsnunca matam um job no meio — esperam o job atual terminar e só então encerram o worker.
Tratamento de falhas
Quando um job lança uma exceção não tratada, o Laravel:
- Decrementa as tentativas restantes;
- Se ainda há tentativas → reagenda com o backoff configurado;
- Se esgotou → move para
failed_jobscom a stack trace completa e chamafailed()no Job (se definido).
class MeuJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle(): void
{
// lógica
}
/** Chamado quando as tentativas se esgotam. */
public function failed(\Throwable $e): void
{
Log::error('Job não entregue', ['error' => $e->getMessage()]);
}
}
Gerenciando jobs falhados
# Listar jobs falhados
php artisan queue:failed
# Re-tentar um job específico (uuid)
php artisan queue:retry <uuid>
# Re-tentar todos
php artisan queue:retry all
# Esquecer (apagar) um job falhado específico
php artisan queue:forget <uuid>
# Apagar TODOS os jobs falhados
php artisan queue:flush
# Limpar jobs PENDENTES de uma fila (não mexe em failed_jobs)
php artisan queue:clear database --queue=emails
Tabelas do banco (conexão iam)
jobs — pendentes
| Coluna | Descrição |
|---|---|
id |
ID do job |
queue |
Nome da fila |
payload |
JSON com classe serializada e dados |
attempts |
Tentativas realizadas |
reserved_at |
Quando foi pego por um worker |
available_at |
Quando pode ser processado (delay) |
created_at |
Criação |
failed_jobs — falhados
| Coluna | Descrição |
|---|---|
id / uuid |
Identificadores |
connection / queue |
Onde rodava |
payload |
JSON original |
exception |
Stack trace completo |
failed_at |
Quando falhou |
Monitorando
A tela Central de Comando → Jobs (admin) mostra pendentes/falhados por fila em tempo real, sem precisar de SSH — útil para conferir se o worker está vivo em produção.
Veja também
- E-mail (MailService) — o worker de fila entrega os e-mails transacionais do app.
- Agendamento (Scheduler) — disparar jobs em horários fixos.