Hello Roland, 
 
thanks for taking the time to answer. 

your description very much sounds like an Actor should be handling the 
> pool, not a router.
>

Alright, however I am still curious as to why the BalancingPool doesn't 
handle resize and why RoundRobinPool + BalancingDispatcher is deprecated. 
 

> You can use the DefaultResizer stand-alone (for determining what to do) 
> and you can also use the RoundRobinRoutingLogic stand-alone (for 
> determining where to send to); then the only missing piece is to place 
> these inside an Actor that will then start new Actors (easy) or stop Actors 
> in a coordinated fashion (straight-forward: just send a termination request 
> and take it out of the list of routees you pass into the RoutingLogic).
>

 starting & stopping actors is indeed easy, using the 
RoundRobinRoutingLogic is fairly straightforward. Implementing the 
management messages is starting to be a bit of a bother. Using 
DefaultResizer for anything else than a fixed size actor based pool is 
really not trivial.

As I said in my introduction 

>  I experimented with a fixed size pool but ultimately I would prefer an 
> elastic pool able to spawn despawn actors depending on request pressure


Hopefully the following will fill the fixed size pool with a round robin 
behavior , an enforced fixed size  and can be safely combined with 
routeeProps having a BalancingDispatcher.

package actors.browser
>  
> import akka.actor.{Terminated, Props, ActorLogging, Actor}
> import akka.routing._
>  
> import scala.collection.immutable.IndexedSeq
>  
> class RoundRobinFixedSizeActorPool(routeeProps:Props, nbActors:Int) extends 
> Actor with ActorLogging{
>   val resizer = DefaultResizer(nbActors, nbActors)
>   val routingLogic = RoundRobinRoutingLogic()
>  
>   var routees: IndexedSeq[Routee] = (1 until resizer.lowerBound).map{_=>
>     val routee = context.actorOf(routeeProps)
>     context.watch(routee)
>     ActorRefRoutee(routee)
>   }
>  
>   override def receive: Receive = {
>     case Terminated(actor) if routees.contains(ActorRefRoutee(actor))=>
>       routees=routees.filterNot(_ == ActorRefRoutee(actor))
>       val routee = context.actorOf(routeeProps)
>       context.watch(routee)
>       routees=routees :+ ActorRefRoutee(routee)
>     case GetRoutees =>
>       sender() ! Routees(routees)
>     case evt => routingLogic.select(evt, routees).send(evt,sender())
>   }
> }
> object RoundRobinFixedSizeActorPool{
>   def props(props:Props, nbActors:Int)=Props(new 
> RoundRobinFixedSizeActorPool(props, nbActors))
> }


How would you recommend going from there to a pressure sensitive actor pool 
oscillating between a min and a max ? 

Does the following look correct (I am unsure how to write tests for this 
... ) ?

package actors.browser
>  
> import java.util.concurrent.atomic.AtomicLong
>  
> import akka.actor._
> import akka.routing._
>  
> import scala.collection.immutable.IndexedSeq
>  
> class RoundRobinActorPool(routeeProps: Props, minRoutees: Int, maxRoutees: 
> Int) extends Actor with ActorLogging {
>   val resizer: Resizer = DefaultResizer(minRoutees, maxRoutees)
>   val nbMsgs = new AtomicLong()
>   val routingLogic = RoundRobinRoutingLogic()
>  
>   var routees: IndexedSeq[Routee] = IndexedSeq()
>   upsize(minRoutees)
>  
>   override def receive: Receive = {
>     case Terminated(actor) if routees.contains(ActorRefRoutee(actor)) =>
>       routees = routees.filterNot(_ == ActorRefRoutee(actor))
>     case GetRoutees =>
>       sender() ! Routees(routees)
>     case evt =>
>       if (resizer.isTimeForResize(nbMsgs.incrementAndGet())) {
>         resizer.resize(routees)
>       }
>  
>       routingLogic.select(evt, routees).send(evt, sender())
>   }
>  
>   private def resize(delta: Int) = {
>     if (delta < 0) downsize(delta)
>     else upsize(delta)
>   }
>  
>   private def downsize(delta: Int) = {
>     val (killed, remaining) = this.routees.splitAt(delta)
>     this.routees = remaining
>     killed.foreach(_.send(PoisonPill, self))
>   }
>  
>   private def upsize(delta: Int) = {
>     routees = routees ++ (1 until minRoutees).map { _ =>
>       val routee = context.actorOf(routeeProps)
>       context.watch(routee)
>       ActorRefRoutee(routee)
>     }
>   }
> }
>  
> object RoundRobinActorPool {
>   def props(props: Props,minRoutees: Int, maxRoutees: Int) = Props(new 
> RoundRobinActorPool(props, minRoutees, maxRoutees))
> }
>
>
Are you aware of a contrib/3rd party package which would offer Actor based 
pools while preserving most of the semantics of router based ones ?

Thanks for your help
Jean

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to