Allow introspection on typed EntityRefs to support serialization #29955

This commit is contained in:
Levi Ramsey 2021-02-16 03:19:36 -05:00 committed by GitHub
parent d92dc9c321
commit d51f1e17b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 106 additions and 15 deletions

View file

@ -84,7 +84,7 @@ Scala
Java
: @@snip [ShardingCompileOnlyTest.java](/akka-cluster-sharding-typed/src/test/java/jdocs/akka/cluster/sharding/typed/ShardingCompileOnlyTest.java) { #init }
Messages to a specific entity are then sent via an `EntityRef`.
Messages to a specific entity are then sent via an `EntityRef`. The `entityId` and the name of the Entity's key can be retrieved from the `EntityRef`.
It is also possible to wrap methods in a `ShardingEnvelope` or define extractor functions and send messages directly to the shard region.
Scala
@ -107,7 +107,16 @@ Scala
Java
: @@snip [ShardingCompileOnlyTest.java](/akka-cluster-sharding-typed/src/test/java/jdocs/akka/cluster/sharding/typed/ShardingCompileOnlyTest.java) { #roles }
### A note about EntityRef and serialization
If including `EntityRef`s in messages or the `State`/`Event`s of an `EventSourcedBehavior`, those `EntityRef`s will need to be serialized.
The @scala[`entityId`, `typeKey`, and (in multi-DC use-cases) `dataCenter` of an `EntityRef`]@java[`getEntityId`, `getTypeKey`, and (in multi-DC use-cases) `getDataCenter` methods of an `EntityRef`]
provide exactly the information needed upon deserialization to regenerate an `EntityRef` equivalent to the one serialized, given an expected
type of messages to send to the entity.
At this time, serialization of `EntityRef`s requires a @ref:[custom serializer](../serialization.md#customization), as the specific
`EntityTypeKey` (including the type of message which the desired entity type accepts) should not simply be encoded in the serialized
representation but looked up on the deserializing side.
## Persistence example

View file

@ -546,3 +546,13 @@ Java
A disadvantage is that a message adapter can't be used so the response has to be in the protocol of the actor being responded to. Additionally the `EntityTypeKey`
could be included in the message if it is not known statically.
As an "alternative to the alternative", an @apidoc[typed.*.EntityRef] can be included in the messages. The `EntityRef` transparently wraps messages in a `ShardingEnvelope` and
sends them via sharding. If the target sharded entity has been passivated, it will be delivered to a new incarnation of that entity; if the target sharded entity
has been moved to a different cluster node, it will be routed to that new node. If using this approach, be aware that at this time, @ref:[a custom serializer is required](cluster-sharding.md#a-note-about-entityref-and-serialization).
As with directly including the `entityId` and `EntityTypeKey` in the message, `EntityRef`s do not support message adaptation: the response has to be in the protocol
of the entity being responded to.
In some cases, it may be useful to define messages with a @apidoc[akka.actor.typed.RecipientRef] which is a common supertype of `ActorRef` and `EntityRef`. At this time,
serializing a `RecipientRef` requires a custom serializer.