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

Hiring Devs - The Seniority Paradox

Hiring Devs - The Seniority Paradox

In IT, there is a paradox when it comes to job titles. Somewhere along the way, the practice of linking job titles to a candidate’s (desired) experience became established in large parts of the market. This then created the now famous and omnipresent job titles like “Senior Software Engineer”, “Professional DevOps Engineer”, etc. In this blog post, I would like to explain the paradox around these designations and how I use them in the course of the talent search…