* Problem when using PersistentChannel from Processor * When the seq numbers of the sending processor and the seq numbers of the PersistentChannel was out of sync the PersistentChannel did not de-duplicate confirmed deliveres that were resent by the processor. * There is a hand-off in the RequestWriter that confirms the Processor seq number, and therefore the seq number of the RequestWriter must be used in the ConfirmablePersistent from the RequestReader * More tests, covering this scenario
91 lines
2.8 KiB
Scala
91 lines
2.8 KiB
Scala
/**
|
|
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
|
*/
|
|
package akka.persistence
|
|
|
|
import scala.language.postfixOps
|
|
|
|
import com.typesafe.config._
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
import akka.actor._
|
|
import akka.persistence._
|
|
|
|
import akka.testkit._
|
|
|
|
object NumberProcessorSpec {
|
|
case class SetNumber(number: Int)
|
|
case class Add(number: Int)
|
|
case class Subtract(number: Int)
|
|
case object DecrementAndGet
|
|
case object GetNumber
|
|
|
|
class NumberProcessorWithPersistentChannel(name: String) extends NamedProcessor(name) {
|
|
override def processorId = name
|
|
var num = 0
|
|
|
|
val channel = context.actorOf(PersistentChannel.props(channelId = "stable_id",
|
|
PersistentChannelSettings(redeliverInterval = 30 seconds, redeliverMax = 15)),
|
|
name = "myPersistentChannel")
|
|
|
|
def receive = {
|
|
case Persistent(SetNumber(number), _) ⇒ num = number
|
|
case Persistent(Add(number), _) ⇒ num = num + number
|
|
case Persistent(Subtract(number), _) ⇒ num = num - number
|
|
case GetNumber ⇒ channel ! Deliver(Persistent(num), sender.path)
|
|
case p @ Persistent(DecrementAndGet, _) ⇒
|
|
num = num - 1
|
|
channel ! Deliver(p.withPayload(num), sender.path)
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This test found the problem described in ticket #3933
|
|
*/
|
|
class NumberProcessorSpec extends AkkaSpec(PersistenceSpec.config("leveldb", "NumberProcessorSpec"))
|
|
with PersistenceSpec {
|
|
import NumberProcessorSpec._
|
|
|
|
"A processor using a persistent channel" must {
|
|
|
|
"resurrect with the correct state, not replaying confirmed messages to clients" in {
|
|
val deliveredProbe = TestProbe()
|
|
system.eventStream.subscribe(deliveredProbe.testActor, classOf[DeliveredByPersistentChannel])
|
|
|
|
val probe = TestProbe()
|
|
|
|
val processor = namedProcessor[NumberProcessorWithPersistentChannel]
|
|
processor.tell(GetNumber, probe.testActor)
|
|
|
|
val zero = probe.expectMsgType[ConfirmablePersistent]
|
|
zero.confirm()
|
|
zero.payload should equal(0)
|
|
|
|
deliveredProbe.expectMsgType[DeliveredByPersistentChannel]
|
|
|
|
processor.tell(Persistent(DecrementAndGet), probe.testActor)
|
|
|
|
val decrementFrom0 = probe.expectMsgType[ConfirmablePersistent]
|
|
decrementFrom0.confirm()
|
|
decrementFrom0.payload should equal(-1)
|
|
|
|
deliveredProbe.expectMsgType[DeliveredByPersistentChannel]
|
|
|
|
watch(processor)
|
|
system.stop(processor)
|
|
expectMsgType[Terminated]
|
|
|
|
val processorResurrected = namedProcessor[NumberProcessorWithPersistentChannel]
|
|
processorResurrected.tell(Persistent(DecrementAndGet), probe.testActor)
|
|
|
|
val decrementFromMinus1 = probe.expectMsgType[ConfirmablePersistent]
|
|
decrementFromMinus1.confirm()
|
|
decrementFromMinus1.payload should equal(-2)
|
|
|
|
deliveredProbe.expectMsgType[DeliveredByPersistentChannel]
|
|
}
|
|
}
|
|
}
|
|
|