trilha

System Design/02 - Componentes/Background Jobs2 min

Returning Results

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Quando o trabalho vira assíncrono, a resposta imediata deixa de conter o resultado. O sistema precisa de um caminho de volta.

O padrão base é Async Request Reply: a API aceita, devolve 202 Accepted com um identificador, e o cliente descobre o desfecho depois.

POST /videos        → 202 Accepted
                      Location: /jobs/abc123
GET  /jobs/abc123   → 200 { status: "processando" }
                    → 200 { status: "pronto", url: "..." }

As quatro formas de devolver

Mecanismo Como funciona Custo
Polling Cliente consulta o status periodicamente Simples; requisições desperdiçadas
Long polling Servidor segura a conexão até haver resposta Menos desperdício; conexões ocupadas
Webhook Servidor chama uma URL do cliente Eficiente; exige o cliente ser alcançável
WebSocket / SSE Canal aberto, push em tempo real Melhor UX; conexão com estado, escala pior

Onde o resultado fica

Um result store (Redis, banco, S3) guarda o desfecho por um tempo. Três decisões: quanto tempo reter, o que fazer se o cliente nunca buscar, e se o resultado é o dado ou apenas um link para ele (resultados grandes devem ir para armazenamento e o job devolver a URL — é o Claim Check).

Trade-offs

Polling é o mais simples e o mais desperdiçador: com intervalo de 1 s e job de 5 min, são 300 requisições para uma resposta útil. Aumentar o intervalo reduz custo e piora a percepção de rapidez. Backoff progressivo (1 s, 2 s, 5 s, 10 s) é o meio-termo usual.

Webhook inverte a responsabilidade: agora você é cliente de um endpoint que pode estar fora do ar, ser lento ou responder erro. Exige retry com backoff, assinatura para autenticidade, e idempotência do lado de quem recebe — porque o webhook vai ser entregue duas vezes eventualmente.

WebSocket dá a melhor experiência e transforma um serviço stateless em stateful: a conexão pertence a uma instância específica, o que complica deploy, balanceamento e escala.

Exemplo prático

Exportação de relatório grande. O usuário clica, a API responde 202 com jobId e a interface mostra uma barra de progresso.

O front faz polling com backoff. Quando o job termina, o resultado não vai na resposta — o worker grava o arquivo no armazenamento de objetos e devolve uma URL assinada com expiração. A API responde { status: "pronto", url: "..." }.

Isso mantém a resposta pequena, tira o tráfego pesado da API e faz o link expirar sozinho. Se o usuário fechar a aba, o relatório continua lá — o desacoplamento entre execução e entrega é o que torna isso possível.

Relacionado


Parte de Background Jobs · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas