Mostrando las entradas con la etiqueta Akka. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Akka. Mostrar todas las entradas

lunes, 5 de junio de 2023

Pekko: El fork open source de Akka que impulsa la escalabilidad en sistemas concurrentes


En el mundo de la programación concurrente y distribuida, Akka ha sido una herramienta ampliamente reconocida y utilizada. Sin embargo, recientemente hubo un cambio de licencia que no cayo nada bien pero por suerte aparecio Pekko, un fork open source de Akka que busca llevar la escalabilidad de sistemas concurrentes a un nuevo nivel. 

¿Qué es Pekko? Pekko es un fork open source de Akka, un framework de programación concurrente y distribuida basado en el modelo de actores. Al igual que Akka, Pekko proporciona una forma elegante y eficiente de construir sistemas altamente concurrentes y escalables. 

Arquitectura de bajo acoplamiento: Pekko ha sido diseñado con una arquitectura de bajo acoplamiento que permite un mejor aislamiento y desacoplamiento entre los actores. Esto se traduce en una mayor flexibilidad y capacidad de escalar los sistemas de forma eficiente.

Rendimiento mejorado: Pekko ha optimizado el rendimiento en comparación con Akka, especialmente en escenarios de alto tráfico y carga intensiva. Gracias a su implementación eficiente y algoritmos optimizados, Pekko es capaz de manejar un mayor número de mensajes por segundo y reducir la latencia en las comunicaciones.

Escalabilidad elástica: Pekko ha introducido un enfoque innovador para la escalabilidad elástica, permitiendo que los sistemas se adapten automáticamente a las demandas cambiantes de carga. Esto se logra mediante la capacidad de ajustar dinámicamente la cantidad de recursos asignados a los actores en función de la demanda, lo que garantiza un rendimiento óptimo en todo momento.

Mejoras en la tolerancia a fallos: Pekko ha fortalecido los mecanismos de tolerancia a fallos, lo que garantiza una mayor robustez en entornos distribuidos. Mediante la implementación de estrategias de recuperación y supervisión mejoradas, Pekko ayuda a gestionar los errores y a mantener la estabilidad del sistema, incluso en situaciones adversas.

Facilidad de migración: Pekko ha sido diseñado para facilitar la migración desde Akka. Los desarrolladores pueden aprovechar su experiencia previa con Akka y adaptarse rápidamente a Pekko sin mayores obstáculos.

Comunidad activa: Pekko cuenta con una comunidad open source vibrante y activa. Esto implica que los desarrolladores pueden colaborar, compartir conocimientos y contribuir a la mejora continua del proyecto.

Documentación exhaustiva: Pekko ofrece una documentación completa y bien estructurada, que incluye guías, tutoriales y ejemplos de código. Esto facilita la adopción y el aprendizaje de la herramienta.

Por ahora Pekko esta en incubador de apache pero creo que tiene futuro. 

Pekko representa un emocionante avance en el mundo de la programación concurrente y distribuida. Con su enfoque en la escalabilidad, rendimiento y facilidad de uso, este fork open source de Akka ofrece una alternativa sólida y poderosa para desarrolladores y arquitectos de sistemas. Si estás interesado en construir sistemas concurrentes altamente escalables, Pekko definitivamente merece tu atención.

Dejo link : https://pekko.apache.org/

Mi experiencia con la programación funcional en Scala


Creo que si leen este blog saben que me encanta la programación funcional y investigar y aprender. Y en eso estoy...


Me gustaría contar un poco mi evolución y mis altibajos para que la gente que sabe me aconseje y los que no saben puedan aprender de mis exitos y derrotas. 


Bueno, todo empezó con un curso de scala de coursera y quede encantado con el lenguaje y la programación funcional. De a poco tambien me interiorice en otros lenguajes como erlang, haskell, Clojure, Elixir, F#, etc ... pero siempre en la volvía a Scala por gusto nomas. Y me iba bastante bien...


Hasta que empece a quedarme corto en scala, quería progresar y decidí ver algunos framework funcionales, leí un libro de Cats y la verdad es que si bien esta bueno, me frustre mucho... porque no sabia porque se hacían ciertas cosas, no entendía porque tan complejo o si bien entendía desconfiaba ( no hay otra forma de hacerlo más fácil) y bueno ... 


