有时候我们原先设计了一套系统,可是并没有按照otp的标准来实现,可是我们又想使用otp进程树的形式对其进行监督和管理时,

这种情况下,我们就可以使用supervisor_bridge进行桥接。

 

如果我们想将进程纳入进树的管理,一般来说,无非是实现gen_server, gen_event, gen_fsm等behaviour,然后用supervisor模块进行管理。

所以supervisor_bridge本质上是一个实现了gen_server behaviour的模块,作为一个子系统进程的容器,定义了两个回调函数。

init/1:supervisor_bridge进程初始化时,对子系统的回调。

terminate/2:supervisor_bridge进程终止时候,对子系统的回调。

我们在使用时,实际是将该模块纳入到supervisor的管理下,方便的对其进行各种管理。

supervisor_bridge 初始化时,link到接入的子系统的进程,当子系统进程结束时候,同时结束自身实现了gen_server的进程,这也实现和子系统进程和进程树的交互。

 

接下来我举个例子,比如我们有一个sub_system模块:

-module(sub_system).
-export([start/0]).



-record(state, {msg}).

start() ->
    register(sub_system, spawn(fun() -> loop(#state{msg = 0}) end)).

loop(State = #state{msg = Msg}) ->
    receive
        Msg ->
            loop(State#state{msg = Msg + 1})
    end.

 

这时候,我们想要用supervisor对其进行管理,只需要实现supervisor_bridge模块,如下:

-module(sub_system).


-behaviour(supervisor_bridge).

-export([start/0]).

-export([init/1, terminate/2]).


-record(state, {msg}).

init([]) ->
    Pid = spawn(fun() -> loop(#state{msg = 0}) end),
    {ok, Pid, []}.


terminate(_Reason, _State) ->
    ok.


%% ==================================================

start() ->
    supervisor_bridge:start_link({local, sub_system}, sub_system, []).

loop(State = #state{msg = Msg}) ->
    receive
        Msg ->
            loop(State#state{msg = Msg + 1})
    end.

同时我们在supervisor里,注册这样的Spec:

SubSystem = {sub_system, {sub_system, start, []},
            permanent, 5000, supervisor, [sub_system]},

 

这样,我们实际生成了一个注册名为sub_system的进程,这个进程作为容器,直接链接到真正子系统进程,我们就可以

通过sub_system进程进行桥接,挂接到进程树上,对子系统进程进行重启,关闭,添加,删除等进程管理。

 

 

 

 

 posted on 2013-02-26 13:41  文武双全大星星  阅读(370)  评论(0编辑  收藏  举报