我不明白在ShardRegion中创建一个新actor时如何分配ID,我正在查看这个示例
如果有人有一个更清晰的例子,那将是伟大的。
所有针对分片角色(实体)的消息都必须通过负责该实体的给定类型的分片区域。可以像这样初始化分片区域:
var sharding = ClusterSharding.Get(system);
var shardRegion = sharding.Start(
typeName: nameof(MyActor),
entityProps: Props.Create<MyActor>(), // the Props used to create entities
settings: ClusterShardingSettings.Create(system),
messageExtractor: messageExtractor
);
为了正确地将消息路由到实体,分片区域必须能够提取该实体的shard-id和entity-id以及它所属的分片。这是一个messageExtractor
对象的工作(它必须实现IMessageExtractor
接口)。
这里的一个常见模式是创建一个专用信封,用于将实际消息路由到实体。下面你可以看到一个例子 - 没有显式提供shard id,而是根据实体id模数的散列计算最大分片数(这个值一旦被选中,就不能改变)。
public sealed class ShardEnvelope
{
public readonly string EntityId;
public readonly object Payload;
public ShardEnvelope(string entityId, object payload)
{
EntityId = entityId;
Payload = payload;
}
}
public sealed class MessageExtractor : HashCodeMessageExtractor
{
public MessageExtractor(int maxNumberOfShards) : base(maxNumberOfShards) { }
public override string EntityId(object message) =>
(message as ShardEnvelope)?.EntityId;
public override object EntityMessage(object message) =>
(message as ShardEnvelope)?.Payload;
}
现在,虽然实体生命周期完全由集群分片管理,并且它们在集群中的实际本地化可能会随着时间的推移而发生变化(由于重新平衡),但它们在给定集群节点内的相对路径始终保持不变,并且它符合以下模式:
/user/sharding/<typeName>/<shard-id>/<entity-id>
这意味着,如果要提取当前actor的entity-id和shard-id,可以直接从actor的路径执行:
var entityId = Self.Path.Name;
var shardId = Self.Path.Parent.Name;