Cambie a Akka, y me pareció bueno y me sentí más en mi mundo, pero justo justo cuando volvia el entuciasmo, cambio de licencia y bueno... Se fue el entusiasmo, ahora sé que existe un fork open source llamado pekko (https://github.com/apache/incubator-pekko) y es de apache. Pero lo veo verde, y no sé cuanto va a crecer ...


Y ahora estoy con ZIO y por ahora todo va bien, por ende la conclusión es si quieren progresar en su conocimiento en Scala, y no vienen del mundo funcional como Haskell, ZIO esta bueno. 

Si son nuevos en el mundo funcional y scala, yo haría lo siguiente: 

1. Estudiar Scala (curso de scala de coursera, el libro rojo de programación funcional en scala, etc ...)

2. Leer y estudiar ZIO 

3. Leer y estudiar Cats


Pero no perder de vista Pekko, para ver como progresa. 


Que opinan? 


lunes, 3 de octubre de 2022

Cambio de licencia de Akka


Les cuento, hace unas semanas me puse a estudiar Akka, que es un conjunto de herramientas para escribir aplicaciones distribuidas concurrentes basadas en el modelo actor, fue creado hace trece años por Jonas Bonér, fundador y director ejecutivo de Lightbend. La compañía ha anunciado recientemente un nuevo modelo de licencia Akka que ha cambiado de Apache 2.0 de código abierto a Business Source License (BSL) 1.1.

Esto significa que el código base de Akka solo es de uso gratuito para el desarrollo y en sistemas que no son de producción. La licencia BSL 1.1 permite que los proyectos elijan otra licencia después de un período de tiempo específico que reemplazará la licencia BSL 1.1. Lightbend decidió revertir la licencia BSL 1.1 a una licencia Apache 2.0 después de tres años. Varios otros proyectos de código abierto, como Couchbase, Sentry y MariaBD, se han movido a la licencia BSL 1.1 en los últimos años.

La nueva licencia afecta a todas las empresas con ingresos superiores a 25 millones de dólares que deseen utilizar la última versión de Akka. Las versiones actuales aún se pueden usar libremente, pero solo se publican actualizaciones y parches de seguridad críticos para la versión 2.6.x bajo la licencia actual de Apache 2.0 hasta septiembre de 2023. Los proyectos de código abierto pueden comunicarse con Lightbend para obtener una subvención de uso adicional.

En resumen, me parece que indicios de que el producto no va por buen camino y desean exprimirlo. 

Que piensan de estos cambios de licencia?

Dejo link: https://www.infoq.com/news/2022/09/akka-no-longer-open-source/#:~:text=The%20company%20has%20recently%20announced,and%20on%20non%2Dproduction%20systems.

sábado, 1 de octubre de 2022

Primeros pasos con Akka


Ante de empezar veamos este link, para ponernos en contexto : 
https://emanuelpeg.blogspot.com/2022/09/por-que-usar-akka.html

Implementamos el trait Actor en una clase simple llamada Contador. 

import akka.actor.Actor


class Counter extends Actor {

  var count = 0

  def receive = {

    case "incr" ⇒ count += 1

    case "get"  ⇒ sender() ! count

  }

}


Este tiene un campo count y debe implementar el método de receive del trait Actor y debe devolver una función parcial. Esa es la función parcial con una declaración de pattern matching con el mensaje entrante. 

Entonces, si recibimos un mensaje con una cadena incr, entonces queremos incrementar el contador. Lo que hacemos aquí. Si queremos que tenga estado, queremos permitir que otros actores averigüen cuál es el valor del contador. Y por lo tanto los actores pueden enviar mensajes a direcciones que conocen. Las direcciones en Akka están modeladas por el tipo ActorRef. Entonces, escribimos otro caso, y si obtenemos una tupla con la cadena get, y algo con tipo ActorRef, que llamamos cliente, entonces podemos enviar al cliente, el conteo como un mensaje. 

El operador de signo de exclamación que se usa para enviar mensajes y se pronuncia tell en Akka. Cada actor conoce su propia dirección. Es un ActorRef llamado self. Y está implícitamente disponible. ActorRef es una cláusula abstracta que tiene un método llamado tell o signo de exclamación. Y si usa el signo de exclamación que es la buena sintaxis de Scala, tell que es más para Java. Esto requiere un argumento implícito. 

El argumento implícito de tipo ActorRef se recoge del entorno. Entonces, si usa el operador Tell dentro de un actor, implícitamente seleccionará al remitente como la referencia propia de ese actor. Dentro del actor receptor, este valor está disponible como remitente, que devuelve la referencia del actor que ha enviado el mensaje que se está procesando actualmente.

La referencia junto con el mensaje al actor receptor debe hacerse explícitamente en otras implementaciones de actor como erlang. Pero como es un patrón tan común, existe el metodo sender()  que es la referencia al que me envia el mensaje.

Un actor puede hacer más cosas que simplemente enviar mensajes. Puede crear otros actores y puede cambiar su comportamiento. Para acceder a estas funciones, necesitamos conocer el contexto del actor. 

El tipo de actor en sí solo tiene el método de recepción, por lo que solo describe el comportamiento del actor. La maquinaria de ejecución la proporciona el contexto del actor. 

Se tienes acceso al contexto dentro del actor simplemente diciendo contexto. Ahora veamos esto en acción. Podemos reformular nuestro contador en uno que no tenga barra. Será un objeto con estado sin una variable explícita. 

Primero, necesitamos definir un método, que nos dé un comportamiento. Este método toma un argumento, cuál es el estado actual del contador. Empezamos con el contador en cero. Si recibimos un mensaje incr aquí, cambiamos nuestro comportamiento para que sea el de un contador de n más 1.  Dentro de este comportamiento del contador, en cualquier momento podemos obtener una solicitud, donde solo respondemos con el valor actual de los contadores. 

import akka.actor.Actor


class Counter extends Actor {

  def counter(n: Int): Receive = {

    case "incr" ⇒ context.became(counter(n + 1))

    case "get"  ⇒ sender() ! n

  }

  def receive = counter(0)

}

Puede ver aquí que se parece un poco a una función recursiva de cola, porque la llamamos dentro de sí misma, pero es asíncrona, porque context.become evalúa lo que se proporciona aquí solo cuando se procesa el siguiente mensaje. 

Esto es funcionalmente equivalente a la versión anterior del contador, pero tiene algunas ventajas. En primer lugar, solo hay un lugar donde se cambia el estado, y ese es el llamado a convertirse, y esto es muy explícito. La otra es que el estado se limita al comportamiento actual, por lo que no hay ninguna variable que podamos dejar en algún lugar en un estado desconocido. Siempre tenemos el estado actual aquí. 

Lo último que uno puede hacer fundamentalmente con los actores es crearlos y detenerlos. El contexto del actor tiene métodos para eso. Primero, actorOf, una descripción sobre cómo crear un actor y un nombre, y devuelve un ActorRef. Además, cada actor puede detener a otros actores. 

Una cosa a tener en cuenta aquí es que los actores siempre son creados por actores. Esto significa que naturalmente forman una jerarquía porque un actor es creado exactamente por otro actor. Y otra cosa a tener en cuenta es que detener aquí a menudo se aplica a la auto referencia, lo que significa que el actor decide que quiere terminar. Probemos todo esto en una aplicación ejecutable. 


import akka.actor.Actor

import akka.actor.Props


class CounterMain extends Actor {

  val counter = context.actorOf(Props[Counter], "counter")


  counter ! "incr"

  counter ! "incr"

  counter ! "get"


  def receive = {

    case count: Int ⇒

      println(s"count was $count")

      context.stop(self)

  }

}


Por supuesto, una aplicación también se modela como un actor en este modelo. Entonces lo llamamos CounterMain. Este es un actor y usa el contexto actorOf para crear un contador. Podemos decir Props Counter para crear un actor que no tome argumentos de constructor. Y como todas las cosas buenas. Necesita un nombre, lo llamamos contador en este caso. 

Luego enviamos mensajes a este contador, en este caso lo enviamos incr tres veces y luego lo enviamos get. Recuerde que enviar con el operador de tell dentro de un actor seleccionará la referencia propia como remitente. Y como el contador responderá, lo recibiremos en este actor. Aquí en nuestro comportamiento, recibimos la cuenta, que es de tipo int. Lo imprimiremos y luego nos detendremos. 

Para ejecutar esto, debemos decirle a Eclipse cómo ejecutar las aplicaciones de actor porque actualmente aún no lo sabe. Entonces creamos una configuración de ejecución. Utiliza la clase principal akka.Main que espera como primer argumento, el nombre de la clase, el nombre completo de la clase de actor que se va a instanciar. Entonces, si ejecutamos esto. Veremos que la cuenta imprime tres. Esta impresión se hizo con esta línea, así que recibimos el conteo del contador y recibimos tres porque incrementamos el contador tres veces.

Ahora hemos visto todas las cosas básicas que pueden hacer los actores. Cuando reciben un mensaje, pueden enviar mensajes, crear actores. Y pueden cambiar su comportamiento para el próximo mensaje,  este es el modelo actor de computación.

Dejo link : https://akka.io/

martes, 27 de septiembre de 2022

Por que usar Akka?


Las transmisiones reactivas fluyen los datos desde los productores hasta los consumidores. Pero todo va más o menos en una dirección. Los actores te dan más libertad que eso. Porque pueden colaborar y comunicarse como lo hacemos los humanos.

En particular, hablaremos sobre cómo los actores pueden crear otros actores. Cómo cambian su comportamiento con el tiempo, cómo intercambian mensajes. 

Antes de sumergirnos en lo que son los Actores, primero echemos un vistazo a por qué queremos investigarlos y de dónde provienen.

El formalismo Actor fue publicado por primera vez por Hewitt, Bishop y Steiger en 1973. Y lo que querían lograr es crear un modelo en el que puedan formular los programas para su investigación de inteligencia artificial.

Uno de los estudiantes de Hewitt publicó su tesis doctoral en 1986. Gul Agha formuló lenguajes de actores, cómo escribir programas de actores, cómo razonar sobre ellos. Describió los patrones de comunicación entre los Actores y cómo usarlos para resolver problemas reales.

En el mismo año, Ericsson comenzó a desarrollar un lenguaje de programación llamado Erlang. Este es un lenguaje de programación puramente funcional, cuyo modelo de concurrencia se basa en Actors. Y que luego se utilizó posteriormente en productos comerciales.

En 1995, Ericsson presentó su nueva plataforma de telecomunicaciones. El cual tuvo un gran éxito. Hubo alrededor de 30 milisegundos de tiempo de inactividad por año. Esta solidez y resiliencia fue posible gracias al modelo Actor.

Inspirado por el éxito de Erlang de Ericsson, Philipp Haller agregó Actors a la biblioteca estándar de Scala en 2006.

Luego, Jonas Bonér fue influenciado por Erlang, así como por Scala Actors para crear Akka en 2009. Akka es un framework de la JVM con APIs para Java y Scala que hace que el modelo Actor esté disponible para una amplia gama de desarrolladores.

Los actores son aplicables en una amplia gama de problemas. En el pasado, los programas se volvieron más rápidos al usar la próxima generación de CPU. Esto se debió a una frecuencia central cada vez mayor. Pero esto se detuvo alrededor del año 2005. Desde entonces, las CPU no son cada vez más rápidas, sino más anchas. Esto significa que, en lugar de hacer que un núcleo de ejecución sea más potente, se incorporan múltiples núcleos de este tipo dentro de un chip, accediendo a la memoria compartida.

Y en algunos de estos, los núcleos incluso están virtualizados, de modo que un núcleo de ejecución física puede albergar múltiples subprocesos de ejecución lógica. Hay diferentes formas de beneficiarse de estas CPU más amplias.

La primera es que puede ejecutar varios programas en paralelo en la misma computadora. Esto se llama multitarea y se ha hecho desde las primeras versiones de Unix. Pero si tiene un solo programa que necesita ejecutar más rápido y no tiene más remedio que ejecutar partes del mismo programa en paralelo. Y esto se llama subprocesos múltiples.

Para lograr subprocesos múltiples, su programa debe estar escrito de una manera diferente a la forma secuencial tradicional.

La diferencia entre ejecutar programas separados en paralelo y usar subprocesos del mismo programa en paralelo es que estos subprocesos colaboran en una tarea común.

Y si piensas en un grupo de personas haciendo algo juntas, necesitarán sincronizar sus acciones. De lo contrario, se pisan. Lo mismo puede suceder en un programa de subprocesos múltiples. Hay una nueva clase de errores y problemas que te esperan allí. Y esta es la razón por la cual los programas deben formularse de manera diferente para estar listos para subprocesos múltiples. Para entender lo que eso significa, echemos un vistazo a una cuenta bancaria:

class BankAccount {

private val balance = 0

def deposit(amount: Int): Unit = if (amount > 0) balance = balance + amount

def withdraw(amount: Int): Int = 

    if (amount  > 0 && amount <  balance) {

        balance = balance - amount 

        balance

    } else throw new Error("Fondo insuficiente")

}


Contiene un campo para el saldo y tiene dos métodos para depositar una cantidad y retirar una cantidad.

Ahora veamos el método de retiro en detalle. Entonces, echemos un vistazo a lo que sucede si dos subprocesos ejecutan este código al mismo tiempo.

Digamos que este es el subproceso 1 y este es el subproceso 2. Son ejecutados por diferentes CPU, por lo que pueden ejecutarse en paralelo.

Entran al método con una cantidad. Digamos que el hilo 1 quiere retirar 50 francos suizos, por ejemplo. Y el hilo 2 quiere retirar 40. Lo primero que harán ambos será leer el saldo actual. En ambos casos, digamos el saldo ahora mismo es 80, por lo que ambos verán 80. Luego, ambos ingresarán la declaración if, del chequeo. ¿La cantidad es positiva? Sí, lo es. ¿Y hay realmente suficientes fondos en la cuenta? Sí hay. Así ambos continuarán. Ellos calcularán el nuevo saldo.

El nuevo saldo en el primer subproceso será 30, y en el segundo será 40. Lo siguiente que harán los subprocesos será escribir el nuevo saldo en el campo de saldo de la cuenta bancaria, objeto.

El primer subproceso escribirá 30 y el segundo escribirá 40. Esto está claramente en conflicto, porque solo uno de los escritores puede ganar al final. El que viene en último lugar, sobrescribirá al que vino antes.

Este es el primer problema que vemos aquí. Es que en realidad se pierde una de las actualizaciones del saldo.

El otro problema es que se viola el invariante de la cuenta bancaria. En eso hemos retirado 50 y 40 francos suizos que son 90 en total, y el saldo era solo 80, lo que no debería haber sido posible. Uno de los hilos debería haber fallado. Y eso, eso no sucedió es el otro problema con este código.

Ahora, ¿qué podemos hacer para solucionar este problema? Necesitamos agregar sincronización. Cuando varios subprocesos trabajan con los mismos datos, necesitan sincronizar sus acciones.

Porque de lo contrario, serían propensos a pisarse. Lo que debemos hacer es asegurarnos de que cuando un subproceso esté trabajando con los datos, los demás se mantengan al margen. Como si pusieras un cartel de no molestar en la puerta de tu hotel.

Entonces, digamos que en este ejemplo estamos viendo el saldo, como los datos que se protegerán. Y lo que tenemos que hacer es poner una valla alrededor, de modo que cuando un subproceso esté trabajando con los datos, digamos el subproceso 1. Que este tenga acceso exclusivo a él. Lo que significa que la transacción 2, si intenta acceder a los datos, en realidad se le negará el acceso en este momento. Y tiene que esperar hasta que la transacción 1 termine con ella. De esta manera, el saldo estará protegido. Y todas las modificaciones realizadas en él se realizan de manera consistente, una tras otra. También decimos serializado.

Las herramientas principales para lograr este tipo de sincronización son lock o mutex. Que es básicamente el mismo concepto que se mostró anteriormente. O un semáforo donde la diferencia es que múltiples pero solo un número definido de subprocesos pueden ingresar a esta región.

En Scala, cada objeto tiene un candado asociado. Al que puede acceder llamando al método sincronizado en él. Y acepta un bloqueo de código que se ejecutará en esta región protegida.

¿Cómo aplicamos esto a la cuenta bancaria para sincronizarla?


def withdraw(amount: Int): Int = this.synchronized {

        if (amount  > 0 && amount <  balance) {

            balance = balance - amount 

            balance

        } else throw new Error("Fondo insuficiente")

}


Bueno, aquí tenemos el método de retiro. Y si lo ponemos todo dentro de un bloque sincronizado, entonces leemos el balance aquí. Realizar el cheque y volver a escribirlo, todo se hará como una acción atómica. Que no puede ser perturbado por otro hilo que ejecuta retirar, al mismo tiempo. Ese otro hilo tendrá que esperar.

Pero, ¿debemos sincronizar también aquí en el método de depósito? El método de depósito también modifica el saldo. Y si no esta sincronizado, entonces podría modificarlo sin protección. Y una vez que el retiro devuelve el saldo aquí, anularía la anulación de la actualización realizada por depósito al mismo tiempo.

Esto es para ilustrar que todos los accesos al saldo deben estar sincronizados, y no solo el que hemos demostrado que es problemático.

Ahora, intentemos transferir algo de dinero de una cuenta bancaria a otra.

Lo que debemos hacer es sincronizar ambos objetos, de modo que estén en un estado consistente. Porque de lo contrario, alguien leyendo el saldo de las cuentas podría encontrar el dinero en fuga. Retiramos de una cuenta. Depositamos después en otro.

Durante este tiempo, el dinero básicamente no está en ninguna parte. Y si la invariante que debe cumplirse es que la suma de from y to debe ser la misma, esto se violará. Por lo tanto, necesitamos sincronizar.

Entonces, primero tomamos el bloqueo en la cuenta de origen. Luego tomamos el bloqueo en la cuenta. Ahora estamos seguros de que ningún otro hilo puede modificar estas dos cuentas, pero nosotros podemos. Una propiedad de los bloqueos en Scala es que son reentrantes, lo que significa que el mismo subproceso puede tomarlo dos veces o cualquier cantidad de veces.

Hay un problema con este código, ya que introduce la posibilidad de un interbloqueo.

Digamos que un hilo quiere transferir de la cuenta A a la cuenta B en un hilo.

Y otro hilo intenta transferir en la dirección opuesta. Si ambos comienzan al mismo tiempo, toman el primer candado, este en la cuenta A, este en la cuenta B.

Luego van a tomar la otra cerradura. Este no logrará tomar el bloqueo, porque ya fue tomado por el otro subproceso para la cuenta B. Lo mismo es cierto para la cuenta A en el otro subproceso.

Esto significa que ninguno de los subprocesos puede progresar, ambos se atascarán para siempre. Porque no hay posibilidad de que ninguno de los dos ceda el candado que ya tienen. Esto se llama interbloqueo o deadlock

Hay soluciones. Por ejemplo, llevar siempre las transacciones en el mismo orden. Debe definir un orden para las cuentas, etc. y entonces podrías potencialmente resolver esto.

Descubrirá que la mayoría de las veces hay soluciones de ese tipo, pero se agregarán y harán que su código sea mucho más complicado con el tiempo. Y en este caso es sencillo, porque ambas son cuentas bancarias. Pero, ¿qué sucede si desea que colaboren objetos que no provienen de la misma base de código, por ejemplo, en los que no puede modificar?

En ese sentido, sería mucho mejor que nuestros objetos no requirieran sincronización o bloqueo. Porque el bloqueo es lo que realmente hace que ocurra el interbloqueo.

El otro problema con el bloqueo es que es malo para la utilización de la CPU. Si hay otros subprocesos para ejecutar, el sistema operativo los ejecutará. Pero de lo contrario, la CPU estará inactiva. Y despertarlo o hacer que un subproceso vuelva a ejecutarse cuando otro subproceso lo ha interrumpido lleva mucho tiempo. Por lo tanto, su programa se ejecutará más lentamente si usa el bloqueo.

Otro problema con el bloqueo de objetos es que la comunicación sincrónica une al emisor y al receptor con bastante fuerza. Porque el remitente debe esperar hasta que el receptor esté listo. Entonces, si llamo a una cuenta bancaria que está sincronizada, esa cuenta bancaria me bloqueará hasta que esté lista. Los objetos que no bloquean son exactamente lo que son los Actores.

Los actores representan objetos y el modelo de actor describe cómo estos objetos interactúan, y todo esto está inspirado en cómo nos organizamos los humanos y respeta especialmente las leyes de la física. ¿Qué quiero decir con esto? Digamos que una persona sin reloj que quiere saber la hora actual y hay otra persona con un reloj. Ahora la primera persona se hará la pregunta, ¿qué hora es?  Y la segunda persona podría responder, son las 12:43. Este es un intercambio simple entre dos humanos y todos hemos hecho algo así antes, así que espero que todos puedan identificarse con este ejemplo. Pero hay más de lo que es visible en la superficie. En primer lugar, tomamos nota de que transmitimos información hablando y escuchando las palabras. Eso significa que la primera persona envía un mensaje a la segunda persona. La segunda persona luego piensa un poco, mira el reloj y responde con otro mensaje, viajando hacia atrás, en ondas de sonido. Las dos cualidades fundamentales aquí son, en primer lugar, que se basa únicamente en mensajes y, en segundo lugar, los mensajes tardan en viajar de un objeto a otro. Es útil pensar en los actores no como estos objetos abstractos a los que llamas métodos. Pero en lugar de visualizarlos como personas que hablan entre sí. Una cosa también a tener en cuenta es que cuando los humanos hablamos, no nos metemos en el cerebro de los demás, por ejemplo, leyendo la mente. nos basamos únicamente en los mensajes, y eso es una parte muy fundamental de los actores. Más formalmente, un actor, tal como lo definen Hewitt, Bishop y Steiger, es un objeto con identidad. Y también tiene un comportamiento, que ya hemos encontrado, y solo interactúa mediante el paso de mensajes. Lo que sigue siendo compatible con la definición de objeto normal, lo especial de los actores es que su paso de mensajes siempre es asíncrono. 

Tenemos un actor, llamémoslo Actor A. Y este quiere enviar un mensaje al actor B. El actor A enviará el mensaje y luego puede continuar haciendo lo que quiera después de eso, sin tener que esperar por el  mensaje, este viajará a B y será procesado por B, especialmente el procesamiento ocurre en un contexto diferente, en un momento posterior diferente según lo determine el sistema en el que se ejecutan los actores. 

Esta es la propiedad de las más importante de los actores. Para esto, usamos los trait de actor en Akka. El tipo de actor define un método abstracto que se llama recibir y este recibir devuelve algo del tipo Receive. Recibir es una función parcial de Any a Unit y describe la respuesta del actor a un mensaje.

Cualquier mensaje podría entrar, por lo tanto es Any, y el actor puede hacer muchas cosas, pero al final, no devuelve nada, debido al paso asincrónico del mensaje.

Por ahora vamos a ver solo estos conseptos, y luego los profundizaremos en post posteriores. 

Dejo link : https://akka.io/

viernes, 23 de octubre de 2020

Cómo y por qué Twitter usa Scala ?


Twitter usa Scala, si! hace mucho. Scala es un lenguaje de programación que combina rasgos de lenguajes orientados a objetos. y lenguajes funcionales con miras a soportar mejor la concurrencia en software a gran escala.

¿Por qué utilizar Scala? Lo que necesitaba a medida que Twitter crecía era procesos pesados ​​de larga ejecución, cola de mensajes, capas de almacenamiento en caché para realizar 20.000 operaciones por segundo. 

¿cuáles fueron los criterios para elegir Scala? Bueno, primero ¿es rápido, divertido y bueno para un proceso de larga duración? ¿Tiene funciones avanzadas? ¿Puede ser productivo rápidamente? Los desarrolladores del lenguaje en sí tenían que ser accesibles para nosotros.

¿Y Scala resultó ser rápido? Bueno, ¿cuál es tu definición de rápido? Casi tan rápido como Java. No tiene que ser tan rápido como C o Assembly. Python no es significativamente más rápido que Ruby. Querían hacer más con menos máquinas, aprovechando mejor la concurrencia; quería que se compilara para que no quemara la CPU haciendo las cosas incorrectas.

Es muy divertido trabajar en Scala; sí, puede escribir código serio, similar a Java, cuando empiece. Más tarde, puede escribir código Scala que casi se parece a Haskell. Puede ser muy idiomático, muy funcional, hay mucha flexibilidad ahí.

Y es rápido. El principal desarrollador de lenguaje de Scala trabajó en la JVM en Sun. Cuando comenzó Java, era claramente un gran lenguaje, pero la máquina virtual era lenta. La JVM se ha llevado a la era moderna y no nos lo pensamos dos veces antes de usarla.

Scala puede tomar prestadas bibliotecas de las bibliotecas de Java; está compilando en código de bytes de Java, y todo está llamando de un modo que es realmente eficiente. No nos hemos encontrado con ninguna dependencia de biblioteca que cause problemas. Podemos contratar personas con Java y pueden hacerlo bastante bien.

La gran teoría unificada de Scala es que combina programación orientada a objetivos (OOP) y programación funcional (FP). El objetivo de Scala es esencialmente decir que OOP y FP no tienen que ser estos mundos separados. Es algo zen, y no lo entiendes cuando empiezas. Es realmente poderoso; es bueno tener un lenguaje con una tesis, en lugar de tratar de atraer a todos los programadores. Scala está tratando de resolver un problema intelectual específico.

Tiene métodos que toman cualquier cosa entre una cadena y varios puntos en la cadena de herencia de una cadena. La sintaxis es más flexible que la de Java; es muy legible por humanos, ya que puede omitir un período entre las llamadas al método para que parezca una serie de palabras. Su programa puede hacer buenas declaraciones declarativas sobre la lógica de lo que está tratando de hacer.

Con Scala, también puede usar rasgo o traits. Esto es útil porque, por supuesto, tiene preocupaciones transversales en su aplicación. Por ejemplo, todos los objetos deben poder registrar cosas, pero no quieres que todo se extienda desde una clase de registrador, eso es una locura. Con Scala, puede usar un rasgo para introducirlo directamente y puede agregar tantos rasgos como desee a una clase u objeto determinado.


Puedes elegir entre mutabilidad e inmutabilidad. Esto puede resultar peligroso. 9 de cada 10 veces usa variables inmutables cuando desea previsibilidad, especialmente cuando tiene cosas ejecutándose al mismo tiempo. Pero Scala confía en el programador para la mutabilidad cuando lo necesita.

Scala tiene el concepto de valores perezosos; se puede decir lazy val x = una función realmente complicada. Eso no se calculará hasta el último segundo, cuando necesite ese valor. Esto es bonito.

Pattern matching también es buena. Le permite sumergirse en una estructura de datos para que pueda, por ejemplo, explotar una colección que coincida con una matriz con "2" como tercer elemento. Puede dividir cadenas y expresiones regulares, y puede combinar grupos de patrones con expresiones regulares.

Una característica extraña que es realmente útil es la capacidad de usar literales XML, de modo que pueda hacer algo igual a un literal XML, como si el literal XML fuera una cadena. No tienes que importar Sax o alguna biblioteca XML.

Cuando la gente lee sobre Scala, casi siempre es en el contexto de la concurrencia. La simultaneidad la puede resolver un buen programador en muchos lenguajes, pero es un problema difícil de resolver. Scala tiene una biblioteca de Actores, Akka, que se usa comúnmente para resolver problemas de concurrencia, y hace que ese problema sea mucho más fácil de resolver.

Un actor es un objeto que tiene un buzón; pone en cola los mensajes y los trata en un bucle, y puede dejar un mensaje en el suelo cuando no sabe qué hacer con él.

Puede modelar la concurrencia como mensajes, una unidad de trabajo, enviados a los actores, lo cual es realmente bueno. Es como usar un sistema de cola. También puede usar Java.util.concurrency, Netty y Apache Mina, colocándolo directamente. Puede reescribir la implementación de Actor, y algunas personas han ido tan lejos como para lanzar sus propias bibliotecas de memoria transaccional de software.

La interoperabilidad de Java es una gran, gran victoria. Hay diez años de grandes bibliotecas, cosas como Jodatime. Usamos mucho Hadoop y ha sido fácil conectar Scala a las bibliotecas de Hadoop. Usamos Thrift, sin tener que parchearlo; utilizamos bibliotecas de Apache Commons y de Google.

En el mundo empresarial, una arquitectura orientada a servicios no es nueva, pero en la Web 2.0 es una ciencia nueva y loca. Con PHP o Ruby on Rails, cuando necesite más funcionalidad, simplemente incluya más complementos y bibliotecas, y los inserte todos en el servidor. El resultado es una bola de barro gigante.

Entonces, cualquier cosa que tenga que hacer un trabajo pesado en nuestra pila será un servicio independiente. Podemos probarlo de forma independiente, es una buena forma de descomponer nuestra arquitectura.

¿Qué servicios de Twitter funcionan con Scala? Tienen un sistema de colas llamado Kestrel. Utiliza una versión mejorada del protocolo mem-cache. Originalmente se escribio en Ruby, pero debido a que Ruby es un lenguaje dinámico, el servicio comenzó a mostrar sus puntos débiles de rendimiento.

Flock usan para almacenar grafos social, como una lista desnormalizada de identificadores de usuario. No es una base de datos de grafos, por lo que no puede realizar recorridos aleatorios a lo largo del grafo. Pero es excelente para almacenar rápidamente conjuntos desnormalizados de ID de usuario y hacer intersecciones. Estan realizando 20.000 operaciones por segundo en ese momento, respaldadas por un esquema MySQL diseñado para mantener tanto como sea posible en la memoria. Ha sido muy eficiente, no se necesitan muchos servidores.

El servicio de búsqueda de personas está impulsada por un servicio creado por Scala que se llama Hawkwind. Es un grupo de objetos de usuario que Hadoop arroja, donde la solicitud se distribuye en varias máquinas y luego se vuelve a unir.

domingo, 2 de julio de 2017

domingo, 6 de septiembre de 2015

Blog.scalac.io


Quiero compartir con ustedes una excelente pagina que contiene un montón de recursos sobre scala y Akka, tal vez ya la conocen scalac.io

Dejo link: http://blog.scalac.io/

martes, 14 de abril de 2015

jueves, 1 de mayo de 2014

Manejar la concurrencia con Actores.


El modelo de actores que fue propuesto por primera vez por Carl Hewitt en 1973; es un modelo de concurrencia computacional que al igual que los hilos, trata de solucionar el problema de la concurrencia.

En el modelo de actores, cada objeto es un actor. Esta es una entidad que tiene una cola de mensajes o buzón y un comportamiento. Los mensajes pueden ser intercambiados entre los actores y se almacenan en el buzón. Al recibir un mensaje, el comportamiento del actor se ejecuta. El actor puede : enviar una serie de mensajes a otros actores, crear una serie de actores y asumir un nuevo comportamiento para el próximo mensaje.

La importancia en este modelo es que todas las comunicaciones se llevan a cabo de forma asincrónica. Esto implica que el remitente no espera a que un mensaje sea recibido en el momento que lo envío, solo sigue su ejecución.

Una segunda característica importante es que todas las comunicaciones se producen por medio de mensajes: no hay un estado compartido entre los actores. Si un actor desea obtener información sobre el estado interno de otro actor, se tendrá que utilizar mensajes para solicitar esta información. Esto permite a los actores controlar el acceso a su estado, evitando problemas.

Erlang es un lenguaje de programación concurrente y un sistema de ejecución que incluye una máquina virtual y bibliotecas. Fue diseñado en la compañía Ericsson para realizar aplicaciones distribuidas, tolerantes a fallos y de funcionamiento ininterrumpido. Originalmente, Erlang era un lenguaje propietario de Ericsson, pero fue cedido como software de código abierto en 1998. La implementación de Ericsson es, principalmente interpretada pero también incluye un compilador HiPE (sólo soportado en algunas plataformas).

Entre los mayores logros de la plataforma podemos destacar que el chat de facebook y la base documental CouchDB.

Sin dudas una cosa que hace muy especial de Erlang es como maneja la concurrencia. Erlang no maneja la concurrencia con hilos como nos tiene acostumbrado C, C++ o Java. Erlang soluciona la programación concurrente mediante el modelo de actores.

En Erlang los procesos o actores:

  • Son rápidos de crear y destruir.
  • El envío de mensajes entre procesos es muy rápido.
  • Es fácil mantener un gran número de procesos.
  • Son ligeros.
  • Son independientes y no comparten memoria.
  • Sólo un proceso tratará un mensaje pasado, en ningún caso pasará por otro proceso.


Parece complicado, pero no lo es. Con un ejemplo vamos a aclarar el tema. Supongamos que queremos hacer un actor saludador, pero no muy simpático; que salude solo a los conocidos; en erlang sería así:

-module(saludador).
-export([loop/0]).
loop() ->
receive
% Saluda a un conocido
"conocido" ->
io:format("Hola!! " ),
loop();
% Un desconocido, no lo saluda
_ ->
io:format(" ... " ),
loop()
end.

En la primera línea declaramos el modulo; luego importamos la función loop, con la cual definimos una función vacía e iteramos para siempre. Con receive recibimos un mensaje, es similar al swich, espera a recibir un mensaje y al recibir un mensaje ejecuta la estructura de código que corresponde al mensaje enviado y el “_” es como el default del swich en c, c++ o java.

Primero compilamos, para esto vamos a guardar nuestro saludador en el fichero saludador.erl y luego en la consola de Erlang escribimos:

1> c(saludador).
{ok,saludador}

Con spawn se puede generar un proceso, spawn nos devolverá el PID del proceso, que nos servirá para enviarle mensajes.

2> Pid = spawn(fun saludador:loop/0).
<0.38.0>

Ahora le vamos a mandar un mensaje:

4> Pid ! "conocido".
Hola!! "conocido"

5> Pid ! "Pepe".
... "Pepe"

Como era de esperar solo dice hola a los conocidos. Con el operador ! enviamos mensajes a un actor a partir de su Pid.

Éste es un pequeño ejemplo de manejo de concurrencia en erlang. La forma en que maneja la concurrencia Scala fue inspirada en Erlang.

Scala implementa el modelo de actores similar a Erlang, veamos un poco de código:

import scala.actors.Actor

class Saludador extends Actor  {
  
  def act() = {
        while (true) {
            receive {
                case "conocido" =>
                    println("Hola!")
                case _ =>
                    println("...")
            }
        }
    }

}

object ActorsTest extends App {

  val saludador = new Saludador
  saludador.start()
  
  saludador ! "otro"
  saludador ! "conocido"
}

Akka es un framework java que nos brinda este modelo en el lenguaje java. Permitiéndonos manejar la concurrencia de forma más simple como lo hace scala o erlang.

Veamos un ejemplo:

import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.actor.ActorRef;

public class HelloWorld extends UntypedActor {

  @Override
  public void preStart() {
    // create the greeter actor
    final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class), "greeter");
    // tell it to perform the greeting
    greeter.tell(Greeter.Msg.GREET, getSelf());
  }

  @Override
  public void onReceive(Object msg) {
    if (msg == Greeter.Msg.DONE) {
      // when the greeter is done, stop this actor and with it the application
      getContext().stop(getSelf());
    } else
      unhandled(msg);
  }
}

