今天MailList中一个问题,在Application和Includeed Application中调用application:get_application/0,返回都是Primary Applicaion Name,为什么是这样呢?
在Erlang OTP中Application可以包其他Application,也就是Included Application。我前阵子在项目中也尝试使用Includeed App,可是等我认真看OTP doc的时候,发现我也理解偏差了。
Primary Application启动时,会Load所有的Included Application,但是不会Start他们,需要在Primary App的Supervisor Tree中启动Inclued Application的Top Superior Tree,所以Included Application其实是作为Primary的一部分,他们运行在一个Supervisor Tree中。
当我们调用application:get_applicaion/0时,调用application_controller:get_application(group_leader()).
而group_leader()此时为Primary Application的Top Supervisor Tree的pid,included Application通过Primary启动,因此其两者group_leader相同。
继续向下进行, application_controller负责管理所有的Applications,其内部通过ets维护所有的Applications信息。application_controller:get_application/1调用:
ets:match(ac_tab, {{application_master, '$1'}, Master}),从ac_tab中获取Application对应的Application Master Name,此Name即是我们的Name.app中的Name。
让我们看清楚Application启动的过程:
application:start/2
application:load/1
application_controller:start_application/2
application_controller:handle_call/3
application_controller:check_start_cond/4
application_controller:spawn_starter/4
(spawn a new process:{M, F} = {application_controller, init_starter})
the new process(In application_controller):
application_controller:init_starter/4
application_controller:start_appl/3
application_master:start_link/2
(spawn a new process :{M, F} = {application_master, init})
application_master创建成功
gen_server:cast application_started
reply_to_requester/3通知application:start/2 caller返回ok
new process(In applicaiton_master):
application_master:init/4
group_leader(self(), self()),
(修改group_leader为自身,即每个Application的gourp leader为对应的application_master)
ets:insert(ac_tab, {{application_master, Name}, self()}),
start_it/2
(spawn a new process: {M,F} = {application_master, start_it})
main_loop/2
new process(In applicaiton_master):
application_master:start_it
start_it_new/7
start_the_app/5
start_supervisor/3
Mod:start/2(即Application Callback Module)
loop_it/4
Wow,经过上面复杂痛苦的过程,我们的Application终于启动了。。
main_loop是application_master对应的loop,其Parent为application_controller
loop_it用来管理top supervisor tree,其Parent为application_master
休息一会,回头说main_loop和loop_it