ANN: AkkaGuice - Integration of Actors into Guice

942 views
Skip to first unread message

Chanan Braunstein

unread,
Jan 27, 2014, 7:30:53 AM1/27/14
to play-fr...@googlegroups.com
Hello,

AkkaGuice (https://github.com/chanan/AkkaGuice) is a play module that integrates actors into Guice for Dependency Injection. 

With AkkaGuice you can:

  1. Register actors in Guice as "singleton" (Same ActorRef will be returned everytime)
  2. Create "Per Request" actors (new ActorRef returned everytime)
  3. Resolve injected dependencies in the actor's constructor.
  4. schedule actors with an annotation
  5. schedule once actors with an annotation
Enjoy,
Chanan.

Chanan Braunstein

unread,
Feb 8, 2014, 10:45:41 AM2/8/14
to play-fr...@googlegroups.com
Jusr released Version 0.5.0 which adds scheduling akka tasks via conf files.

mkr...@trialfire.com

unread,
Feb 27, 2014, 2:32:11 PM2/27/14
to play-fr...@googlegroups.com
AWESOME AWESOME AWESOME. Thank you. 

There are few things I can't figure out and it seems you've spent a lot of time wrangling Akka + Guice in Java so please entertain a few questions.

1) Let's say I want to create actors directly in my controller without DI or simply maintain a static reference to a supervisor and that actor needs access to a service injected by guice. Here is what I have:

The service
public interface EventService{

public abstract String whoAmI();
}
the implementation...
public class EventServiceImpl implements EventService{
public String whoAmI(){
return "I am the Event Service";
}
}
and the Actor


public class EventSupervisor extends UntypedActor{

final String name;
@Inject
EventService eventService;
public EventSupervisor(String name) {
this.name = name;
}
@Override
public void onReceive(Object msg) throws Exception{
if (msg instanceof model.Event) {
Logger.info( 
String.format("Received message `%s` in actor %s", 
((model.Event) msg).id 
, getSelf().path().name())
);
Logger.info(getSender().path().toString());
Logger.info(eventService.whoAmI());
}
else unhandled(msg);
}
}

I've also created an IndirectActorProducer as discussed in the Akka docs:

package actor;

import com.google.inject.Injector;

import akka.actor.Actor;
import akka.actor.IndirectActorProducer;

public class ActorDependencyInjector implements IndirectActorProducer{

final Injector injector;
final Class<? extends Actor> actorClass;
public ActorDependencyInjector(Injector injector, Class<? extends Actor> actorClass){
this.injector = injector;
this.actorClass = actorClass;
}
@Override
public Class<? extends Actor> actorClass(){
return actorClass;
}

@Override
public Actor produce(){
return injector.getInstance(actorClass);
}

}

In my controller I'm doing the following:

public class EventController extends Controller{
static final ActorRef eventRouter2 =  Akka.system().actorOf(Props.create(ActorDependencyInjector.class, Guice.createInjector(Stage.PRODUCTION, new GuiceModule()),EventSupervisor.class)); 

....

Now I know the above isn't pretty, I really don't want to create another injector (I already have one in my Global object) but I couldn't figure out how to get a reference to it. Bottom line is I get the following error:

 Guice configuration errors:


1) No implementation for data.service.EventService was bound.
 
while locating data.service.EventService
   
for field at actor.EventSupervisor.eventService(EventSupervisor.java:10)
 
while locating actor.EventSupervisor


What am I missing here?

Any help is greatly appreciated as I'm still trying to wrap my mind out around Guice and Akka work together under Play






Chanan Braunstein

unread,
Feb 28, 2014, 9:36:04 AM2/28/14
to play-fr...@googlegroups.com
Hi,

Well, if you use AkkaGuice instead of creating your own Producer you won't have these problems :) That's the point of using AkkaGuice, you just inject the ActorRef into your controller, and AkkaGuice will take care of using Guice to inject your dependencies. Or, if you prefer, you can use AkkaGuice's PropsContext to get the Props of an Actor (again all dependencies are taken care of) and create an ActorRef yourself.

However, if you do want to create your own producer and not use AkkaGuice then here is how I did it:



ActorRefProvider that is registered in Guice to provide ActorRef's using the above classes: https://github.com/chanan/AkkaGuice/blob/master/module/app/akkaGuice/ActorRefProvider.java


Hope that helps!

But you really should use AkkaGuice directly ;)






mkr...@trialfire.com

unread,
Feb 28, 2014, 11:36:40 AM2/28/14
to play-fr...@googlegroups.com
I will definitely give it a try. I just want to understand all the mechanics first. One more question. I see that the akka extension GuiceExtension has an initialize method that takes the injector. Where is that called? Are you using the the same injector that you use in the GlobalSettings to inject controllers? How are you passing it in?

-Max 

mkr...@trialfire.com

unread,
Feb 28, 2014, 11:39:01 AM2/28/14
to play-fr...@googlegroups.com
Nevermind, its right there in your README. duh!  AkkaGuice.InitializeInjector(injector, "services");

Chanan Braunstein

unread,
Feb 28, 2014, 11:43:19 AM2/28/14
to play-fr...@googlegroups.com
Yep! :) Basically from the app global

James Leskovar

unread,
Apr 14, 2014, 7:11:00 PM4/14/14
to play-fr...@googlegroups.com

Looks great Chanan. Just had a couple of questions:

1) Are there any plans of making a completely stand-alone version of Akka Guice? As far as I can tell, the dependency on the Play framework is only used for logging and obtaining the global Akka system, both of which I imagine would be fairly simple to refactor out.

2) I haven't studied all the ins and outs of Akka yet, so I'm a little bit confused as to the purpose of the Akka extension. Could you elaborate a bit on what its purpose is, and why it's needed? As far as I can tell, the ActorRefProvider uses the global instance of the GuiceExtension -- `GuiceProvider' -- to create the Props for an IndirectActorProducer, which requires the Injector and Actor class that is to be created. Could we instead simply inject the Guice Injector into the ActorRefProvider itself? 

- James

Chanan Braunstein

unread,
Apr 15, 2014, 1:24:52 PM4/15/14
to play-fr...@googlegroups.com
Hi James,

Thanks!

Here are the answer:

0) You didn't ask, but I will say anyway, I didnt test this with Akka 2.3 yet. I doubt it will work without modifications though. Since Akka 2.3 introduced AbstractActor. I didn't check if it extends UntypedActor or not yet.

1) I didn't plan on releasing AkkaGuice without Play. You (almost) right: Logging, Global Akka and the last item would be configuration. All stuff that can be handled. Although, I am not sure how to handle config since I would like to keep the config in the same file as Play - application.conf - I will take a look at this. (PS - feel free to submit a PR :) )

2) Tthe Akka extension is the correct way to start an Actor with Dependency Injection. You can see the description at: http://doc.akka.io/docs/akka/2.3.2/java/untyped-actors.html, click on "Dependency Injection" in the Contents (Why there is not anchor in those links...). You may also look at: http://letitcrash.com/post/55958814293/akka-dependency-injection - If I understand correctly, when Akka creates an Actor it will use the ActorRefProvider's get method to create an Actor, which will call the props method of the GuiceExentsion's to get the props which will use the injector to inject the dependencies.

Chanan.
Reply all
Reply to author
Forward
0 new messages