Como podemos ver en ejemplo podemos hacer un manejo de actores de forma remota. Akka es tolerable a fallos dado que fue concedido con tecnología Let it crash/Embrace failure. Akka es de código abierto y está disponible bajo la licencia Apache 2. A la vez está basado en scala y provee una Api para este lenguaje.

Akka tiene integración con Spring, soporta OSGI, se integra con Apache Camel y la última versión soporta Java 8. ¡Solo falta que cocine y lave la ropa!

Desarrollar aplicaciones concurrentes puede ser un dolor de cabeza. Por este motivo nació el modelo de actores, para simplificar el desarrollo concurrente.

domingo, 6 de abril de 2014

Show Off. Get Proof. Convince Your Boss.


No soy asiduo de hacer publicidad a empresas pero quiero recomendarles la pagina de Typesafe.

Go Typesafe es un conjunto de recursos para ayudar a convencer a sus compañeros para utilizar la plataforma reactive de Typesafe: Play Framework, Akka y Scala.

Dejo link:
http://go.typesafe.com/

miércoles, 5 de marzo de 2014

Nueva versión de Akka


Hoy me entere de un nuevo release del framework de la empresa Typesafe. El pasado 5 de marzo se dio a conocer la nueva versión de Akka 2.3.0.

Para el que no conoce Akka es un framework open source basado en el concepto de Actores. Este framework nos facilita la creación de aplicaciones distribuidas y concurrentes. Fue escrito en Scala y se puede utilizar en cualquier lenguaje de la plataforma Java.

