Fail open, fail closed - decide una vez, por cada dependencia

Cada servicio externo al que llama tu sistema dejará de estar disponible en algún momento. No "podría" - lo hará. La única pregunta es qué hace tu sistema durante esos minutos, y esa pregunta tiene una respuesta correcta por dependencia, no por sistema.

Las dos opciones

Fail closed: la dependencia está caída, así que la operación se rechaza. Seguro, evidente, y lo que hace la mayor parte del código por accidente, porque una excepción que no ha capturado nadie hace fail closed por defecto.

Fail open: la dependencia está caída, así que la operación continúa, y el trabajo que falta entra en una cola y se marca para una persona. Requiere un diseño deliberado y un sitio donde caiga la marca.

La pregunta que lo decide

Pregúntate: si este tercero está caído una hora, ¿quién paga?

Piensa en una verificación anti-bot en un formulario de reserva. Si el proveedor no está accesible y haces fail closed, rechazas todas las reservas durante una hora - has convertido la caída de otro en tus ingresos perdidos, para evitar quizá dos envíos de spam. Haz fail open, acepta la reserva, márcala como no verificada y ocúpate a mano de las pocas que sean malas.

Ahora piensa en tu propio rate limiter. Si falla, no hay ningún tercero a quien echarle la culpa, y hacer fail open significa que simplemente has apagado una protección justo en las condiciones en las que es más probable que haga falta. Ese hace fail closed.

El patrón que sale es el mismo en cada sistema que he construido:

  • Fail open - la entrega de SMS y correos, la analítica y los eventos de píxel, las verificaciones anti-bot, la sincronización de facturación y contabilidad, el push al CRM, la búsqueda de direcciones. Cualquier cosa cuyo valor esté registrado en otro sitio o se pueda conciliar más tarde.
  • Fail closed - la autorización de pagos, la autenticación y las verificaciones de sesión, las verificaciones de permisos, tus propios rate limits y validaciones, y cualquier cosa que pudiera dejar a un cliente ver los datos de otro cliente.

Fail open no significa "lo lanzas y te olvidas"

El modo de fallo de un fail open mal implementado es peor que fail closed, porque es silencioso. Tres cosas lo hacen honesto:

  • El registro lleva el estado - unverified, invoice_pending - no un comentario en un fichero de log.
  • Algo reintenta, con backoff, y se rinde de forma ruidosa, no en silencio.
  • Alguien puede ver la cola. Una pantalla de admin que lista lo que está esperando, con un número, vista por una persona que se dará cuenta si no es cero.

Sin la tercera, no has construido resiliencia. Has construido un sitio donde se acumulan problemas que no encontrará nadie.

Escribe la decisión en algún sitio

La parte que de verdad importa no es el código. Es que esta decisión se toma una sola vez, de forma explícita, para cada dependencia - y se deja constancia, para que la siguiente persona no la invierta por error mientras arregla otra cosa. Una tabla en el documento de arquitectura con tres columnas: la dependencia, el comportamiento y una frase de por qué. Diez minutos, y cierra una discusión que, de lo contrario, se repetiría cada año.

El mismo razonamiento se aplica a aquello sobre lo que se escribe la decisión: un sistema cuyas cuentas no controlas ya ha hecho fail open, de forma permanente. De eso trata la nota sobre lo que de verdad es tuyo.