How does akka.net restart a remote node if that process crashes? - akka.net

Suppose that, I have an actor that has a child actor that runs remotely. And suppose that, the child actor's process crashed with an unrecoverable exception like StackOverflowException for some reason or due to a bug.
In this case, how does the parent node in akka.net restart the crashed remote child?

It won't. Child actor lives under a specific address, and if it cannot be resurrected there, it will stay dead. All of the messages directed to it will land in dead letters.
If this is not the case for you, you can always use Akka.Cluster.Sharding, which is a higher level abstraction that automatically manages actor lifecycle.

Related

How Akka.Net handles system falts during message processing

Suppose that one of cluster nodes received a message and one of actors started to process it. Somewhere in the middle this node died for some reason. What will happen with message, I mean will it be processed by another available node or will be lost?
By default akka (and every other actor model framework) offers at-most-once delivery. This means that messages are send to actors using best effort guarantees - if they won't reach the target they won't be redelivered. This also means, that if message reached the target, but the process associated with it was interrupted before finishing, it won't be retried.
That being said, there are numerous ways to offer a redelivery between actors with various guarantees.
The simplest and most unreliable is to use Ask pattern in combination with i.e. Polly library. This however won't help if a node, on which sender lives, will die - simply because message are still stored only in memory.
The more reliable pattern is to use some event log/queue in front of your cluster (i.e. Azure Service Bus, RabbitMQ or Kafka). In this approach clients are sending requests via bus/queue, while the first actor in process pipeline is responsible for picking it up. If some actor or node in pipeline dies, the whole pipeline for that message is being retried.
Another idea is to use at-least-once delivery found in Akka.Peristence module. It allows you to use eventsourcing capabilities of persistent actors to persist messages. However IMO it requires a bit of exerience with Akka.
All of these approaches present at-least-once delivery guarantees, which means that it's possible to send the same message to its destination more than once. This also means, that your processing logic needs to acknowledge that by either an idempotent behavior or by recognizing and removing duplicates on the receiver side.

Akka.net - Reconnect of remote actor

Just if i miss something a question regarding Akka.Net and a remote Actor scenario.
If i implement an Actor A (local) and deploying an Actor B (remote), and afterwards sending a Message from A to B it is totally easy.
After sending a Message, B tells A a result (at some point later).
For that reason, we are switching A with a Behavior into a "waiting" state.
Also, that works like a charm, but what can happen is that B is going down for any reason.
If so, A is waiting forever for an answer and will freeze in this state.
How is such a situation handled correctly / how should it be designed?
Idiomatic message-based approach: when changing behavior into Waiting state, actor can schedule message to itself (Context.System.Scheduler.ScheduleTellOnceCancellable(timeout, Self, cancelMessage, ActorRefs.NoSender)), which will trigger after desired timeout. So, a waiting actor behavior will react on the response or cancellation, and i.e. stash all other messages - unstashing can happen after response or cancellation is handled.
Non-idiomatic, probably also more expensive (in terms of CPU/memory), but simpler: simply use targetActor.Ask<Response>(request, timeout). You can also setup global timeout from HOCON config: akka.actor.ask-timeout = 10s.

In akka does a child process run in the same process as its parent actor?

In akka does a child process always run in the same process as its parent actor?
Is there documentation?
By default, all actors are created within the same process (and AppDomain) as their parent. There are few situations where this is not the case:
Remote deployment
Cluster pool routers
In both of those, all parameters send to an actor constructor will be serialized and passed to another machine, which will work as a physical host for an actor instance.

How to successfully set up a simple cluster singleton in Akka.NET

I was running into a problem attempting to set up a Cluster Singleton within an Akka.NET cluster where more than one instance of the singleton was starting up and running within my cluster. The cluster consists of Lighthouse (the seed node) and x number of instances of the main cluster node of which there are cluster shards as well as this singleton that exist within this node.
In order to reproduce the problem I was having I set up an example solution in GitHub but unfortunately I'm having a different problem here as I always get Singleton not available messages and my singleton never receives a message. This is sort of opposite problem that I was getting originally but nonetheless I would like to sort out a working example of cluster singleton.
[DEBUG][8/22/2016 3:06:18 PM][Thread
0015][[akka://singletontest/user/my-singleton-proxy#1237572454]]
Singleton not available, buffering message type [System.String]
In the Lighthouse process I see the following messags.
Akka.Remote.EndpointWriter: Dropping message
[Akka.Actor.ActorSelectionMessage] for non-local recipient
[[akka.tcp://sync#127.0.0.1:4053/]] arriving at
[akka.tcp://sync#127.0.0.1:4053] inbound addresses
[akka.tcp://singletontest#127.0.0.1:4053]
Potentially related:
https://github.com/akkadotnet/akka.net/issues/1960
It appears that the only bit that was missing was that the actor system specified in the actor path for my seed node did not match the actor system name specified in both Lighthouse and my Cluster Node processes. After ensuring that it matches in all three places the cluster is now behaving as expected.
https://github.com/jpierson/x-akka-cluster-singleton/commit/77ae63209042841c144f69d4cd70e9925b68a79a
Special thanks to Chris G. Stevens for his assistance.

NServiceBus worker unregistration not working

I'm trying to unregister a worker node as described here, but the procedure doesn't seem to work correctly. If the distributor has any control messages related to the disconnecting worker when running the unregistration script, next time messages come in, it will consume those (effectively sending more work to the node). It's only afterwards that the distributor will reject control messages coming from the node.
Has anyone got this to work correctly = the worker should not receive any new messages RIGHT AFTER unregistration?
What you describe is the intended behaviour for the unregister operation. It was designed and implemented like that.
It does not actively remove the existing ready messages for the worker from the distributors storage queue. It only makes sure that the worker will not send any new ready messages back to, and thus request more work from, the distributor after the unregister.