Entre las novedades de la nueva versión podemos nombrar:

  • Akka Persistence: Este módulo le permite escribir Actores con estado persistente que sobrevivan a los fallos de hardware y software, y también proporciona un mecanismo de opt-in.
  • Soporte para Java 8: Akka viene preparando la cancha para la nueva versión de Java y dejando todo preparado para el uso de lambda.  
  • Mejoras en el uso de Cluster: La gente de Akka aprendió varias cosas dado que ejecuto Akka en 2400 nodos, dando lugar a varias mejoras de rendimiento y mejoras de usabilidad.
  • Activator Templates: Activator es como Maven (salvando las diferencias) y los templates como los archetypes. La gente de Akka creo nuevos templates, para que tengamos menos trabajo al crear un nuevo proyecto que use Akka:

Akka es un framework que esta ganando espacio y creciendo rápidamente y no debemos perderle la pisada.

Dejo link:
https://typesafe.com/blog/akka-230-major-release

sábado, 26 de octubre de 2013

7 días para Principles of Reactive Programming

El martes 23 de agosto, postee sobre el nuevo curso que dicta Martin Odersky, por medio de la pagina Coursera; ahora solo faltan 7 días así que si no te inscribiste; estas a tiempo!!



Dejo link:
https://www.coursera.org/course/reactive

