Alex Fernández
Físico de carrera
Ingeniero de software de profesión
Reversibilidad e irreversibilidad
Desarrollo de software
Arquitectura de software
DevOps
Gestión y toma de decisiones
Ni computación reversible
Ni ingeniería inversa
Ni termodinámica
ni teoría de (la) información
No es ciencia dura sino ingeniería
calor
energía
caos
desorden
irreversibilidad
incertidumbre
degradación
complejidad
¿Quieres saber lo que es la "entropía"?
¡A quién le importa, hablemos de reversibilidad!
Un sistema reversible:
Es el proceso más eficiente
Puede revertirse en el tiempo
sin usar energía extra
Funciona en ambas direcciones
Lleva al sistema a su estado inicial
sin efectos colaterales
El proceso debe ser infinitamente lento
No puede tener efectos colaterales:
¿cómo sabemos que ha ocurrido?
Ah, y ya puestos:
es imposible en el mundo real
Eficiencia
Estabilidad
Predecibilidad
Lentitud
No puede revertirse en el tiempo
Sólo funciona en una dirección
Es imposible llevar al sistema al estado inicial
Tiene pérdidas y disipación:
es ineficiente
Velocidad
Turbulencia
Caos
Complejidad
Operaciones básicas:
Alta ↔ Baja
Modificación
Consulta
Tests autocontenidos: dejan el sistema intacto
Pero con efectos colaterales (log, consola)
Puede revertirse en el tiempo
(al menos para nuestro sistema)
Puede funcionar en ambas direcciones
(con una fuente de energía)
Lleva al sistema de vuelta a su estado inicial
(con efectos colaterales)
Usa un proceso ineficiente
Trabaja en ciclos
Cada ciclo cuesta un poco de esfuerzo
Cada ciclo puede revertirse
a un coste pequeño
Los ciclos pequeños son mejores que los grandes
CVS guarda los cambios en un fichero de log
SVN guarda las revisiones como diffs
Git almacena la historia en deltas
Fácil volver al HEAD previo
Fácil revertir un commit previo
Fácil truncar la historia y resetear
Volver a un punto arbitrario del pasado
¡fácilmente!
Snapshots automáticos
Cruces de ramas
Aplicación visual con comandos
Cada comando puede deshacerse
... y rehacerse
Mucho más fácil probar distintos cambios
Pequeños ciclos de escribir-compilar-enlazar-correr
Ciclos más grandes de escribir-probar-depurar-corregir
Ciclos enormes de escribir-integrar-desplegar
Cuanto más pequeño el ciclo, más eficiente el proceso
Reducir el ciclo: escribir-compilar-enlazar-correr
Reducir el ciclo: escribir-probar-depurar-corregir
Reducir el ciclo: escribir-integrar-desplegar
Graba y despliega sólo si compila y pasa pruebas
Todas las peticiones son autocontenidas
El servidor no tiene contexto
El cliente mantiene su propio estado
Puede paralelizarse
No guarda estado en memoria
(excepto datos cacheados)
Puede resetearse a voluntad
Toda la información se vuelca en sistemas externos
(y en ficheros de log)
Evita romper las APIs existentes
Porfa porfa plís
Mantén la compatibilidad hacia atrás
... ¡y hacia delante!
Avisa sobre funciones deprecadas
Sólo se pueden eliminar las funciones sin usuarios
¡Expulsa tu calor extra por el escape!
La información no es “entropía negativa”
¡La entropía es lo mismo que la información!
Expulsa tu información sobrante por un “escape”
a un “reservorio”
Reservorios de información:
Más capas de compatibilidad
Compatibilidad hacia delante y hacia atrás
Ejemplo: Migración de Python 2.x → 3.x
¡y migración 3.x → 2.x!
Tras la integración, deberíamos volver al estado inicial
Debería ser un proceso repetible
Entorno ideal: creado ad hoc
y luego destruído (como Travis-CI)
El proceso reversible está siempre en equilibrio
El sistema está estable cuando pasa todos los tests
No dejes que tu sistema se aleje del equilibrio
Es mucho más difícil volver al camino
Haz tu desarrollo en pasos pequeños
Pasa las suites de pruebas a menudo
y corrige los fallos antes de seguir
Snapshots de disco
Snapshots del sistema operativo
En la nube: snapshots en todas partes
Permiten un rollback inmediato a estados previos
Snapshots diferenciales
Vuelve atraś una parte manteniendo el resto
Ejemplo: revertir el sistema operativo, mantener aplicaciones
Control de versiones para ficheros de configuración
Pon tu código en producción
Pon tu código en producción
Despliega en incrementos pequeños
Rollbacks inmediatos
Rollbacks automáticos
Hacer que sea fácil volver a un momento previo
¡y volver hacia delante de nuevo!
Los rollbacks automáticos deberían ser sencillos
y ubicuos
Reducir los ciclos de despliegue aún más
hasta tiempo real (en según qué entornos)
Ciclo de dos fases
Primero despliega el código inactivo
Luego activa la funcionalidad
Ambas partes son reversibles
Muchos pasos irreversibles
Las tareas cerradas no se pueden revisitar
... son irreversibles por naturaleza
Un proceso repetible está más cerca de la reversibilidad
Las funcionalidades se liberan sólo cuando están listas
Las tareas pueden reabrirse si hace falta
¡y no es un drama!
Las funcionalidades pueden mejorarse
Las versiones están orientadas a la mejora
Las releases pequeñas son mejores que las grandes
Ejemplo: Linux 2.4.x -> 2.6.x: cambio grande y peludo
Linux 2.6.x -> 3.x: mejora continua
Evita las releases si puedes
¡Las “rolling releases” son la mejor opción!
Así que la clave para evitar las grandes decisiones es evitar hacer cosas que no tienen remedio. No dejes que te arrinconen sin escapatoria posible. Una rata arrinconada puede ser peligrosa -- un manager arrinconado es patético.