+per #15229 defer for PersistentActor

* Deferred events are not persisted, thus will not participate in replays
  etc. If users want events to be persisted, they can simply use
  `persistAsync` instead.
* This, 3rd, rewrite extends the Persistent hierarchy by a top level
  trait "Resequenceable", which is used to mark every event to be sent
  in sequence back to the PersistentActor. These are split into
  NonPersistentRepr or PersistentRepr, and acted upon accordingly.
* defer is guaranteed to be called, even after persistence failures
* Includes docs updates for java/scala/java8

Resolves #15229
Depends on #15227

Conflicts:
	akka-docs/rst/scala/code/docs/persistence/PersistenceDocSpec.scala
	akka-persistence/src/main/scala/akka/persistence/JournalProtocol.scala
	akka-persistence/src/main/scala/akka/persistence/Processor.scala
	akka-persistence/src/test/scala/akka/persistence/PersistentActorSpec.scala
	project/AkkaBuild.scala
This commit is contained in:
Konrad 'ktoso' Malawski 2014-06-03 16:40:44 +02:00
parent 580b5af816
commit a71790bb18
19 changed files with 905 additions and 159 deletions

View file

@ -23,7 +23,7 @@ trait PersistenceDocSpec {
trait SomeOtherMessage
val system: ActorSystem
implicit val system: ActorSystem
import system._
@ -33,11 +33,11 @@ trait PersistenceDocSpec {
class MyProcessor extends Processor {
def receive = {
case Persistent(payload, sequenceNr) =>
case Persistent(payload, sequenceNr) =>
// message successfully written to journal
case PersistenceFailure(payload, sequenceNr, cause) =>
// message failed to be written to journal
case m: SomeOtherMessage =>
case m: SomeOtherMessage =>
// message not written to journal
}
}
@ -367,6 +367,45 @@ trait PersistenceDocSpec {
//#persist-async
}
new AnyRef {
import akka.actor.ActorRef
val processor = system.actorOf(Props[MyPersistentActor]())
//#defer
class MyPersistentActor extends PersistentActor {
def receiveRecover: Receive = {
case _ => // handle recovery here
}
def receiveCommand: Receive = {
case c: String => {
sender() ! c
persistAsync(s"evt-$c-1") { e => sender() ! e }
persistAsync(s"evt-$c-2") { e => sender() ! e }
defer(s"evt-$c-3") { e => sender() ! e }
}
}
}
//#defer
//#defer-caller
processor ! "a"
processor ! "b"
// order of received messages:
// a
// b
// evt-a-1
// evt-a-2
// evt-a-3
// evt-b-1
// evt-b-2
// evt-b-3
//#defer-caller
}
new AnyRef {
import akka.actor.Props
@ -385,4 +424,47 @@ trait PersistenceDocSpec {
view ! Update(await = true)
//#view-update
}
new AnyRef {
// ------------------------------------------------------------------------------------------------
// FIXME: uncomment once going back to project dependencies (in akka-stream-experimental)
// ------------------------------------------------------------------------------------------------
/*
//#producer-creation
import org.reactivestreams.api.Producer
import akka.persistence.Persistent
import akka.persistence.stream.{ PersistentFlow, PersistentPublisherSettings }
import akka.stream.{ FlowMaterializer, MaterializerSettings }
import akka.stream.scaladsl.Flow
val materializer = FlowMaterializer(MaterializerSettings())
val flow: Flow[Persistent] = PersistentFlow.fromProcessor("some-processor-id")
val producer: Producer[Persistent] = flow.toProducer(materializer)
//#producer-creation
//#producer-buffer-size
PersistentFlow.fromProcessor("some-processor-id", PersistentPublisherSettings(maxBufferSize = 200))
//#producer-buffer-size
//#producer-examples
// 1 producer and 2 consumers:
val producer1: Producer[Persistent] =
PersistentFlow.fromProcessor("processor-1").toProducer(materializer)
Flow(producer1).foreach(p => println(s"consumer-1: ${p.payload}")).consume(materializer)
Flow(producer1).foreach(p => println(s"consumer-2: ${p.payload}")).consume(materializer)
// 2 producers (merged) and 1 consumer:
val producer2: Producer[Persistent] =
PersistentFlow.fromProcessor("processor-2").toProducer(materializer)
val producer3: Producer[Persistent] =
PersistentFlow.fromProcessor("processor-3").toProducer(materializer)
Flow(producer2).merge(producer3).foreach { p =>
println(s"consumer-3: ${p.payload}")
}.consume(materializer)
//#producer-examples
*/
}
}