如何让scala参与者报告任务完成情况



我需要将一系列远程调用分割成块。我想过用演员。

我想到了这样的东西:

class ControlActor() extends Actor{
  var counter = 1000
  def act{
     for (i <- 1 until 1000) { new RequestActor(this) start }
    while(true){
      receive{
        case "Stop" =>{counter = counter-1; if(counter==0){return}}
      }
    } 
  }
}
class RequestActor(parent:ControlActor) extends actor{ ... }

但这有一个明显的问题:当我进入recieve块时,一些RequestActor实例可能已经执行完毕。如果他们向尚未处于消息接收状态的参与者发送消息,会发生什么?消息是排队还是被丢弃?

最重要的是:我如何创建能够通知创建它们的演员的儿童演员,即使它们很快返回

还相关:将当前参与者实例(this)传递给其他参与者是否是一种好的做法?由于某种原因,我没有看到任何人这样做。

你很好;actor中未处理的消息将直接进入邮箱,并在actor准备就绪时进行处理。但是,对于参与者回复其呼叫者,通常不需要传递对this的引用,因为参与者可以使用reply直接与呼叫者通信。这里有一个简单的例子:

class MyActor(n: Int) extends Actor {
  def act() {
    loop {
      react {
        case m: Int => reply(n + m)  // Use `reply` to reply to caller
      }
    }
  }
}
// new MyActor(0), new MyActor(10), new MyActor(20), ...
val actors = (0 to 100 by 10) map (new MyActor(_).start())
// Message each actor with '5', expecting a response (that's what `!?` does)
val responses = actors map (_ !? 5)
responses foreach println

中的结果

5
15
25
35
45
55
65
75
85
95
105

然而,!?操作符将阻塞主线程,直到我们得到对其消息的回复。因此,actors map (_ !? 5)实际上并不是那么并发。相反,您可以使用!!来生成未来(您可以在此期间进行计算,并推迟评估,直到您准备好为止)。所以…把最后两行改成

val futures = actors map (_ !! 5)
futures foreach (future => println(future()))

将用"5"给第一个参与者发消息,给我一个在此期间可以抓住的未来,然后用"5"给第二个参与者发信息,给我在此期间可以握住的未来,等等。当我们准备好时,我们可以评估未来(future())并以某种方式使用其结果(如打印出来)。

只要参与者已经启动,发送给它的消息就会排队等待下一个接收/反应调用。

通过构造函数传递Actor也是可以的,但应该将它们作为Actor而不是派生类型传递,以消除直接访问Actor状态的诱惑。

你通常不会看到这种情况,因为通常演员都是通过消息传递的。但是你所做的并没有错。

最新更新