在多代理系统中实施同步性

时间:2012-06-02 01:20:04

标签: scala akka agent

为了学习斯卡拉和阿卡,我正在写一个战舰游戏。我还没有开始编写任何代码,我只是在考虑事情是如何运作的。

我有船只和球员队的代理人,以及诸如“射击”,“击中”,“未命中”,“所有船只被杀”等​​消息。我的第一个绊脚石是,当玩家1射击时会产生一系列事件,而玩家2必须等到所有人都已经安定下来然后才能轮到他。我怎样才能确定?我想也许我总是发送一个回复,无论如何,然后计算一个发送者收到与发送的消息完全一样多的答案。也许Battleship不是代理商的最佳候选应用程序。

这也带来了一个问题:在没有接收答案之间做出区别,因为消息尚未处理,代理没有回复任何内容,或者代理人死亡。但是我会把它保存下来。

1 个答案:

答案 0 :(得分:1)

您可能希望在此处执行以下操作:

  • 让第一个演员收到对其每条消息的回复,然后将你的回合消息发送给第二个演员

  • 向第二个演员发送消息,指出必须接收给定回合中的事件数量

这些可以实现如下:

import akka.pattern._
(d1 ? m1) zip (d2 ? m2) pipeTo that

在上面的示例中,d1/2是目标actor,m1/2是要发送的消息。这些演员的回复被压缩在一起(进入Tuple2)并转发给第二个演员(示例中为that

第二种机制涉及更多;我用SyncPoints写了类似的东西。所以,像这样:

case class SyncPoint(id: UUID, participants: ActorRef*)
object SyncPoint {
  def newFor(participants: ActorRef*) = SyncPoint(UUID.createRandomUUID, participants)
}

然后,消息的创建者首先向最终观察者发送一个SyncPoint

val sync = SyncPoint.newFor(d1, d2)
that ! sync

现在终极接收者知道每个参与者都希望在此SyncPoint上留言。

d1 ! SyncPart(m1, sync)
d2 ! SyncPart(m2, sync)

哪里

case class SyncPart(msg: Any, sync: SyncPoint)

演员d1d2会在处理完消息后转发that

case class SyncPartial(sync: SyncPoint, participant: ActorRef)

通过这种方式,that知道它期待来自多个参与者的消息,然后可以跟踪这些参与者何时执行了他们的处理。