=per #15457 Correlate persistAsync handlers with journal messages

We have assumed that the handlers can be popped when replies come back from journal, but if messages to journal are in flight when the actor is restarted the handlers does not match up with journal replies.

This solution ignores journal replies that were emitted by an old PersistentActor instance
by passing an uid with the journal messages. This means that the handler will not be
invoked for such messages.

(cherry picked from commit 7ebaaab669c9e467a1ffb4d9ed8b6500e1801a7c)

Conflicts:
	akka-persistence/src/main/scala/akka/persistence/JournalProtocol.scala
	akka-persistence/src/main/scala/akka/persistence/Processor.scala
	akka-persistence/src/main/scala/akka/persistence/journal/AsyncWriteJournal.scala
This commit is contained in:
Patrik Nordwall 2014-06-26 17:35:46 +02:00
parent 33c7f6bb4f
commit 8eec3f92d3
11 changed files with 126 additions and 56 deletions

View file

@ -299,6 +299,25 @@ object PersistentActorSpec {
}
}
class AsyncPersistHandlerCorrelationCheck(name: String) extends ExamplePersistentActor(name) {
var counter = 0
val receiveCommand: Receive = commonBehavior orElse {
case Cmd(data)
persistAsync(Evt(data)) { evt
if (data != evt.data)
sender() ! s"Expected [$data] bot got [${evt.data}]"
if (evt.data == "done")
sender() ! "done"
}
}
private def incCounter(): Int = {
counter += 1
counter
}
}
class UserStashFailureProcessor(name: String) extends ExamplePersistentActor(name) {
val receiveCommand: Receive = commonBehavior orElse {
case Cmd(data)
@ -661,6 +680,14 @@ abstract class PersistentActorSpec(config: Config) extends AkkaSpec(config) with
expectNoMsg(100.millis)
}
"correlate persistAsync handlers after restart" in {
val processor = namedProcessor[AsyncPersistHandlerCorrelationCheck]
for (n 1 to 100) processor ! Cmd(n)
processor ! "boom"
for (n 1 to 20) processor ! Cmd(n)
processor ! Cmd("done")
expectMsg(5.seconds, "done")
}
"allow deferring handlers in order to provide ordered processing in respect to persist handlers" in {
val processor = namedProcessor[DeferringWithPersistActor]
processor ! Cmd("a")