Akka的Actors与Erlang的Actors中消息顺序语义的后果

时间:2014-12-11 14:35:26

标签: scala erlang akka actor

来自课程反应性规划的原则:

“如果演员发送多条消息到同一目的地,它们将不会无序到达(这是Akka特定的)。”

演员A和B

A发送B msg1 A发送B msg2

B将收到msg1,然后收到msg2

警告:我从未在Erlang编程

我相信在Erlang中无法保证此消息排序语义。这似乎是一个巨大的差异,它会影响您可以使用类似框架编写的不同类型的程序。

例如在Akka你可以这样做:

case class msg(x: Int)
case object report
class B extends Actor {

var i: Int = 0
def recieve = {
    case msg(x) => i = i + x
    case report => sender ! i
 }
}

然后你可以做

发送B msg(5)

发送B msg(6)

发送B报告//保证总和为11

我的主要观点是,Erlang看起来你无法保证返回的金额是11。Erlang不鼓励甚至禁止Actors包含任何可变状态吗?任何人都可以详细说明Scala的Akka vs. Erlang中可以和不能用Actors编写的不同类型的程序吗?

3 个答案:

答案 0 :(得分:4)

答案是肯定的,这是有保证的:见FAQ(它没有明确写出,但以已知顺序发送消息的唯一方法是从同一进程发送消息)

10.8  Is the order of message reception guaranteed?

Yes, but only within one process.

If there is a live process and you send it message A and then message B, it's guaranteed that if message B arrived, message A arrived before it.

On the other hand, imagine processes P, Q and R. P sends message A to Q, and then message B to R. There is no guarantee that A arrives before B. (Distributed Erlang would have a pretty tough time if this was required!)

答案 1 :(得分:4)

正如Pascal所说,两个进程之间的消息顺序是有保证的。 在Erlang中,拥有一些可变状态的唯一方法是#34;是隐藏在演员身后。它通常以这种方式完成:

loop(Sum) ->
    NewSum = receive Message of
        {msg, Number, Sender} -> add_and_reply(Sum, Number, Sender);
        _ -> Sum
    end,
    loop(NewSum).

add_and_reply(Sum, Number, Sender) ->
    NewSum = Sum + Number,
    Sender ! NewSum,
    NewSum.

这样,你就不会改变任何东西。您创建新状态并将其作为无限递归中的参数传递。运行循环的Actor确保所有调用都是逐个提供的,因为它一次只接受一条消息。

对我来说,Erlang和Akka之间的主要区别是抢占式调度。在Erlang中,您可以编写执行此操作的actor:

loop(Foo) ->
    something_processor_consuming(),
    loop(Foo).

,您的系统将正常运行。大多数通过库添加actor的语言将转到此线程,它将永远运行阻止一个CPU核心执行。 Erlang能够阻止该线程,运行其他东西并返回它,所以即使你搞砸了,它也可以很好地运行。 Read more here。在Erlang中,您可以从外部exit(Pid, kill)终止进程,它将立即终止。在Akka中,它将继续处理,直到它准备好接收下一条消息(你可以使用trap_exit标志来模拟Erlang。

从一开始就是

Erlang was built with fault tolerance and soft real time systems in mind,因此OTP强调监督流程。例如,在Scala主管有机会在出错时恢复孩子,而在Erlang中,孩子在出错时崩溃并且必须重新启动。这是因为假设,崩溃意味着糟糕的状态,我们不想传播它。

答案 2 :(得分:0)

是的,您可以保证这种情况 - " Erlang消息"并不意味着"简单的UDP"。

A可以发送B" 1,2,3,4,5"它将准确地得到" 1,2,3,4,5"按顺序,无论A和B在群集中的哪个位置 - 考虑该陈述的最后部分的含义......

什么不保证是什么订单消息" a,b,c,d,e"从C到B将到达B relative 以可能与A&的并发消息流交织。 " 1,2,A,B,C,3,4,5,d,E"和#34; 1,2,3,4,5,a,b,c,d,e"或者两个独立排序的消息流的任何其他交织。