From af2ac0aac8795116a0e7a4150608c8b50c81114d Mon Sep 17 00:00:00 2001 From: Patrik Nordwall Date: Mon, 25 Mar 2019 10:21:33 +0100 Subject: [PATCH] fix race condition in Running.storingSnapshot, #26601 * When storing a snapshot, and waiting for the response, it received a response from a previous/concurrent delete snapshot (DeleteSnapshotSuccess) which it handled as a response for the save snapshot, i.e. tryUnstashOne, applySideEffects, and changing phase to HandlingCommands. Thereby missing the SaveSnapshotSuccess. --- .../persistence/typed/internal/Running.scala | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/akka-persistence-typed/src/main/scala/akka/persistence/typed/internal/Running.scala b/akka-persistence-typed/src/main/scala/akka/persistence/typed/internal/Running.scala index 6f626ed162..f1f0dd1dc8 100644 --- a/akka-persistence-typed/src/main/scala/akka/persistence/typed/internal/Running.scala +++ b/akka-persistence-typed/src/main/scala/akka/persistence/typed/internal/Running.scala @@ -321,11 +321,11 @@ private[akka] object Running { Behaviors.unhandled } else { stashUser(cmd) - storingSnapshot(state, sideEffects) + Behaviors.same } } - def onSnapshotterResponse(response: SnapshotProtocol.Response): Unit = { + def onSaveSnapshotResponse(response: SnapshotProtocol.Response): Unit = { val signal = response match { case e @ SaveSnapshotSuccess(meta) => // # 24698 The deletion of old events are automatic, snapshots are triggered by the SaveSnapshotSuccess. @@ -342,7 +342,6 @@ private[akka] object Running { Some(SnapshotFailed(SnapshotMetadata.fromUntyped(meta), error)) case _ => - onDeleteSnapshotResponse(response) None } @@ -356,9 +355,14 @@ private[akka] object Running { onCommand(cmd) case JournalResponse(r) => onDeleteEventsJournalResponse(r) - case SnapshotterResponse(r) => - onSnapshotterResponse(r) - tryUnstashOne(applySideEffects(sideEffects, state)) + case SnapshotterResponse(response) => + response match { + case _: SaveSnapshotSuccess | _: SaveSnapshotFailure => + onSaveSnapshotResponse(response) + tryUnstashOne(applySideEffects(sideEffects, state)) + case _ => + onDeleteSnapshotResponse(response) + } case _ => Behaviors.unhandled }