阿卡发送关闭远程演员
我想封闭发送到远程的演员。远程参与者应该对其数据运行关闭并发回结果。 可能这是不可取的,但为了好奇这就是我想做的事情现在
但我观察,如果一个封闭作为一个匿名函数创建的,它抓住了外部对象也并试图封送它,这如果外部对象不可序列化,则失败,如在这种情况下。
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
定义本地变量和到位的演员成员变量的使用它。但我觉得这是一种解决方法,而不是解决方案。如果封闭更复杂,我将必须非常小心。
另一种方法是定义继承自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
的身体,当我从一个本地定义封闭创建MyFunc
的实例分配的apply
的身体吗?
例如
server ! new Message(new MyFunc(every){ // not valid scala code
x % every == 0
})
where every
是一个局部变量?
基本上我希望将两种方法结合起来,即发送的Function1
对象到远程演员与Function1
通过在其中创建Function1
实例地方定义一个匿名函数所定义的身体。
感谢,
当然,你可以发送行为的演员,但它被认为是一种不好的做法,你的问题是对问题的一个很好的答案:“为什么”。
由于BGR指出在这个问题上有documentation特殊部分,但它没有例子。
所以,当你发送闭包作为消息时,你发送一些额外的“隐式”状态。它可能不像文档中提到的那样易变,但即使在这种情况下,它也会产生问题。
这里scala的问题在于它没有严格的功能语言 - 它是多种语言的语言。换句话说,你可以在功能范式中使用命令式风格的代码。没有这样的问题,例如haskell,这是纯粹的功能。
如果您的“具体查询”,我会建议您使用一组预定义的功能。这完全相当于带有闭包的变体,但有一些简洁的语法。由于您在运行时不生成代码,因此您使用的所有函数都是在有限集内定义的,并且(看起来像)按值进行参数化。这使得你的代码不像闭包一样灵活,但最终它会成为等价的情况。
所以,我的所有文章的中心思想:如果你要发送行为的演员应该是稳如磐石的原子(在意义上没有任何依赖关系)
我想你知道你在做什么,但我想以确保你知道发送关闭被认为是一个不好的做法,正如[文档](http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html)中明确解释的那样 - Actor最佳实践alinea 3 – 2013-03-22 06:10:19
感谢您指出。或者我可以将这种行为封装在actor中并动态创建它?即基于闭包来决定演员的行为,而不是将闭包本身发送给演员。 – weima 2013-03-22 06:15:45
有很多你可以做的,但我有一种感觉,你正试图实现对特定问题的“错误”/尴尬的解决方案。我相信如果你编辑你的问题并描述你想达到的目标,你会在SO – 2013-03-22 06:26:01