如何在Akka 2.3中使用自定义路由器?

时间:2014-04-16 18:17:03

标签: scala akka

更新:整个akka project is now available here的源代码,此问题归档为issue

我无法从Akka Concurrency书中重写自定义路由器的示例(第10.6节)。以下是有问题的代码:

package zzz.akka.avionics

import akka.actor.{Props, SupervisorStrategy}
import akka.dispatch.Dispatchers
import akka.routing.{RouterConfig, RouteeProvider, Route, Destination}

class SectionSpecificAttendantRouter extends RouterConfig {
  this: FlightAttendantProvider =>

  // The RouterConfig requires us to fill out these two
  // fields. We know what the supervisorStrategy is but we're
  // only slightly aware of the Dispatcher, which will be
  // discussed in detail later
  def routerDispatcher: String = Dispatchers.DefaultDispatcherId
  def supervisorStrategy: SupervisorStrategy =
    SupervisorStrategy.defaultStrategy

  // The createRoute method is what invokes the decision
  // making code.  We instantiate the Actors we need and then
  // create the routing code
  def createRoute(routeeProvider: RouteeProvider): Route = {
    // Create 5 flight attendants
    val attendants = (1 to 5) map { n =>
      routeeProvider.context.actorOf(Props(newFlightAttendant), "Attendant-" + n)
    }

    // Register them with the provider - This is important.
    // If you forget to do this, nobody's really going to
    // tell you about it :)
    routeeProvider.registerRoutees(attendants)

    // Now the partial function that calculates the route.
    // We are going to route based on the name of the
    // incoming sender.  Of course, you would cache this or
    // do something slicker.
    {
      case (sender, message) =>
        import Passenger.SeatAssignment
        val SeatAssignment(_, row, _) = sender.path.name
        List(Destination(sender,
             attendants(math.floor(row.toInt / 11).toInt)))
    }
  }
}

我的问题:

  1. 我应该延长PoolRouterConfig还是CustomRouterConfig
  2. 我如何获得sender参考,以便从空乘人员的路径计算索引?
  3. 这是我的开始:

    class SpecificRoutingLogic extends RoutingLogic {
      override def select(message: Any, routees: IndexedSeq[Routee]): Routee = {
        ??? no sender here!
      }
    }
    class SectionSpecificAttendantRouter extends CustomRouterConfig {
      this: FlightAttendantProvider =>
    
      override def routerDispatcher: String = Dispatchers.DefaultDispatcherId
    
      //override def supervisorStrategy: SupervisorStrategy = SupervisorStrategy.defaultStrategy
    
      override def createRouter(system: ActorSystem): Router = {
        // Create 5 flight attendants
        val attendants = (1 to 5) map { n =>
          system.actorOf(Props(newFlightAttendant()), "Attendant-" + n)
        }
        new Router(new SpecificRoutingLogic())
      }
    }
    

1 个答案:

答案 0 :(得分:1)

文档未提及您何时从CustomRouterConfig继承,Akka引擎不会为您创建路由。因此,没有路由您的邮件。我会这样做:

class SpecificRoutingLogic extends RoutingLogic {
  override def select(message: Any, routees: IndexedSeq[Routee]): Routee = {
    val selected = routees.take(5)
    if(selected.isEmpty) NoRoutee
    else selected
  }
}
class SectionSpecificAttendantRouter(nrOfInstances: Int) extends Pool {
  this: FlightAttendantProvider =>

  override def routerDispatcher: String = Dispatchers.DefaultDispatcherId

  override def createRouter(system: ActorSystem): Router = {
    new Router(new SpecificRoutingLogic())
  }
}

由于我上面写的问题,我已经更改SectionSpecificAttendantRouter现在延长Pool而不是CustomRouterConfig。当你有这个实现(我认为那就是全部)你创建路由器时你必须做这样的事情SectionSpecificAttendantRouter(5).props(Props[YourWorker]) - 这个代码必须在例如system.actorOf()里面调用来创建具体的路由器。请记住,如果要直接从CustomRouterConfig继承,则必须自己实现创建Routees。查看课程akka.routing.RoutedActorCell特定方法start()。如果你使用的东西不是Pool或Group,你必须自己做一些初始化的事情。