2013-10-08 11:46:02 +02:00
|
|
|
/**
|
2014-02-02 19:05:45 -06:00
|
|
|
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
2013-10-08 11:46:02 +02:00
|
|
|
* Copyright (C) 2012-2013 Eligotech BV.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package akka.persistence.journal
|
|
|
|
|
|
2013-10-27 08:01:14 +01:00
|
|
|
import scala.collection.immutable
|
2013-10-08 11:46:02 +02:00
|
|
|
import scala.util._
|
|
|
|
|
|
|
|
|
|
import akka.actor.Actor
|
2013-12-06 12:48:44 +01:00
|
|
|
import akka.pattern.pipe
|
2013-10-08 11:46:02 +02:00
|
|
|
import akka.persistence._
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Abstract journal, optimized for synchronous writes.
|
|
|
|
|
*/
|
2014-01-17 06:58:25 +01:00
|
|
|
trait SyncWriteJournal extends Actor with AsyncRecovery {
|
2013-10-08 11:46:02 +02:00
|
|
|
import JournalProtocol._
|
|
|
|
|
import context.dispatcher
|
|
|
|
|
|
|
|
|
|
private val extension = Persistence(context.system)
|
2014-01-17 06:58:25 +01:00
|
|
|
private val publish = extension.settings.internal.publishPluginCommands
|
2013-10-08 11:46:02 +02:00
|
|
|
|
|
|
|
|
final def receive = {
|
2014-01-17 06:58:25 +01:00
|
|
|
case WriteMessages(persistentBatch, processor) ⇒
|
|
|
|
|
Try(writeMessages(persistentBatch.map(_.prepareWrite()))) match {
|
2013-11-20 13:47:42 +01:00
|
|
|
case Success(_) ⇒
|
2014-05-21 01:35:21 +02:00
|
|
|
processor ! WriteMessagesSuccessful
|
2014-01-17 06:58:25 +01:00
|
|
|
persistentBatch.foreach(p ⇒ processor.tell(WriteMessageSuccess(p), p.sender))
|
2013-11-20 13:47:42 +01:00
|
|
|
case Failure(e) ⇒
|
2014-05-21 01:35:21 +02:00
|
|
|
processor ! WriteMessagesFailed(e)
|
2014-01-17 06:58:25 +01:00
|
|
|
persistentBatch.foreach(p ⇒ processor tell (WriteMessageFailure(p, e), p.sender))
|
2013-11-20 13:47:42 +01:00
|
|
|
throw e
|
2013-10-08 11:46:02 +02:00
|
|
|
}
|
2014-01-23 10:43:02 +01:00
|
|
|
case r @ ReplayMessages(fromSequenceNr, toSequenceNr, max, processorId, processor, replayDeleted) ⇒
|
2014-01-17 06:58:25 +01:00
|
|
|
asyncReplayMessages(processorId, fromSequenceNr, toSequenceNr, max) { p ⇒
|
|
|
|
|
if (!p.deleted || replayDeleted) processor.tell(ReplayedMessage(p), p.sender)
|
2013-10-08 11:46:02 +02:00
|
|
|
} map {
|
2014-01-17 06:58:25 +01:00
|
|
|
case _ ⇒ ReplayMessagesSuccess
|
2013-10-08 11:46:02 +02:00
|
|
|
} recover {
|
2014-01-17 06:58:25 +01:00
|
|
|
case e ⇒ ReplayMessagesFailure(e)
|
2014-01-23 10:43:02 +01:00
|
|
|
} pipeTo (processor) onSuccess {
|
|
|
|
|
case _ if publish ⇒ context.system.eventStream.publish(r)
|
|
|
|
|
}
|
2014-01-17 06:58:25 +01:00
|
|
|
case ReadHighestSequenceNr(fromSequenceNr, processorId, processor) ⇒
|
|
|
|
|
asyncReadHighestSequenceNr(processorId, fromSequenceNr).map {
|
|
|
|
|
highest ⇒ ReadHighestSequenceNrSuccess(highest)
|
|
|
|
|
} recover {
|
|
|
|
|
case e ⇒ ReadHighestSequenceNrFailure(e)
|
|
|
|
|
} pipeTo (processor)
|
|
|
|
|
case WriteConfirmations(confirmationsBatch, requestor) ⇒
|
|
|
|
|
Try(writeConfirmations(confirmationsBatch)) match {
|
|
|
|
|
case Success(_) ⇒ requestor ! WriteConfirmationsSuccess(confirmationsBatch)
|
|
|
|
|
case Failure(e) ⇒ requestor ! WriteConfirmationsFailure(e)
|
|
|
|
|
}
|
|
|
|
|
case d @ DeleteMessages(messageIds, permanent, requestorOption) ⇒
|
|
|
|
|
Try(deleteMessages(messageIds, permanent)) match {
|
|
|
|
|
case Success(_) ⇒
|
|
|
|
|
requestorOption.foreach(_ ! DeleteMessagesSuccess(messageIds))
|
|
|
|
|
if (publish) context.system.eventStream.publish(d)
|
|
|
|
|
case Failure(e) ⇒
|
|
|
|
|
requestorOption.foreach(_ ! DeleteMessagesFailure(e))
|
2013-12-06 12:48:44 +01:00
|
|
|
}
|
2014-01-17 06:58:25 +01:00
|
|
|
case d @ DeleteMessagesTo(processorId, toSequenceNr, permanent) ⇒
|
|
|
|
|
Try(deleteMessagesTo(processorId, toSequenceNr, permanent)) match {
|
|
|
|
|
case Success(_) ⇒ if (publish) context.system.eventStream.publish(d)
|
|
|
|
|
case Failure(e) ⇒
|
|
|
|
|
}
|
|
|
|
|
case LoopMessage(message, processor) ⇒
|
|
|
|
|
processor forward LoopMessageSuccess(message)
|
2013-10-08 11:46:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#journal-plugin-api
|
2013-10-27 08:01:14 +01:00
|
|
|
/**
|
2013-11-07 10:45:02 +01:00
|
|
|
* Plugin API: synchronously 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.
|
2013-10-27 08:01:14 +01:00
|
|
|
*/
|
2014-01-17 06:58:25 +01:00
|
|
|
def writeMessages(messages: immutable.Seq[PersistentRepr]): Unit
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Plugin API: synchronously writes a batch of delivery confirmations to the journal.
|
|
|
|
|
*/
|
|
|
|
|
def writeConfirmations(confirmations: immutable.Seq[PersistentConfirmation]): Unit
|
2013-10-27 08:01:14 +01:00
|
|
|
|
2013-10-08 11:46:02 +02:00
|
|
|
/**
|
2014-01-17 06:58:25 +01:00
|
|
|
* Plugin API: synchronously deletes messages identified by `messageIds` from the
|
|
|
|
|
* journal. If `permanent` is set to `false`, the persistent messages are marked as
|
|
|
|
|
* deleted, otherwise they are permanently deleted.
|
2013-10-08 11:46:02 +02:00
|
|
|
*/
|
2014-01-17 06:58:25 +01:00
|
|
|
def deleteMessages(messageIds: immutable.Seq[PersistentId], permanent: Boolean): Unit
|
2013-10-08 11:46:02 +02:00
|
|
|
|
|
|
|
|
/**
|
2014-01-17 06:58:25 +01:00
|
|
|
* Plugin API: synchronously deletes all persistent messages up to `toSequenceNr`
|
|
|
|
|
* (inclusive). If `permanent` is set to `false`, the persistent messages are marked
|
|
|
|
|
* as deleted, otherwise they are permanently deleted.
|
2013-10-08 11:46:02 +02:00
|
|
|
*/
|
2014-01-17 06:58:25 +01:00
|
|
|
def deleteMessagesTo(processorId: String, toSequenceNr: Long, permanent: Boolean): Unit
|
2013-10-08 11:46:02 +02:00
|
|
|
//#journal-plugin-api
|
|
|
|
|
}
|