pekko/akka-actor-tests/src/test/scala/akka/pattern/CircuitBreakerStressSpec.scala

83 lines
2.3 KiB
Scala

/**
* Copyright (C) 2015-2016 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.pattern
import scala.concurrent.Promise
import scala.concurrent.duration._
import java.util.concurrent.ThreadLocalRandom
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.Status.Failure
import akka.testkit.AkkaSpec
import akka.testkit.ImplicitSender
import java.util.concurrent.TimeoutException
object CircuitBreakerStressSpec {
case object JobDone
case object GetResult
case class Result(doneCount: Int, timeoutCount: Int, failCount: Int, circCount: Int)
class StressActor(breaker: CircuitBreaker) extends Actor with ActorLogging with PipeToSupport {
import context.dispatcher
private var doneCount = 0
private var timeoutCount = 0
private var failCount = 0
private var circCount = 0
private def job = {
val promise = Promise[JobDone.type]()
context.system.scheduler.scheduleOnce(ThreadLocalRandom.current.nextInt(300).millisecond) {
promise.success(JobDone)
}
promise.future
}
override def receive = {
case JobDone
doneCount += 1
breaker.withCircuitBreaker(job).pipeTo(self)
case Failure(ex: CircuitBreakerOpenException)
circCount += 1
breaker.withCircuitBreaker(job).pipeTo(self)
case Failure(_: TimeoutException)
timeoutCount += 1
breaker.withCircuitBreaker(job).pipeTo(self)
case Failure(_)
failCount += 1
breaker.withCircuitBreaker(job).pipeTo(self)
case GetResult
sender() ! Result(doneCount, timeoutCount, failCount, circCount)
}
}
}
// reproducer for issue #17415
class CircuitBreakerStressSpec extends AkkaSpec with ImplicitSender {
import CircuitBreakerStressSpec._
muteDeadLetters(classOf[AnyRef])(system)
"A CircuitBreaker" in {
val breaker = CircuitBreaker(system.scheduler, 5, 200.millisecond, 200.seconds)
val stressActors = Vector.fill(3) {
system.actorOf(Props(classOf[StressActor], breaker))
}
for (_ 0 to 1000; a stressActors) {
a ! JobDone
}
// let them work for a while
Thread.sleep(3000)
stressActors.foreach { a
a ! GetResult
val result = expectMsgType[Result]
result.failCount should be(0)
}
}
}