!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:
Martin Krasser 2013-10-27 08:01:14 +01:00
parent 8eeaadfee0
commit 1da3369643
29 changed files with 1324 additions and 76 deletions

View file

@ -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.
*