笔记四 - OTP应用程序基本框架

最近工作忙,但是花了点时间看了些资料又学了很多东东,今天做一下application笔记.

看着这个单词就是应用程序意思,我就当它是一个应用程序了.那怎么使用呢?

第一步:
需要一个实现以下模式的模块(一般文件名为"*_app.erl"形式,模块也就是"*_app"形式),也就是应用程序入口一样,很简单两个函数,开启与关闭:

-module(my_app).
-behaviour(application).
-export([start/2, stop/1]).

start(_Type, StartArgs) -> 
    case my_sup:start_link(StartArgs) of
	{ok, Pid} ->
	    {ok, Pid};
	Error ->
	    Error
    end.
stop(State) -> ok.

参数Type有normal,takeover,failover,一般为normal

参数StartArgs为app传进来的参数,应用程序配置app文件传进来,那个值就在mod那里.

返回值有三个,其中Pid,该Pid为my_sup:start_link返回值,也就是实现了-behaviour(supervisor).模式的模块,作为主守护进程.

1.{ok, Pid}
2.{ok, Pid, State}
3.{error, Reason}

 

 第二步:
需要一个观察者模块(一般文件名为"*_sup.erl"形式,模块也就是"*_sup"形式),也就是上面说的-behaviour(supervisor).模式,实际作用就是一个守护进程,当子进程崩溃后就会按照相关条件参数来执行接下来的操作.他的子进程有两种,一种是supervisor子守护进程,还有一种是worker子工作进程.守护进程下有子守护进程和子工作进程,子守护进程下有子守护进程和子工作进程,一颗庞大的树.

-module(my_sup).
-behaviour(supervisor).
-export([init/1]).
init([_StartArgs]) ->  %% 系统自动会调用
    AChild = {'AName',{'AModule',start_link,[]},
	      permanent,2000,worker,['AModule']},
    {ok,{{one_for_all,0,1}, [AChild]}}.

-export([start_link/1]).  %% 这个是自定义函数
start_link(StartArgs) ->
    supervisor:start_link({local,?SERVER}, ?MODULE, [StartArgs]). %% 调用系统函数

函数init([_StartArgs])中参数为start_link(StartArgs)传进来的参数.
返回值有点复杂了,简化一下其实就是{ok,{{one_for_all,0,1}, [AChild1,AChild2,...]}}.什么意思呢?
{one_for_all,0,1} 第一个值有 one_for_all,  one_for_one, rest_for_one, simple_one_for_one 四种
one_for_all:  该子进程终止之后,影响相关的子进程
one_for_one: 该进程终止之后,不影响其他子进程.
rest_for_one : 
simple_one_for_one  : 
第二个0,表示重启次数.第三个表示时间秒.该元组的意思就是,在该子进程终止后也关闭其他相关进程,并且抛出异常.
{one_for_one,4,3600}这个表示该子进程终止,在一小时内最多自动重启4次,如果再次被终止那么则退出,并且抛出异常.
最后一个数组[AChild1,AChild2,...]表示子进程的启动方式可以多个,也可以只有一个,具体介绍下面:
一个子进程的参数{'AName',{'AModule',start_link,[]}, permanent,2000,worker,['AModule']}
'AName' 为子进程的ID,别名,用来系统内部识别. 
{'AModule',start_link,[]} 为启动函数{模块,函数,[参数]}.
permanent 为自动启动方式 还有temporary和transient.

                temporary :  该进程终止之后,不影响其他进程.,一般用这个.
                permanent  : 该进程终止之后整个应用程序终止.
                transient  :  这个......
2000 为当进程终止后等待时间.还有其他参数 brutal_kill:立即终止不等待.
worker 表示子进程的类型,只有两个worker(子工作进程)或者supervisor(子观察者|子守护进程).
['AModule'] 表示该子进程的依赖模块,一般为调用模块[my_sup],也可以是原子dynamic

 第三步:
新建启动配置文件,文件名为"你的模块名.app",比如这里"my.app"

{
	application, my,
	[
		{description, "this is my app description"},
		{vsn, "0.1.0"},
		{modules, [my]},
		{registered, [my_sup]},
		{applications, [kernel, stdlib, sasl]},
		{mod, {my_app,[]}}, %% 这个就是启动参数,{mod, {模块, [参数]}},这项必须要,其他随便
		{start_phases, []},
		{env, [{file,"..."}]}
	]
 }.

其他步骤:
有时我们的程序需要有个强大的外部配置文件,上面的env可能满足不了,那么我们就用config文件,文件命名"*.config".

应用程序启动

application:start(my).

注意这里的start跟my_app.erl中实现接口的start不是同一个. my_app.erl中那个是回调函数,erlang底层自动调用.

你可能感兴趣的:(erlang)