Pular para conteúdo

0025 — Contingência: poll de pedidos a cada 5 min enquanto o webhook está calado

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-30 · Decidido em: 2026-09-30

Contexto

Em 29/09/2026 a rede do servidor oscilou às 18:02 BRT (Read Timeout, depois Temporary failure in name resolution no log), quatro minutos depois do último webhook recebido. A PIED desativou o webhook, como em 18/09 (0023). O journal do host não registra queda de interface: a falha é do link, fora da máquina.

Na manhã de 30/09 cinco pedidos foram pagos com o webhook ainda desligado — 260086701, 260086026, 260086330, 260086034, 260087074. O cliente cobrou o 260086701. O watchdog alertou às 08:47, como previsto.

A 0023 não cobria este caso, e não por defeito: o resgate dela é para o pedido visto pela primeira vez já pago. Aqui os cinco já estavam em CAPTURADO com o pagamento pendente, então o pagamento é uma transição comum — o upsert a reconhece venha do webhook ou da REST. O que faltava era alguém trazer o pagamento: o único outro caminho é o poll periódico, de 6h. A rodada das 03:57 veio antes dos pagamentos; a próxima só às 10:00. Ou seja, o sistema já se recuperaria sozinho, mas com até 6h de atraso, na hora em que o cliente está esperando.

O intervalo de 6h existe por causa de produtos e clientes, que re-varrem tudo a cada rodada. O poll de pedidos é incremental (lastUpdateAfter) e custa de 1 a 4 chamadas.

Decisão

Um job novo, ContingenciaPedidosJob, roda no mesmo intervalo do watchdog (5 min). Quando o webhook está calado há 15 minutos comerciais ou mais (PIED_WATCHDOG_LIMITE_MIN_POLL), ele roda um poll só de pedidos (PollService.executarPedidos()). O pedido pago entra em pied_rest, a normalização (5 min) faz o upsert, o upsert vê a transição e o gate envia.

Desliga sozinho. A condição é recalculada a cada rodada a partir do max(recebido_em): chegou webhook, o silêncio zera e o job para de puxar. Não há estado persistido. O log marca a virada — WARN ao ligar, INFO ao desligar.

Detalhes:

  • Régua comercial (seg–sex, 8h–18h), a mesma do alerta. À noite o silêncio de horas é normal e o poll de 6h cobre; um apagão iniciado às 18:02 aciona a contingência às 08:13 do dia seguinte.
  • 15 min, abaixo dos 45 do alerta. No histórico medido para a 0023, só dois silêncios comerciais passaram de 15 min. O falso acionamento custa algumas chamadas REST; o verdadeiro entrega o pedido pago cerca de 20 min depois do pagamento.
  • Mesmo lock do poll periódico (pied_poll): os dois escrevem o cursor de pedidos, então nunca rodam juntos; quem chega depois coalesce.
  • Não depende do alerta: a contingência entrega os pedidos, e o watchdog continua avisando que o webhook precisa ser recadastrado.

Consequências

  • Pedido pago durante um apagão chega ao X-Adm sem ação manual, em ~20 min dentro do expediente. O "Puxar PIED" do console deixa de ser necessário nesse cenário.
  • Custo só durante o apagão: webhook saudável, o job só lê max(recebido_em). Apagão, 12 rodadas/hora de 1 a 4 chamadas cada — dentro da cota horária da PIED; um 429 vira WARN e a rodada seguinte retoma (0017).
  • pied_rest cresce durante o apagão (cada rodada regrava os pedidos do dia); a retenção de 7 dias limpa.
  • Não resolve o webhook. Eventos que não mudam o pagamento (edição de itens, status sem gatilho) seguem atrasados até o recadastro, e o recadastro continua manual.
  • O furo da 1ª captura já paga segue com a 0023: se o pedido nasce e é pago dentro do apagão, a contingência o traz já pago e quem o envia é o resgate da 0023.

Alternativas consideradas

  • Poll de pedidos fixo a cada 10–15 min, sempre: mais simples e cobriria evento solto perdido, mas o filtro da PIED só aceita a data (lastUpdateAfter=AAAA-MM-DD), então cada rodada traz de novo todos os pedidos do dia — ~100 mil linhas raw por semana em pied_rest para cobrir um caso raro. Rejeitado.
  • Baixar o intervalo do poll geral: também re-varreria produtos e clientes. Rejeitado.
  • Recadastrar o webhook automaticamente: a PIED não expõe API para isso (ver 0023). Pedido aberto com a PIED; se vier, complementa esta decisão.
  • Receber o webhook fora do link on-prem (receptor em nuvem com fila): tira a nossa rede do caminho de entrega, mas é um componente novo. Fica para o caso de as quedas continuarem e a PIED não oferecer retentativa.