繁体   English   中英

akka向远程演员发送封闭

[英]akka sending a closure to remote actor

背景

我想向一个远程演员发送一个闭包。 远程actor应该对其数据运行闭包并发回结果。 可能是不可取的,但出于好奇的缘故,我现在想做

但我观察到,如果一个闭包被创建为一个匿名函数,它也会捕获外部对象并尝试编组它,如果外部对象不可序列化,则会失败,就像在这种情况下一样。

class Client(server: ActorRef) extends Actor {

  var every = 2

  override def preStart() = {
    println("client started. sending message....")
    server ! new Message((x) => x % every == 0)
  }

}

上面的代码在调用远程actor时生成异常。 我可以在方法preStart()定义一个局部变量

val every_ = every

并用它代替actor成员变量。 但我觉得这是一种解决方法而不是解决方案。 如果封闭更复杂,我必须非常小心。

另一种方法是定义一个继承自Function1[A,B] ,并将其实例作为闭包发送。

class MyFunc(every : Int) extends Function1[Int,Boolean] with Serializable {

  def apply(v1 :Int) : Boolean = {
    v1 % every == 0
  }  
}


server ! new Message(new MyFunc(every))

但是这将闭包定义与它所使用的地方分开,并且破坏了使用函数语言的整个目的。 并且还使得定义闭包逻辑变得更加困难。

具体查询

有没有办法我可以推迟定义Function1.apply的主体, apply在从本地定义的闭包创建MyFunc实例时分配apply的主体?

例如

server ! new Message(new MyFunc(every){ // not valid scala code
  x % every == 0
})

其中, every一个局部变量?

基本上我想要结合两种方法,即将Function1的对象发送到远程actor,其中Function1的主体由在创建Function1实例的位置定义的anon函数定义。

谢谢,

当然,你可以向演员发送行为,但它被认为是一种不好的做法,你的问题是一个很好的答案:“为什么”。

正如BGR所指出的,关于这个问题的文档中有特殊的部分,但它没有例子。

因此,当您发送一个闭包作为消息时,您会发送一些额外的“隐含”状态。 如文档中所述,它可能不是可变的,但即使在这种情况下,它也可能产生问题。

scala的问题在于它不是严格的函数式语言 - 它是多范式语言。 换句话说,您可以在功能范例中将代码与命令式样式中的代码并排放置。 没有这样的问题,例如具有纯功能的haskell。

如果您的“特定查询”,我建议您使用一组预定义的函数。 这完全等同于带闭包的变体,但语法有点繁琐。 由于您在运行期间不生成代码,因此您使用的所有函数都在有限集中定义,并且(看起来像)按值参数化。 这使得您的代码不像闭包那样灵活,但最终它将是相同的情况。

所以,作为我所有帖子的主题:如果你要向演员发送行为,它应该是坚如磐石的原子(意思是没有任何依赖)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM