fix NPE in SnapshotStore, #26580
* access of context.system from Future callback * also changed import context.dispatcher, shouldn't be needed but rather safe than sorry
This commit is contained in:
parent
886088f03b
commit
610a89c2d0
2 changed files with 84 additions and 74 deletions
|
|
@ -5,14 +5,17 @@
|
|||
package akka.persistence.journal
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.actor._
|
||||
import akka.pattern.pipe
|
||||
import akka.persistence._
|
||||
import akka.util.Helpers.toRootLowerCase
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.concurrent.Future
|
||||
import scala.util.{ Failure, Success, Try }
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
import akka.pattern.CircuitBreaker
|
||||
|
||||
/**
|
||||
|
|
@ -21,7 +24,6 @@ import akka.pattern.CircuitBreaker
|
|||
trait AsyncWriteJournal extends Actor with WriteJournalBase with AsyncRecovery {
|
||||
import AsyncWriteJournal._
|
||||
import JournalProtocol._
|
||||
import context.dispatcher
|
||||
|
||||
private val extension = Persistence(context.system)
|
||||
private val publish = extension.settings.internal.publishPluginCommands
|
||||
|
|
@ -56,6 +58,8 @@ trait AsyncWriteJournal extends Actor with WriteJournalBase with AsyncRecovery {
|
|||
final val receiveWriteJournal: Actor.Receive = {
|
||||
// cannot be a val in the trait due to binary compatibility
|
||||
val replayDebugEnabled: Boolean = config.getBoolean("replay-filter.debug")
|
||||
val eventStream = context.system.eventStream // used from Future callbacks
|
||||
implicit val ec: ExecutionContext = context.dispatcher
|
||||
|
||||
{
|
||||
case WriteMessages(messages, persistentActor, actorInstanceId) =>
|
||||
|
|
@ -71,7 +75,7 @@ trait AsyncWriteJournal extends Actor with WriteJournalBase with AsyncRecovery {
|
|||
catch { case NonFatal(e) => Future.failed(e) }
|
||||
case f @ Failure(_) =>
|
||||
// exception from preparePersistentBatch => rejected
|
||||
Future.successful(messages.collect { case a: AtomicWrite => f })
|
||||
Future.successful(messages.collect { case _: AtomicWrite => f })
|
||||
}).map { results =>
|
||||
if (results.nonEmpty && results.size != atomicWriteCount)
|
||||
throw new IllegalStateException(
|
||||
|
|
@ -171,7 +175,7 @@ trait AsyncWriteJournal extends Actor with WriteJournalBase with AsyncRecovery {
|
|||
}
|
||||
.pipeTo(replyTo)
|
||||
.foreach { _ =>
|
||||
if (publish) context.system.eventStream.publish(r)
|
||||
if (publish) eventStream.publish(r)
|
||||
}
|
||||
|
||||
case d @ DeleteMessagesTo(persistenceId, toSequenceNr, persistentActor) =>
|
||||
|
|
@ -185,7 +189,7 @@ trait AsyncWriteJournal extends Actor with WriteJournalBase with AsyncRecovery {
|
|||
}
|
||||
.pipeTo(persistentActor)
|
||||
.onComplete { _ =>
|
||||
if (publish) context.system.eventStream.publish(d)
|
||||
if (publish) eventStream.publish(d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
package akka.persistence.snapshot
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.Future
|
||||
|
||||
import akka.actor._
|
||||
import akka.pattern.pipe
|
||||
import akka.persistence._
|
||||
|
|
@ -16,7 +18,6 @@ import akka.pattern.CircuitBreaker
|
|||
*/
|
||||
trait SnapshotStore extends Actor with ActorLogging {
|
||||
import SnapshotProtocol._
|
||||
import context.dispatcher
|
||||
|
||||
private val extension = Persistence(context.system)
|
||||
private val publish = extension.settings.internal.publishPluginCommands
|
||||
|
|
@ -32,6 +33,10 @@ trait SnapshotStore extends Actor with ActorLogging {
|
|||
final def receive = receiveSnapshotStore.orElse[Any, Unit](receivePluginInternal)
|
||||
|
||||
final val receiveSnapshotStore: Actor.Receive = {
|
||||
val eventStream = context.system.eventStream // used from Future callbacks
|
||||
implicit val ec: ExecutionContext = context.dispatcher
|
||||
|
||||
{
|
||||
case LoadSnapshot(persistenceId, criteria, toSequenceNr) =>
|
||||
if (criteria == SnapshotSelectionCriteria.None) {
|
||||
senderPersistentActor() ! LoadSnapshotResult(snapshot = None, toSequenceNr)
|
||||
|
|
@ -78,7 +83,7 @@ trait SnapshotStore extends Actor with ActorLogging {
|
|||
}
|
||||
.pipeTo(self)(senderPersistentActor())
|
||||
.onComplete {
|
||||
case _ => if (publish) context.system.eventStream.publish(d)
|
||||
case _ => if (publish) eventStream.publish(d)
|
||||
}
|
||||
|
||||
case evt: DeleteSnapshotSuccess =>
|
||||
|
|
@ -99,7 +104,7 @@ trait SnapshotStore extends Actor with ActorLogging {
|
|||
}
|
||||
.pipeTo(self)(senderPersistentActor())
|
||||
.onComplete {
|
||||
case _ => if (publish) context.system.eventStream.publish(d)
|
||||
case _ => if (publish) eventStream.publish(d)
|
||||
}
|
||||
|
||||
case evt: DeleteSnapshotsFailure =>
|
||||
|
|
@ -109,6 +114,7 @@ trait SnapshotStore extends Actor with ActorLogging {
|
|||
try tryReceivePluginInternal(evt)
|
||||
finally senderPersistentActor() ! evt
|
||||
}
|
||||
}
|
||||
|
||||
/** Documents intent that the sender() is expected to be the PersistentActor */
|
||||
@inline private final def senderPersistentActor(): ActorRef = sender()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue