AKKA-源码-dispatcher的构建过程

来源:互联网 发布:联通在线网络测速 编辑:程序博客网 时间:2024/06/05 14:19

ActorSystem中对dispatcher的定义如下

val dispatchers: Dispatchers = new Dispatchers(settings, DefaultDispatcherPrerequisites(  threadFactory, eventStream, scheduler, dynamicAccess, settings, mailboxes, defaultExecutionContext))val dispatcher: ExecutionContextExecutor = dispatchers.defaultGlobalDispatcher

可以看到,先定义了一个dispatchers,然后再通过dispatchers获取了默认的dispatcher。

接下来具体看下通过dispatchers获取默认dispatcher的过程。

/** * The one and only default dispatcher. * */def defaultGlobalDispatcher: MessageDispatcher = lookup(DefaultDispatcherId)

看下lookup的具体实现,调用了lookupConfigurator获取了一个MessageDispatcherConfigurator,然后再调用dispatcher方法获取实例。

def lookup(id: String): MessageDispatcher = lookupConfigurator(id).dispatcher()

接着看lookupConfigurator的实现

private def lookupConfigurator(id: String): MessageDispatcherConfigurator = {  //dispatcherConfigurators就是一个id->MessageDispatcherConfigurator的映射map,每次新建一个,都会添加到这个map  dispatcherConfigurators.get(id) match {    case null//如果map中不存在该id对应的MessageDispatcherConfigurator,则新建一个      val newConfigurator =        //如果配置文件中有akka.actor.default-dispatcher的配置,则根据配置创建MessageDispatcherConfigurator        if (cachingConfig.hasPath(id)) configuratorFrom(config(id))        else throw new ConfigurationException(s"Dispatcher [$id] not configured")      dispatcherConfigurators.putIfAbsent(id, newConfigurator) match {        case null     ⇒ newConfigurator        case existing ⇒ existing      }    case existing ⇒ existing  }}

其中config(id)就是将配置文件的akka.actor.default-dispatcher下的配置提取出来,同时加入了两个新的key-value,就id->akka.actor.default-dispatchername->default-dispatcher,经过config(id)处理后,返回的配置参数如下

id = “akka.actor.default-dispatcher”name = “default-dispatcher"type = "Dispatcher"executor = "default-executor"default-executor {  fallback = "fork-join-executor"}fork-join-executor {  parallelism-min = 8  parallelism-factor = 3.0  parallelism-max = 64}thread-pool-executor {  keep-alive-time = 60s  core-pool-size-min = 8  core-pool-size-factor = 3.0  core-pool-size-max = 64  max-pool-size-min = 8  max-pool-size-factor  = 3.0  max-pool-size-max = 64  task-queue-size = -1  task-queue-type = "linked"  allow-core-timeout = on}shutdown-timeout = 1sthroughput = 5throughput-deadline-time = 0msattempt-teamwork = onmailbox-requirement = ""

接下来看下configuratorFrom的实现

private def configuratorFrom(cfg: Config): MessageDispatcherConfigurator = {  //如果配置文件中,没有加入id的配置,则直接报错,这个id主要用来做标识用  cfg.getString("type") match {    case "BalancingDispatcher""During a migration period you can still use BalancingDispatcher by specifying the full class name: " +    case "PinnedDispatcher"new PinnedDispatcherConfigurator(cfg, prerequisites)      val args = List(classOf[Config] -> cfg, classOf[DispatcherPrerequisites] -> prerequisites)        case exception ⇒            ("Cannot instantiate MessageDispatcherConfigurator type [%s], defined in [%s], " +              "[akka.dispatch.DispatcherPrerequisites] parameters")      }).get}  if (!cfg.hasPath("id")) throw new ConfigurationException("Missing dispatcher 'id' property in config: " + cfg.root.render)  //根据type的配置,来决定创建什么MessageDispatcherConfigurator,默认是Dispatcher    case "Dispatcher"new DispatcherConfigurator(cfg, prerequisites)      // FIXME remove this case in 2.4      throw new IllegalArgumentException("BalancingDispatcher is deprecated, use a BalancingPool instead. " +        classOf[BalancingDispatcherConfigurator].getName)    case fqn ⇒      prerequisites.dynamicAccess.createInstanceFor[MessageDispatcherConfigurator](fqn, args).recover({          throw new ConfigurationException(              "make sure it has constructor with [com.typesafe.config.Config] and " +              .format(fqn, cfg.getString("id")), exception)  }

通过这个方法返回的就是一个DispatcherConfigurator的实例,这个类的定义如下

class DispatcherConfigurator(config: Config, prerequisites: DispatcherPrerequisites)  extends MessageDispatcherConfigurator(config, prerequisites) {  private val instance = new Dispatcher(    this,    config.getString("id"),    config.getInt("throughput"),    config.getNanosDuration("throughput-deadline-time"),    configureExecutor(),    config.getMillisDuration("shutdown-timeout"))  /**   * Returns the same dispatcher instance for each invocation   */  override def dispatcher(): MessageDispatcher = instance}

定义很简洁,而dispatcher方法就是直接返回了一个Dispatcher类的实例,DispatcherConfigurator的父类MessageDispatcherConfigurator中的configureExecutor方法的实现如下:

def configureExecutor(): ExecutorServiceConfigurator = {  //这里默认传进来的executor的值就是fork-join-executor,所以这个方法默认返回就是一个ForkJoinExecutorConfigurator的实例    case null | "" | "fork-join-executor"new ForkJoinExecutorConfigurator(config.getConfig("fork-join-executor"), prerequisites)    case fqcn ⇒        classOf[Config] -> config,      prerequisites.dynamicAccess.createInstanceFor[ExecutorServiceConfigurator](fqcn, args).recover({          ("""Cannot instantiate ExecutorServiceConfigurator ("executor = [%s]"), defined in [%s], make sure it has an accessible constructor with a [%s,%s] signature""")      }).get  //获取executor的配置,默认配置是default-execrtor,所有这里就是创建一个DefaultExecutorServiceConfigurator实例    case "default-executor"new DefaultExecutorServiceConfigurator(config.getConfig("default-executor"), prerequisites, configurator(config.getString("default-executor.fallback")))  }  def configurator(executor: String): ExecutorServiceConfigurator = executor match {    case "thread-pool-executor"new ThreadPoolExecutorConfigurator(config.getConfig("thread-pool-executor"), prerequisites)      val args = List(        classOf[DispatcherPrerequisites] -> prerequisites)        case exception ⇒ throw new IllegalArgumentException(            .format(fqcn, config.getString("id"), classOf[Config], classOf[DispatcherPrerequisites]), exception)  }  config.getString("executor") match {    case other              ⇒ configurator(other)}

这个方法返回的ExecutorServiceConfigurator的子类实现就是DefaultExecutorServiceConfigurator的实例,DefaultExecutorServiceConfigurator的输入参数中前两个是相关配置,第三个参数就是一个ExecutorServiceConfigurator的子类实现,默认的及时ForkJoinExecutorConfigurator

DefaultExecutorServiceConfigurator的主要方法就是createExecutorServiceFactory,而该方法则主要是通过调用provider这个变量来实现,provider的定义如下

val provider: ExecutorServiceFactoryProvider =  prerequisites.defaultExecutionContext match {    case Some(ec) ⇒      prerequisites.eventStream.publish(Debug("DefaultExecutorServiceConfigurator", this.getClass, s"Using passed in ExecutionContext as default executor for this ActorSystem. If you want to use a different executor, please specify one in akka.actor.default-dispatcher.default-executor."))      new AbstractExecutorService with ExecutorServiceFactory with ExecutorServiceFactoryProvider {        def createExecutorServiceFactory(id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = this                def createExecutorService: ExecutorService = this                def shutdown(): Unit = ()        def isTerminated: Boolean = false                def awaitTermination(timeout: Long, unit: TimeUnit): Boolean = false                def shutdownNow(): ju.List[Runnable] = ju.Collections.emptyList()        def execute(command: Runnable): Unit = ec.execute(command)        def isShutdown: Boolean = false          }    case None ⇒ fallback  }

默认的prerequisites.defaultExecutionContext是null,所有会直接返回fallback,也就是上面说的ForkJoinExecutorConfigurator

至此,Dispatcher构建完毕。

原创粉丝点击