martes, 27 de agosto de 2013

Principles of Reactive Programming

Como lo anuncio este blog, en un post anterior el señor Martin Odersky, estaba trabajando en otro curso. Se hizo esperar pero ya nos podemos inscribir a "Principles of Reactive Programming".

Que podemos aprender en este curso? Vamos a aprender a escribir aplicaciones basadas en componentes, orientadas a eventos, escalable y resistente a fallas.

Dejo el link:
https://www.coursera.org/course/reactive

Dejo un video:

 


domingo, 6 de enero de 2013

Scala 2.10.0 fue liberado!!


Scala 2.10 ha sido lanzado oficialmente incluyendo muchas nuevas características. Incluyendo nuevas características. Entre ellas se puede nombrar, interpolación de strings, actores de Akka ahora son parte del lenguaje.

Dejo el link:
http://www.scala-lang.org/node/27499

viernes, 9 de marzo de 2012

Akka 2.0 Released!

Akka el framework para Scala y java a sacado una nueva versión; como recordaran akka es un framework que se basa en el concepto de actores para brindarnos una arquitectura distribuida.

Para más información del release dejo el link:

http://akka.io/news/2012/03/06/akka-20-released.html


jueves, 17 de noviembre de 2011

Typesafe incluye a play en su Stack


Typesafe le empresa formada a raíz de Scala anuncio que agregara a play 2.0 a su stack.  Stack de typesafe es una plataforma que permite desarrollar software con scala teniendo a Akka como midleware. Bueno este stack va a tener a play como plataforma para desarrollo web. Recordemos que play es un framework para desarrollo ágil en Java y Scala (a partir de la versión 2.0).

