Play Framework Actor Pooling with Guice (Java)

Post image

Working with the Play! Framework means working with Akka, intentionally or not. But working with Akka Actors can be tricky, especially when it comes to dependency injection. Play! 2.4 uses Google’s Guice for DI and of course it has the ability to also bind Actors so an ActorRef can be injected anywhere.

Single Actor DI

Biding and injecting one single Actor is simple and well documented . Just bind it in a Module:

package modules;

import actors.MyExampleActor;
import com.google.inject.AbstractModule;
import play.libs.akka.AkkaGuiceSupport;

public class ActorModule extends AbstractModule implements AkkaGuiceSupport {

    public static final String EXAMPLE_ACTOR_DI_NAME = "my-example-actor";

    @Override
    protected void configure() {
        bindActor(MyExampleActor.class, EXAMPLE_ACTOR_DI_NAME);
    }
}

Enable the module in the app configuration:

play.modules.enabled = ${play.modules.enabled} [
  modules.ActorModule
]

Now you can inject the bound actor into every class using the @Inject and @Named annotation, e.g. in a Controller:

Keep in mind: Actors should always be injected as ActorRef and not as the concrete class which has been implemented.

package controllers;

import akka.actor.ActorRef;
import akka.util.Timeout;
import modules.ActorModule;
import play.mvc.Controller;
import play.mvc.Result;
import scala.concurrent.Await;
import scala.concurrent.duration.Duration;
import scala.concurrent.duration.FiniteDuration;

import javax.inject.Inject;
import javax.inject.Named;
import java.util.concurrent.TimeUnit;

public class AssetController extends Controller {

    @Inject
    @Named(ActorModule.EXAMPLE_ACTOR_DI_NAME)
    ActorRef exampleActor;

    public Result publish(String assetType, String assetUuid) {
        FiniteDuration duration = Duration.create(5, TimeUnit.SECONDS);
        String response = Await.result(
                ask(exampleActor, "ask something", new Timeout(duration)).mapTo(classTag(Strijg.class)),
                duration
        );
        return ok(response);
    }
}

// disclaimer: Stuff like error handling and message protocols intentionally left out in favor of clarity

Actor Pools

As you maybe know, there is the possibility to create pools of Actors instead of only one single instance. A pool behaves like a single actor, using a router to distribute messages to different child actors. The configuration options are huge, but most of the time, I personally only need an option to bind an actor pool using round robin distribution. No problems to achive this using the Akka configuration, but I could not find any documentation how to combine it using Play / Guice DI (in Java).

It turned out, that it is simple once you know it. Just pass the props of a RoundRobinPool to the bindActor method as a third argument:

bindActor(MyExampleActor.class, EXAMPLE_ACTOR_DI_NAME, p -> new RoundRobinPool(5).props(p));

Now, instead of a single instance of MyExampleActor there is a pool of 5 of them waiting for messages.

The example works for Play! Framework 2.4 using Java 8 and will maybe break in future versions.

You May Also Like

Understanding Stemmers (Natural Language Processing)

Understanding Stemmers (Natural Language Processing)

I am interested in NLP and have already some experience with Apache Solr. It’s time to dig a little in-deep regarding stemmers. First of all, I was looking for a general definition of what a stemmer is, and I found this one, which IMHO is quite good:

stemmer — an algorithm for removing inflectional and derivational endings in order to reduce word forms to a common stem

How a Strong Type System Saves You Documentation, Tests, and Nerves

How a Strong Type System Saves You Documentation, Tests, and Nerves

I was recently inspired to finally write this post. Especially in weakly- or untyped languages, such as the JavaScript or PHP world, the added value of strict type systems is often not recognized. Instead, many discussions and comments revolve around the need for tests or code comments. Contrary to that, in the functional programming world, we leave such checks to the compiler. In this post I would like to give a short overview and explain how to use a strict type system for everyday checks instead of writing type checks, tests and documentation for it.