Todos os serviços externos que o teu sistema chama vão estar indisponíveis a certa altura. Não «podem estar» - vão estar. A única pergunta é o que faz o teu sistema durante esses minutos, e essa pergunta tem uma resposta certa por dependência, não por sistema.
As duas opções
Fail closed: a dependência está em baixo, portanto a operação é recusada. Seguro, óbvio, e o que a maior parte do código faz por acaso, porque uma exceção que ninguém apanhou faz fail closed por omissão.
Fail open: a dependência está em baixo, portanto a operação continua, e o trabalho que falta entra em fila e fica marcado para um humano. Exige um desenho deliberado e um sítio para onde essa sinalização vá.
A pergunta que decide
Pergunta-te: se este terceiro estiver em baixo durante uma hora, quem paga?
Pega numa verificação anti-bot num formulário de marcação. Se o fornecedor não estiver acessível e fizeres fail closed, recusas todas as marcações durante uma hora - transformaste a avaria de outra pessoa na tua receita perdida, para evitares talvez dois formulários de spam. Faz fail open, aceita a marcação, marca-a como não verificada e trata à mão das poucas que forem más.
Agora pega no teu próprio rate limiter. Se falhar, não tens nenhum terceiro a quem deitar as culpas, e fazer fail open significa que simplesmente desligaste uma proteção exatamente nas condições em que é mais provável que seja precisa. Esse faz fail closed.
O padrão que daí sai é o mesmo em todos os sistemas que construí:
- Fail open - a entrega de SMS e e-mails, analytics e os eventos de pixel, as verificações anti-bot, a sincronização de faturação e contabilidade, o push para o CRM, a procura de moradas. Tudo aquilo cujo valor fica registado noutro sítio ou pode ser reconciliado mais tarde.
- Fail closed - a autorização de pagamentos, a autenticação e as verificações de sessão, as verificações de permissões, os teus próprios rate limits e validações, e tudo o que possa deixar um cliente ver os dados de outro cliente.
Fail open não quer dizer «lançar e esquecer»
O modo de falha de um fail open mal implementado é pior do que fail closed, porque é silencioso. Três coisas o tornam honesto:
- O registo transporta o estado -
unverified,invoice_pending- não um comentário num ficheiro de log. - Alguma coisa volta a tentar, com backoff, e desiste com barulho, não em surdina.
- Alguém consegue ver a fila. Um ecrã de admin que lista o que está à espera, com uma contagem, visto por uma pessoa que vai reparar se não estiver a zero.
Sem a terceira, não construíste resiliência. Construíste um sítio onde se acumulam problemas que ninguém vai encontrar.
Escreve a decisão
A parte que conta mesmo não é o código. É que esta decisão é tomada uma única vez, explicitamente, para cada dependência - e fica registada, para que a próxima pessoa não a inverta por engano enquanto arranja outra coisa. Uma tabela no documento de arquitetura com três colunas: a dependência, o comportamento e uma frase de porquê. Dez minutos, e fecha uma discussão que de outra forma se repetiria todos os anos.
O mesmo raciocínio aplica-se àquilo sobre o qual a decisão está escrita: um sistema cujas contas não controlas já está em fail open, permanentemente. É disso que trata a nota sobre o que realmente possuis.