Hacker News new | ask | show | jobs
by reubenbond 2076 days ago
> Orleans doesn't have any ordering guarantees. While this is not a firm requirement of the Actor model itself, both Erlang and Akka guarantee ordering between a given Sender-receiver pair (i.e. messages sent from A to C will be sent in order)

Ordering has a performance cost. It needs to either be maintained at all levels, or reconstructed from unordered messages at a later point. Even something simple like an m:n thread pool scheduler can ruin ordering guarantees. My view (Orleans core developer) is this: if you want ordering, await your calls. That way, you are guaranteed ordering regardless of any message reordering that can occur in the scheduling or networking layers, or due to failure and recovery of a host. So you can choose when to pay that cost and when to reap the performance benefits of not paying it (by firing off multiple calls in parallel).

> A stable and properly configured Akka Shard cluster will never have more than one of the same entity actor alive at a time.

Likewise for Orleans, but the caveat of a "stable cluster" doesn't do much for users. "Stable cluster" falls apart frequently in real scenarios, which can be as simple as a single machine being abruptly restarted. Developers must account for the error scenarios.

> Akka and Erlang have the concept of Supervision.

Orleans does not have supervision, since each grain stands on its own (no hierarchy) and have an eternal nature (managed lifecycle). Grains are not destroyed when a method throws an exception: the exception is propagated back to the caller and the caller can use try/catch to handle the exception. This is similar to what .NET developers are used to, since regular objects are also not destroyed when a method throws an exception, and the caller is able to handle the exception. My belief is that this kind of exception handling is usually appropriate, since the caller has context which can be useful in handling the error. The developer can also write per-grain or global call filters which can operate on all calls and handle any exception, so if that's preferred, then it's available.

1 comments

> Ordering has a performance cost. It needs to either be maintained at all levels, or reconstructed from unordered messages at a later point.

Yep, although it's not typically as bad as it sounds even in Akka/Erlang; TCP gets you most of the way there. It does however become a problem when want to try to scale 'out' (i.e. use multiple links for message prioritization, etc.)

> Likewise for Orleans, but the caveat of a "stable cluster" doesn't do much for users. "Stable cluster" falls apart frequently in real scenarios, which can be as simple as a single machine being abruptly restarted. Developers must account for the error scenarios.

For sure, Akka doesn't do it for you. I think one of the biggest yak shaves in setting up would be picking your partition strategy and making sure it works the way you intended. But, once you do it's fun to watch the metrics graphs move when you cut nodes. :)

> This is similar to what .NET developers are used to, since regular objects are also not destroyed when a method throws an exception, and the caller is able to handle the exception.

Yeah supervision can be a bit weird to explain properly.

It all goes back to that first point though; Orleans is a very guided implementation and has very nice, C#-like bindings. Akka is in my view (Akka.NET project contributor, have also written some frameworks and in-production business apps using) more of a 'Toolkit'. You can see this in the various modules that result from it, such as Akka Streams, Spray/Play. Lagom, etc. Use Orleans if you want to write distributed code in C# quickly and within it's constraints. Use Akka if you want to write distributed code or just a quick and dirty Message-passing Scheduler/kernel.