Problema
WebhookDeliveryJob#perform chama WebhookDelivery.entregar e descarta o retorno:
def perform(subscription_id, event, payload)
subscription = WebhookSubscription.find_by(id: subscription_id)
WebhookDelivery.entregar(subscription, event, payload)
end
WebhookDelivery captura falha de rede, registra log e retorna false. Como o job não levanta nada, o Active Job considera a execução bem-sucedida e nunca reagenda. Uma entrega perdida por endpoint fora do ar, timeout ou 5xx desaparece em silêncio: o log registra, mas ninguém reprocessa.
Isto é independente do backend de fila (#2): mesmo com Solid Queue, um job que nunca falha nunca é repetido.
Proposta
Distinguir erro recuperável (timeout, 5xx, conexão recusada) de definitivo (URL agora privada, assinatura pausada/excluída, 4xx). Para o recuperável, levantar exceção e configurar retry_on com backoff e limite; para o definitivo, discard_on ou simplesmente registrar e encerrar.
Vale decidir explicitamente o que fazer depois do último retry — hoje não existe nem o conceito.
Critério de aceite
- Uma entrega que falha por erro recuperável reagenda, com backoff, até um limite explícito.
- Uma recusa definitiva (
PublicHttpTarget reprovando a URL, assinatura inativa) não consome retries.
- Specs cobrindo os dois caminhos, sem chamada real de rede (o transporte já é injetável).
Onde
app/jobs/webhook_delivery_job.rb
app/services/webhook_delivery.rb
spec/services/webhook_delivery_spec.rb
Problema
WebhookDeliveryJob#performchamaWebhookDelivery.entregare descarta o retorno:WebhookDeliverycaptura falha de rede, registra log e retornafalse. Como o job não levanta nada, o Active Job considera a execução bem-sucedida e nunca reagenda. Uma entrega perdida por endpoint fora do ar, timeout ou 5xx desaparece em silêncio: o log registra, mas ninguém reprocessa.Isto é independente do backend de fila (#2): mesmo com Solid Queue, um job que nunca falha nunca é repetido.
Proposta
Distinguir erro recuperável (timeout, 5xx, conexão recusada) de definitivo (URL agora privada, assinatura pausada/excluída, 4xx). Para o recuperável, levantar exceção e configurar
retry_oncom backoff e limite; para o definitivo,discard_onou simplesmente registrar e encerrar.Vale decidir explicitamente o que fazer depois do último retry — hoje não existe nem o conceito.
Critério de aceite
PublicHttpTargetreprovando a URL, assinatura inativa) não consome retries.Onde
app/jobs/webhook_delivery_job.rbapp/services/webhook_delivery.rbspec/services/webhook_delivery_spec.rb