PersistentEntity to glue together Sharding and PersistentBehavior better
* Makes the combination more visable
* You don't have to worry about the persistenceId, only EntityTypeKey and entityId
* The glue is stronger in the javadsl because of two reasons
* Couldn't realisticly create a PersistentEntity class extending PersistenBehavior (which
contains all the optional parameters and functions) since that would duplicate too much.
* The ActorContext would be needed in the ShardedEntityContext parameter and because of the
additional M type parameters the type inference breaks down when using the factory. Would
require specifying the type of the ShardedEntityContex[M] parameter. That problem doesn't
seem to exist in Java.
renamed:
s/ShardedEntityContext/EntityContext/
s/ShardedEntity/Entity/
This commit is contained in:
parent
bed17cc172
commit
2672bd7a95
19 changed files with 670 additions and 165 deletions
|
|
@ -64,24 +64,36 @@ Java
|
|||
When using sharding entities can be moved to different nodes in the cluster. Persistence can be used to recover the state of
|
||||
an actor after it has moved.
|
||||
|
||||
Taking the larger example from the @ref:[persistence documentation](persistence.md#larger-example) and making it into
|
||||
a sharded entity is the same as for a non persistent behavior. The behavior:
|
||||
Akka Persistence is based on the single-writer principle, for a particular `persitenceId` only one persistent actor
|
||||
instance should be active. If multiple instances were to persist events at the same time, the events would be
|
||||
interleaved and might not be interpreted correctly on replay. Cluster sharding is typically used together with
|
||||
persistence to ensure that there is only one active entity for each `persistenceId` (`entityId`).
|
||||
|
||||
Here is an example of a persistent actor that is used as a sharded entity:
|
||||
|
||||
Scala
|
||||
: @@snip [BlogPostExample.scala](/akka-persistence-typed/src/test/scala/docs/akka/persistence/typed/BlogPostExample.scala) { #behavior }
|
||||
: @@snip [HelloWorldPersistentEntityExample.scala](/akka-cluster-sharding-typed/src/test/scala/docs/akka/cluster/sharding/typed/HelloWorldPersistentEntityExample.scala) { #persistent-entity }
|
||||
|
||||
Java
|
||||
: @@snip [BlogPostExample.java](/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java) { #behavior }
|
||||
: @@snip [HelloWorldPersistentEntityExample.java](/akka-cluster-sharding-typed/src/test/java/jdocs/akka/cluster/sharding/typed/HelloWorldPersistentEntityExample.java) { #persistent-entity-import #persistent-entity }
|
||||
|
||||
To create the entity:
|
||||
Note that `PersistentEntity` is used in this example. Any `Behavior` can be used as a sharded entity actor,
|
||||
but the combination of sharding and persistent actors is very common and therefore the `PersistentEntity`
|
||||
@scala[factory]@java[class] is provided as convenience. It selects the `persistenceId` automatically from
|
||||
the `EntityTypeKey` and `entityId` @java[constructor] parameters by using `EntityTypeKey.persistenceIdFrom`.
|
||||
|
||||
To initialize and use the entity:
|
||||
|
||||
Scala
|
||||
: @@snip [ShardingCompileOnlySpec.scala](/akka-cluster-sharding-typed/src/test/scala/docs/akka/cluster/sharding/typed/ShardingCompileOnlySpec.scala) { #persistence }
|
||||
: @@snip [HelloWorldPersistentEntityExample.scala](/akka-cluster-sharding-typed/src/test/scala/docs/akka/cluster/sharding/typed/HelloWorldPersistentEntityExample.scala) { #persistent-entity-usage }
|
||||
|
||||
Java
|
||||
: @@snip [ShardingCompileOnlyTest.java](/akka-cluster-sharding-typed/src/test/java/jdocs/akka/cluster/sharding/typed/ShardingCompileOnlyTest.java) { #persistence }
|
||||
: @@snip [HelloWorldPersistentEntityExample.java](/akka-cluster-sharding-typed/src/test/java/jdocs/akka/cluster/sharding/typed/HelloWorldPersistentEntityExample.java) { #persistent-entity-usage-import #persistent-entity-usage }
|
||||
|
||||
Sending messages to persistent entities is the same as if the entity wasn't persistent. The only difference is
|
||||
when an entity is moved the state will be restored. In the above example @ref:[ask](interaction-patterns.md#outside-ask)
|
||||
is used but `tell` or any of the other @ref:[Interaction Patterns](interaction-patterns.md) can be used.
|
||||
|
||||
Sending messages to entities is the same as the example above. The only difference is when an entity is moved the state will be restored.
|
||||
See @ref:[persistence](persistence.md) for more details.
|
||||
|
||||
## Passivation
|
||||
|
|
@ -92,7 +104,7 @@ the entity actors for example by defining receive timeout (`context.setReceiveTi
|
|||
If a message is already enqueued to the entity when it stops itself the enqueued message
|
||||
in the mailbox will be dropped. To support graceful passivation without losing such
|
||||
messages the entity actor can send `ClusterSharding.Passivate` to to the
|
||||
@scala:[`ActorRef[ShardCommand]`]@java:[`ActorRef<ShardCommand>`] that was passed in to
|
||||
@scala[`ActorRef[ShardCommand]`]@java[`ActorRef<ShardCommand>`] that was passed in to
|
||||
the factory method when creating the entity. The specified `handOffStopMessage` message
|
||||
will be sent back to the entity, which is then supposed to stop itself. Incoming messages
|
||||
will be buffered by the `Shard` between reception of `Passivate` and termination of the
|
||||
|
|
|
|||
|
|
@ -169,8 +169,8 @@ The response adapting function is running in the receiving actor and can safely
|
|||
* When `ask` times out, the receiving actor does not know and may still process it to completion, or even start processing it after the fact
|
||||
* Finding a good value for the timeout, especially when `ask` is triggers chained `ask`s in the receiving actor. You want a short timeout to be responsive and answer back to the requester, but at the same time you do not want to have many false positives
|
||||
|
||||
|
||||
## Request-Response with ask from outside the ActorSystem
|
||||
<a id="outside-ask"></a>
|
||||
## Request-Response with ask from outside an Actor
|
||||
|
||||
Some times you need to interact with actors from outside of the actor system, this can be done with fire-and-forget as described above or through another version of `ask` that returns a @scala[`Future[Response]`]@java[`CompletionStage<Response>`] that is either completed with a successful response or failed with a `TimeoutException` if there was no response within the specified timeout.
|
||||
|
||||
|
|
|
|||
|
|
@ -130,8 +130,19 @@ Scala
|
|||
Java
|
||||
: @@snip [PersistentActorCompileOnyTest.java](/akka-persistence-typed/src/test/java/akka/persistence/typed/javadsl/PersistentActorCompileOnlyTest.java) { #behavior }
|
||||
|
||||
The `PersistentBehavior` can then be run as with any plain typed actor as described in [typed actors documentation](actors-typed.md).
|
||||
## Cluster Sharding and persistence
|
||||
|
||||
In a use case where the number of persistent actors needed are higher than what would fit in the memory of one node or
|
||||
where resilience is important so that if a node crashes the persistent actors are quickly started on a new node and can
|
||||
resume operations @ref:[Cluster Sharding](cluster-sharding.md) is an excellent fit to spread persistent actors over a
|
||||
cluster and address them by id.
|
||||
|
||||
The `PersistentBehavior` can then be run as with any plain typed actor as described in [actors documentation](actors-typed.md),
|
||||
but since Akka Persistence is based on the single-writer principle the persistent actors are typically used together
|
||||
with Cluster Sharding. For a particular `persistenceId` only one persistent actor instance should be active at one time.
|
||||
If multiple instances were to persist events at the same time, the events would be interleaved and might not be
|
||||
interpreted correctly on replay. Cluster Sharding ensures that there is only one active entity for each id. The
|
||||
@ref:[Cluster Sharding example](cluster-sharding.md#persistence-example) illustrates this common combination.
|
||||
|
||||
## Accessing the ActorContext
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue