diff --git a/src/benchmark/Akka.Cluster.Benchmarks/Sharding/ShardMessageRoutingBenchmarks.cs b/src/benchmark/Akka.Cluster.Benchmarks/Sharding/ShardMessageRoutingBenchmarks.cs
index 4e456f5e8c2..59a28ec48b8 100644
--- a/src/benchmark/Akka.Cluster.Benchmarks/Sharding/ShardMessageRoutingBenchmarks.cs
+++ b/src/benchmark/Akka.Cluster.Benchmarks/Sharding/ShardMessageRoutingBenchmarks.cs
@@ -20,7 +20,7 @@
namespace Akka.Cluster.Benchmarks.Sharding
{
- //[DotTraceDiagnoser]
+ [DotTraceDiagnoser]
[Config(typeof(MonitoringConfig))]
[SimpleJob(RunStrategy.Monitoring, launchCount: 10, warmupCount: 10)]
public class ShardMessageRoutingBenchmarks
diff --git a/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingRememberEntitiesNewExtractorSpec.cs b/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingRememberEntitiesNewExtractorSpec.cs
index c3caf1eca5f..6a195ada788 100644
--- a/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingRememberEntitiesNewExtractorSpec.cs
+++ b/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingRememberEntitiesNewExtractorSpec.cs
@@ -263,7 +263,7 @@ private void Cluster_with_min_nr_of_members_using_sharding_must_start_new_nodes_
{
Within(TimeSpan.FromSeconds(30), () =>
{
- // start it with a new shard id extractor, which will put the entities
+ // start it with a new shard id messageExtractor, which will put the entities
// on different shards
RunOn(() =>
diff --git a/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingSpec.cs b/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingSpec.cs
index 6a0a004faff..b6553f50db9 100644
--- a/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingSpec.cs
+++ b/src/contrib/cluster/Akka.Cluster.Sharding.Tests.MultiNode/ClusterShardingSpec.cs
@@ -523,8 +523,7 @@ private IActorRef CreateRegion(string typeName, bool rememberEntities)
entityProps: _ => QualifiedCounter.Props(typeName),
settings: settings,
coordinatorPath: "/user/" + typeName + "Coordinator/singleton/coordinator",
- extractEntityId: ExtractEntityId,
- extractShardId: ExtractShardId,
+ new DeprecatedHandlerExtractorAdapter(ExtractEntityId, ExtractShardId),
handOffStopMessage: PoisonPill.Instance,
rememberEntitiesProvider: rememberEntitiesProvider),
name: typeName + "Region");
@@ -684,8 +683,7 @@ private void ClusterSharding_should_support_proxy_only_mode()
typeName: "counter",
settings: settings,
coordinatorPath: "/user/counterCoordinator/singleton/coordinator",
- extractEntityId: ExtractEntityId,
- extractShardId: ExtractShardId),
+ new DeprecatedHandlerExtractorAdapter(ExtractEntityId, ExtractShardId)),
"regionProxy");
proxy.Tell(new Get(1));
diff --git a/src/contrib/cluster/Akka.Cluster.Sharding.Tests/RememberEntitiesShardIdExtractorChangeSpec.cs b/src/contrib/cluster/Akka.Cluster.Sharding.Tests/RememberEntitiesShardIdExtractorChangeSpec.cs
index 0482621555d..e24dd558e2e 100644
--- a/src/contrib/cluster/Akka.Cluster.Sharding.Tests/RememberEntitiesShardIdExtractorChangeSpec.cs
+++ b/src/contrib/cluster/Akka.Cluster.Sharding.Tests/RememberEntitiesShardIdExtractorChangeSpec.cs
@@ -21,7 +21,7 @@
namespace Akka.Cluster.Sharding.Tests
{
///
- /// Covers that remembered entities is correctly migrated when used and the shard id extractor
+ /// Covers that remembered entities is correctly migrated when used and the shard id messageExtractor
/// is changed so that entities should live on other shards after a full restart of the cluster.
///
public class RememberEntitiesShardIdExtractorChangeSpec : AkkaSpec
diff --git a/src/contrib/cluster/Akka.Cluster.Sharding.Tests/ShardEntityFailureSpec.cs b/src/contrib/cluster/Akka.Cluster.Sharding.Tests/ShardEntityFailureSpec.cs
index 56446c49cf0..874b24c049d 100644
--- a/src/contrib/cluster/Akka.Cluster.Sharding.Tests/ShardEntityFailureSpec.cs
+++ b/src/contrib/cluster/Akka.Cluster.Sharding.Tests/ShardEntityFailureSpec.cs
@@ -126,8 +126,7 @@ public async Task Persistent_Shard_must_recover_from_failing_entity(Props entity
"shard-1",
_ => entityProp,
settings,
- extractEntityId,
- extractShardId,
+ new ExtractorAdapter(new DeprecatedHandlerExtractorAdapter(extractEntityId, extractShardId)),
PoisonPill.Instance,
provider
));
diff --git a/src/contrib/cluster/Akka.Cluster.Sharding/ClusterSharding.cs b/src/contrib/cluster/Akka.Cluster.Sharding/ClusterSharding.cs
index e944e0f18e6..896d755ba5d 100644
--- a/src/contrib/cluster/Akka.Cluster.Sharding/ClusterSharding.cs
+++ b/src/contrib/cluster/Akka.Cluster.Sharding/ClusterSharding.cs
@@ -5,15 +5,18 @@
//
//-----------------------------------------------------------------------
+#nullable enable
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using Akka.Actor;
+using Akka.Cluster.Sharding.Serialization.Proto.Msg;
using Akka.Cluster.Tools.Singleton;
using Akka.Configuration;
using Akka.Dispatch;
@@ -33,15 +36,10 @@ namespace Akka.Cluster.Sharding
public interface IClusterShardingSerializable { }
///
- /// TBD
+ /// INTERNAL API
///
- public class ClusterShardingExtensionProvider : ExtensionIdProvider
+ public sealed class ClusterShardingExtensionProvider : ExtensionIdProvider
{
- ///
- /// TBD
- ///
- /// TBD
- /// TBD
public override ClusterSharding CreateExtension(ExtendedActorSystem system)
{
var extension = new ClusterSharding(system);
@@ -49,6 +47,53 @@ public override ClusterSharding CreateExtension(ExtendedActorSystem system)
}
}
+ ///
+ /// INTERNAL API
+ ///
+ /// Used to automatically handle built-in sharding messages when used with ClusterSharding.
+ ///
+ internal sealed class ExtractorAdapter : IMessageExtractor
+ {
+ private readonly IMessageExtractor _underlying;
+
+ public ExtractorAdapter(IMessageExtractor underlying)
+ {
+ _underlying = underlying;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public string? EntityId(Msg message)
+ {
+ return message switch
+ {
+ ShardingEnvelope se => se.EntityId,
+ _ => _underlying.EntityId(message)
+ };
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Msg? EntityMessage(Msg message)
+ {
+ return message switch
+ {
+ ShardingEnvelope se => se.Message,
+ _ => _underlying.EntityMessage(message)
+ };
+ }
+
+ [Obsolete("Use ShardId(EntityId, object) instead.")]
+ public string? ShardId(Msg message)
+ {
+ return _underlying.ShardId(message);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public string ShardId(string entityId, Msg? messageHint = null)
+ {
+ return _underlying.ShardId(entityId, messageHint);
+ }
+ }
+
///
/// Convenience implementation of that
/// construct ShardId based on the of the EntityId.
@@ -56,20 +101,20 @@ public override ClusterSharding CreateExtension(ExtendedActorSystem system)
///
public abstract class HashCodeMessageExtractor : IMessageExtractor
{
- private class Implementation : HashCodeMessageExtractor
+ private sealed class Implementation : HashCodeMessageExtractor
{
- private readonly Func