From 35e350a3d70740ef746ff4ddeeb39a59288cd63d Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Thu, 31 Oct 2024 15:56:52 -0500 Subject: [PATCH] Added reproduction for missing `Stash.Stash` messages in Akka.,Persistence actors reproduces #7373 --- .../Akka.Persistence.Tests/Bugfix7373Specs.cs | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/core/Akka.Persistence.Tests/Bugfix7373Specs.cs diff --git a/src/core/Akka.Persistence.Tests/Bugfix7373Specs.cs b/src/core/Akka.Persistence.Tests/Bugfix7373Specs.cs new file mode 100644 index 00000000000..6817db97bb4 --- /dev/null +++ b/src/core/Akka.Persistence.Tests/Bugfix7373Specs.cs @@ -0,0 +1,81 @@ +// ----------------------------------------------------------------------- +// +// Copyright (C) 2009-2024 Lightbend Inc. +// Copyright (C) 2013-2024 .NET Foundation +// +// ----------------------------------------------------------------------- + +using System.Threading.Tasks; +using Akka.Actor; +using Akka.TestKit; +using Xunit; +using Xunit.Abstractions; + +namespace Akka.Persistence.Tests; + +public class Bugfix7373Specs : AkkaSpec +{ + public Bugfix7373Specs(ITestOutputHelper output) : base(output) + { + } + + /// + /// Reproduction for https://github.com/akkadotnet/akka.net/issues/7373 + /// + [Fact] + public async Task ShouldDeliverAllStashedMessages() + { + // arrange + var actor = Sys.ActorOf(Props.Create()); + + // act + var msg = new Msg(1); + actor.Tell(msg); + actor.Tell(msg); + + actor.Tell("Initialize"); + + // assert + await ExpectMsgAsync($"Processed: {msg}"); + await ExpectMsgAsync($"Processed: {msg}"); + } + + public sealed record Msg(int Id); + + public class MinimalStashingActor : UntypedPersistentActor, IWithStash + { + public override string PersistenceId => "minimal-stashing-actor"; + + protected override void OnCommand(object message) + { + Sender.Tell($"Processed: {message}"); + } + + private void Ready(object message) + { + switch (message) + { + case "Initialize": + Persist("init", e => + { + Stash.UnstashAll(); // Unstash all stashed messages + Become(OnCommand); // Transition to ready state + }); + break; + default: + Stash.Stash(); // Stash messages until initialized + break; + } + } + + protected override void OnRecover(object message) + { + switch (message) + { + case RecoveryCompleted: + Become(Ready); + break; + } + } + } +} \ No newline at end of file