简体   繁体   English

akka向远程演员发送封闭

[英]akka sending a closure to remote actor

Background 背景

i want to send a closure to a remote actor. 我想向一个远程演员发送一个闭包。 remote actor should run the closure on its data and send back the result. 远程actor应该对其数据运行闭包并发回结果。 May be it is not advisable, but for curiosity's sake that's i want to do now 可能是不可取的,但出于好奇的缘故,我现在想做

But i observe that if a closure is created as an anonymous function, it captures the outer object also and tries to marshal it, which fails if the outer object is not serializable, as in this case. 但我观察到,如果一个闭包被创建为一个匿名函数,它也会捕获外部对象并尝试编组它,如果外部对象不可序列化,则会失败,就像在这种情况下一样。

class Client(server: ActorRef) extends Actor {

  var every = 2

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

}

the above code generates exception while calling the remote actor. 上面的代码在调用远程actor时生成异常。 i could define a local variable in the method preStart() 我可以在方法preStart()定义一个局部变量

val every_ = every

and use it in place of actor member variable. 并用它代替actor成员变量。 But i feel it is a workaround not a solution. 但我觉得这是一种解决方法而不是解决方案。 and i will have to be very careful if the closure is any bit more complex. 如果封闭更复杂,我必须非常小心。

Alternative is to define a class inheriting from Function1[A,B] and send its instances as closure. 另一种方法是定义一个继承自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))

But this separates the closure definition from the place it is used, and defeats the whole purpose of using a functional language. 但是这将闭包定义与它所使用的地方分开,并且破坏了使用函数语言的整个目的。 and also makes defining the closure logic more difficult. 并且还使得定义闭包逻辑变得更加困难。

Specific Query 具体查询

Is there a way i can defer defining the body of the Function1.apply and assign the body of apply when i create the instance of MyFunc from a locally defined closure? 有没有办法我可以推迟定义Function1.apply的主体, apply在从本地定义的闭包创建MyFunc实例时分配apply的主体?

eg 例如

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

where every is a local variable? 其中, every一个局部变量?

basically i want to combine the two approaches ie send an object of Function1 over to remote actor with the body of Function1 defined by an anon function defined in place where Function1 instance is created. 基本上我想要结合两种方法,即将Function1的对象发送到远程actor,其中Function1的主体由在创建Function1实例的位置定义的anon函数定义。

Thanks, 谢谢,

Sure, you could send behaviour to actor, but it considered to be a bad practice, and your questions is a good answer on question: "why". 当然,你可以向演员发送行为,但它被认为是一种不好的做法,你的问题是一个很好的答案:“为什么”。

As BGR pointed out there is special section in documentation on this question, but it has no example. 正如BGR所指出的,关于这个问题的文档中有特殊的部分,但它没有例子。

So, when you sending a closure as message you sending some extra "implicit" state with it. 因此,当您发送一个闭包作为消息时,您会发送一些额外的“隐含”状态。 It could be not mutable as said in documentation, but even in this case it can create problems. 如文档中所述,它可能不是可变的,但即使在这种情况下,它也可能产生问题。

The problem with scala here is that it not strictly functional language - it is multiparadigm language. scala的问题在于它不是严格的函数式语言 - 它是多范式语言。 In other words you could have code in functional paradigm side by side with code in imperative style. 换句话说,您可以在功能范例中将代码与命令式样式中的代码并排放置。 There is no such problems in, for example haskell, which is purely functional. 没有这样的问题,例如具有纯功能的haskell。

In case of your "specific query" I'll suggest you to use set of predefined functions. 如果您的“特定查询”,我建议您使用一组预定义的函数。 This is full equivalent of variant with closures but with a bit chatty syntax. 这完全等同于带闭包的变体,但语法有点繁琐。 Since you do not generate code during runtime all functions you use are defined in limited set and (looks like) parameterized by value. 由于您在运行期间不生成代码,因此您使用的所有函数都在有限集中定义,并且(看起来像)按值参数化。 This makes your code not so flexible like with closures, but in the end it will be equivalent cases. 这使得您的代码不像闭包那样灵活,但最终它将是相同的情况。

So, as a leitmotif of all my post: if you going to send behaviour to actor it should be rock solid atomic (in meaning have no any dependencies) 所以,作为我所有帖子的主题:如果你要向演员发送行为,它应该是坚如磐石的原子(意思是没有任何依赖)

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

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