【问题标题】:ejabberd supervisor moduleejabberd 主管模块
【发布时间】:2010-12-29 14:10:58
【问题描述】:

我需要保持 gen_mod 进程运行,因为它每分钟循环一次并进行一些清理。但是每隔几天它就会崩溃一次,我必须手动重新启动它。

我可以使用一个在 ejabberd_sup 中实现主管的基本示例,这样它就可以继续运行。我正在努力理解使用 gen_server 的示例。

感谢您的帮助。

【问题讨论】:

  • 你能给我们一些代码,或者你在哪里的提示,以便我们帮助你吗?

标签: erlang ejabberd mnesia


【解决方案1】:

这是一个结合了 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

【讨论】:

  • 嗯,好像 start_link 永远不会被调用...有什么想法吗?
  • 哦 - 明白了... start_link 应该是 start_link/2 因为我们正在传递 Host 和 Opts。有用!现在我会尝试让它崩溃......
  • 好点,发帖时错过了这个问题。将在代码中修复它
  • OTP 文档状态“如果在最后 MaxT 秒内发生的重启次数超过 MaxR,则主管终止所有子进程,然后终止自身”。在绑定到 ejabberd_sup 之后,我们崩溃的模块是否会导致其他模块或 ejabberd 本身重新启动或崩溃?
猜你喜欢
  • 2012-07-27
  • 2014-07-12
  • 2016-05-24
  • 2018-12-03
  • 1970-01-01
  • 2011-11-26
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多