2011-07-28 15:48:03 +03:00
|
|
|
package akka.routing
|
2010-08-24 23:21:28 +02:00
|
|
|
|
|
|
|
|
import java.util.concurrent.atomic.AtomicInteger
|
2011-11-11 19:57:27 +01:00
|
|
|
import akka.actor._
|
2011-07-28 15:48:03 +03:00
|
|
|
import collection.mutable.LinkedList
|
|
|
|
|
import akka.routing.Routing.Broadcast
|
2011-07-28 16:56:35 +03:00
|
|
|
import java.util.concurrent.{ CountDownLatch, TimeUnit }
|
2011-10-07 15:42:55 +02:00
|
|
|
import akka.testkit._
|
2011-05-23 17:08:45 +02:00
|
|
|
|
|
|
|
|
object RoutingSpec {
|
|
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
class TestActor extends Actor with Serializable {
|
|
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case _ ⇒
|
2011-07-28 15:48:03 +03:00
|
|
|
println("Hello")
|
2011-05-23 17:08:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
2011-12-11 22:34:38 +01:00
|
|
|
|
2011-05-23 17:08:45 +02:00
|
|
|
}
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-10-21 17:01:22 +02:00
|
|
|
@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner])
|
2011-12-05 20:01:42 +01:00
|
|
|
class RoutingSpec extends AkkaSpec with DefaultTimeout {
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val impl = system.asInstanceOf[ActorSystemImpl]
|
|
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
import akka.routing.RoutingSpec._
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
"no router" must {
|
2011-07-28 15:48:03 +03:00
|
|
|
"be started when constructed" in {
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(NoRouter))
|
|
|
|
|
routedActor.isTerminated must be(false)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"send message to connection" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(1)
|
|
|
|
|
|
|
|
|
|
val counter = new AtomicInteger(0)
|
2011-12-11 22:34:38 +01:00
|
|
|
|
|
|
|
|
class Actor1 extends Actor {
|
2011-04-19 17:45:01 +12:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case _ ⇒ counter.incrementAndGet
|
2011-04-19 17:45:01 +12:00
|
|
|
}
|
2011-12-11 22:34:38 +01:00
|
|
|
}
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new Actor1).withRouting(NoRouter))
|
2011-07-28 15:48:03 +03:00
|
|
|
routedActor ! "hello"
|
|
|
|
|
routedActor ! "end"
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
counter.get must be(1)
|
2011-04-19 17:45:01 +12:00
|
|
|
}
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2010-08-24 23:21:28 +02:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
"round robin router" must {
|
|
|
|
|
"be started when constructed" in {
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(RoundRobinRouter(nrOfInstances = 1)))
|
|
|
|
|
routedActor.isTerminated must be(false)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-07-13 19:18:04 +02:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
//In this test a bunch of actors are created and each actor has its own counter.
|
|
|
|
|
//to test round robin, the routed actor receives the following sequence of messages 1 2 3 .. 1 2 3 .. 1 2 3 which it
|
|
|
|
|
//uses to increment his counter.
|
|
|
|
|
//So after n iteration, the first actor his counter should be 1*n, the second 2*n etc etc.
|
|
|
|
|
"deliver messages in a round robin fashion" in {
|
|
|
|
|
val connectionCount = 10
|
|
|
|
|
val iterationCount = 10
|
|
|
|
|
val doneLatch = new CountDownLatch(connectionCount)
|
|
|
|
|
|
|
|
|
|
//lets create some connections.
|
2011-12-11 22:34:38 +01:00
|
|
|
var actors = new LinkedList[ActorRef]
|
2011-07-28 15:48:03 +03:00
|
|
|
var counters = new LinkedList[AtomicInteger]
|
2011-07-28 16:56:35 +03:00
|
|
|
for (i ← 0 until connectionCount) {
|
2011-07-28 15:48:03 +03:00
|
|
|
counters = counters :+ new AtomicInteger()
|
|
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val actor = system.actorOf(new Actor {
|
2011-07-28 15:48:03 +03:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counters.get(i).get.addAndGet(msg)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-12-11 22:34:38 +01:00
|
|
|
actors = actors :+ actor
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-07-13 19:18:04 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(RoundRobinRouter(targets = actors)))
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
//send messages to the actor.
|
2011-07-28 16:56:35 +03:00
|
|
|
for (i ← 0 until iterationCount) {
|
|
|
|
|
for (k ← 0 until connectionCount) {
|
2011-12-11 22:34:38 +01:00
|
|
|
routedActor ! (k + 1)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
|
|
|
|
}
|
2011-07-13 19:18:04 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
routedActor ! Broadcast("end")
|
2011-07-28 15:48:03 +03:00
|
|
|
//now wait some and do validations.
|
|
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
2011-03-16 12:37:48 +01:00
|
|
|
|
2011-07-28 16:56:35 +03:00
|
|
|
for (i ← 0 until connectionCount) {
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter = counters.get(i).get
|
|
|
|
|
counter.get must be((iterationCount * (i + 1)))
|
2011-06-02 22:54:38 +02:00
|
|
|
}
|
2011-03-16 12:37:48 +01:00
|
|
|
}
|
|
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
"deliver a broadcast message using the !" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(2)
|
2011-03-16 12:37:48 +01:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter1 = new AtomicInteger
|
2011-12-11 22:34:38 +01:00
|
|
|
val actor1 = system.actorOf(new Actor {
|
2011-07-28 15:48:03 +03:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter1.addAndGet(msg)
|
2011-04-19 17:45:01 +12:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-03-16 12:37:48 +01:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter2 = new AtomicInteger
|
2011-12-11 22:34:38 +01:00
|
|
|
val actor2 = system.actorOf(new Actor {
|
2011-04-19 17:45:01 +12:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter2.addAndGet(msg)
|
2011-04-19 17:45:01 +12:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-03-16 13:20:00 +01:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(RoundRobinRouter(targets = List(actor1, actor2))))
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
routedActor ! Broadcast(1)
|
|
|
|
|
routedActor ! Broadcast("end")
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
counter1.get must be(1)
|
|
|
|
|
counter2.get must be(1)
|
2011-03-16 13:20:00 +01:00
|
|
|
}
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
// TODO (HE) : Is this still a valid test case?
|
|
|
|
|
/*
|
2011-07-28 15:48:03 +03:00
|
|
|
"fail to deliver a broadcast message using the ?" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(1)
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter1 = new AtomicInteger
|
2011-12-07 11:10:54 +01:00
|
|
|
val connection1 = system.actorOf(new Actor {
|
2011-03-16 13:20:00 +01:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case _ ⇒ counter1.incrementAndGet()
|
2011-02-28 22:55:02 +01:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(RoundRobinRouter(targets = List(connection1))))
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
intercept[RoutingException] {
|
|
|
|
|
routedActor ? Broadcast(1)
|
|
|
|
|
}
|
2011-07-28 15:48:03 +03:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
routedActor ! "end"
|
2011-07-28 15:48:03 +03:00
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
|
|
|
|
counter1.get must be(0)
|
2011-03-16 13:20:00 +01:00
|
|
|
}
|
2011-12-11 22:34:38 +01:00
|
|
|
*/
|
|
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-03-16 13:20:00 +01:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
"random router" must {
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
"be started when constructed" in {
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(RandomRouter(nrOfInstances = 1)))
|
|
|
|
|
routedActor.isTerminated must be(false)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
"deliver a broadcast message" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(2)
|
2011-03-16 13:20:00 +01:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter1 = new AtomicInteger
|
2011-12-11 22:34:38 +01:00
|
|
|
val actor1 = system.actorOf(new Actor {
|
2011-07-28 15:48:03 +03:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter1.addAndGet(msg)
|
2011-02-28 22:55:02 +01:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-03-16 13:20:00 +01:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter2 = new AtomicInteger
|
2011-12-11 22:34:38 +01:00
|
|
|
val actor2 = system.actorOf(new Actor {
|
2011-07-28 15:48:03 +03:00
|
|
|
def receive = {
|
2011-07-28 16:56:35 +03:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter2.addAndGet(msg)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(RandomRouter(targets = List(actor1, actor2))))
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
routedActor ! Broadcast(1)
|
|
|
|
|
routedActor ! Broadcast("end")
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
counter1.get must be(1)
|
|
|
|
|
counter2.get must be(1)
|
2011-03-16 13:20:00 +01:00
|
|
|
}
|
|
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
// TODO (HE) : Is this still a valid test case?
|
|
|
|
|
/*
|
|
|
|
|
"fail to deliver a broadcast message using the ?" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(1)
|
|
|
|
|
|
|
|
|
|
val counter1 = new AtomicInteger
|
|
|
|
|
val connection1 = system.actorOf(new Actor {
|
|
|
|
|
def receive = {
|
|
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case _ ⇒ counter1.incrementAndGet()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new RandomRouter, connectionManager = new LocalConnectionManager(List(connection1)))
|
|
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
actor ? Broadcast(1)
|
|
|
|
|
fail()
|
|
|
|
|
} catch {
|
|
|
|
|
case e: RoutingException ⇒
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actor ! "end"
|
|
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
|
|
|
|
counter1.get must be(0)
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"broadcast router" must {
|
|
|
|
|
"be started when constructed" in {
|
|
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(BroadcastRouter(nrOfInstances = 1)))
|
|
|
|
|
routedActor.isTerminated must be(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"broadcast message using !" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(2)
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
val counter1 = new AtomicInteger
|
2011-12-11 22:34:38 +01:00
|
|
|
val actor1 = system.actorOf(new Actor {
|
2011-07-28 15:48:03 +03:00
|
|
|
def receive = {
|
2011-12-11 22:34:38 +01:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter1.addAndGet(msg)
|
2011-07-28 15:48:03 +03:00
|
|
|
}
|
2011-09-08 11:02:17 +02:00
|
|
|
})
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val counter2 = new AtomicInteger
|
|
|
|
|
val actor2 = system.actorOf(new Actor {
|
|
|
|
|
def receive = {
|
|
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter2.addAndGet(msg)
|
|
|
|
|
}
|
|
|
|
|
})
|
2011-04-19 17:45:01 +12:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(BroadcastRouter(targets = List(actor1, actor2))))
|
|
|
|
|
routedActor ! 1
|
|
|
|
|
routedActor ! "end"
|
2011-03-16 13:20:00 +01:00
|
|
|
|
2011-07-28 15:48:03 +03:00
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
2011-12-11 22:34:38 +01:00
|
|
|
|
|
|
|
|
counter1.get must be(1)
|
|
|
|
|
counter2.get must be(1)
|
2011-03-16 13:20:00 +01:00
|
|
|
}
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
"broadcast message using ?" in {
|
|
|
|
|
val doneLatch = new CountDownLatch(2)
|
|
|
|
|
|
|
|
|
|
val counter1 = new AtomicInteger
|
|
|
|
|
val actor1 = system.actorOf(new Actor {
|
|
|
|
|
def receive = {
|
|
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒
|
|
|
|
|
counter1.addAndGet(msg)
|
|
|
|
|
sender ! "ack"
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
val counter2 = new AtomicInteger
|
|
|
|
|
val actor2 = system.actorOf(new Actor {
|
|
|
|
|
def receive = {
|
|
|
|
|
case "end" ⇒ doneLatch.countDown()
|
|
|
|
|
case msg: Int ⇒ counter2.addAndGet(msg)
|
|
|
|
|
}
|
|
|
|
|
})
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(BroadcastRouter(targets = List(actor1, actor2))))
|
|
|
|
|
routedActor ? 1
|
|
|
|
|
routedActor ! "end"
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
doneLatch.await(5, TimeUnit.SECONDS) must be(true)
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
counter1.get must be(1)
|
|
|
|
|
counter2.get must be(1)
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
// TODO (HE) : add tests below
|
|
|
|
|
/*
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
"Scatter-gather router" must {
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
"return response, even if one of the actors has stopped" in {
|
|
|
|
|
val shutdownLatch = new TestLatch(1)
|
|
|
|
|
val actor1 = newActor(1, Some(shutdownLatch))
|
|
|
|
|
val actor2 = newActor(2, Some(shutdownLatch))
|
|
|
|
|
val routedActor = system.actorOf(Props(new TestActor).withRouting(ScatterGatherFirstCompletedRouter(targets = List(actor1, actor2))))
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
routedActor ! Broadcast(Stop(Some(1)))
|
|
|
|
|
shutdownLatch.await
|
|
|
|
|
(routedActor ? Broadcast(0)).get.asInstanceOf[Int] must be(1)
|
|
|
|
|
}
|
2011-10-07 15:42:55 +02:00
|
|
|
|
|
|
|
|
"throw an exception, if all the connections have stopped" in {
|
|
|
|
|
|
|
|
|
|
val shutdownLatch = new TestLatch(2)
|
|
|
|
|
|
2011-11-11 19:57:27 +01:00
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(List(newActor(0, Some(shutdownLatch)), newActor(1, Some(shutdownLatch)))))
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
2011-10-07 15:42:55 +02:00
|
|
|
|
|
|
|
|
actor ! Broadcast(Stop())
|
|
|
|
|
|
|
|
|
|
shutdownLatch.await
|
|
|
|
|
|
|
|
|
|
(intercept[RoutingException] {
|
|
|
|
|
actor ? Broadcast(0)
|
|
|
|
|
}) must not be (null)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"return the first response from connections, when all of them replied" in {
|
|
|
|
|
|
2011-11-11 19:57:27 +01:00
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(List(newActor(0), newActor(1))))
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
2011-10-07 15:42:55 +02:00
|
|
|
|
|
|
|
|
(actor ? Broadcast("Hi!")).get.asInstanceOf[Int] must be(0)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"return the first response from connections, when some of them failed to reply" in {
|
2011-11-11 19:57:27 +01:00
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(List(newActor(0), newActor(1))))
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
2011-10-07 15:42:55 +02:00
|
|
|
|
|
|
|
|
(actor ? Broadcast(0)).get.asInstanceOf[Int] must be(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"be started when constructed" in {
|
2011-11-11 19:57:27 +01:00
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(List(newActor(0))))
|
2011-11-16 17:18:36 +01:00
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-11-23 19:03:56 +01:00
|
|
|
actor.isTerminated must be(false)
|
2011-10-07 15:42:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"deliver one-way messages in a round robin fashion" in {
|
|
|
|
|
val connectionCount = 10
|
|
|
|
|
val iterationCount = 10
|
|
|
|
|
val doneLatch = new TestLatch(connectionCount)
|
|
|
|
|
|
|
|
|
|
var connections = new LinkedList[ActorRef]
|
|
|
|
|
var counters = new LinkedList[AtomicInteger]
|
|
|
|
|
for (i ← 0 until connectionCount) {
|
|
|
|
|
counters = counters :+ new AtomicInteger()
|
|
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val connection = system.actorOf(new Actor {
|
2011-10-07 15:42:55 +02:00
|
|
|
def receive = {
|
2011-12-11 22:34:38 +01:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
2011-10-07 15:42:55 +02:00
|
|
|
case msg: Int ⇒ counters.get(i).get.addAndGet(msg)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
connections = connections :+ connection
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-11 19:57:27 +01:00
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(connections))
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
2011-10-07 15:42:55 +02:00
|
|
|
|
|
|
|
|
for (i ← 0 until iterationCount) {
|
|
|
|
|
for (k ← 0 until connectionCount) {
|
|
|
|
|
actor ! (k + 1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actor ! Broadcast("end")
|
|
|
|
|
|
|
|
|
|
doneLatch.await
|
|
|
|
|
|
|
|
|
|
for (i ← 0 until connectionCount) {
|
|
|
|
|
val counter = counters.get(i).get
|
|
|
|
|
counter.get must be((iterationCount * (i + 1)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"deliver a broadcast message using the !" in {
|
|
|
|
|
val doneLatch = new TestLatch(2)
|
|
|
|
|
|
|
|
|
|
val counter1 = new AtomicInteger
|
2011-11-16 17:18:36 +01:00
|
|
|
val connection1 = system.actorOf(new Actor {
|
2011-10-07 15:42:55 +02:00
|
|
|
def receive = {
|
2011-12-11 22:34:38 +01:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
2011-10-07 15:42:55 +02:00
|
|
|
case msg: Int ⇒ counter1.addAndGet(msg)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
val counter2 = new AtomicInteger
|
2011-11-16 17:18:36 +01:00
|
|
|
val connection2 = system.actorOf(new Actor {
|
2011-10-07 15:42:55 +02:00
|
|
|
def receive = {
|
2011-12-11 22:34:38 +01:00
|
|
|
case "end" ⇒ doneLatch.countDown()
|
2011-10-07 15:42:55 +02:00
|
|
|
case msg: Int ⇒ counter2.addAndGet(msg)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2011-11-11 19:57:27 +01:00
|
|
|
val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(List(connection1, connection2)))
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-11-16 17:18:36 +01:00
|
|
|
val actor = new RoutedActorRef(system, props, impl.guardian, "foo")
|
2011-10-07 15:42:55 +02:00
|
|
|
|
|
|
|
|
actor ! Broadcast(1)
|
|
|
|
|
actor ! Broadcast("end")
|
|
|
|
|
|
|
|
|
|
doneLatch.await
|
|
|
|
|
|
|
|
|
|
counter1.get must be(1)
|
|
|
|
|
counter2.get must be(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
case class Stop(id: Option[Int] = None)
|
2011-10-07 15:42:55 +02:00
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
def newActor(id: Int, shudownLatch: Option[TestLatch] = None) = system.actorOf(new Actor {
|
|
|
|
|
def receive = {
|
|
|
|
|
case Stop(None) ⇒
|
|
|
|
|
println(">>>> STOPPING : " + id)
|
|
|
|
|
self.stop()
|
|
|
|
|
case Stop(Some(_id)) if (_id == id) ⇒
|
|
|
|
|
println(">>>> STOPPING >: " + id)
|
|
|
|
|
self.stop()
|
|
|
|
|
case _id: Int if (_id == id) ⇒
|
|
|
|
|
println("-----> ID MATCH - do nothing")
|
|
|
|
|
case x ⇒ {
|
|
|
|
|
Thread sleep 100 * id
|
|
|
|
|
println("-----> SENDING REPLY: " + id)
|
|
|
|
|
sender.tell(id)
|
2011-10-07 15:42:55 +02:00
|
|
|
}
|
2011-11-24 16:35:37 +01:00
|
|
|
}
|
|
|
|
|
|
2011-12-11 22:34:38 +01:00
|
|
|
override def postStop = {
|
|
|
|
|
println("***** POSTSTOP")
|
|
|
|
|
shudownLatch foreach (_.countDown())
|
2011-11-24 16:35:37 +01:00
|
|
|
}
|
2011-12-11 22:34:38 +01:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
*/
|
2010-08-24 23:21:28 +02:00
|
|
|
}
|