Fila (Queue)
Fila de tarefas em background, com pool de workers, retry automático e
drenagem no shutdown. Ativada via QUEUE_ENABLED=true.
Cache, EventBus e Queue têm papéis distintos:
| Componente | Papel | Garantia |
|---|---|---|
fw.Cache |
Armazenamento chave/valor com TTL | Leitura rápida; dados podem expirar |
fw.Events (EventBus) |
Pub/sub fire-and-forget | TODOS os subscribers recebem; sem retry |
fw.Queue |
Fila de tarefas em background | Cada tarefa processada por UM worker, com retry e drenagem no shutdown |
Use a Queue para trabalho que não pode se perder num pico: e-mails, webhooks, processamento de mídia.
Configuração
QUEUE_ENABLED=true
QUEUE_DRIVER=memory # memory | redis
QUEUE_WORKERS=4
# Só com QUEUE_DRIVER=redis — fila compartilhada entre réplicas via
# LPUSH/BRPOP, em vez de um channel local ao processo:
QUEUE_ADDR=127.0.0.1:6379
QUEUE_PASSWORD= # AUTH do redis; vazio = sem senha
Com QUEUE_DRIVER=redis, todas as réplicas do processo precisam registrar
os mesmos handlers — qualquer réplica pode processar uma tarefa
enfileirada por outra. Se a conexão falhar no boot, o bootstrap cai para
fila em memória (não compartilhada entre réplicas) e loga um aviso, em vez
de recusar subir.
Registrar handlers e enfileirar
// Register do app — antes de qualquer Enqueue:
fw.Queue.Register("email.boasvindas", func(payload any) error {
return enviarEmail(payload.(string)) // erro ≠ nil → retry (3× com backoff)
})
// Na view:
if err := fw.Queue.Enqueue("email.boasvindas", usuario.Email); err != nil {
// ErrQueueFull = backpressure explícito: decida entre 503, log ou retry
log.Printf("fila cheia: %v", err)
}
No shutdown do servidor a fila é drenada antes do processo encerrar —
tarefas enfileiradas não se perdem num deploy (no modo redis, tarefas
ainda na lista continuam lá para a próxima subida consumir). Um panic num
handler não derruba o worker (logado com stack trace).