Merge pull request #1697 from akka/wip-3565-props-apply-master-patriknw

=act #3565 Add ClassTag in Props.apply(creator) (forward port)
This commit is contained in:
Patrik Nordwall 2013-08-28 10:11:53 -07:00
commit 48c83f545a
4 changed files with 35 additions and 23 deletions

View file

@ -128,6 +128,8 @@ object ActorMailboxSpec {
class StashQueueReportingActor extends QueueReportingActor with Stash
class StashQueueReportingActorWithParams(i: Int, s: String) extends StashQueueReportingActor
val UnboundedMailboxTypes = Seq(classOf[UnboundedMessageQueueSemantics])
val BoundedMailboxTypes = Seq(classOf[BoundedMessageQueueSemantics])
val UnboundedDeqMailboxTypes = Seq(
@ -174,6 +176,12 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
"get an unbounded deque message queue when it's only mixed with Stash" in {
checkMailboxQueue(Props[StashQueueReportingActor],
"default-override-from-stash", UnboundedDeqMailboxTypes)
checkMailboxQueue(Props(new StashQueueReportingActor),
"default-override-from-stash2", UnboundedDeqMailboxTypes)
checkMailboxQueue(Props(classOf[StashQueueReportingActorWithParams], 17, "hello"),
"default-override-from-stash3", UnboundedDeqMailboxTypes)
checkMailboxQueue(Props(new StashQueueReportingActorWithParams(17, "hello")),
"default-override-from-stash4", UnboundedDeqMailboxTypes)
}
"get a bounded message queue when it's configured as mailbox" in {

View file

@ -17,7 +17,8 @@ import org.scalatest.junit.JUnitSuiteLike
object ActorWithStashSpec {
class StashingActor(implicit sys: ActorSystem) extends Actor with Stash {
class StashingActor extends Actor with Stash {
import context.system
def greeted: Receive = {
case "bye"
state.s = "bye"
@ -34,7 +35,7 @@ object ActorWithStashSpec {
}
}
class StashingTwiceActor(implicit sys: ActorSystem) extends Actor with Stash {
class StashingTwiceActor extends Actor with Stash {
def receive = {
case "hello"
try {
@ -48,7 +49,8 @@ object ActorWithStashSpec {
}
}
class ActorWithProtocol(implicit sys: ActorSystem) extends Actor with Stash {
class ActorWithProtocol extends Actor with Stash {
import context.system
def receive = {
case "open"
unstashAll()
@ -73,9 +75,6 @@ object ActorWithStashSpec {
val testConf = """
akka.actor.serialize-messages = off
my-dispatcher {
mailbox-type = "akka.dispatch.UnboundedDequeBasedMailbox"
}
"""
}
@ -86,20 +85,16 @@ class JavaActorWithStashSpec extends StashJavaAPI with JUnitSuiteLike
class ActorWithStashSpec extends AkkaSpec(ActorWithStashSpec.testConf) with DefaultTimeout with BeforeAndAfterEach {
import ActorWithStashSpec._
implicit val sys = system
override def atStartup {
system.eventStream.publish(Mute(EventFilter[Exception]("Crashing...")))
}
override def beforeEach() = state.finished.reset
def myProps(creator: Actor): Props = Props(creator).withDispatcher("my-dispatcher")
"An Actor with Stash" must {
"stash messages" in {
val stasher = system.actorOf(myProps(new StashingActor))
val stasher = system.actorOf(Props(new StashingActor))
stasher ! "bye"
stasher ! "hello"
state.finished.await
@ -107,7 +102,7 @@ class ActorWithStashSpec extends AkkaSpec(ActorWithStashSpec.testConf) with Defa
}
"support protocols" in {
val protoActor = system.actorOf(myProps(new ActorWithProtocol))
val protoActor = system.actorOf(Props[ActorWithProtocol])
protoActor ! "open"
protoActor ! "write"
protoActor ! "open"
@ -120,20 +115,20 @@ class ActorWithStashSpec extends AkkaSpec(ActorWithStashSpec.testConf) with Defa
"throw an IllegalStateException if the same messages is stashed twice" in {
state.expectedException = new TestLatch
val stasher = system.actorOf(myProps(new StashingTwiceActor))
val stasher = system.actorOf(Props[StashingTwiceActor])
stasher ! "hello"
stasher ! "hello"
Await.ready(state.expectedException, 10 seconds)
}
"process stashed messages after restart" in {
val boss = system.actorOf(myProps(new Supervisor(
val boss = system.actorOf(Props(new Supervisor(
OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 1 second)(List(classOf[Throwable])))))
val restartLatch = new TestLatch
val hasMsgLatch = new TestLatch
val slaveProps = myProps(new Actor with Stash {
val slaveProps = Props(new Actor with Stash {
def receive = {
case "crash"
throw new Exception("Crashing...")

View file

@ -63,20 +63,29 @@ object Props {
}
/**
* Returns a Props that has default values except for "creator" which will be a function that creates an instance
* Scala API: Returns a Props that has default values except for "creator" which will be a function that creates an instance
* of the supplied type using the default constructor.
*
* Scala API.
*/
def apply[T <: Actor: ClassTag](): Props = apply(defaultDeploy, implicitly[ClassTag[T]].runtimeClass, Vector.empty)
/**
* Returns a Props that has default values except for "creator" which will be a function that creates an instance
* Scala API: Returns a Props that has default values except for "creator" which will be a function that creates an instance
* using the supplied thunk.
*
* Scala API.
* CAVEAT: Required mailbox type cannot be detected when using anonymous mixin composition
* when creating the instance. For example, the following will not detect the need for
* `DequeBasedMessageQueueSemantics` as defined in `Stash`:
* {{{
* 'Props(new Actor with Stash { ... })
* }}}
* Instead you must create a named class that mixin the trait,
* e.g. `class MyActor extends Actor with Stash`.
*/
def apply(creator: Actor): Props = default.withCreator(creator)
def apply[T <: Actor: ClassTag](creator: T): Props =
mkProps(implicitly[ClassTag[T]].runtimeClass, () creator)
private def mkProps(classOfActor: Class[_], ctor: () Actor): Props =
Props(classOf[TypedCreatorFunctionConsumer], classOfActor, ctor)
/**
* Returns a Props that has default values except for "creator" which will be a function that creates an instance

View file

@ -127,9 +127,9 @@ object TestActorRef {
"$" + akka.util.Helpers.base64(l)
}
def apply[T <: Actor](factory: T)(implicit system: ActorSystem): TestActorRef[T] = apply[T](Props(factory), randomName)
def apply[T <: Actor](factory: T)(implicit system: ActorSystem): TestActorRef[T] = apply[T](Props.empty.withCreator(factory), randomName)
def apply[T <: Actor](factory: T, name: String)(implicit system: ActorSystem): TestActorRef[T] = apply[T](Props(factory), name)
def apply[T <: Actor](factory: T, name: String)(implicit system: ActorSystem): TestActorRef[T] = apply[T](Props.empty.withCreator(factory), name)
def apply[T <: Actor](props: Props)(implicit system: ActorSystem): TestActorRef[T] = apply[T](props, randomName)