-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add documentation for AK1002 (#7066)
* Add documentation for AK1002 * Fix wrong heading * Fix wrong header
- Loading branch information
Showing
1 changed file
with
52 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<T>()`](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<T>()` 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<string>(async str => { | ||
await Context.Self.GracefulStop(); // THIS WILL DEADLOCK | ||
}): | ||
} | ||
} | ||
``` | ||
|
||
## Resolution | ||
|
||
If you absolutely need to invoke `Self.GracefulStop()` inside `ReceiveAsync<T>()` 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<string>(async str => { | ||
_ = Context.Self.GracefulStop(); | ||
}): | ||
} | ||
} | ||
``` |