From 809c43272f6ec93d638d4bad553973fb9ff8bbd4 Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Thu, 18 Jan 2024 09:51:11 +0700 Subject: [PATCH] Add documentation for AK1002 (#7066) * Add documentation for AK1002 * Fix wrong heading * Fix wrong header --- docs/articles/debugging/rules/AK1002.md | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 docs/articles/debugging/rules/AK1002.md diff --git a/docs/articles/debugging/rules/AK1002.md b/docs/articles/debugging/rules/AK1002.md new file mode 100644 index 00000000000..5feb64bc34b --- /dev/null +++ b/docs/articles/debugging/rules/AK1002.md @@ -0,0 +1,52 @@ +--- +uid: AK1002 +title: Akka.Analyzers Rule AK1002 - "Must not await `Self.GracefulStop()` inside `ReceiveAsync` or `ReceiveAnyAsync`" +--- + +# AK1002 - Error + +You should never await [`Self`](xref:Akka.Actor.ActorBase#Akka_Actor_ActorBase_Self).[`GracefulStop()`](xref:Akka.Actor.GracefulStopSupport#Akka_Actor_GracefulStopSupport_GracefulStop_Akka_Actor_IActorRef_System_TimeSpan_) inside [`ReceiveActor`](xref:Akka.Actor.ReceiveActor) [`ReceiveAsync()`](xref:Akka.Actor.ReceiveActor#Akka_Actor_ReceiveActor_ReceiveAsync__1_System_Func___0_System_Threading_Tasks_Task__System_Predicate___0__) or [`ReceiveAnyAsync()`](xref:Akka.Actor.ReceiveActor#Akka_Actor_ReceiveActor_ReceiveAnyAsync_System_Func_System_Object_System_Threading_Tasks_Task__) + +## Cause + +Awaiting `Self.GracefulStop()` inside `ReceiveAsync()` or `ReceiveAnyAsync()` will cause a deadlock because the `ReceiveActor` will block and wait inside the message handler for itself to terminate while its `PoisonPill` signal is stuck inside its `MailBox`, waiting to be processed. + +An example: + +```csharp +using Akka.Actor; +using System.Threading.Tasks; +using System; + +public sealed class MyActor : ReceiveActor +{ + public MyActor() + { + ReceiveAsync(async str => { + await Context.Self.GracefulStop(); // THIS WILL DEADLOCK + }): + } +} +``` + +## Resolution + +If you absolutely need to invoke `Self.GracefulStop()` inside `ReceiveAsync()` or `ReceiveAnyAsync()`, make sure that you're using a detached `Task` instead of awaiting for it to complete. + +Here's an example below: + +```csharp +using Akka.Actor; +using System.Threading.Tasks; +using System; + +public sealed class MyActor : ReceiveActor +{ + public MyActor() + { + ReceiveAsync(async str => { + _ = Context.Self.GracefulStop(); + }): + } +} +```