protoactor-dotnet icon indicating copy to clipboard operation
protoactor-dotnet copied to clipboard

Document deadlock when using await inside actors

Open rogeralsing opened this issue 2 years ago • 4 comments

https://twitter.com/andreabalducci/status/1415226443198513153

This is a classic case of an actor passing a message to itself, and then awaiting on this task. This will deadlock as the request is now stuck in the mailbox while the mailbox is awaiting the task to complete.

The same thing can happen in cyclic graphs of actors, so this is not unique to self messaging.

There is no generic rule that can be applied here, awaiting is fine, awaiting in cyclic message flows is not. The only thing that can be done is to have better documentation for this.

ReenterAfter do prevent this type of deadlock, but will not help when the actor is supposed to be shut down. there is nothing to reenter in.

rogeralsing avatar Jul 14 '21 08:07 rogeralsing

To add some context. Actor is awaiting. The message that will complete the task is stuck in the mailbox as the actor is awaiting

Skärmavbild 2021-07-14 kl  11 23 42

rogeralsing avatar Jul 14 '21 09:07 rogeralsing

cc @andreabalducci

rogeralsing avatar Jul 14 '21 09:07 rogeralsing

was unsure. first checked on issues, then forked the doc, then checked again the sources. At first my suggestion was for throwing an exception if context was used to RequestAsync<> on self, but was unsure if context is "safe" to be used outside the actor message loop.

Agree for a better doc, is up to the dev.

andreabalducci avatar Jul 14 '21 10:07 andreabalducci

Usually in my code every RequestAsync has a timeout / cancellation token, I've checked the sources and PoisonAsync doesn't use a CancellationToken. Tried await context.RequestAsync<Terminated> ( context.Self, PoisonPill.Instance, CancellationTokens.WithTimeout(200) ); and timeout kicks in as expected without blocking the message loop.

andreabalducci avatar Jul 14 '21 12:07 andreabalducci