diff --git a/src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs b/src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs index 374eb34d557..58311a000b0 100644 --- a/src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs +++ b/src/Orleans.Runtime/Placement/Repartitioning/ActivationRepartitioner.MessageSink.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; @@ -53,7 +54,8 @@ private async Task ProcessPendingEdges(CancellationToken cancellationToken) { foreach (var message in drainBuffer[..count]) { - if (!_messageFilter.IsAcceptable(message, out var isSenderMigratable, out var isTargetMigratable)) + if (!IsFullyAddressed(message) || // The silo addresses (likely the target) is set null some time later (after the message is recorded), this can lead to a NRE + !_messageFilter.IsAcceptable(message, out var isSenderMigratable, out var isTargetMigratable)) { continue; } @@ -118,7 +120,7 @@ private void RecordMessage(Message message) } // Sender and target need to be fully addressable to know where to move to or towards. - if (!message.IsSenderFullyAddressed || !message.IsTargetFullyAddressed) + if (!IsFullyAddressed(message)) { return; } @@ -129,6 +131,10 @@ private void RecordMessage(Message message) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsFullyAddressed(Message message) => + message.IsSenderFullyAddressed && message.IsTargetFullyAddressed; + async ValueTask IActivationRepartitionerSystemTarget.FlushBuffers() { while (_pendingMessages.Count > 0) @@ -148,4 +154,4 @@ async ValueTask IActivationRepartitionerSystemTarget.FlushBuffers() Message = "{Service} has stopped." )] private static partial void LogTraceServiceStopped(ILogger logger, string service); -} \ No newline at end of file +} diff --git a/src/Orleans.Runtime/Placement/Repartitioning/RepartitionerMessageFilter.cs b/src/Orleans.Runtime/Placement/Repartitioning/RepartitionerMessageFilter.cs index 954af5497e0..9853fc76cc4 100644 --- a/src/Orleans.Runtime/Placement/Repartitioning/RepartitionerMessageFilter.cs +++ b/src/Orleans.Runtime/Placement/Repartitioning/RepartitionerMessageFilter.cs @@ -30,4 +30,4 @@ public bool IsAcceptable(Message message, out bool isSenderMigratable, out bool // If both are not migratable types we ignore this. But if one of them is not, then we allow passing, as we wish to move grains closer to them, as with any type of grain. return isSenderMigratable || isTargetMigratable; } -} \ No newline at end of file +}