Akka,单个邮箱多个(相同)演员?

时间:2018-04-04 13:43:00

标签: akka

我试图对Akka进行非常基本的使用,同时对于浏览所有大量文档并不感到兴奋。

我有一个有效的演员。它是无状态的,但是CPU密集且长时间运行。我希望有一小部分这些东西,这样我就可以同时处理多条消息(我有8个内核,所以其中8个似乎是可能的选择)。 / p>

我的问题是我不知道文档在哪里开始查找。我想我会感激和#34;给一条鱼" (告诉我该怎么做),但与此同时,知道在哪里查看文档(教我钓鱼)将是非常有价值的,也可能更有价值。

在尝试这一点的建议时,我首先使用路由器,因为它看起来最简单。但是,正如此示例所示,我不认为它解决了我的问题。使用下面的代码,一些消息可以找到进入邮箱的邮箱,而这个邮件并不是第一个可用的邮件。

package routeex

import java.util.concurrent.ThreadLocalRandom

import akka.actor.{Actor, ActorSystem, Props, Terminated}
import akka.routing.{ActorRefRoutee, RoundRobinRoutingLogic, Router, SmallestMailboxRoutingLogic}

case class Work(message: String, dur: Int = 0)

object Worker {
  private val startTime = System.currentTimeMillis()
  private var nextId = 1
  def getMyId: Int = {
    val id = nextId
    nextId += 1
    id
  }
  def timestamp: String = f"${System.currentTimeMillis() - startTime}%6.3f"
}

class Worker extends Actor {
  val myId = Worker.getMyId
  println(s"making actor, id is $myId")

  override def receive: Receive = {
    case Work("slow", delay) => {
      println(s"${Worker.timestamp} Actor $myId going slow for $delay...")
      Thread.sleep(delay)
      println(s"${Worker.timestamp} Actor $myId awake again...")
    }
    case Work("report", _) => println(s"${Worker.timestamp} Actor $myId reporting for duty!")
    case m => println(s"${Worker.timestamp} Actor $myId got unexpected message $m")
  }
}

class Master extends Actor {
  var router = {
    val routees = Vector.fill(2) {
      val r = context.actorOf(Props[Worker])
      context watch r
      ActorRefRoutee(r)
    }
//    Router(RoundRobinRoutingLogic(), routees)
    Router(SmallestMailboxRoutingLogic(), routees)
  }

  def receive = {
    case w: Work =>
      router.route(w, sender())
    case Terminated(a) =>
      router = router.removeRoutee(a)
      val r = context.actorOf(Props[Worker])
      context watch r
      router = router.addRoutee(r)
  }
}

object TryIt {
  def main(args: Array[String]): Unit = {
    val system = ActorSystem.create("System")
    val m = system.actorOf(Props[Master])

    m ! Work("slow", 10000)
    m ! Work("slow", 1000)
    m ! Work("slow", 1000)
    m ! Work("slow", 1000)
    m ! Work("report")
    m ! Work("report")
    m ! Work("report")
    m ! Work("report")

    Thread.sleep(30000)
    system.terminate()
  }
}

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

  

我希望“第一个可用的”演员拉下一条消息。

根据您的上述评论,路由器不是您想要的。相反,请考虑使用“工作拉动”模式。这种模式的要点是:

  • 主演员协调多个工人演员的工作单位。
  • 工人向主人注册,这意味着可以动态添加或删除工人。
  • 当主人收到要完成的工作时,主人通知工人工作可用。工人在准备就绪时拉出工作单位,做各自工作单位需要做的工作,然后在工作完成后让师傅做更多的工作。

Akka documentation中列出的以下链接描述了这种模式:

您可以根据自己的需要调整Pollmeier's implementation