重写阿卡的Scala演员

时间:2014-04-02 01:46:15

标签: scala akka actor

更新:我用不稳定的风格重写了它并将其发布在github上 - 我很感激一些反馈:https://github.com/drozzy/parallel-discrete-event-akka/tree/master/src/main/scala

任何人都可以帮我重新编写“并行离散事件模拟”示例来自Martin Odersky的Scala编程中的“第32章:Actors and Concurrency”吗?

它最初是在Scala演员中编写的,但转换为Akka我遇到了很多问题。

一些例子

演员继承(第708页)

这样的代码:

trait Simulant extends Actor
class Wire extends Simulant

我不知道如何翻译成Akka,因为根据我的理解,我们从不直接实例化它们。

主循环

作者经常在演员中使用循环,我不知道他们是什么:

def act() {
    loop {
       if (running && busySimulants.isEmpty)
          advance()
       reactToOneMessage()
    }
}

类型

大多数情况下,我正在努力应对强类型 - 似乎Akka,由于要求ActorRefs阻止我依赖于特定类型的演员。例如,在本书中,以下内容:

trait Simulant extends Actor {
  val clock: Clock
  ...

取决于强类型演员Clock。然后它只是在实现actor中“实例化”:

class Wire(name: String, init: Boolean) extends Simulant {
   def this(name: String) { this(name, false) }
   def this() { this("unnamed") }

   val clock = Circuit.this.clock

在我的实施中,我有以下几点:

trait Simulant extends Actor {
  val clock: ActorRef
  ...

我不知道如何“实例化”它。我现在(未经测试)的是:

class Wire(val clock:ActorRef, name:String, init: Boolean) extends Actor{
  def this(clock:ActorRef, name:String) {this(clock, name, false)}
  def this(clock:ActorRef){this(clock, "unnamed")}

所以我最终只是拖拽演员们围绕构造函数的参与者!

连接组件

如何将组件相互连接?例如,将AndGate连接到Wire - 这样,当线上的信号发生变化时,它会向门发送消息。

我通过发送Add条消息(即AndGateAdd发送到Wire来实现此目的,以便有线可以将其添加到其订阅者列表中),所以在开始模拟之前等待所有人到达。有没有办法避免(等待)? (在原始实现中,使用Scala Actors,一些actor只是从全局范围访问,有时actor直接调用其他actor的方法!)

源代码

可以在以下网址中找到该示例的源代码: http://booksites.artima.com/programming_in_scala_2ed/examples/html/ch32.html
在标题下:
32.6更长的例子:并行离散事件模拟

P.S。:我是akka的新手,请原谅我的无知。

1 个答案:

答案 0 :(得分:3)

我无法提供任何迁移的源代码,但此链接可能对您有所帮助: actors migration guide

一些意见:

演员继承

您可以在Akka中执行此操作,但类Wire必须实现接收方法。

主循环

在Akka中,您实现了receive方法而不是主循环。

<强>类型

您可以使用ActorRef作为构造函数参数,但必须在调用构造函数之前创建(并启动)它,例如: with context.system.actorOf(...)。 在Akka中有一种叫做Typed Actors的东西。

我也强烈建议您查看documentation

修改

我(快速)查看了源代码,这些是我的发现:

  • 在Scala中,并不像Java那样常见(并且没有强制执行)每个文件只存在一个公共类(尽管它可以improve compile speed)。
  • Demo.scala:第11行,使用var而不是val
  • 构造函数初始化(例如在FullAdder,Gate,...中):你应该小心 因为每次重新启动actor时都会执行构造函数;也许用 preStart方法会更好。
  • FullAdder,HalfAdder:对消息没有反应(或只返回单位)的演员是 在我看来奇怪的事情。也许你找到另一种构建加法器的解决方案。
  • Clock.advance:使用return不是很好的scala风格(我相信它不起作用) 在这种情况下)。改为使用别人。