Akka for Java Developer (Part 1)

    Recently, quite a few programming languages ​​have appeared that use the JVM as a platform for execution. One of the hottest topics to discuss recently is Scala. In this article I will not deserve to consider it well or not, I just want to tell how you can use the tools of this language using Java and without writing a single line in Scala.

    The concept of actors was born long before Scala and was implemented in various programming languages, including Java. In a nutshell, actor is an object that processes messages sent to it. It is important that messages are immutable and the sequence of their processing corresponds to the order in which they are received. Actually, this is the basis of the concept, and then the implementation features come up: is there a message queue for the object, is there an opportunity to change the message processing code in the process, is the actor attached to a thread or thread pool, the ability to send messages to actors on other machines and etc.

    In general, if anyone is familiar with JEE, then actor is very similar to a Message bean, only the message queue lives inside the JVM.
    The author of the Scala language decided to implement the concept of actors for the Scala language and named it Akka and is developing this project as a commercial open source project. The project is developing quite actively, the current version 1.1.3 and work is underway on version 2.0, which they are going to release in the fall. There will be support for distributed queues and better organization of clusters.

    Why did I choose Akka? First, I wanted to feel a new way to deal with the complexity of distributed computing and high-load systems. The second and very important is the documentation. Only two projects of JetLang and Akka are currently active about actors, and Akka captivates with detailed documentation for both Java and Scala, with code examples and detailed explanations of where and why. And actually the third reason is the lack of the need to learn a new language in order to get the benefits of using technology.

    So, let's begin.

    In order to write something using Akka, you need to download the akka.io/downloads distribution kit or connect the following libraries to maven.


    akka.repository
    Akka Maven Repository
    akka.io/repository



      se.scalablesolutions.akka
      akka-actor
     1.1.3



      se.scalablesolutions.akka
      akka-typed-actor
     1.1.3


    * This source code was highlighted with Source Code Highlighter.


    Akka implements two types of actors - UntypedActor and TypedActor. UntypedActor provides a standard interface for processing messages through the onReceive method

    import akka.actor.UntypedActor;

    public class TestUntypedActor extends UntypedActor {

    public void onReceive(Object message) throws Exception {
      if (message instanceof MySuperMessage) {
      System.out.println("We've got super message - " + message);
     } else if (message instance of String) {
      System.out.println("Process string - " + message);
    }
    }

    * This source code was highlighted with Source Code Highlighter.


    This way we get a lot of classes that you can interact with by sending messages.
    For TypedActor, you must first describe the interaction interface, and then implement it using actor.

    interface RegistrationService {
    void register(User user, Credentials cred);
    User getUserFor(String username);
    }

    import akka.actor.TypedActor;

    public class RegistrationServiceImpl extends TypedActor implements RegistrationService {
    public void register(User user, Credentials cred) {
      ... // Регистрация пользователя
    }

    public User getUserFor(String username) {
      ... // Реализация поиска пользователя
     return user;
    }
    }

    * This source code was highlighted with Source Code Highlighter.


    In this case, we will have many classes with interfaces for business logic and implementation using actors. And if you use Spring in your application, then the integration of actors into existing applications will be at the configuration level and will be almost painless (in the next articles I will show how).

    So we have actor descriptions, and now we need to create instances of classes somehow, because the simple new does not work here. Actors factory is used to create UntypedActor.

    ActorRef testActor = Actors.actorOf(TestUntypedActor.class);

    * This source code was highlighted with Source Code Highlighter.


    After creation, the factory returns a link (ActorRef) to a specific instance of the actor, which can be serialized or sent to another machine to send a message to a specific instance (in the case of remote actor).

    Use the following code to create a TypedActor.

    // Первый параметр - интерфейс, второй - реализация
    UserService service =
    (UserService) TypedActor.newInstance(UserService.class, UserServiceImpl.class);

    // Или если у TypedActor нет конструктора без параметров

    UserService service = TypedActor.newInstance(UserService.class, new TypedActorFactory() {
    public TypedActor create() {
      return new UserServiceImpl("default user storage"));
    });

    * This source code was highlighted with Source Code Highlighter.


    Which returns a link to the interface for communicating with the actor.

    Akka implements three types of sending messages to actors: fire-and-forget (“send and forget”, asynchronous sending of a message without waiting for a result), request-reply (“question-answer”, sending a message and waiting for a response, synchronous mode) , request-reply-with-future ("send and receive a response in the future", sending a message and receiving a response further in the code using a special object).

    For UntypedActor, all three methods look like this

    actorRef.sendOneWay("Hello"); // Посылает в качестве сообщения строчку

    actorRef.sendOneWay(new MySuperObject(), сontext()); // Отправить объект в качестве сообщения. Кроме того будет отправлен context текущего actor'а (из которого происходит вызов), для того чтобы можно было отправить ответ с помощью context().reply()

    Object result = actorRef.sendRequestReply("get result"); // Отправить строчку как сообщение и ждать ответ. В методе можно также передать context() и таймаут для ожидания ответа (при истечении таймаута будет ActorTimeoutException)

    Future future = actorRef.sendRequestReplyFuture("Hello"); // Отправить сообщение и получить объект для извлечения результатов. Можно передать context() и таймаут. У самого объекта Future есть методы await (ожидание результата), result (получить результат), exception (получить исключение если было)

    * This source code was highlighted with Source Code Highlighter.


    For TypedActor, the calling methods depend on the method signature. If the method does not return value values ​​(void), then the fire-and-forget call is implicitly used. If any object is returned, then request-reply is used. If the method returns Future, then request-reply-with-future is used.

    Well, the last for today - do not forget to start UntypedActors and stop to free resources. If you send messages to an actor that has not started, they will be added to his turn and not processed. Therefore, to understand that something is not working will be difficult.

    Also popular now: