Hello World in Akka (Part II: Revenge)

Last week we learnt what an actor-based model was. Moreover, we saw how to create our own actor in Akka. Let me remind you what we obtained:

class MyFirstActor extends Actor {

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

}

I’m sure some of you thought: ‘Mmm…perfect. And what am I supposed to do with this?’

wtfshit

Fine, today we are finishing our Hello World. We just have to learn two more important concepts to complete the example:

  • Now we know how to define actors, how can we instantiate them?
  • Once we have instances from actors, how can we send messages to them?

Once we are comfortable with these two last things, we will have our Hello World ready to run.

Actor creation

The first thing we need to know is that all actors in Akka are created in a particular context. That context can be an actor system of the type ActorSystem. That system is in charge of handling the whole actor-based model that runs on top of it. To create it, this single line has to be included:

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

A String is passed as argument in the ActorSystem creation for it to be recognizable by a particular name. This system will be the context where all the actors in our program shall live. Provided that it is quite a heavy object, it is recommended that there is only one instance of this per program.

Other possible option is to create an actor inside other actor. This way we would be creating an actor inside the context of the other actor. This is what is called Supervision. Since our goal is to create a simple Hello World, we will not look further into that.

Now we have a system, we can create actors in it. The first think we could have thought of would be using the constructor of an Actor. Well… we can’t. Not everything is that simple. In order to create an actor, a Props needs to be used. The Props is a configuration object that allows us to create an actor and define the arguments (in case there are some) that we want to pass to it. Let’s look at a simple example:

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

As can be observed, the system has a method to create actors. That method (called actorOf) receives a Props as argument, and optionally, a name to identify the actor.

It is important to know that the actorOf method does not return an instance of Actor. Instead, a reference to the actor is returned, an ActorRef. But there’s nothing to worry about. With this ActorRef, messages can be sent to the actor without any trouble.

Sending messages to actors

Defining actors is pretty good. Creating them is even better. But we shall not forget that the essence of an actor is substantially reactive. If we don’t know how to send messages to trigger a reaction, an actor is rather useless.
In Akka, there are two ways to send messages to actors. The more basic approach is to use the method tell.

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

This method allows us to send a message to an actor (actorRef) and… that’all. We are not getting a response. That’s the reason why the method returns Unit. Besides, it is important to know that at the sender field, we have to write the reference to the actor that we want to behave as sender. It’s not much use in our Hello World, but further on we’ll see how, by using this sender variable, an actor A (which sends a message to an actor B) can make actor B send its response to an actor C.

tellExampleSender

Tell signature seems a little bit cumbersome. This is why there’s a shorter way to use this method with just a spoonful of syntactic sugar:

actorRef ! "Yeah, madafaka!"

With this line we are sending our Bronx greetings to an actor whose reference is in the variable actorRef. Provided that we use the ‘!’ in our tell method, the sender will be the instance of the actor that sent the original message.

However, we might want to have some feedback from the actor. We might want to wait for its response. Don’t panic! For that, we can use the ask method:

import akka.pattern.ask

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

In addition to the message we want to send and the actor we’re sending the message to, a timeout needs to be set for not being waiting for an answer indefinitely. In this case, no sender has be defined and it will always be the actor that sent the message.

Since we are waiting for the response in an asynchronous way, the answer will come to us in a future. A future? What the #$?& is that? For now, and without going into much detail, we’ll say that a future is a container in which some data will be generated, when that data is ready. Later on, in future posts, we’ll go into Future type in detail.

Just like with tell method, we also have a simpler way to use ask method, with ‘?’ symbol:

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

Finally, the Hello World

Now we know how to create actors and send messages to them, if we use the previously defined actor, we can finish the implementation of the “Hello World” in 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!"

}

We just need to create an ActorSystem, an actor in that system and send a message to the actor for him to println “Hello World” when that message is processed.

If everything goes ok and we run the program, we will see a beautiful Hello World on the screen.

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