El framework play va podes ser usado tanto en Java como en scala.

 Dejo links:

http://typesafe.com/stack
http://typesafe.com/company/news/15856
http://blog.typesafe.com/typesafe-stack-adds-play-framework
http://typesafe.com/technology/play

miércoles, 2 de noviembre de 2011

Actores con Akka

La concurrencia se puede manejar de dos formas a travez de hilos o thread como c++ y java o por medio de actores como erlang y scala. El modelo de actores es un modelo de concurrencia computacional que trata a los "actores" como los primitivos universal de la computación digital en paralelo: en respuesta a un mensaje que recibe, un actor puede tomar decisiones locales, crear más actores, envía más mensajes, y determinar cómo responder al siguiente mensaje recibido.

Si buscamos en la wikipedia dice lo siguiente:

En informática, el modelo de actor es un modelo matemático de cálculo simultáneas que trata a los "actores", como los primitivos universales de la computación digital simultáneas: en respuesta a un mensaje que recibe,un actor puede tomar decisiones locales, crear más actores, enviar más mensajes, y determinar cómo responder a la siguiente mensaje recibido. El modelo de actor se originó en 1973.  Se ha utilizado tantocomo un marco para una comprensión teórica de la computación, y como la base teórica para variasaplicaciones prácticas de los sistemas concurrentes. La relación de la modelo para otros trabajos se discute enla indeterminación en el cálculo simultáneo y el modelo de actor y cálculos proceso. Toma tu torta!!

