diff --git a/akka-docs/rst/java/code/jdocs/persistence/LambdaPersistenceDocTest.java b/akka-docs/rst/java/code/jdocs/persistence/LambdaPersistenceDocTest.java index 0b452622be..435462664d 100644 --- a/akka-docs/rst/java/code/jdocs/persistence/LambdaPersistenceDocTest.java +++ b/akka-docs/rst/java/code/jdocs/persistence/LambdaPersistenceDocTest.java @@ -422,6 +422,41 @@ public class LambdaPersistenceDocTest { } }; + static Object o100 = new Object() { + //#defer-with-persist + class MyPersistentActor extends AbstractPersistentActor { + + @Override public String persistenceId() { + return "my-stable-persistence-id"; + } + + private void handleCommand(String c) { + persist(String.format("evt-%s-1", c), e -> { + sender().tell(e, self()); + }); + persist(String.format("evt-%s-2", c), e -> { + sender().tell(e, self()); + }); + + deferAsync(String.format("evt-%s-3", c), e -> { + sender().tell(e, self()); + }); + } + + @Override public Receive createReceiveRecover() { + return receiveBuilder(). + match(String.class, this::handleCommand).build(); + } + + @Override public Receive createReceive() { + return receiveBuilder(). + match(String.class, this::handleCommand).build(); + } + } + //#defer-with-persist + + }; + static Object o11 = new Object() { class MyPersistentActor extends AbstractPersistentActor { diff --git a/akka-docs/rst/java/persistence.rst b/akka-docs/rst/java/persistence.rst index f77a328efd..2fcf3b607e 100644 --- a/akka-docs/rst/java/persistence.rst +++ b/akka-docs/rst/java/persistence.rst @@ -273,8 +273,8 @@ The ordering between events is still guaranteed ("evt-b-1" will be sent after "e Deferring actions until preceding persist handlers have executed ---------------------------------------------------------------- -Sometimes when working with ``persistAsync`` you may find that it would be nice to define some actions in terms of -''happens-after the previous ``persistAsync`` handlers have been invoked''. ``PersistentActor`` provides an utility method +Sometimes when working with ``persistAsync`` or ``persist`` you may find that it would be nice to define some actions in terms of +''happens-after the previous ``persistAsync``/``persist`` handlers have been invoked''. ``PersistentActor`` provides an utility method called ``deferAsync``, which works similarly to ``persistAsync`` yet does not persist the passed in event. It is recommended to use it for *read* operations, and actions which do not have corresponding events in your domain model. @@ -288,6 +288,10 @@ of the command for which this ``deferAsync`` handler was called. .. includecode:: code/jdocs/persistence/LambdaPersistenceDocTest.java#defer-caller +You can also call ``deferAsync`` with ``persist``. + +.. includecode:: code/docs/persistence/LambdaPersistenceDocTest.java#defer-with-persist + .. warning:: The callback will not be invoked if the actor is restarted (or stopped) in between the call to ``deferAsync`` and the journal has processed and confirmed all preceding writes. diff --git a/akka-docs/rst/scala/code/docs/persistence/PersistenceDocSpec.scala b/akka-docs/rst/scala/code/docs/persistence/PersistenceDocSpec.scala index b60fe923d9..d076177ce6 100644 --- a/akka-docs/rst/scala/code/docs/persistence/PersistenceDocSpec.scala +++ b/akka-docs/rst/scala/code/docs/persistence/PersistenceDocSpec.scala @@ -280,6 +280,28 @@ object PersistenceDocSpec { //#defer-caller } + object DeferWithPersist { + //#defer-with-persist + class MyPersistentActor extends PersistentActor { + + override def persistenceId = "my-stable-persistence-id" + + override def receiveRecover: Receive = { + case _ => // handle recovery here + } + + override def receiveCommand: Receive = { + case c: String => { + sender() ! c + persist(s"evt-$c-1") { e => sender() ! e } + persist(s"evt-$c-2") { e => sender() ! e } + deferAsync(s"evt-$c-3") { e => sender() ! e } + } + } + } + //#defer-with-persist + } + object NestedPersists { class MyPersistentActor extends PersistentActor { diff --git a/akka-docs/rst/scala/persistence.rst b/akka-docs/rst/scala/persistence.rst index 728d68f442..00dd83785c 100644 --- a/akka-docs/rst/scala/persistence.rst +++ b/akka-docs/rst/scala/persistence.rst @@ -273,8 +273,8 @@ The ordering between events is still guaranteed ("evt-b-1" will be sent after "e Deferring actions until preceding persist handlers have executed ---------------------------------------------------------------- -Sometimes when working with ``persistAsync`` you may find that it would be nice to define some actions in terms of -''happens-after the previous ``persistAsync`` handlers have been invoked''. ``PersistentActor`` provides an utility method +Sometimes when working with ``persistAsync`` or ``persist`` you may find that it would be nice to define some actions in terms of +''happens-after the previous ``persistAsync``/``persist`` handlers have been invoked''. ``PersistentActor`` provides an utility method called ``deferAsync``, which works similarly to ``persistAsync`` yet does not persist the passed in event. It is recommended to use it for *read* operations, and actions which do not have corresponding events in your domain model. @@ -290,6 +290,10 @@ The calling side will get the responses in this (guaranteed) order: .. includecode:: code/docs/persistence/PersistenceDocSpec.scala#defer-caller +You can also call ``deferAsync`` with ``persist``. + +.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#defer-with-persist + .. warning:: The callback will not be invoked if the actor is restarted (or stopped) in between the call to ``deferAsync`` and the journal has processed and confirmed all preceding writes. diff --git a/akka-persistence/src/main/scala/akka/persistence/Eventsourced.scala b/akka-persistence/src/main/scala/akka/persistence/Eventsourced.scala index 1dc5327726..d099294a63 100644 --- a/akka-persistence/src/main/scala/akka/persistence/Eventsourced.scala +++ b/akka-persistence/src/main/scala/akka/persistence/Eventsourced.scala @@ -351,7 +351,7 @@ private[persistence] trait Eventsourced extends Snapshotter with PersistenceStas */ @InternalApi final private[akka] def internalDeferAsync[A](event: A)(handler: A ⇒ Unit): Unit = { - if (recoveryRunning) throw new IllegalStateException("Cannot persist during replay. Events can be persisted when receiving RecoveryCompleted or later.") + if (recoveryRunning) throw new IllegalStateException("Cannot defer during replay. Events can be deferred when receiving RecoveryCompleted or later.") if (pendingInvocations.isEmpty) { handler(event) } else { diff --git a/akka-persistence/src/main/scala/akka/persistence/PersistentActor.scala b/akka-persistence/src/main/scala/akka/persistence/PersistentActor.scala index 830a956801..c2784dbfd5 100644 --- a/akka-persistence/src/main/scala/akka/persistence/PersistentActor.scala +++ b/akka-persistence/src/main/scala/akka/persistence/PersistentActor.scala @@ -246,7 +246,7 @@ trait PersistentActor extends Eventsourced with PersistenceIdentity { /** * Defer the handler execution until all pending handlers have been executed. * Allows to define logic within the actor, which will respect the invocation-order-guarantee - * in respect to `persistAsync` calls. That is, if `persistAsync` was invoked before `deferAsync`, + * in respect to `persistAsync` or `persist` calls. That is, if `persistAsync` or `persist` was invoked before `deferAsync`, * the corresponding handlers will be invoked in the same order as they were registered in. * * This call will NOT result in `event` being persisted, use `persist` or `persistAsync` instead @@ -360,7 +360,7 @@ abstract class UntypedPersistentActor extends UntypedActor with Eventsourced wit /** * Defer the handler execution until all pending handlers have been executed. * Allows to define logic within the actor, which will respect the invocation-order-guarantee - * in respect to `persistAsync` calls. That is, if `persistAsync` was invoked before defer, + * in respect to `persistAsync` or `persist` calls. That is, if `persistAsync` or `persist` was invoked before `deferAsync`, * the corresponding handlers will be invoked in the same order as they were registered in. * * This call will NOT result in `event` being persisted, please use `persist` or `persistAsync`,