From b75add65acaf7068841b2223f1b33bf019f18d98 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 14:20:13 -0500 Subject: [PATCH 1/8] working on cleaning up the MNTR --- src/Directory.Build.props | 2 +- src/core/Akka.Remote.TestKit/Player.cs | 104 ++++++++---------- .../Akka.TestKit/TestKitBase_AwaitAssert.cs | 11 +- .../Akka.Tests/Pattern/CircuitBreakerSpec.cs | 2 +- 4 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3038f169242..2dbcc5e19c4 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -37,7 +37,7 @@ 2.16.6 2.0.3 6.0.1 - 1.5.19 + 1.5.25 [6.0.*,) [6.0.*,) 0.2.5 diff --git a/src/core/Akka.Remote.TestKit/Player.cs b/src/core/Akka.Remote.TestKit/Player.cs index 34154f94758..51a59add202 100644 --- a/src/core/Akka.Remote.TestKit/Player.cs +++ b/src/core/Akka.Remote.TestKit/Player.cs @@ -33,7 +33,7 @@ namespace Akka.Remote.TestKit /// partial class TestConductor //Player trait in JVM version { - IActorRef _client; + private IActorRef _client; public IActorRef Client { @@ -58,8 +58,7 @@ public Task StartClient(RoleName name, IPEndPoint controllerAddr) if(_client != null) throw new IllegalStateException("TestConductorClient already started"); _client = _system.ActorOf(Props.Create(() => new ClientFSM(name, controllerAddr)), "TestConductorClient"); - - //TODO: IRequiresMessageQueue + var a = _system.ActorOf(Props.Create()); return a.Ask(_client); @@ -71,38 +70,33 @@ private class WaitForClientFSMToConnect : UntypedActor protected override void OnReceive(object message) { - var fsm = message as IActorRef; - if (fsm != null) + if (message is IActorRef fsm) { _waiting = Sender; fsm.Tell(new FSMBase.SubscribeTransitionCallBack(Self)); return; } - var transition = message as FSMBase.Transition; - if (transition != null) + + if (message is FSMBase.Transition transition) { - if (transition.From == ClientFSM.State.Connecting && transition.To == ClientFSM.State.AwaitDone) - return; - if (transition.From == ClientFSM.State.AwaitDone && transition.To == ClientFSM.State.Connected) + switch (transition.From) { - _waiting.Tell(Done.Instance); - Context.Stop(Self); - return; + case ClientFSM.State.Connecting when transition.To == ClientFSM.State.AwaitDone: + return; + case ClientFSM.State.AwaitDone when transition.To == ClientFSM.State.Connected: + _waiting.Tell(Done.Instance); + Context.Stop(Self); + return; + default: + _waiting.Tell(new Exception("unexpected transition: " + transition)); + Context.Stop(Self); + break; } - _waiting.Tell(new Exception("unexpected transition: " + transition)); - Context.Stop(Self); } - var currentState = message as FSMBase.CurrentState; - if (currentState != null) - { - if (currentState.State == ClientFSM.State.Connected) - { - _waiting.Tell(Done.Instance); - Context.Stop(Self); - return; - } - } + if (message is not FSMBase.CurrentState { State: ClientFSM.State.Connected }) return; + _waiting.Tell(Done.Instance); + Context.Stop(Self); } } @@ -173,8 +167,7 @@ public Task
GetAddressFor(RoleName name) /// INTERNAL API. /// [InternalApi] - class ClientFSM : FSM, ILoggingFSM - //TODO: RequireMessageQueue + internal class ClientFSM : FSM, ILoggingFSM { public enum State { @@ -196,9 +189,8 @@ public Data(IChannel channel, (string, IActorRef)? runningOp) _channel = channel; _runningOp = runningOp; } - - /// - protected bool Equals(Data other) + + private bool Equals(Data other) { return Equals(_channel, other._channel) && Equals(_runningOp, other._runningOp); } @@ -208,7 +200,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; + if (obj.GetType() != GetType()) return false; return Equals((Data) obj); } @@ -370,26 +362,22 @@ public void InitFSM() When(State.AwaitDone, @event => { - if (@event.FsmEvent is Done) + switch (@event.FsmEvent) { - _log.Debug("received Done: starting test"); - return GoTo(State.Connected); + case Done: + _log.Debug("received Done: starting test"); + return GoTo(State.Connected); + case INetworkOp: + _log.Error("Received {0} instead of Done", @event.FsmEvent); + return GoTo(State.Failed); + case IServerOp: + return Stay().Replying(new Failure(new IllegalStateException("not connected yet"))); + case StateTimeout: + _log.Error("connect timeout to TestConductor"); + return GoTo(State.Failed); + default: + return null; } - if (@event.FsmEvent is INetworkOp) - { - _log.Error("Received {0} instead of Done", @event.FsmEvent); - return GoTo(State.Failed); - } - if (@event.FsmEvent is IServerOp) - { - return Stay().Replying(new Failure(new IllegalStateException("not connected yet"))); - } - if (@event.FsmEvent is StateTimeout) - { - _log.Error("connect timeout to TestConductor"); - return GoTo(State.Failed); - } - return null; }, _settings.BarrierTimeout); When(State.Connected, @event => @@ -558,16 +546,16 @@ public void InitFSM() /// internal class PlayerHandler : ChannelHandlerAdapter { - readonly IPEndPoint _server; - int _reconnects; - readonly TimeSpan _backoff; - readonly int _poolSize; - readonly IActorRef _fsm; - readonly ILoggingAdapter _log; - readonly IScheduler _scheduler; + private readonly IPEndPoint _server; + private int _reconnects; + private readonly TimeSpan _backoff; + private readonly int _poolSize; + private readonly IActorRef _fsm; + private readonly ILoggingAdapter _log; + private readonly IScheduler _scheduler; private bool _loggedDisconnect = false; - - Deadline _nextAttempt; + + private Deadline _nextAttempt; /// /// Shareable, since the handler may be added multiple times during reconnect diff --git a/src/core/Akka.TestKit/TestKitBase_AwaitAssert.cs b/src/core/Akka.TestKit/TestKitBase_AwaitAssert.cs index 473297345b8..88b2322844b 100644 --- a/src/core/Akka.TestKit/TestKitBase_AwaitAssert.cs +++ b/src/core/Akka.TestKit/TestKitBase_AwaitAssert.cs @@ -8,6 +8,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Akka.Event; using Akka.TestKit.Internal; using Nito.AsyncEx.Synchronous; @@ -45,9 +46,11 @@ public async Task AwaitAssertAsync(Action assertion, TimeSpan? duration=null, Ti var intervalValue = interval.GetValueOrDefault(TimeSpan.FromMilliseconds(100)); if(intervalValue == Timeout.InfiniteTimeSpan) intervalValue = TimeSpan.MaxValue; intervalValue.EnsureIsPositiveFinite(nameof(interval)); + var start = Now; var max = RemainingOrDilated(duration); var stop = Now + max; var t = max.Min(intervalValue); + var attempts = 0; while(true) { cancellationToken.ThrowIfCancellationRequested(); @@ -59,9 +62,15 @@ public async Task AwaitAssertAsync(Action assertion, TimeSpan? duration=null, Ti } catch(Exception) { - if(Now + t >= stop) + var stopped = Now + t; + if (stopped >= stop) + { + Sys.Log.Warning("AwaitAssert failed, timeout [{0}] is over after [{1}] attempts and [{2}] elapsed time", max, attempts, stopped - start); throw; + } + } + attempts++; await Task.Delay(t, cancellationToken); t = (stop - Now).Min(intervalValue); } diff --git a/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs b/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs index fff4b9eb4ec..efd88c6b513 100644 --- a/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs +++ b/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs @@ -84,7 +84,7 @@ public async Task Must_increment_failure_count_on_callTimeout_before_call_finish { var breaker = ShortCallTimeoutCb(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed - // meant to run as detatched task + // meant to run as detached task Task.Run(() => breaker.Instance.WithSyncCircuitBreaker(() => Thread.Sleep(Dilated(TimeSpan.FromSeconds(1))))); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed var epsilon = TimeSpan.FromMilliseconds(500); // need to pad timeouts due to non-determinism of OS scheduler From 761c3767ef471d3c7b28ffb2bd2233ede0f62131 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 14:26:28 -0500 Subject: [PATCH 2/8] added better logging to barrier entry --- src/core/Akka.Remote.TestKit/DataTypes.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/Akka.Remote.TestKit/DataTypes.cs b/src/core/Akka.Remote.TestKit/DataTypes.cs index ad242dbdd82..520d873e5dc 100644 --- a/src/core/Akka.Remote.TestKit/DataTypes.cs +++ b/src/core/Akka.Remote.TestKit/DataTypes.cs @@ -292,10 +292,10 @@ public Address Address } } - sealed class EnterBarrier : IServerOp, INetworkOp + internal sealed class EnterBarrier : IServerOp, INetworkOp { - readonly string _name; - readonly TimeSpan? _timeout; + private readonly string _name; + private readonly TimeSpan? _timeout; public EnterBarrier(string name, TimeSpan? timeout) { @@ -303,6 +303,11 @@ public EnterBarrier(string name, TimeSpan? timeout) _timeout = timeout; } + public override string ToString() + { + return $"EnterBarrier(Name: {_name}, Timeout:{(_timeout.HasValue ? _timeout.Value.ToString() : "null")})"; + } + private bool Equals(EnterBarrier other) { return string.Equals(_name, other._name) && _timeout.Equals(other._timeout); From 9ec8e1062bf9d98b8ba28f33ada27774003f5a02 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 14:35:13 -0500 Subject: [PATCH 3/8] more type cleanup --- src/core/Akka.Remote.TestKit/DataTypes.cs | 99 +++++++++-------------- src/core/Akka.Remote.TestKit/Player.cs | 1 - 2 files changed, 40 insertions(+), 60 deletions(-) diff --git a/src/core/Akka.Remote.TestKit/DataTypes.cs b/src/core/Akka.Remote.TestKit/DataTypes.cs index 520d873e5dc..7a58a39179a 100644 --- a/src/core/Akka.Remote.TestKit/DataTypes.cs +++ b/src/core/Akka.Remote.TestKit/DataTypes.cs @@ -134,29 +134,24 @@ interface IToServer object Msg { get; } } - class ToServer : IToServer where T : IServerOp, INetworkOp + internal class ToServer : IToServer where T : IServerOp, INetworkOp { - readonly T _msg; - public ToServer(T msg) { - _msg = msg; + Msg = msg; } - public T Msg - { - get { return _msg; } - } + public T Msg { get; } object IToServer.Msg { - get { return _msg; } + get { return Msg; } } protected bool Equals(ToServer other) { - return EqualityComparer.Default.Equals(_msg, other._msg); + return EqualityComparer.Default.Equals(Msg, other.Msg); } @@ -171,7 +166,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return EqualityComparer.Default.GetHashCode(_msg); + return EqualityComparer.Default.GetHashCode(Msg); } /// @@ -200,40 +195,38 @@ public override int GetHashCode() /// /// messages sent to from Conductor to Player /// - interface IClientOp { } + internal interface IClientOp { } /// /// messages sent to from Player to Conductor /// - interface IServerOp { } + internal interface IServerOp { } /// /// messages sent from TestConductorExt to Conductor /// - interface ICommandOp { } + internal interface ICommandOp { } /// /// messages sent over the wire /// - interface INetworkOp { } + internal interface INetworkOp { } /// /// unconfirmed messages going to the Player /// - interface IUnconfirmedClientOp : IClientOp { } - interface IConfirmedClientOp : IClientOp { } + internal interface IUnconfirmedClientOp : IClientOp { } + + internal interface IConfirmedClientOp : IClientOp { } /// /// First message of connection sets names straight. /// - sealed class Hello : INetworkOp + internal sealed class Hello : INetworkOp { - readonly string _name; - readonly Address _address; - private bool Equals(Hello other) { - return string.Equals(_name, other._name) && Equals(_address, other._address); + return string.Equals(Name, other.Name) && Equals(Address, other.Address); } @@ -249,7 +242,7 @@ public override int GetHashCode() { unchecked { - return ((_name != null ? _name.GetHashCode() : 0) * 397) ^ (_address != null ? _address.GetHashCode() : 0); + return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ (Address != null ? Address.GetHashCode() : 0); } } @@ -277,40 +270,37 @@ public override int GetHashCode() public Hello(string name, Address address) { - _name = name; - _address = address; + Name = name; + Address = address; } - public string Name - { - get { return _name; } - } + public string Name { get; } - public Address Address + public Address Address { get; } + + public override string ToString() { - get { return _address; } + return $"Hello(Name: {Name}, Address: {Address})"; } } internal sealed class EnterBarrier : IServerOp, INetworkOp { - private readonly string _name; - private readonly TimeSpan? _timeout; - - public EnterBarrier(string name, TimeSpan? timeout) + public EnterBarrier(string name, TimeSpan? timeout, Address address) { - _name = name; - _timeout = timeout; + Name = name; + Timeout = timeout; + Address = address; } public override string ToString() { - return $"EnterBarrier(Name: {_name}, Timeout:{(_timeout.HasValue ? _timeout.Value.ToString() : "null")})"; + return $"EnterBarrier(Name: {Name}, Timeout:{(Timeout.HasValue ? Timeout.Value.ToString() : "null")})"; } private bool Equals(EnterBarrier other) { - return string.Equals(_name, other._name) && _timeout.Equals(other._timeout); + return string.Equals(Name, other.Name) && Timeout.Equals(other.Timeout); } @@ -326,7 +316,7 @@ public override int GetHashCode() { unchecked { - return ((_name != null ? _name.GetHashCode() : 0) * 397) ^ _timeout.GetHashCode(); + return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ Timeout.GetHashCode(); } } @@ -352,34 +342,25 @@ public override int GetHashCode() return !Equals(left, right); } - public string Name - { - get { return _name; } - } + public string Name { get; } - public TimeSpan? Timeout - { - get { return _timeout; } - } + public TimeSpan? Timeout { get; } + + public Address Address { get; } } - sealed class FailBarrier : IServerOp, INetworkOp + internal sealed class FailBarrier : IServerOp, INetworkOp { - readonly string _name; - public FailBarrier(string name) { - _name = name; + Name = name; } - public string Name - { - get { return _name; } - } + public string Name { get; } private bool Equals(FailBarrier other) { - return string.Equals(_name, other._name); + return string.Equals(Name, other.Name); } @@ -393,7 +374,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return (_name != null ? _name.GetHashCode() : 0); + return (Name != null ? Name.GetHashCode() : 0); } /// @@ -419,7 +400,7 @@ public override int GetHashCode() } } - sealed class BarrierResult : IUnconfirmedClientOp, INetworkOp + internal sealed class BarrierResult : IUnconfirmedClientOp, INetworkOp { readonly string _name; readonly bool _success; diff --git a/src/core/Akka.Remote.TestKit/Player.cs b/src/core/Akka.Remote.TestKit/Player.cs index 51a59add202..e207bf9bdca 100644 --- a/src/core/Akka.Remote.TestKit/Player.cs +++ b/src/core/Akka.Remote.TestKit/Player.cs @@ -18,7 +18,6 @@ using Akka.Event; using Akka.Pattern; using Akka.Remote.Transport; -using Akka.Util; using Akka.Util.Internal; using DotNetty.Transport.Channels; using Akka.Configuration; From 2377a5782c6747b520f72c9458fe6713724c500d Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 14:59:41 -0500 Subject: [PATCH 4/8] fixed issues with encoding `RoleName` into `EnterBarrier` and `FailBarrier` messages --- .../Akka.Remote.TestKit.Tests/BarrierSpec.cs | 108 +++++++------ .../Akka.Remote.TestKit/BarrierCoordinator.cs | 8 +- src/core/Akka.Remote.TestKit/DataTypes.cs | 11 +- src/core/Akka.Remote.TestKit/MsgDecoder.cs | 8 +- src/core/Akka.Remote.TestKit/MsgEncoder.cs | 152 ++++++++---------- src/core/Akka.Remote.TestKit/MultiNodeSpec.cs | 2 +- src/core/Akka.Remote.TestKit/Player.cs | 12 +- src/protobuf/TestConductorProtocol.proto | 1 + 8 files changed, 150 insertions(+), 152 deletions(-) diff --git a/src/core/Akka.Remote.TestKit.Tests/BarrierSpec.cs b/src/core/Akka.Remote.TestKit.Tests/BarrierSpec.cs index 8ea7830f1d9..e7849c28a0c 100644 --- a/src/core/Akka.Remote.TestKit.Tests/BarrierSpec.cs +++ b/src/core/Akka.Remote.TestKit.Tests/BarrierSpec.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Immutable; +using System.Threading.Tasks; using Akka.Actor; using Akka.TestKit; using Xunit; @@ -110,33 +111,33 @@ public void A_BarrierCoordinator_must_register_clients_and_disconnect_them() } [Fact] - public void A_BarrierCoordinator_must_fail_entering_barrier_when_nobody_registered() + public async Task A_BarrierCoordinator_must_fail_entering_barrier_when_nobody_registered() { var b = GetBarrier(); - b.Tell(new EnterBarrier("bar1", null), TestActor); - ExpectMsg(new ToClient(new BarrierResult("bar1", false)), TimeSpan.FromSeconds(300)); + b.Tell(new EnterBarrier("bar1", null, new RoleName("b")), TestActor); + await ExpectMsgAsync(new ToClient(new BarrierResult("bar1", false)), TimeSpan.FromSeconds(300)); } [Fact] - public void A_BarrierCoordinator_must_enter_barrier() + public async Task A_BarrierCoordinator_must_enter_barrier() { var barrier = GetBarrier(); var a = CreateTestProbe(); var b = CreateTestProbe(); barrier.Tell(new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref)); barrier.Tell(new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); - a.Send(barrier, new EnterBarrier("bar2", null)); + a.Send(barrier, new EnterBarrier("bar2", null, new RoleName("a"))); NoMsg(a, b); - Within(TimeSpan.FromSeconds(2), () => + await WithinAsync(TimeSpan.FromSeconds(2), async () => { - b.Send(barrier, new EnterBarrier("bar2", null)); - a.ExpectMsg(new ToClient(new BarrierResult("bar2", true))); - b.ExpectMsg(new ToClient(new BarrierResult("bar2", true))); + b.Send(barrier, new EnterBarrier("bar2", null, new RoleName("b"))); + await a.ExpectMsgAsync(new ToClient(new BarrierResult("bar2", true))); + await b.ExpectMsgAsync(new ToClient(new BarrierResult("bar2", true))); }); } [Fact] - public void A_BarrierCoordinator_must_enter_barrier_with_joining_node() + public async Task A_BarrierCoordinator_must_enter_barrier_with_joining_node() { var barrier = GetBarrier(); var a = CreateTestProbe(); @@ -144,21 +145,21 @@ public void A_BarrierCoordinator_must_enter_barrier_with_joining_node() var c = CreateTestProbe(); barrier.Tell(new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref)); barrier.Tell(new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); - a.Send(barrier, new EnterBarrier("bar3", null)); + a.Send(barrier, new EnterBarrier("bar3", null, new RoleName("a"))); barrier.Tell(new Controller.NodeInfo(C, Address.Parse("akka://sys"), c.Ref)); - b.Send(barrier, new EnterBarrier("bar3", null)); + b.Send(barrier, new EnterBarrier("bar3", null, new RoleName("b"))); NoMsg(a, b, c); - Within(TimeSpan.FromSeconds(2), () => + await WithinAsync(TimeSpan.FromSeconds(2), async () => { - c.Send(barrier, new EnterBarrier("bar3", null)); - a.ExpectMsg(new ToClient(new BarrierResult("bar3", true))); - b.ExpectMsg(new ToClient(new BarrierResult("bar3", true))); - c.ExpectMsg(new ToClient(new BarrierResult("bar3", true))); + c.Send(barrier, new EnterBarrier("bar3", null, new RoleName("c"))); + await a.ExpectMsgAsync(new ToClient(new BarrierResult("bar3", true))); + await b.ExpectMsgAsync(new ToClient(new BarrierResult("bar3", true))); + await c.ExpectMsgAsync(new ToClient(new BarrierResult("bar3", true))); }); } [Fact] - public void A_BarrierCoordinator_must_enter_barrier_with_leaving_node() + public async Task A_BarrierCoordinator_must_enter_barrier_with_leaving_node() { var barrier = GetBarrier(); var a = CreateTestProbe(); @@ -167,47 +168,49 @@ public void A_BarrierCoordinator_must_enter_barrier_with_leaving_node() barrier.Tell(new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref)); barrier.Tell(new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); barrier.Tell(new Controller.NodeInfo(C, Address.Parse("akka://sys"), c.Ref)); - a.Send(barrier, new EnterBarrier("bar4", null)); - b.Send(barrier, new EnterBarrier("bar4", null)); + a.Send(barrier, new EnterBarrier("bar4", null, new RoleName("a"))); + b.Send(barrier, new EnterBarrier("bar4", null, new RoleName("b"))); barrier.Tell(new BarrierCoordinator.RemoveClient(A)); barrier.Tell(new Controller.ClientDisconnected(A)); NoMsg(a, b, c); - Within(TimeSpan.FromSeconds(2), () => + await WithinAsync(TimeSpan.FromSeconds(2), async () => { barrier.Tell(new BarrierCoordinator.RemoveClient(C)); - b.ExpectMsg(new ToClient(new BarrierResult("bar4", true))); + await b.ExpectMsgAsync(new ToClient(new BarrierResult("bar4", true))); }); barrier.Tell(new Controller.ClientDisconnected(C)); - ExpectNoMsg(TimeSpan.FromSeconds(1)); + await ExpectNoMsgAsync(TimeSpan.FromSeconds(1)); } [Fact] - public void A_BarrierCoordinator_must_enter_leave_barrier_when_last_arrived_is_removed() + public async Task A_BarrierCoordinator_must_enter_leave_barrier_when_last_arrived_is_removed() { var barrier = GetBarrier(); + var roleName = new RoleName("normal"); var a = CreateTestProbe(); var b = CreateTestProbe(); barrier.Tell(new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref)); barrier.Tell(new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); - a.Send(barrier, new EnterBarrier("bar5", null)); + a.Send(barrier, new EnterBarrier("bar5", null, roleName)); barrier.Tell(new BarrierCoordinator.RemoveClient(A)); - b.Send(barrier, new EnterBarrier("foo", null)); - b.ExpectMsg(new ToClient(new BarrierResult("foo", true))); + b.Send(barrier, new EnterBarrier("foo", null, roleName)); + await b.ExpectMsgAsync(new ToClient(new BarrierResult("foo", true))); } [Fact] - public void A_BarrierCoordinator_must_fail_barrier_with_disconnecting_node() + public async Task A_BarrierCoordinator_must_fail_barrier_with_disconnecting_node() { var barrier = GetBarrier(); + var roleName = new RoleName("normal"); var a = CreateTestProbe(); var b = CreateTestProbe(); var nodeA = new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref); barrier.Tell(nodeA); barrier.Tell(new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); - a.Send(barrier, new EnterBarrier("bar6", null)); + a.Send(barrier, new EnterBarrier("bar6", null, roleName)); //TODO: EventFilter? barrier.Tell(new Controller.ClientDisconnected(B)); - var msg = ExpectMsg(); + var msg = await ExpectMsgAsync(); Assert.Equal(new BarrierCoordinator.ClientLostException( new BarrierCoordinator.Data( ImmutableHashSet.Create(nodeA), @@ -218,9 +221,11 @@ public void A_BarrierCoordinator_must_fail_barrier_with_disconnecting_node() } [Fact] - public void A_BarrierCoordinator_must_fail_barrier_when_disconnecting_node_who_already_arrived() + public async Task A_BarrierCoordinator_must_fail_barrier_when_disconnecting_node_who_already_arrived() { var barrier = GetBarrier(); + var roleNameA = new RoleName("a"); + var roleNameB = new RoleName("b"); var a = CreateTestProbe(); var b = CreateTestProbe(); var c = CreateTestProbe(); @@ -229,11 +234,11 @@ public void A_BarrierCoordinator_must_fail_barrier_when_disconnecting_node_who_a barrier.Tell(nodeA); barrier.Tell(new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); barrier.Tell(nodeC); - a.Send(barrier, new EnterBarrier("bar7", null)); - b.Send(barrier, new EnterBarrier("bar7", null)); + a.Send(barrier, new EnterBarrier("bar7", null, roleNameA)); + b.Send(barrier, new EnterBarrier("bar7", null, roleNameB)); //TODO: Event filter? barrier.Tell(new Controller.ClientDisconnected(B)); - var msg = ExpectMsg(); + var msg = await ExpectMsgAsync(); Assert.Equal(new BarrierCoordinator.ClientLostException( new BarrierCoordinator.Data( ImmutableHashSet.Create(nodeA, nodeC), @@ -245,22 +250,24 @@ public void A_BarrierCoordinator_must_fail_barrier_when_disconnecting_node_who_a } [Fact] - public void A_BarrierCoordinator_must_fail_when_entering_wrong_barrier() + public async Task A_BarrierCoordinator_must_fail_when_entering_wrong_barrier() { var barrier = GetBarrier(); + var roleName = new RoleName("failer"); var a = CreateTestProbe(); var b = CreateTestProbe(); var nodeA = (new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref)); barrier.Tell(nodeA); var nodeB = (new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref)); barrier.Tell(nodeB); - a.Send(barrier, new EnterBarrier("bar8", null)); + a.Send(barrier, new EnterBarrier("bar8", null, roleName)); //TODO: Event filter - b.Send(barrier, new EnterBarrier("foo", null)); - var msg = ExpectMsg(); + b.Send(barrier, new EnterBarrier("foo", null, roleName)); + var msg = await ExpectMsgAsync(); Assert.Equal(new BarrierCoordinator.WrongBarrierException( "foo", b.Ref, + roleName, new BarrierCoordinator.Data( ImmutableHashSet.Create(nodeA, nodeB), "bar8", @@ -270,13 +277,14 @@ public void A_BarrierCoordinator_must_fail_when_entering_wrong_barrier() } [Fact] - public void A_BarrierCoordinator_must_fail_barrier_after_first_failure() + public async Task A_BarrierCoordinator_must_fail_barrier_after_first_failure() { var barrier = GetBarrier(); var a = CreateTestProbe(); + var roleName = new RoleName("failer"); //TODO: EventFilter barrier.Tell(new BarrierCoordinator.RemoveClient(A)); - var msg = ExpectMsg(); + var msg = await ExpectMsgAsync(); Assert.Equal(new BarrierCoordinator.BarrierEmptyException( new BarrierCoordinator.Data( ImmutableHashSet.Create(), @@ -285,24 +293,25 @@ public void A_BarrierCoordinator_must_fail_barrier_after_first_failure() ((BarrierCoordinator.BarrierEmptyException)msg.Exception).BarrierData.Deadline) , "cannot remove RoleName(a): no client to remove"), msg.Exception); barrier.Tell(new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref)); - a.Send(barrier, new EnterBarrier("bar9", null)); + a.Send(barrier, new EnterBarrier("bar9", null, roleName)); a.ExpectMsg(new ToClient(new BarrierResult("bar9", false))); } [Fact] - public void A_BarrierCoordinator_must_fail_after_barrier_timeout() + public async Task A_BarrierCoordinator_must_fail_after_barrier_timeout() { var barrier = GetBarrier(); + var roleName = new RoleName("failer"); var a = CreateTestProbe(); var b = CreateTestProbe(); var nodeA = new Controller.NodeInfo(A, Address.Parse("akka://sys"), a.Ref); var nodeB = new Controller.NodeInfo(B, Address.Parse("akka://sys"), b.Ref); barrier.Tell(nodeA); barrier.Tell(nodeB); - a.Send(barrier, new EnterBarrier("bar10", null)); - EventFilter.Exception().ExpectOne(() => + a.Send(barrier, new EnterBarrier("bar10", null, roleName)); + await EventFilter.Exception().ExpectOneAsync(async () => { - var msg = ExpectMsg(TimeSpan.FromSeconds(7)); + var msg = await ExpectMsgAsync(TimeSpan.FromSeconds(7)); Assert.Equal(new BarrierCoordinator.BarrierTimeoutException( new BarrierCoordinator.Data( ImmutableHashSet.Create(nodeA, nodeB), @@ -347,8 +356,8 @@ private IActorRef GetBarrier() private class BarrierCoordinatorSupervisor : UntypedActor { - readonly IActorRef _testActor; - readonly IActorRef _barrier; + private readonly IActorRef _testActor; + private readonly IActorRef _barrier; public BarrierCoordinatorSupervisor(IActorRef testActor) { @@ -376,11 +385,6 @@ private void NoMsg(params TestProbe[] probes) ExpectNoMsg(TimeSpan.FromSeconds(1)); foreach (var probe in probes) Assert.False(probe.HasMessages); } - - public IActorRef Self - { - get { return TestActor; } - } } } diff --git a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs index a0ae256eb2d..84e0bbc11d8 100644 --- a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs +++ b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs @@ -299,8 +299,8 @@ public override int GetHashCode() public sealed class WrongBarrierException : Exception { - public WrongBarrierException(string barrier, IActorRef client, Data barrierData) - : base($"[{client}] tried to enter '{barrier}' while we were waiting for '{barrierData.Barrier}'") + public WrongBarrierException(string barrier, IActorRef client, RoleName roleName, Data barrierData) + : base($"[{client}] [{roleName}] tried to enter '{barrier}' while we were waiting for '{barrierData.Barrier}'") { BarrierData = barrierData; Client = client; @@ -564,7 +564,7 @@ protected void InitFSM() { case EnterBarrier barrier: if (barrier.Name != currentBarrier) - throw new WrongBarrierException(barrier.Name, Sender, @event.StateData); + throw new WrongBarrierException(barrier.Name, Sender, barrier.Role, @event.StateData); var together = clients.Any(x => Equals(x.FSM, Sender)) ? @event.StateData.Arrived.Add(Sender) : @event.StateData.Arrived; @@ -588,7 +588,7 @@ protected void InitFSM() case FailBarrier barrier: if(barrier.Name != currentBarrier) - throw new WrongBarrierException(barrier.Name, Sender, @event.StateData); + throw new WrongBarrierException(barrier.Name, Sender, barrier.Role, @event.StateData); throw new FailedBarrierException(@event.StateData); case StateTimeout _: diff --git a/src/core/Akka.Remote.TestKit/DataTypes.cs b/src/core/Akka.Remote.TestKit/DataTypes.cs index 7a58a39179a..ea76d797fb1 100644 --- a/src/core/Akka.Remote.TestKit/DataTypes.cs +++ b/src/core/Akka.Remote.TestKit/DataTypes.cs @@ -286,11 +286,11 @@ public override string ToString() internal sealed class EnterBarrier : IServerOp, INetworkOp { - public EnterBarrier(string name, TimeSpan? timeout, Address address) + public EnterBarrier(string name, TimeSpan? timeout, RoleName role) { Name = name; Timeout = timeout; - Address = address; + Role = role; } public override string ToString() @@ -346,17 +346,20 @@ public override int GetHashCode() public TimeSpan? Timeout { get; } - public Address Address { get; } + public RoleName Role { get; } } internal sealed class FailBarrier : IServerOp, INetworkOp { - public FailBarrier(string name) + public FailBarrier(string name, RoleName role) { Name = name; + Role = role; } public string Name { get; } + + public RoleName Role { get; } private bool Equals(FailBarrier other) { diff --git a/src/core/Akka.Remote.TestKit/MsgDecoder.cs b/src/core/Akka.Remote.TestKit/MsgDecoder.cs index 1e91207d871..4481e766c91 100644 --- a/src/core/Akka.Remote.TestKit/MsgDecoder.cs +++ b/src/core/Akka.Remote.TestKit/MsgDecoder.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using Akka.Actor; +using Akka.Remote.TestKit.Proto.Msg; using Akka.Remote.Transport; using Akka.Util; using DotNetty.Codecs; @@ -41,8 +42,7 @@ protected object Decode(object message) { _logger.LogDebug("Decoding {0}", message); - var w = message as Proto.Msg.Wrapper; - if (w != null) + if (message is Wrapper w) { if (w.Hello != null) { @@ -54,9 +54,9 @@ protected object Decode(object message) { case Proto.Msg.EnterBarrier.Types.BarrierOp.Succeeded: return new BarrierResult(w.Barrier.Name, true); case Proto.Msg.EnterBarrier.Types.BarrierOp.Failed: return new BarrierResult(w.Barrier.Name, false); - case Proto.Msg.EnterBarrier.Types.BarrierOp.Fail: return new FailBarrier(w.Barrier.Name); + case Proto.Msg.EnterBarrier.Types.BarrierOp.Fail: return new FailBarrier(w.Barrier.Name, new RoleName(w.Barrier.RoleName)); case Proto.Msg.EnterBarrier.Types.BarrierOp.Enter: - return new EnterBarrier(w.Barrier.Name, w.Barrier.Timeout > 0 ? (TimeSpan?)TimeSpan.FromTicks(w.Barrier.Timeout) : null); + return new EnterBarrier(w.Barrier.Name, w.Barrier.Timeout > 0 ? (TimeSpan?)TimeSpan.FromTicks(w.Barrier.Timeout) : null, new RoleName(w.Barrier.RoleName)); } } else if (w.Failure != null) diff --git a/src/core/Akka.Remote.TestKit/MsgEncoder.cs b/src/core/Akka.Remote.TestKit/MsgEncoder.cs index 8e633a74107..7008ba75af2 100644 --- a/src/core/Akka.Remote.TestKit/MsgEncoder.cs +++ b/src/core/Akka.Remote.TestKit/MsgEncoder.cs @@ -48,101 +48,91 @@ protected override void Encode(IChannelHandlerContext context, object message, L var wrapper = new Proto.Msg.Wrapper(); - if (message is Hello hello) + switch (message) { - wrapper.Hello = new Proto.Msg.Hello - { - Name = hello.Name, - Address = AddressMessageBuilder(hello.Address) - }; - } - else if (message is EnterBarrier enterBarrier) - { - wrapper.Barrier = new Proto.Msg.EnterBarrier - { - Name = enterBarrier.Name, - Timeout = enterBarrier.Timeout?.Ticks ?? 0, - Op = Proto.Msg.EnterBarrier.Types.BarrierOp.Enter, - }; - } - else if (message is BarrierResult barrierResult) - { - wrapper.Barrier = new Proto.Msg.EnterBarrier - { - Name = barrierResult.Name, - Op = barrierResult.Success - ? Proto.Msg.EnterBarrier.Types.BarrierOp.Succeeded - : Proto.Msg.EnterBarrier.Types.BarrierOp.Failed - }; - } - else if (message is FailBarrier failBarrier) - { - wrapper.Barrier = new Proto.Msg.EnterBarrier - { - Name = failBarrier.Name, - Op = Proto.Msg.EnterBarrier.Types.BarrierOp.Fail - }; - } - else if (message is ThrottleMsg throttleMsg) - { - wrapper.Failure = new Proto.Msg.InjectFailure - { - Address = AddressMessageBuilder(throttleMsg.Target), - Failure = Proto.Msg.InjectFailure.Types.FailType.Throttle, - Direction = Direction2Proto(throttleMsg.Direction), - RateMBit = throttleMsg.RateMBit - }; - } - else if (message is DisconnectMsg disconnectMsg) - { - wrapper.Failure = new Proto.Msg.InjectFailure - { - Address = AddressMessageBuilder(disconnectMsg.Target), - Failure = disconnectMsg.Abort - ? Proto.Msg.InjectFailure.Types.FailType.Abort - : Proto.Msg.InjectFailure.Types.FailType.Disconnect - }; - } - else if (message is TerminateMsg terminate) - { - if (terminate.ShutdownOrExit.IsRight) - { + case Hello hello: + wrapper.Hello = new Proto.Msg.Hello + { + Name = hello.Name, + Address = AddressMessageBuilder(hello.Address) + }; + break; + case EnterBarrier enterBarrier: + wrapper.Barrier = new Proto.Msg.EnterBarrier + { + Name = enterBarrier.Name, + Timeout = enterBarrier.Timeout?.Ticks ?? 0, + Op = Proto.Msg.EnterBarrier.Types.BarrierOp.Enter, + RoleName = enterBarrier.Role.Name + }; + break; + case BarrierResult barrierResult: + wrapper.Barrier = new Proto.Msg.EnterBarrier + { + Name = barrierResult.Name, + Op = barrierResult.Success + ? Proto.Msg.EnterBarrier.Types.BarrierOp.Succeeded + : Proto.Msg.EnterBarrier.Types.BarrierOp.Failed + }; + break; + case FailBarrier failBarrier: + wrapper.Barrier = new Proto.Msg.EnterBarrier + { + Name = failBarrier.Name, + Op = Proto.Msg.EnterBarrier.Types.BarrierOp.Fail, + RoleName = failBarrier.Role.Name + }; + break; + case ThrottleMsg throttleMsg: + wrapper.Failure = new Proto.Msg.InjectFailure + { + Address = AddressMessageBuilder(throttleMsg.Target), + Failure = Proto.Msg.InjectFailure.Types.FailType.Throttle, + Direction = Direction2Proto(throttleMsg.Direction), + RateMBit = throttleMsg.RateMBit + }; + break; + case DisconnectMsg disconnectMsg: + wrapper.Failure = new Proto.Msg.InjectFailure + { + Address = AddressMessageBuilder(disconnectMsg.Target), + Failure = disconnectMsg.Abort + ? Proto.Msg.InjectFailure.Types.FailType.Abort + : Proto.Msg.InjectFailure.Types.FailType.Disconnect + }; + break; + case TerminateMsg terminate when terminate.ShutdownOrExit.IsRight: wrapper.Failure = new Proto.Msg.InjectFailure() { Failure = Proto.Msg.InjectFailure.Types.FailType.Exit, ExitValue = terminate.ShutdownOrExit.ToRight().Value }; - } - else if (terminate.ShutdownOrExit.IsLeft && !terminate.ShutdownOrExit.ToLeft().Value) - { + break; + case TerminateMsg terminate when terminate.ShutdownOrExit.IsLeft && !terminate.ShutdownOrExit.ToLeft().Value: wrapper.Failure = new Proto.Msg.InjectFailure() { Failure = Proto.Msg.InjectFailure.Types.FailType.Shutdown }; - } - else - { + break; + case TerminateMsg terminate: wrapper.Failure = new Proto.Msg.InjectFailure() { Failure = Proto.Msg.InjectFailure.Types.FailType.ShutdownAbrupt }; - } - } - else if (message is GetAddress getAddress) - { - wrapper.Addr = new Proto.Msg.AddressRequest { Node = getAddress.Node.Name }; - } - else if (message is AddressReply addressReply) - { - wrapper.Addr = new Proto.Msg.AddressRequest - { - Node = addressReply.Node.Name, - Addr = AddressMessageBuilder(addressReply.Addr) - }; - } - else if (message is Done) - { - wrapper.Done = " "; + break; + case GetAddress getAddress: + wrapper.Addr = new Proto.Msg.AddressRequest { Node = getAddress.Node.Name }; + break; + case AddressReply addressReply: + wrapper.Addr = new Proto.Msg.AddressRequest + { + Node = addressReply.Node.Name, + Addr = AddressMessageBuilder(addressReply.Addr) + }; + break; + case Done: + wrapper.Done = " "; + break; } output.Add(wrapper); diff --git a/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs b/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs index 78fe9eeca2c..8b2d210d774 100644 --- a/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs +++ b/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs @@ -549,7 +549,7 @@ public bool IsNode(params RoleName[] nodes) /// public void EnterBarrier(params string[] name) { - TestConductor.Enter(RemainingOr(TestConductor.Settings.BarrierTimeout), name.ToImmutableList()); + TestConductor.Enter(RemainingOr(TestConductor.Settings.BarrierTimeout), Myself, name.ToImmutableList()); } /// diff --git a/src/core/Akka.Remote.TestKit/Player.cs b/src/core/Akka.Remote.TestKit/Player.cs index e207bf9bdca..a98927184b0 100644 --- a/src/core/Akka.Remote.TestKit/Player.cs +++ b/src/core/Akka.Remote.TestKit/Player.cs @@ -103,16 +103,16 @@ protected override void OnReceive(object message) /// Enter the named barriers, one after the other, in the order given. Will /// throw an exception in case of timeouts or other errors. /// - public void Enter(string name) + public void Enter(RoleName roleName, string name) { - Enter(Settings.BarrierTimeout, ImmutableList.Create(name)); + Enter(Settings.BarrierTimeout, roleName, ImmutableList.Create(name)); } /// /// Enter the named barriers, one after the other, in the order given. Will /// throw an exception in case of timeouts or other errors. /// - public void Enter(TimeSpan timeout, ImmutableList names) + public void Enter(TimeSpan timeout, RoleName roleName, ImmutableList names) { _system.Log.Debug("entering barriers {0}", names.Aggregate((a, b) => "(" + a + "," + b + ")")); var stop = Deadline.Now + timeout; @@ -122,7 +122,7 @@ public void Enter(TimeSpan timeout, ImmutableList names) var barrierTimeout = stop.TimeLeft; if (barrierTimeout.Ticks < 0) { - _client.Tell(new ToServer(new FailBarrier(name))); + _client.Tell(new ToServer(new FailBarrier(name, roleName))); throw new TimeoutException("Server timed out while waiting for barrier " + name); } try @@ -130,11 +130,11 @@ public void Enter(TimeSpan timeout, ImmutableList names) var askTimeout = barrierTimeout + Settings.QueryTimeout; // Need to force barrier to wait here, so we can pass along a "fail barrier" message in the event // of a failed operation - var result = _client.Ask(new ToServer(new EnterBarrier(name, barrierTimeout)), askTimeout).Result; + var result = _client.Ask(new ToServer(new EnterBarrier(name, barrierTimeout, roleName)), askTimeout).Result; } catch (AggregateException ex) { - _client.Tell(new ToServer(new FailBarrier(name))); + _client.Tell(new ToServer(new FailBarrier(name, roleName))); throw new TimeoutException("Client timed out while waiting for barrier " + name, ex); } catch (OperationCanceledException) diff --git a/src/protobuf/TestConductorProtocol.proto b/src/protobuf/TestConductorProtocol.proto index a66abb8ebd8..eb6a8f87844 100644 --- a/src/protobuf/TestConductorProtocol.proto +++ b/src/protobuf/TestConductorProtocol.proto @@ -31,6 +31,7 @@ message EnterBarrier { string name = 1; BarrierOp op = 2; int64 timeout = 3; + string roleName = 4; } message AddressRequest { From fde81c5cfbd350ef5296cb63f4d21e92f4667177 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 15:02:42 -0500 Subject: [PATCH 5/8] added better pretty-printing for `EnterBarrier` and `FailBarrier` --- src/core/Akka.Remote.TestKit/DataTypes.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/Akka.Remote.TestKit/DataTypes.cs b/src/core/Akka.Remote.TestKit/DataTypes.cs index 6ca7ff54dc6..f77d9d14637 100644 --- a/src/core/Akka.Remote.TestKit/DataTypes.cs +++ b/src/core/Akka.Remote.TestKit/DataTypes.cs @@ -295,7 +295,7 @@ public EnterBarrier(string name, TimeSpan? timeout, RoleName role) public override string ToString() { - return $"EnterBarrier(Name: {Name}, Timeout:{(Timeout.HasValue ? Timeout.Value.ToString() : "null")})"; + return $"EnterBarrier(Name: {Name}, Role: [{Role}], Timeout:{(Timeout.HasValue ? Timeout.Value.ToString() : "null")})"; } private bool Equals(EnterBarrier other) @@ -366,7 +366,12 @@ private bool Equals(FailBarrier other) return string.Equals(Name, other.Name); } - + public override string ToString() + { + return $"FailBarrier(Name: {Name}, Role: [{Role}])"; + } + + public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; From 1275c0b5536fdd376a9a7d96c5b60979b39b30b5 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 15:13:50 -0500 Subject: [PATCH 6/8] cleaning up some mutability warnings --- .../Akka.Remote.TestKit/BarrierCoordinator.cs | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs index fe9041a932b..94f0981d8fb 100644 --- a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs +++ b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs @@ -10,7 +10,6 @@ using System.Collections.Immutable; using System.Linq; using Akka.Actor; -using Akka.Util.Internal; using Akka.Event; namespace Akka.Remote.TestKit @@ -45,19 +44,11 @@ public RemoveClient(RoleName name) Name = name; } - public RoleName Name { get; private set; } + public RoleName Name { get; } } public sealed class Data { - public Data(IEnumerable clients, string barrier, IEnumerable arrived, Deadline deadline) : - this(clients == null ? ImmutableHashSet.Create() : ImmutableHashSet.Create(clients.ToArray()), - barrier, - arrived == null ? ImmutableHashSet.Create() : ImmutableHashSet.Create(arrived.ToArray()), - deadline) - { - } - public Data(ImmutableHashSet clients, string barrier, ImmutableHashSet arrived, Deadline deadline) { Deadline = deadline; @@ -66,13 +57,13 @@ public Data(ImmutableHashSet clients, string barrier, Immut Clients = clients; } - public ImmutableHashSet Clients { get; private set; } + public ImmutableHashSet Clients { get; } - public string Barrier { get; private set; } + public string Barrier { get; } - public ImmutableHashSet Arrived { get; private set; } + public ImmutableHashSet Arrived { get; } - public Deadline Deadline { get; private set; } + public Deadline Deadline { get; } public Data Copy(ImmutableHashSet clients = null, string barrier = null, ImmutableHashSet arrived = null, Deadline deadline = null) @@ -143,7 +134,7 @@ public BarrierTimeoutException(Data barrierData) BarrierData = barrierData; } - public Data BarrierData { get; private set; } + public Data BarrierData { get; } private bool Equals(BarrierTimeoutException other) { @@ -195,7 +186,7 @@ public FailedBarrierException(Data barrierData) BarrierData = barrierData; } - public Data BarrierData { get; private set; } + public Data BarrierData { get; } private bool Equals(FailedBarrierException other) { @@ -248,9 +239,9 @@ public DuplicateNodeException(Data barrierData, Controller.NodeInfo node) BarrierData = barrierData; } - public Data BarrierData { get; private set; } + public Data BarrierData { get; } - public Controller.NodeInfo Node { get; private set; } + public Controller.NodeInfo Node { get; } private bool Equals(DuplicateNodeException other) { @@ -369,7 +360,7 @@ public BarrierEmptyException(Data barrierData, string message) BarrierData = barrierData; } - public Data BarrierData { get; private set; } + public Data BarrierData { get; } private bool Equals(BarrierEmptyException other) { From 01d57fd96ede279d6cfff67cdd1495e674175867 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 15:14:51 -0500 Subject: [PATCH 7/8] more cleanup --- src/core/Akka.Remote.TestKit/BarrierCoordinator.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs index 94f0981d8fb..a2e82284065 100644 --- a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs +++ b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs @@ -298,11 +298,11 @@ public WrongBarrierException(string barrier, IActorRef client, RoleName roleName Barrier = barrier; } - public string Barrier { get; private set; } + public string Barrier { get; } - public IActorRef Client { get; private set; } + public IActorRef Client { get; } - public Data BarrierData { get; private set; } + public Data BarrierData { get; } private bool Equals(WrongBarrierException other) { @@ -413,9 +413,9 @@ public ClientLostException(Data barrierData, RoleName client) BarrierData = barrierData; } - public Data BarrierData { get; private set; } + public Data BarrierData { get; } - public RoleName Client { get; private set; } + public RoleName Client { get; } private bool Equals(ClientLostException other) { @@ -622,7 +622,7 @@ public State HandleBarrier(Data data) } } - public Deadline GetDeadline(TimeSpan? timeout) + public static Deadline GetDeadline(TimeSpan? timeout) { return Deadline.Now + (timeout ?? TestConductor.Get(Context.System).Settings.BarrierTimeout); } From 4555e2ac9d49efa5f34a5fc7451935f59c8145a0 Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Fri, 16 Aug 2024 15:26:16 -0500 Subject: [PATCH 8/8] final MNTR fixes --- .../Akka.Remote.TestKit/BarrierCoordinator.cs | 2 +- src/core/Akka.Remote.TestKit/MultiNodeSpec.cs | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs index a2e82284065..8ca95ca2f13 100644 --- a/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs +++ b/src/core/Akka.Remote.TestKit/BarrierCoordinator.cs @@ -27,7 +27,7 @@ namespace Akka.Remote.TestKit /// ///INTERNAL API. /// - internal class BarrierCoordinator : FSM, ILoggingFSM + internal sealed class BarrierCoordinator : FSM, ILoggingFSM { #region State types and messages diff --git a/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs b/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs index ffddf41467e..604ff08613c 100644 --- a/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs +++ b/src/core/Akka.Remote.TestKit/MultiNodeSpec.cs @@ -579,7 +579,7 @@ public void MuteDeadLetters(ActorSystem system = null, params Type[] messageClas * Implementation (i.e. wait for start etc.) */ - readonly IPEndPoint _controllerAddr; + private readonly IPEndPoint _controllerAddr; protected void AttachConductor(TestConductor tc) { @@ -601,19 +601,17 @@ protected void AttachConductor(TestConductor tc) // now add deployments, if so desired - sealed class Replacement + private sealed class Replacement { - readonly string _tag; - public string Tag { get { return _tag; } } - readonly RoleName _role; - public RoleName Role { get { return _role; } } - readonly Lazy _addr; + public string Tag { get; } + public RoleName Role { get; } + private readonly Lazy _addr; public string Addr { get { return _addr.Value; } } public Replacement(string tag, RoleName role, MultiNodeSpec spec) { - _tag = tag; - _role = role; + Tag = tag; + Role = role; _addr = new Lazy(() => spec.Node(role).Address.ToString()); } }