Case 2 is the most popular one.
Sometimes people migrate from Case 1 when they start hitting performance bottlenecks of hitting database on every request or/and experience congestions from uncoordinated concurrent writes.
Orleans doesn't make a lot of sense for Case 3 IMO. Peer-to-peer is not a good environment for forming stable clusters and making resource management decision the way the are done in the traditional server-side case.
I'm also one of the core developers of Orleans. Ironically, I recently joined Temporal. There are definitely some similarities, but also major differences between the models, especially when it comes to the execution model and fault tolerance.
After more than a decade of working on Orleans and only three weeks on Temporal it's foolish of me to talk about what I "like better" :-). I'm working on a couple of conference talks to compare the two approaches.
In short, Orleans is biased towards quick low latency operations. Longer running workflow style operations are totally doable, but require extra application logic and thinking.
Temporal's main abstraction is a workflow. So, it's biased towards reliable execution (with retries if needed) of business processes that may take seconds or days/months.
Orleans executes application code within the runtime process. Temporal orchestrates execution of external application workers (processes) I started referring to it as Inversion of Execution.
Orleans is .NET. Temporal currently provides Go and Java SDKs.
These are just top-level differences that come mind. There are many others. But there are also major similarities.
Grains are not supposed to share state directly and are expected to only use message passing. But the runtime, being just a .NET library, cannot enforce this rule. So it's merely a convention, which is trivial to violate if necessary. For example, for sharing an immutable piece of state within a silo.
Thanks for the clear reply. I also read your paper. Immutable should be adequate for avoiding the serialization tax in hybrid applications that need 'symmetry breaking' of location transparency.
In Orleans an actor cannot physically fail, just like an object in a process cannot fail. If an unhandled exception is thrown by actor code, the runtime will deliver the exception to the caller and break the TPL task of the call. Actor code is free to logically fail, e.g. by catching an exception, detecting an internal inconsistency, etc., and can handle such a case any way it wants. For example, it can set an internal failure flag and/or ask runtime to deactivate it immediately.
I guess it's a bit of a philosophical question - what is considered a failure. Orleans doesn't impose its own definition of that on actors.