!per #3681 Performance and consistency improvements
- batch-write of persistent messages (user API) - batch-write of events (in EventsourcedProcessor) - command processing in EventsourcedProcessor by unstashing messages one-by-one from the internal stash * fixes performance issues that come up with unstashAll - commands are not looped through journal actor but processed directly - initial performance tests * command sourcing * event sourcing * event sourcing with user stash operations - suppress stack traces in tests
This commit is contained in:
parent
8eeaadfee0
commit
1da3369643
29 changed files with 1324 additions and 76 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package akka.persistence.journal
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.Future
|
||||
import scala.util._
|
||||
|
||||
|
|
@ -11,7 +12,6 @@ import akka.actor._
|
|||
import akka.pattern.{ pipe, PromiseActorRef }
|
||||
import akka.persistence._
|
||||
import akka.persistence.JournalProtocol._
|
||||
import akka.serialization.Serialization
|
||||
|
||||
/**
|
||||
* Abstract journal, optimized for asynchronous, non-blocking writes.
|
||||
|
|
@ -28,13 +28,26 @@ trait AsyncWriteJournal extends Actor with AsyncReplay {
|
|||
val csdr = sender
|
||||
val cctr = resequencerCounter
|
||||
val psdr = if (sender.isInstanceOf[PromiseActorRef]) context.system.deadLetters else sender
|
||||
writeAsync(persistent.copy(sender = psdr, resolved = false, confirmTarget = null, confirmMessage = null)) map {
|
||||
writeAsync(persistent.prepareWrite(psdr)) map {
|
||||
_ ⇒ Desequenced(WriteSuccess(persistent), cctr, processor, csdr)
|
||||
} recover {
|
||||
case e ⇒ Desequenced(WriteFailure(persistent, e), cctr, processor, csdr)
|
||||
} pipeTo (resequencer)
|
||||
resequencerCounter += 1
|
||||
}
|
||||
case WriteBatch(persistentBatch, processor) ⇒ {
|
||||
val csdr = sender
|
||||
val cctr = resequencerCounter
|
||||
val psdr = if (sender.isInstanceOf[PromiseActorRef]) context.system.deadLetters else sender
|
||||
def resequence(f: PersistentImpl ⇒ Any) = persistentBatch.zipWithIndex.foreach {
|
||||
case (p, i) ⇒ resequencer ! Desequenced(f(p), cctr + i, processor, csdr)
|
||||
}
|
||||
writeBatchAsync(persistentBatch.map(_.prepareWrite(psdr))) onComplete {
|
||||
case Success(_) ⇒ resequence(WriteSuccess(_))
|
||||
case Failure(e) ⇒ resequence(WriteFailure(_, e))
|
||||
}
|
||||
resequencerCounter += persistentBatch.length
|
||||
}
|
||||
case Replay(fromSequenceNr, toSequenceNr, processorId, processor) ⇒ {
|
||||
// Send replayed messages and replay result to processor directly. No need
|
||||
// to resequence replayed messages relative to written and looped messages.
|
||||
|
|
@ -73,6 +86,14 @@ trait AsyncWriteJournal extends Actor with AsyncReplay {
|
|||
*/
|
||||
def writeAsync(persistent: PersistentImpl): Future[Unit]
|
||||
|
||||
/**
|
||||
* Plugin API.
|
||||
*
|
||||
* Asynchronously writes a batch of persistent messages to the journal. The batch write
|
||||
* must be atomic i.e. either all persistent messages in the batch are written or none.
|
||||
*/
|
||||
def writeBatchAsync(persistentBatch: immutable.Seq[PersistentImpl]): Future[Unit]
|
||||
|
||||
/**
|
||||
* Plugin API.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue