2009-12-23 96 views
2

我需要保持一個gen_mod進程運行,因爲它每分鐘循環並進行一些清理。然而,每隔幾天它就會崩潰,我將不得不手動重新啓動備份。ejabberd監督模塊

我可以使用一個基本的例子來實現一個監督員到ejabberd_sup中,這樣它就可以繼續工作。我很努力去理解使用gen_server的例子。

感謝您的幫助。

+0

你能告訴我們一些代碼,或者你在哪裏提示,這樣我們就可以幫你嗎? – Zed 2009-12-23 20:36:49

回答

7

下面是一個示例模塊,結合了ejabberd的gen_mod和OTP的gen_server。代碼中內聯解釋。

-module(cleaner). 

-behaviour(gen_server). 
-behaviour(gen_mod). 

%% gen_mod requires these exports 
-export([start/2, stop/1]). 

%% these are exports for gen_server 
-export([start_link/0]). 
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 
     terminate/2, code_change/3]). 

-define(INTERVAL, timer:minutes(1)). 

-record(state, {}). 

%% ejabberd calls this function when this module is loaded 
%% basically it adds gen_server defined by this module to 
%% ejabberd main supervisor 
start(Host, Opts) -> 
    Proc = gen_mod:get_module_proc(Host, ?MODULE), 
    ChildSpec = {Proc, 
       {?MODULE, start_link, [Host, Opts]}, 
       permanent, 
       1000, 
       worker, 
       [?MODULE]}, 
    supervisor:start_child(ejabberd_sup, ChildSpec). 

%% this is called by ejabberd when module is unloaded, so it 
%% does the opposite of start/2 :) 
stop(Host) -> 
    Proc = gen_mod:get_module_proc(Host, ?MODULE), 
    supervisor:terminate_child(ejabberd_sup, Proc), 
    supervisor:delete_child(ejabberd_sup, Proc). 

%% it will be called by supervisor when it is time to start 
%% this gen_server under control of supervisor 
start_link(_Host, _Opts) -> 
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 

%% it is an initialization function for gen_server 
%% it starts a timer, which sends 'tick' message periodically to itself 
init(_) -> 
    timer:send_interval(?INTERVAL, self(), tick), 
    {ok, #state{}}. 

handle_call(_Request, _From, State) -> 
    Reply = ok, 
    {reply, Reply, State}. 

handle_cast(_Msg, State) -> 
    {noreply, State}. 

%% this function is called whenever gen_server receives a 'tick' message 
handle_info(tick, State) -> 
    State2 = do_cleanup(State), 
    {noreply, State2}; 

handle_info(_Info, State) -> 
    {noreply, State}. 

terminate(_Reason, _State) -> 
    ok. 

code_change(_OldVsn, State, _Extra) -> 
    {ok, State}. 


%% this function is called by handle_info/2 when tick message is received 
%% so put all cleanup code here 
do_cleanup(State) -> 
    %% do all cleanup work here 
    State. 

This blog post給出了很好的解釋gen_servers是如何工作的。當然,請確保重新閱讀gen_serversupervisor上的OTP設計原則。

Ejabberd的模塊的研究與開發描述here

+0

非常感謝!我會馬上試試這個,並且仔細閱讀你寄給我的鏈接。 – ewindsor 2009-12-23 23:05:07

+0

不客氣:) – gleber 2009-12-23 23:54:38

+0

嗯,看起來像start_link永遠不會被稱爲...任何想法? – ewindsor 2009-12-24 00:47:15