diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorWithBoundedStashSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorWithBoundedStashSpec.scala index ae683b648b..1658eed81d 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorWithBoundedStashSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorWithBoundedStashSpec.scala @@ -61,17 +61,27 @@ object ActorWithBoundedStashSpec { val dispatcherId1 = "my-dispatcher-1" val dispatcherId2 = "my-dispatcher-2" + val mailboxId1 = "my-mailbox-1" + val mailboxId2 = "my-mailbox-2" - val testConf: Config = ConfigFactory.parseString(""" - %s { - mailbox-type = "%s" + val testConf: Config = ConfigFactory.parseString(s""" + $dispatcherId1 { + mailbox-type = "${classOf[Bounded10].getName}" stash-capacity = 20 } - %s { - mailbox-type = "%s" + $dispatcherId2 { + mailbox-type = "${classOf[Bounded100].getName}" stash-capacity = 20 } - """.format(dispatcherId1, classOf[Bounded10].getName, dispatcherId2, classOf[Bounded100].getName)) + $mailboxId1 { + mailbox-type = "${classOf[Bounded10].getName}" + stash-capacity = 20 + } + $mailboxId2 { + mailbox-type = "${classOf[Bounded100].getName}" + stash-capacity = 20 + } + """) } @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) @@ -88,38 +98,56 @@ class ActorWithBoundedStashSpec extends AkkaSpec(ActorWithBoundedStashSpec.testC override def afterEach(): Unit = system.eventStream.unsubscribe(testActor, classOf[DeadLetter]) - "An Actor with Stash" must { - - "end up in DeadLetters in case of a capacity violation" in { - val stasher = system.actorOf(Props[StashingActor].withDispatcher(dispatcherId1)) - // fill up stash - for (n ← 1 to 11) { - stasher ! "hello" + n - expectMsg("ok") - } - - // cause unstashAll with capacity violation - stasher ! "world" - expectMsg(DeadLetter("hello1", testActor, stasher)) - - stasher ! PoisonPill - // stashed messages are sent to deadletters when stasher is stopped - for (n ← 2 to 11) expectMsg(DeadLetter("hello" + n, testActor, stasher)) + def testDeadLetters(stasher: ActorRef): Unit = { + // fill up stash + for (n ← 1 to 11) { + stasher ! "hello" + n + expectMsg("ok") } - "throw a StashOverflowException in case of a stash capacity violation" in { + // cause unstashAll with capacity violation + stasher ! "world" + expectMsg(DeadLetter("hello1", testActor, stasher)) + + stasher ! PoisonPill + // stashed messages are sent to deadletters when stasher is stopped + for (n ← 2 to 11) expectMsg(DeadLetter("hello" + n, testActor, stasher)) + } + + def testStashOverflowException(stasher: ActorRef): Unit = { + // fill up stash + for (n ← 1 to 20) { + stasher ! "hello" + n + expectMsg("ok") + } + + stasher ! "hello21" + expectMsg("STASHOVERFLOW") + + // stashed messages are sent to deadletters when stasher is stopped, + for (n ← 1 to 20) expectMsg(DeadLetter("hello" + n, testActor, stasher)) + } + + "An Actor with Stash" must { + + "end up in DeadLetters in case of a capacity violation when configured via dispatcher" in { + val stasher = system.actorOf(Props[StashingActor].withDispatcher(dispatcherId1)) + testDeadLetters(stasher) + } + + "end up in DeadLetters in case of a capacity violation when configured via mailbox" in { + val stasher = system.actorOf(Props[StashingActor].withMailbox(mailboxId1)) + testDeadLetters(stasher) + } + + "throw a StashOverflowException in case of a stash capacity violation when configured via dispatcher" in { val stasher = system.actorOf(Props[StashingActorWithOverflow].withDispatcher(dispatcherId2)) - // fill up stash - for (n ← 1 to 20) { - stasher ! "hello" + n - expectMsg("ok") - } + testStashOverflowException(stasher) + } - stasher ! "hello21" - expectMsg("STASHOVERFLOW") - - // stashed messages are sent to deadletters when stasher is stopped, - for (n ← 1 to 20) expectMsg(DeadLetter("hello" + n, testActor, stasher)) + "throw a StashOverflowException in case of a stash capacity violation when configured via mailbox" in { + val stasher = system.actorOf(Props[StashingActorWithOverflow].withMailbox(mailboxId2)) + testStashOverflowException(stasher) } } } diff --git a/akka-actor/src/main/scala/akka/actor/Stash.scala b/akka-actor/src/main/scala/akka/actor/Stash.scala index b61a6858aa..1b1edfe144 100644 --- a/akka-actor/src/main/scala/akka/actor/Stash.scala +++ b/akka-actor/src/main/scala/akka/actor/Stash.scala @@ -5,6 +5,7 @@ package akka.actor import akka.dispatch.{ UnboundedDequeBasedMessageQueueSemantics, RequiresMessageQueue, Envelope, DequeBasedMessageQueueSemantics } import akka.AkkaException +import akka.dispatch.Mailboxes /** * The `Stash` trait enables an actor to temporarily stash away messages that can not or @@ -65,11 +66,14 @@ trait UnrestrictedStash extends Actor { */ private var theStash = Vector.empty[Envelope] - /* The capacity of the stash. Configured in the actor's dispatcher config. + /* The capacity of the stash. Configured in the actor's mailbox or dispatcher config. */ private val capacity: Int = { val dispatcher = context.system.settings.config.getConfig(context.props.dispatcher) - val config = dispatcher.withFallback(context.system.settings.config.getConfig("akka.actor.default-mailbox")) + val fallback = dispatcher.withFallback(context.system.settings.config.getConfig(Mailboxes.DefaultMailboxId)) + val config = + if (context.props.mailbox == Mailboxes.DefaultMailboxId) fallback + else context.system.settings.config.getConfig(context.props.mailbox).withFallback(fallback) config.getInt("stash-capacity") } diff --git a/akka-docs/rst/java/untyped-actors.rst b/akka-docs/rst/java/untyped-actors.rst index d250aa1283..2b06e31fab 100644 --- a/akka-docs/rst/java/untyped-actors.rst +++ b/akka-docs/rst/java/untyped-actors.rst @@ -779,7 +779,7 @@ stash the same message twice; to do so results in an in which case invoking ``stash()`` may lead to a capacity violation, which results in a ``StashOverflowException``. The capacity of the stash can be configured using the ``stash-capacity`` setting (an ``Int``) of the -dispatcher's configuration. +mailbox's configuration. Invoking ``unstashAll()`` enqueues messages from the stash to the actor's mailbox until the capacity of the mailbox (if any) has been diff --git a/akka-docs/rst/scala/actors.rst b/akka-docs/rst/scala/actors.rst index 16594d8442..15585e0f04 100644 --- a/akka-docs/rst/scala/actors.rst +++ b/akka-docs/rst/scala/actors.rst @@ -870,7 +870,7 @@ stash the same message twice; to do so results in an in which case invoking ``stash()`` may lead to a capacity violation, which results in a ``StashOverflowException``. The capacity of the stash can be configured using the ``stash-capacity`` setting (an ``Int``) of the -dispatcher's configuration. +mailbox's configuration. Invoking ``unstashAll()`` enqueues messages from the stash to the actor's mailbox until the capacity of the mailbox (if any) has been