主要逻辑:
- 检查实体参数,若无则实例化默认参数。
- 进行实体注册
1 检查实体参数
核心代码:
override def init[M, E](entity: scaladsl.Entity[M, E]): ActorRef[E] = {
val settings = entity.settings match {
case None => ClusterShardingSettings(system)
case Some(s) => s
}
val extractor = (entity.messageExtractor match {
case None => new HashCodeMessageExtractor[M](settings.numberOfShards)
case Some(e) => e
}).asInstanceOf[ShardingMessageExtractor[E, M]]
val settingsWithRole = entity.role.fold(settings)(settings.withRole)
val settingsWithDataCenter = entity.dataCenter.fold(settingsWithRole)(settingsWithRole.withDataCenter)
internalInit(
entity.createBehavior,
entity.entityProps,
entity.typeKey,
entity.stopMessage,
settingsWithDataCenter,
extractor,
entity.allocationStrategy)
}
核心逻辑:
- 检查实体中是否存在设置,若无则使用默认设置。
- 检查实体是否指定了消息提取器,若无则使用默认的消息提取器。
2 实体注册
核心代码
@InternalApi private[akka] def internalStart(
typeName: String,
entityProps: String => Props,
settings: ClusterShardingSettings,
extractEntityId: ShardRegion.ExtractEntityId,
extractShardId: ShardRegion.ExtractShardId,
allocationStrategy: ShardAllocationStrategy,
handOffStopMessage: Any): ActorRef = {
if (settings.stateStoreMode == ClusterShardingSettings.StateStoreModePersistence)
log.warning("Cluster Sharding has been set to use the deprecated `persistence` state store mode.")
if (settings.shouldHostShard(cluster)) {
regions.get(typeName) match {
case null =>
// it's ok to Start several time, the guardian will deduplicate concurrent requests
implicit val timeout = system.settings.CreationTimeout
val startMsg = Start(
typeName,
entityProps,
settings,
extractEntityId,
extractShardId,
allocationStrategy,
handOffStopMessage)
val Started(shardRegion) = Await.result(guardian ? startMsg, timeout.duration)
regions.put(typeName, shardRegion)
shardRegion
case ref => ref // already started, use cached ActorRef
}
} else {
log.debug("Starting Shard Region Proxy [{}] (no actors will be hosted on this node)...", typeName)
startProxy(
typeName,
settings.role,
dataCenter = None, // startProxy method must be used directly to start a proxy for another DC
extractEntityId,
extractShardId)
}
}
核心逻辑
- 获取region Actor,若无则创建。
创建region Actor需要的参数 - 实体类型名称
- 实体Props
- 设置
- 抽取实体Id的函数
- 抽取Shard Id的函数
- Sharding Location 策略
- 停止消息的类型。