Integrações na prática

A fila que ninguém olha: o que acontece com o que falhou

Falha temporária ou permanente, quantas tentativas e com que espaçamento, por que reprocessar às cegas é perigoso e o que precisa estar visível na fila.

Leonardo Peron5 min de leitura

Toda integração séria tem uma fila de erro. Poucas têm alguém que a abre. O padrão é conhecido: a fila nasceu junto com a integração, funcionou como previsto, e meses depois acumula itens que ninguém leu — porque nada quebrou de um jeito visível, e o que não aparece na tela de ninguém não existe.

O problema não é a fila ter crescido. É ela ser a única evidência de um defeito que continua acontecendo.

Temporária ou permanente não é a mesma pergunta que o código de erro

A distinção que organiza tudo é esta: a mesma requisição, repetida depois, teria sucesso sem ninguém tocar em nada?

Tempo esgotado, erro interno do servidor, indisponibilidade e excesso de requisições respondem que sim. Campo obrigatório ausente, formato inválido e referência que não existe no destino respondem que não — a décima tentativa falha igual à primeira.

Duas fronteiras merecem atenção. Falha de autenticação parece permanente e quase sempre é temporária: uma credencial expirada volta a funcionar depois da renovação, e classificar isso como defeito de dado é o engano que enche a fila mais rápido. E conflito de estado é ambíguo — pode ser o destino já tendo o registro, caso em que não há o que fazer, ou uma condição que muda sozinha.

Há ainda o pior caso, que não vira item nenhum: o fornecedor que responde sucesso com o erro escrito dentro do corpo. Nada falha, a fila fica vazia, e o dado não chegou. Se a integração nunca teve um item de erro, essa é a primeira hipótese a investigar.

Quantas tentativas, com que espaçamento

Não há número universal, e quem oferece um está chutando. O que decide são duas medidas da sua operação: quanto tempo o destino costuma levar para voltar, o que dá para observar no histórico, e por quanto tempo aquele evento ainda é útil. Evento que perde o sentido em meia hora não deveria passar seis horas tentando.

O espaçamento cresce, com teto. E precisa de uma variação aleatória em cima: sem ela, tudo que falhou no mesmo segundo tenta de novo no mesmo segundo, e o destino que acabou de se recuperar leva a mesma rajada que o derrubou. O rebanho sincronizado é um problema que a própria retentativa cria.

O item que envelheceu

Aqui está a razão pela qual reprocessar às cegas é perigoso, e ela é mais grave que a duplicação.

Um evento parado é a fotografia de um estado passado. Meses depois, o pedido pode ter sido cancelado, e reprocessar o recria. O preço que viaja dentro da mensagem pode estar velho, e reprocessar escreve o valor antigo por cima do atual. Alguém pode ter resolvido o caso na mão, e reprocessar faz de novo.

Vale a distinção entre dois tipos de evento. O que carrega referência — o identificador e nada mais, obrigando a reler o estado atual na origem antes de agir — envelhece bem. O que carrega o conteúdo inteiro envelhece mal, e quanto mais tempo parado, pior.

E um alerta sobre o alcance da idempotência: ela impede criar duas vezes, não impede sobrescrever o novo com o velho. São problemas diferentes, e o segundo pede outra proteção — comparar versão ou data de alteração antes de gravar e recusar a escrita quando o destino já está mais adiantado. Isso pressupõe ter decidido quem é o dono daquele campo, o que raramente está resolvido quando a fila é aberta.

Reprocessar é um procedimento, não um botão

Uma fila com duzentos itens raramente tem uma causa só. Mandar tudo de uma vez trata como iguais casos que exigem decisões diferentes, e o resultado é metade voltando para a fila com o mesmo erro.

O caminho que funciona é chato: agrupar por causa antes de qualquer coisa e tratar cada grupo como uma decisão. Depois reprocessar um punhado pequeno, olhar o que aconteceu de verdade no destino — não só o código de retorno — e só então liberar o resto. E registrar quem reprocessou e quando, porque essa ação altera dado em produção e vai ser perguntada depois.

Itens que não devem voltar precisam de um destino explícito, com o motivo escrito. Descartar em silêncio é exatamente como o item entrou na fila.

O que precisa estar visível

Tamanho da fila é o número menos útil dos disponíveis. Ele não distingue mil itens de uma causa boba de dois itens que representam dinheiro parado.

Três coisas dizem mais.

Entrada por causa. Agrupada, não somada. É o que transforma "a fila cresceu" em "há um defeito novo desde ontem às onze".

Um aviso na primeira ocorrência de uma causa inédita. Limiar por quantidade esconde justamente o que interessa, porque defeito novo começa com um item.

A data em que alguém resolveu alguma coisa ali. Fila só encolhe por ação humana. Se essa data está longe, a fila deixou de ser fila e virou depósito — e nenhum painel de tamanho ia contar isso.

O teste que confirma

Injete de propósito um evento com defeito permanente, um campo obrigatório em branco, e acompanhe o percurso inteiro.

O certo é: algumas tentativas e a desistência, sem laço infinito; o item na fila com a causa legível por quem não escreveu o código; um aviso saindo para um canal que alguém lê; e, corrigido o dado, o reprocessamento entrando uma vez só.

O detalhe que vale mais que o resto é cronometrar quanto tempo passou até alguém ser avisado. Se você teve que ir olhar por conta própria, o teste já entregou a resposta mais importante — a de que, na próxima vez, ninguém vai olhar.

Isso é o que fazemos em integração de sistemas

ERP, e-commerce, CRM, banco e planilha falando entre si por API, webhook ou arquivo. Sem duplicar pedido e sem uma pessoa no meio copiando dado.

Resposta em até 1 dia útil