Akka es un framework java que nos brinda este modelo en el lenguaje java. Permitiéndonos manejar la concurrencia de forma más simple como lo hace scala o erlang.

Veamos un ejemplo:

// server code
class HelloWorldActor extends UntypedActor {
  public void onReceive(Object msg) {
    getContext().tryReply(msg + " World");
  }
}

remote().start("localhost", 2552).register(
  "hello-service",
   actorOf(HelloWorldActor.class));

// client code
ActorRef actor = remote().actorFor(
  "hello-service", "localhost", 2552);
Object res = actor.ask("Hello").get();



Como podemos ver en ejemplo podemos hacer un manejo de actores de forma remota.  Akka Utiliza el modelo del actor junto con la memoria transaccional de software que elevar el nivel de abstracción y proporcionar una mejor plataforma para construir aplicaciones concurrentes correcta y escalable. A la vez es tolerante a fallos dado que fue concedido con tecnología Let it crash/Embrace failure. Akka es de código abierto y disponible bajo la licencia Apache 2. A la vez esta basado en scala y provee una api para este lenguaje, escrita en este lenguaje.

Tiene integración con Spring, soporta OSGI, se integra con Apache Camel. Solo falta que te cocine y te lave la ropa!

Seguramente vamos a seguir escribiendo sobre este framework, dado que esta muy bueno!

Dejo links:
http://en.wikipedia.org/wiki/Actor_model
http://akka.io/
http://akka.io/docs/
http://akka.io/docs/akka-modules/1.1.3/modules/spring.html