diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StashBufferSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StashBufferSpec.scala index 484b1ae7e2..71e768b00a 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StashBufferSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StashBufferSpec.scala @@ -195,6 +195,46 @@ class StashBufferSpec extends AnyWordSpec with Matchers with LogCapturing { buffer.size should ===(0) } + "clear" in { + val buffer = StashBuffer[String](context, 10) + buffer.stash("m1") + buffer.stash("m2") + buffer.clear() + buffer.size should ===(0) + buffer.stash("m3") + buffer.size should ===(1) + } + + "be able to clear while unstashing" in { + val buffer = StashBuffer[String](context, 10) + buffer.stash("m1") + buffer.stash("m2") + buffer.stash("clear") + buffer.stash("m3") + + val valueInbox = TestInbox[String]() + def behavior(state: String): Behavior[String] = + Behaviors.receive[String] { (_, message) => + if (message == "get") { + valueInbox.ref ! state + Behaviors.same + } else if (message == "clear") { + buffer.clear() + Behaviors.same + } else { + behavior(state + message) + } + } + + val b2 = buffer.unstashAll(behavior("")) + buffer.size should ===(0) + + buffer.stash("get") + buffer.unstashAll(b2) + // clear called before processing m3 so not included + valueInbox.expectMessage("m1m2") + } + "fail quick on invalid start behavior" in { val stash = StashBuffer[String](context, 10) stash.stash("one") diff --git a/akka-actor-typed/src/main/mima-filters/2.6.4.backwards.excludes/issue-28786-stash-clear.excludes b/akka-actor-typed/src/main/mima-filters/2.6.4.backwards.excludes/issue-28786-stash-clear.excludes new file mode 100644 index 0000000000..136e6687e1 --- /dev/null +++ b/akka-actor-typed/src/main/mima-filters/2.6.4.backwards.excludes/issue-28786-stash-clear.excludes @@ -0,0 +1,3 @@ +# #28786 add clear to StashBuffer, ok because of DoNotInherit +ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.actor.typed.javadsl.StashBuffer.clear") +ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.actor.typed.scaladsl.StashBuffer.clear") diff --git a/akka-actor-typed/src/main/scala/akka/actor/typed/internal/StashBufferImpl.scala b/akka-actor-typed/src/main/scala/akka/actor/typed/internal/StashBufferImpl.scala index 6857b01e68..1612143ec1 100644 --- a/akka-actor-typed/src/main/scala/akka/actor/typed/internal/StashBufferImpl.scala +++ b/akka-actor-typed/src/main/scala/akka/actor/typed/internal/StashBufferImpl.scala @@ -78,6 +78,13 @@ import akka.util.{ unused, ConstantFun } this } + override def clear(): Unit = { + _first = null + _last = null + _size = 0 + stashCleared(ctx) + } + @InternalStableApi private def createNode(message: T, @unused ctx: scaladsl.ActorContext[T]): Node[T] = { new Node(null, message) diff --git a/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/StashBuffer.scala b/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/StashBuffer.scala index 5c9e97f975..88a4534395 100644 --- a/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/StashBuffer.scala +++ b/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/StashBuffer.scala @@ -74,6 +74,11 @@ import akka.japi.function.Procedure */ def forEach(f: Procedure[T]): Unit + /** + * Removes all messages from the buffer. + */ + def clear(): Unit + /** * Process all stashed messages with the `behavior` and the returned * [[Behavior]] from each processed message. The `StashBuffer` will be diff --git a/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/StashBuffer.scala b/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/StashBuffer.scala index 33ae4a2f09..8f05a95e91 100644 --- a/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/StashBuffer.scala +++ b/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/StashBuffer.scala @@ -85,6 +85,11 @@ import akka.annotation.{ DoNotInherit, InternalApi } */ def foreach(f: T => Unit): Unit + /** + * Removes all messages from the buffer. + */ + def clear(): Unit + /** * Process all stashed messages with the `behavior` and the returned * [[Behavior]] from each processed message. The `StashBuffer` will be