Skip to content

Commit ee08dba

Browse files
close #4096 - documented how to terminate remembered entities (#4928)
Updated the Akka.Cluster.Sharding documentation to explain how to terminate remembered-entities.
1 parent 56cae11 commit ee08dba

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

docs/articles/clustering/cluster-sharding.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,43 @@ public sealed class MessageExtractor : HashCodeMessageExtractor
115115

116116
Using `ShardRegion.StartEntity` implies, that you're able to infer a shard id given an entity id alone. For this reason, in example above we modified a cluster sharding routing logic to make use of `HashCodeMessageExtractor` - in this variant, shard id doesn't have to be provided explicitly, as it will be computed from the hash of entity id itself. Notice a `maxNumberOfShards`, which is the maximum available number of shards allowed for this type of an actor - this value must never change during a single lifetime of a cluster.
117117

118+
### Terminating remembered entities
119+
One complication that `akka.cluster.sharding.remember-entities = true` introduces is that your sharded entity actors can no longer be terminated through the normal Akka.NET channels, i.e. `Context.Stop(Self)`, `PoisonPill.Instance`, and the like. This is because as part of the `remember-entities` contract - the sharding system is going to insist on keeping all remembered entities alive until explictily told to stop.
120+
121+
To terminate a remembered entity, the sharded entity actor needs to send a [`Passivate` command](xref:Akka.Cluster.Sharding.Passivate) _to its parent actor_ in order to signal to the sharding system that we no longer need to remember this particular entity.
122+
123+
```csharp
124+
protected override bool ReceiveCommand(object message)
125+
{
126+
switch (message)
127+
{
128+
case Increment _:
129+
Persist(new CounterChanged(1), UpdateState);
130+
return true;
131+
case Decrement _:
132+
Persist(new CounterChanged(-1), UpdateState);
133+
return true;
134+
case Get _:
135+
Sender.Tell(_count);
136+
return true;
137+
case ReceiveTimeout _:
138+
// send Passivate to parent (shard actor) to stop remembering this entity.
139+
// shard actor will send us back a `Stop.Instance` message
140+
// as our "shutdown" signal - at which point we can terminate normally.
141+
Context.Parent.Tell(new Passivate(Stop.Instance));
142+
return true;
143+
case Stop _:
144+
Context.Stop(Self);
145+
return true;
146+
}
147+
return false;
148+
}
149+
```
150+
151+
It is common to simply use `Context.Parent.Tell(new Passivate(PoisonPill.Instance));` to passivate and shutdown remembered-entity actors.
152+
153+
To recreate a remembered entity actor after it has been passivated all you have to do is message the `ShardRegion` actor with a message containing the entity's `EntityId` again just like how you instantiated the actor the first time.
154+
118155
## Retrieving sharding state
119156

120157
You can inspect current sharding stats by using following messages:

src/contrib/cluster/Akka.Cluster.Sharding/ShardingMessages.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ private Terminate()
4040
/// reduce memory consumption. This is done by the application specific implementation of
4141
/// the entity actors for example by defining receive timeout (<see cref="IActorContext.SetReceiveTimeout"/>).
4242
/// If a message is already enqueued to the entity when it stops itself the enqueued message
43-
/// in the mailbox will be dropped. To support graceful passivation without loosing such
43+
/// in the mailbox will be dropped. To support graceful passivation without losing such
4444
/// messages the entity actor can send this <see cref="Passivate"/> message to its parent <see cref="ShardRegion"/>.
4545
/// The specified wrapped <see cref="StopMessage"/> will be sent back to the entity, which is
4646
/// then supposed to stop itself. Incoming messages will be buffered by the `ShardRegion`
4747
/// between reception of <see cref="Passivate"/> and termination of the entity. Such buffered messages
4848
/// are thereafter delivered to a new incarnation of the entity.
4949
///
50-
/// <see cref="PoisonPill"/> is a perfectly fine <see cref="StopMessage"/>.
50+
/// <see cref="PoisonPill.Instance"/> is a perfectly fine <see cref="StopMessage"/>.
5151
/// </summary>
5252
[Serializable]
5353
public sealed class Passivate : IShardRegionCommand

0 commit comments

Comments
 (0)