演员“队列”?

时间:2010-06-07 22:03:00

标签: scala

在Java中,为了编写一个向服务器发出请求的库,我通常会实现某种调度程序(与Twitter4J库中的一个调度程序不同:http://github.com/yusuke/twitter4j/blob/master/twitter4j-core/src/main/java/twitter4j/internal/async/DispatcherImpl.java)来限制连接数,执行异步任务等。

这个想法是创建了N个线程。 “任务”排队并通知所有线程,其中一个线程在准备就绪时,将从队列中弹出一个项目,完成工作,然后返回等待状态。如果所有线程都忙于处理任务,那么任务就会排队,下一个可用的线程将接受它。

这使最大连接数保持为N,并且最多允许N个任务同时运行。

我想知道我可以用Actors创建什么样的系统来完成同样的事情?有没有办法拥有N个Actors,当一条新消息准备就绪时,将它传递给一个Actor来处理它 - 如果所有的Actors都忙,那么只需对消息进行排队?

2 个答案:

答案 0 :(得分:4)

Akka Framework 旨在解决此类问题,而这正是您所寻求的。

通过这个docu来看 - 有很多高度可配置的调度程序(基于事件,基于线程,负载平衡,工作窃取等)来管理actor邮箱,并允许它们一起工作。您可能还会发现有趣的this blog post

例如。此代码基于固定的线程池实例化新的工作窃取调度程序,它实现了它监督的参与者之间的负载平衡:

  val workStealingDispatcher = Dispatchers.newExecutorBasedEventDrivenWorkStealingDispatcher("pooled-dispatcher")
  workStealingDispatcher
  .withNewThreadPoolWithLinkedBlockingQueueWithUnboundedCapacity
  .setCorePoolSize(16)
  .buildThreadPool

使用调度程序的Actor:

class MyActor extends Actor {

    messageDispatcher = workStealingDispatcher

    def receive = {
      case _ =>
    }
  }

现在,如果您启动了2个以上的actor实例,调度程序将平衡actor的邮箱(队列)之间的负载(在邮箱中有太多邮件的actor将“捐赠”一些没有任何东西的actor做)。

答案 1 :(得分:1)

嗯,你必须看看演员调度器,因为演员通常不会与线程一对一。演员背后的想法是你可能有很多,但线程的实际数量将被限制在合理的范围内。它们也不应该长时间运行,而是快速回复它们收到的消息。简而言之,该代码的架构似乎与设计演员系统的方式完全不一致。

但是,每个工作的演员都可以向队列演员发送消息,要求下一个任务,然后循环回来做出反应。此队列角色将接收排队消息或出列消息。它可以这样设计:

val q: Queue[AnyRef] = new Queue[AnyRef]
loop {
  react {
    case Enqueue(d) => q enqueue d
    case Dequeue(a) if q.nonEmpty => a ! (q dequeue)
    }
}