[Play 2.3.7] How to limit number of active Akka actor instances

342 views
Skip to first unread message

sachin walia

unread,
Jan 30, 2015, 5:11:26 PM1/30/15
to play-fr...@googlegroups.com
I am building a webapp that upon receiving an http post request needs to do some encoding jobs. 
Basically Play controller receives a media file as a request body. 
Upon receiving this file it needs to pass it to an Akka Actor for further encoding.
Akka Actor will invoke an external shell process via Java Process Builder.
However in order for system to not through out of memory errors I want to make sure there is a limit on number of Active Akka instances that trigger such process.

Is there something in the framework that I can use or do I need to build from groundup?

thanks,

Sachin Walia

James Roper

unread,
Feb 1, 2015, 10:52:45 PM2/1/15
to play-framework
It depends - are you actors blocking while they wait for the process to finish?  If so, you can do it in Akka with a router.  If they don't block while waiting for the process to finish, then you need to implement a job queue yourself - which is pretty straight forward.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
James Roper
Software Engineer

Typesafe – Build reactive apps!
Twitter: @jroper

sachin walia

unread,
Feb 2, 2015, 12:25:01 PM2/2/15
to play-fr...@googlegroups.com
Thanks James. The actors are indeed blocking. Each instance of actor is responsible for encoding to a desired format and then uploading to the CDN. It needs to complete in a single blocking cycle.

FYI I am using Google guice and akka IndirectActorProducer to create a instance of an actors. 

public class GuiceActorProducer implements IndirectActorProducer {
 
final Injector injector;
 
final Class<? extends Actor> actorClass;

 
public GuiceActorProducer(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);
 
}
}

and it is used like this from Service Layer:

ActorRef optimizationActor = PluginUtils.getActorSystem().actorOf(Props.create(GuiceActorProducer.class, injector, OptimizeImageActor.class));
optimizationActor
.tell(compressionMessage, null);

Is it during lookup of ActorRef that I need to use RoundRobinRouter?

thanks,

Sachin Walia

James Roper

unread,
Feb 2, 2015, 8:32:54 PM2/2/15
to play-framework
Hi Sachin,

You can either configure Akka to use a router when creating that actor in application.conf, or you can do it programatically.  Also, I would not recommend using a round robin actor, since if some of the tasks take longer than others, you may end up with many tasks backing up in one actors mailbox while the other actors are idle doing nothing.  I'd use a SmallestMailboxRouter.  You can read about configuring that here:


And finally, since you're blocking, make sure you're using a dispatcher that's been configured for that in that actor, eg using the withDispatcher method on the props to do it programatically, or in the configuration by setting the dispatcher either inline or to refer to one that you've created elsewhere.

Cheers,

James
Reply all
Reply to author
Forward
0 new messages