ejabberd 管理模块

发布于 2024-08-15 19:26:34 字数 163 浏览 2 评论 0原文

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

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

感谢您的帮助。

I need to keep a gen_mod process running as it loops every minute and does some cleanup. However once every few days it will crash and I'll have to manually start it back up again.

I could use a basic example of implementing a supervisor into ejabberd_sup so it can keep going. I am struggling to understand the examples that use gen_server.

Thanks for the help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没结果 2024-08-22 19:26:34

下面是一个结合了 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.

这篇博文很好地解释了 gen_servers 的工作原理。当然,请务必重新阅读 gen_server主管

此处描述了 Ejabberd 的模块开发

Here's an example module combining ejabberd's gen_mod and OTP's gen_server. Explanation is inlined in the code.

-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 gives a good explanation how gen_servers work. Of course make sure to re-read OTP design principles on gen_server and on supervisor.

Ejabberd's module developement is described here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文