Search code examples
erlangejabberd

ejabberd gen_mod development issue


Following this stackoverflow question, and this tutorial series, I implemented mod_test module, which implements both gen_mod and gen_server behaviours. It is very stupid for now, since it does nothing more that adding itself to ejabber_sup.

My problem is that I am not sure whether the module is started by ejabberd_sup or not since I can't find it in the list provided by:

supervisor:which_children(ejabberd_sup).

Given that I have gen_mod.beam and mod_test.erl in the same directory, I compiled my code using:

erlc -pa ./ mod_test.erl

and this gives no errors. After compilation, I copied the file into ebin folder of ejabberd installation and changed ejabberd.cfg adding:

....
{mod_test, []},
....

My code is the following:

-module(mod_test).

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

-export([start/2, stop/1]).

-export([start_link/2]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).


-record(state, {}).

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).

stop(Host) ->
    Proc = gen_mod:get_module_proc(Host, ?MODULE),
    supervisor:terminate_child(ejabberd_sup, Proc),
    supervisor:delete_child(ejabberd_sup, Proc).

start_link(_Host, _Opts) ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->
    {ok, #state{}}.

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

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

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

terminate(_Reason, _State) ->
    ok.

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

Is something wrong in my approach? How can I be sure that the module is correctly started?


Solution

  • I reinstalled ejabberd (vsn 2.1.11) and now it is working. I add in this answer the parts of the code which are different from the code in the questoin. Changes were done following mod_echo.erl

    -define(PROCNAME, ejabberd_mod_test).
    
    start_link(Host, Opts) ->
        Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
        gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
    
    start(Host, Opts) ->
        Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
        ChildSpec =
        {Proc,
         {?MODULE, start_link, [Host, Opts]},
         temporary,
         1000,
         worker,
         [?MODULE]},
        supervisor:start_child(ejabberd_sup, ChildSpec).
    
    stop(Host) ->
        Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
        gen_server:call(Proc, stop),
        supervisor:terminate_child(ejabberd_sup, Proc),
        supervisor:delete_child(ejabberd_sup, Proc).
    

    Hope this will help somebody else as well.