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-dispatcher
、name->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构建完毕。
- AKKA-源码-dispatcher的构建过程
- AKKA-源码-mailbox构建的主要逻辑
- 学习akka之dispatcher
- 构建一个完整的Akka
- Akka学习过程的疑问
- Akka的Cluster源码分析
- AKKA-源码-Actor的结构设计
- Akka 【七】 Dispatcher and Router
- akka 之 Dispatcher学习笔记
- Akka 配置Dispatcher(一)
- Dispatcher 源码
- Gephi 源码构建过程
- Spark源码分析之Akka的启动
- SBT构建Akka项目
- MXNet源码级构建过程
- Akka FSM 源码分析
- akka源码分析
- akka构建简单分布式应用
- 扎实 Javascript 基础 计划
- Virus_LPK专杀
- 移动端meta设置大全
- Spring项目HTTPS
- python pandas dataframe 小结(包括集合set)
- AKKA-源码-dispatcher的构建过程
- Repairing a Road(floyd算法)
- 二叉排序树
- python学习:while循环,输出1到10,除了7
- SQL语句中JOIN的用法
- 算法训练 字符删除
- 线性布局小实现——计算器的简单布局
- Live555源码分析之1
- ubuntu16 解压zip文件中文名乱码