Hello World en Akka (Parte II: La Venganza)

La semana pasada aprendimos que era eso del modelo de actores. Además, vimos como crear nuestro propio actor en Akka. Recordemos como nos quedó:

class MyFirstActor extends Actor {

  def receive = {
    case _ => println("Hello World!")
  }

}

Y seguro que alguno pensasteis: “Pues qué bien. ¿Y que hago yo ahora con esto?”.

wtfshit

Bueno, hoy vamos a acabar este Hello World. Solo nos queda aprender dos conceptos importantes para terminar el ejemplo:

  • Ahora que ya sabemos definir actores, ¿cómo podemos instanciarlos?
  • Una vez que tenemos instancias de actores, ¿cómo podemos enviarle mensajes?

Una vez que tengamos claro como hacer estas dos últimas cosas, podremos tener funcionando nuestro Hello World.

Creación de Actores

Lo primero que tenemos que saber es que todos los actores en Akka se crean en un determinado contexto. Dicho contexto puede ser un sistema de actores del tipo ActorSystem. Dicho sistema será el encargado de manejar y gestionar todo el modelo de actores que montemos en él. Para crearlo basta con incluir la siguiente línea:

val system = ActorSystem("my-first-system")

Utilizaremos un String en el argumento en el ActorSystem para poder identificarlo mediante un nombre concreto. Este sistema será el contexto donde vivirán todos los actores de nuestro programa. Debido a que es un objeto bastante pesado, recomiendan solo tener una instancia por programa.

Otra opción posible es crear un actor dentro de otro actor. De esta manera estaríamos creando un actor dentro del contexto de otro. Esto es a lo que se le llama Supervision. Pero como nuestro objetivo es hacer un sencillo Hello World, no vamos a entrar en ello.

Ahora que ya tenemos un sistema, podemos crear actores en él. Lo primero que se nos ocurriría sería utilizar el constructor de un Actor. Pues no. No todo es tan sencillo. Para crear un actor es necesario usar un Props. El Props es un objeto de configuración que nos permitirá crear un actor y definir los argumentos que queremos pasarle al mismo (en caso de que los tenga). Vamos a ver un ejemplo sencillo:

system.actorOf(Props[MyFirstActor], "myFirstActor")

Como se puede observar, el sistema tiene un método para crear actores. Dicho método (llamado actorOf) recibe como argumento un Props y, de forma opcional, un nombre para identificar al actor.

Es importante saber, que el método actorOf no nos devolverá una instancia de Actor. Realmente nos devolverá una referencia al actor. Nos devolverá un ActorRef. Pero no hay que preocuparse. Mediante este ActorRef podremos enviar mensajes al actor sin ningún problema.

Envío de mensajes

Definir actores está muy bien. Crearlos mejor aún. Pero no hay que olvidar que la naturaleza de un actor es sustancialmente reactiva. Si no sabemos enviarles mensajes para causar una reacción, un actor no sirve de mucho.
En Akka hay dos formas de enviar mensajes a los actores. La forma más básica es usar el método tell.

actorRef.tell(msg: Any, sender: ActorRef): Unit

Este método nos permite enviar un mensaje a un actor (actorRef) y…..ya está. No vamos a esperar a recibir una respuesta. Esa es la razón por la que el método devuelve Unit. Además, es importante saber que en el campo sender insertaremos la referencia al actor que queremos que aparezca como remitente. Para nuestro Hello World no es importante, pero más adelante veremos que mediante esta variable podemos hacer que un actor A que envía un mensaje a un actor B consiga que el actor B responda a otro actor C mediante esta variable llamada sender.

tellExampleSender

La signatura de tell parece un poco aparatosa. Por ello existe una forma abreviada, mediante sintactic sugar, de utilizar dicho método:

actorRef ! "Yeah, madafaka!"

Mediante esta linea estamos mandando un saludo muy del Bronx a un actor cuya referencia está en la variable actorRef. En este caso, siempre que utilicemos el método tell mediante ‘!’, el remitente coincidirá con la instancia de actor que haya enviado el mensaje.

Pero quizás puede que queramos tener un feedback del actor. Puede que queramos esperar una respuesta del mismo. Don’t Panic! Para ello usamos el método ask:

import akka.pattern.ask

def ask(actorRef: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any])

Además del mensaje que queremos enviar y del actor al que enviamos el mensaje, será necesario establecer un timeout para no estar esperando una respuesta de forma indefinida. En este caso no es necesario establecer un sender (remitente) ya que que siempre será el actor que ha enviado el mensaje.

Como la respuesta la esperamos de manera asíncrona, vendrá devuelta en un futuro. ¿Un futuro? ¿Qué #$?& es eso? Por ahora, sin entrar en detalles, diremos que un futuro es un contenedor en el que se generará un dato, cuando dicho dato esté listo. Más adelante, en futuros post, veremos el tipo Future con más detalle.

Como en el caso de tell, también tenemos una forma más simple de utilizar el método ask utilizando el símbolo ‘?’:

val response: Future[Any] = actorRef ? "What time is it?"

Finalmente, el Hello World

Ahora que ya sabemos crear actores y enviar mensajes, utilizando el actor que definimos anteriormente podremos terminar de implementar el “Hello World” en Akka:

class MyFirstActor extends Actor {

  def receive = {
    case _ => println("Hello World!")
  }

}

object HelloWorldBoot extends App {

  val system = ActorSystem("my-first-system")
  val myActor: ActorRef = 
    system.actorOf(Props[MyFirstActor],"my-first-actor")

  myActor ! "Start!"

}

Basta con crear un ActorSystem, un actor en el sistema y enviar un mensaje para que el actor, al recibirlo, haga un println de “Hello World”.

Si todo ha ido bien, después de lanzar el programa veremos un Hello World muy hermoso por pantalla.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s