La apuesta hecha con Typesafe que me llevó a desarrollar Akka
This was originally posted on Takipi blog. Takipi tells you when and why code breaks in production. Learn more.
Yendo a las raíces: las líneas perdidas de código en el camino hacia Akka Streams, Akka HTTP y Akka Typed
Si alguna vez has sentido curiosidad sobre cómo son desarrolladas las funcionalidades esenciales y sobre por qué tus tecnologías favoritas toman cierto rumbo, has arribado al lugar indicado. En la nueva serie de artículos del blog Takipi sobre decisiones de diseño, descubrirás quiénes llevan el timón de las herramientas y frameworks que usas a diario. Verás qué es lo que los hace aprobar algo y darlo por realizado, cómo las cosas van encajando. Conocerás a los desarrolladores detrás de todas esas líneas de código y tendrás la posibilidad de sumarte y formular esas intrigantes preguntas que siempre has querido que te contestaran.
http://bit.ly/1GYUr7j pic.twitter.com/H5oTlhD9Uz
En la primera entrevista, hablamos con el doctor Roland Kuhn, líder tecnológico de Akka en Typesafe, para conseguir una visión, desde adentro, del trabajo que hay detrás de Akka. En Typesafe, Kuhn y su equipo son los responsables de decidir cuál será el siguiente paso con el framework, las semánticas de las nuevas operaciones, así como también de determinar cuáles son las soluciones adecuadas para los problemas que se aspira a resolver. Lo que no es tan sabido es que Roland se convirtió en un colaborador esencial de Akka justo antes del lanzamiento de la versión 1.0, en enero del 2011. En Navidad, él le propuso a Viktor Klang, que actualmente es el director alterno de tecnología de Typesafe, la idea del CallingThreadDispatcher, a lo cual la respuesta fue: - ”Nooo, no puedes hacer eso. ¡Te reto a escribir uno!”. Y eso fue precisamente lo que sucedió. “Trabajar en un proyecto de código abierto ha sido mi sueño por ya ni sé cuánto tiempo” decía Roland, y eso fue lo que lo llevó allí.
De izquierda a derecha: Konrad Malawski, Martynas Mickevičius, Roland Kuhn, Endre Sándor Varga, y Patrik Nordwall.
El equipo Akka está compuesto por 5 desarrolladores y el único requisito para sumarse consiste en vivir en Europa o mudarse hacia allí. Aunque es un equipo distribuido, ellos se juntan de manera regular y están siempre casi dentro del mismo huso horario. Pero esa no es toda la historia, ya que en el caso de Akka, la comunidad cobra, asimismo, un rol preponderante y es probablemente la mayor motivación detrás de la creación del framework.
Los problemas que Akka aborda son los de la computación distribuida
“Se ha descrito al modelo de actores como un constructo de la concurrencia; pero ese es un punto de vista muy acotado”, sostiene Roland. “En realidad, está ligado a la distribución. Agentes independientes distribuidos que se comunican usando mensajes, y eso es precisamente en lo que nosotros nos enfocamos; todo en Akka apunta hacia allí. Puedes ejecutar tu aplicación en un proceso único, y también puedes ejecutarla en clúster de unos cuantos miles de nodos, si fuera necesario. Todas las funcionalidades que hemos incorporado se centran en posibilitar que los actores hagan algo”.
“La preocupación que ocupa el escalafón superior siempre es la de mantener el modelo puro y simple. Así que la facilidad de uso, como se le define habitualmente, no es nuestro objetivo primordial. Nuestra perspectiva es la de que necesitamos exponer la complejidad esencial del dominio que modelamos. Y en términos de computación distribuida, eso significa que si tú realmente quieres escribir una aplicación distribuida, entonces tendrás que entender qué es lo que eso implica, Akka no te libera de ese aspecto. Lo que sí hacemos es brindar una abstracción, un actor en este caso, que destila la esencia de lo que implica la distribución y que, tras ello, simplemente funciona. Envías un mensaje a un actor y el mensaje será enviado a dicho actor, sin importar en qué parte de un clúster viva el destinatario”.
“Somos fuertes defensores de usar la herramienta apropiada para cada trabajo, así que intentamos desarrollar algo simple, y por lo tanto fácil de entender, pero tú tienes que estar dispuesto a analizar lo que estás usando. Y deberá funcionar sin compromisos en todas las situaciones, aun cuando eso pueda significar un pequeño sacrificio en rendimiento. Y, aún dentro de estas limitaciones, tratamos de hacerlo lo más veloz posible”.
Seis versiones de Akka Streams fueron desechadas antes de quedarse con esta
“Dejamos que la comunidad nos guíe, aunque esa no es la pura verdad, pues a veces es necesario que caminemos unos pasitos adelante y entonces algunos nos seguirán y validarán, o bien, bueno, simplemente nos dirán qué hay de malo con nuestras ideas. Akka Streams, por ejemplo, fue concebido tras notar, en nuestra lista de correo, que los desarrolladores que usan Akka frecuentemente enfrentan dos tipos de problema:
1. Envían mensajes de un actor a otro, y el actor destinatario tiene un buzón de correo con capacidad ilimitada así que no lidian con back pressure, o no se preocupan por ella, tras lo cual dicho buzón crece sin límites hasta que aparece un OutOfMemoryError. Así que el patrón que debe ser implementado aquí es el control de flujo.
2. Actualmente, los actores no están “tipados provechosamente”, como me gusta llamarlo, están “unitipados”. Puedes enviar cualquier mensaje a cualquier actor. Estamos intentando cambiar eso, y creo que tenemos buenas chances de lograrlo con el proyecto Akka Typed. Pero, al mismo tiempo, esto concede mucha libertad, así que puedes modelar cualquier patrón de mensajería con él”.
“Básicamente, Akka Streams es algo que la comunidad pedía a gritos”
“Así que, vimos estos problemas y pensamos, bueno, empaquetemos todo eso y creemos una abstracción que lo resuelva, que terminó siendo Akka Streams. Pensamos que tenía que ejercer back pressure, no podía quedarse sin memoria, y sus tipos debían ser verificados de forma apropiada, toda la configuración. Estas no son limitaciones muy específicas, y eso explica por qué nos llevó un año y medio de experimentar, generar nuevas soluciones y descartarlas creo que como seis veces, al menos hasta cuando llevé la cuenta, antes de decidirnos por un diseño que ahora sí pensamos que va a ser exitoso.”
El estado de Akka Streams: ¿Está listo para producción?
Akka Streams está diseñado como una solución genérica para el problema del proceso de flujos. Te permite describir cualquier tipo de flujo de datos, modelar cualquier tipo de combinación, y ya no solo confiar en transformaciones como Map o Filter, sino también modificar la frecuencia con la que los elementos fluyen. Esto significa que puedes combinar múltiples elementos en uno solo, si la entrada es demasiado rápida, o extrapolar, convirtiendo un elemento en varios. Otra de las operaciones, también incluida, es la modelación de cruces, de forma que es posible combinar, así como encaminar a múltiples destinatarios.
Además, Roland dice “Intentamos ser tan profundos y meticulosos como podemos en nuestras revisiones. Así que los códigos deberían funcionar, aun cuando es una rama del desarrollo, y por lo tanto presenta errores, la gente ya lo está usando en sistemas de producción. Resuelve estos problemas de back pressure y de tener más seguridad con los tipos y la gente está deseando eso, y tanto es así que usan hasta estas versiones preliminares, aún en desarrollo. Buscamos que la próxima versión satisfaga esta demanda.”
“Al usar Akka Streams, estamos cambiando la perspectiva de cómo el HTTP debería ser manejado”
Lo próximo que aparece en el mapa es Akka HTTP. Tradicionalmente, HTTP era manejado de manera que una solicitud era un objeto y la respuesta era otro. Recibes una solicitud, y entonces generas una respuesta que es pasada de vuelta a la capa HTTP y de vuelta al cliente. Según Roland, eso ya se está convirtiendo en la antigüa manera de hacer las cosas: “Se ha vuelto más y más claro que no solo quieres intercambiar pequeños pares de solicitudes y respuestas, sino que a veces tienes que subir y bajar algunos gigabytes de datos y allí este modelo no se ajusta a las necesidades. Ya que estamos arrancando de cero, Akka HTTP está completamente diseñado en Akka Streams. Por lo tanto, cuando recibes una solicitud HTTP en Akka HTTP, en realidad se trata de un flujo de cadenas de bytes que puedes redactar, puedes transformar, puedes pasar a otro servidor o a un archivo sin necesidad de tener bytes en memoria. Y creo que eso es algo nuevo que agregamos, hacemos un manejo HTTP completamente basado en flujos”.
Akka Typed: una solución que funciona no necesariamente es la solución apropiada
Otro proyecto planificado para el futuro de Akka es Akka Typed, que hará que la verificación de tipo esté disponible para la interacción entre los distintos actores. Roland comenzó con ello en Akka 1.2, al intentar unificar Futures y ActorRefs con la abstracción de un canal: “Al final eso no funcionó y lo quité. Más tarde, cuando salieron las macros de Scala, creamos otra implementación que funcionaba pero tampoco tuvo éxito, pues las macros son una funcionalidad experimental y mucha gente no se animaba a usarla para productos comerciales. Así que ese es el motivo por el cual Typed Channels también fue descartado. Funcionaban pero eran demasiado complejos, así que fue un experimento abortado. Tras haber visto estos fracasos, al final me rendí y simplifiqué toda la propuesta, quitando de nuestra implementación del modelo de actores aquellas funcionalidades de Akka que no están en el modelo original”.
“Akka Typed será parte de nuestra próxima versión: en una versión preliminar aún más experimental que lo habitual. Va a tomar un buen tiempo hasta que esta parte sea calificada de estable”.
“En vez de ActorRefs, ahora son ActorRefs de cierto tipo T, y no puedes enviar mensajes de otro tipo que no sea T a este ActorRef. Este es el cambio básico, aunque también cambia mucho en lo interno. No estoy seguro cuándo o si es que alguna vez vamos a eliminar los actores no tipados, puede que ambos convivan por un tiempo, mientras todos experimentamos con Akka Typed y aguardamos por las opiniones de la comunidad con respecto a qué dirección tomar”.
¡Selfi en la Hangout!
“Una cosa que no hemos terminado de arreglar es Akka Persistence , así que todavía tiene el indicador de experimental. Dados los comentarios de la comunidad, concluimos que teníamos que lanzar Akka Streams primero, para poder usarlo en Akka Persistence. Eso es algo en lo que también trabajaremos en este año”. También preguntamos si habían algunos otros arreglos esperando ser introducidos en Akka:
“Cometimos algunos pecados en el diseño que ahora ya son imposibles de solucionar, pues se llenaría el código de errores”.
“Uno de ellos es que puedes llamar a System.ActorOf y recibir un ActorRef, de forma sincrónica. Esto no debería ser así, tal como lo demuestra el código que fue necesario escribir para apoyarlo. Es realmente sutil y demasiado complejo. Ya que no podemos eliminar System.ActorOf, la manera en la que pensamos modificar esto es al no incluirlo en Akka Typed. En Akka Typed, hay un nuevo tipo de sistema de actores que cumple con el mismo objetivo, pero ya no tiene ningún ActorOf. Así que mi astuto plan consiste en ofrecer esto, mostrárselo a la comunidad y ver si alguien grita: “NECESITO MI ACTOROF EN EL SISTEMA!”.
“Lo cómico de esto es que, con todos estos cambios, estamos eliminando aspectos que hemos ido añadiendo sobre el modelo de actores original. Así que estamos haciendo las cosas más compactas, estamos volviendo más y más cerca del modelo de actores que anteriormente supimos tener”.
“Seguimos sintiéndonos inspirados por ideas de tiempo atrás, así que lo que escribió Carl Hewitt en 1973 todavía está vigente y lo implementamos, pero también nos producen inspiración los avances más recientes en el campo teórico de las ciencias de la computación. Por ejemplo, los CRDTs (Conflict-free Replicated Data Types, o tipos de datos replicados sin conflicto) nos parecen sumamente interesantes. Nos topamos con uno cuando implementamos el clúster de Akka, implementamos nuestro propio CRDT antes de que la documentación que lo describe fuera publicada, y pienso que vamos a seguir trabajando con ellos”.
Con relación al soporte para Java y Scala, Roland dice “Nuestra filosofía en general ha sido la de ofrecer API para Java y para Scala en los mismos objetos. Todo lo que hacemos funciona bien tanto en Java como en Scala e intentamos ofrecer las mismas posibilidades a ambas”.
Depuración de actores a escala: el mundo ya está distribuido y no podrás pararlo
La antigüa estrategia de añadir un depurador, dar con un punto de interrupción y entonces parar el mundo ya no funciona: “Otros sistemas también van a estar ejecutándose mientras tú verificas tus datos, generalmente aparecerán timeouts, y el comportamiento del programa al usar el depurador, en fase de desarrollo, será muy distinto del que tú quieras entender en producción. Ese es el motivo por el cual, para depurar sistemas reactivos de cualquier tipo, vas a tener que confiar en el seguimiento, el monitoreo y el registro (logging) en un sistema en funcionamiento. No puedes poner un punto de interrupción en tu entorno de desarrollo y ver qué ocurre pues, frecuentemente, eso no te dice lo que tú necesitas saber”.
¿Cómo depurar sistemas distribuidos?
Los entornos de producción a gran escala pueden producir millones de errores por día desde cientos de áreas distintas del código. Mientras que puede que algunos no sean gran cosa, otros hacen que funcionalidades críticas fallen y, por lo tanto, afectan al usuario final sin que tú te enteres. Habitualmente, para identificar y resolver estos errores, tendrías que confiar en tus archivos de log o en una herramienta de manejo de logs para, por lo menos, saber qué fue lo que ocurrió, ni hablemos de arreglarlo. PERO… si estás depurando una aplicación en Scala o en Java, ahora las cosas son algo distintas. Con Takipi entre tus aplicaciones de monitoreo, puedes detectar excepciones capturadas o no capturadas, errores de log y de actores, y ver el código y el estado de variable que los causó. Compruébalo por ti mismo aquí.
Para concluir, queremos darle las gracias a Roland por aceptar esta entrevista con nosotros, y deseamos que te haya parecido interesante a ti, ¡tanto como a nosotros! Ha sido un paseo interesante y deseamos que ahora puedas entender mejor cómo funciona Akka, en qué está basado, y cuáles son las fuerzas que continúan moviéndolo mientras nosotros hablamos. También ha estado genial conocer más sobre el recorrido de Roland, desde que siguió un mensaje en la lista de correo de Scala, hasta que se convirtió en el líder tecnológico de Akka, cumpliendo su sueño de trabajar en un proyecto de código abierto. Es interesante pensar en cómo continuará este recorrido y dónde nos llevará en la próxima.
Si tienes más preguntas o sientes curiosidad por aclarar algunos asuntos que no hayan sido cubiertos en esta entrevista, siéntete libre de formular tus preguntas en la sección de comentarios que aparece más abajo.
Encuentra el código y el estado de variable detrás de tus errores en producción: Prueba Takipi para Scala
Reader Comments