I have developed a chat app and its server is 'message_server' here. This is a distributed app and I can spawn multiple chat users on multiple nodes by giving an atomic name for each of them. The messaging between two chat users are done by sending a message to the chat user's node. I can not start this server with a supervisor. How to solve this problem. I need the supervisor to supervise the chat users.
message_server code
-module(message_server).
-behaviour(gen_server).
-export([send_message/2, receive_message/3, start_link/1, stop/0, recv_msg/1, readyto_send/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
-define(SERVER, ?MODULE).
-record(message_server_state, {from, to, msgsent, msgreceived}).
%%%===================================================================
%%% Spawning and gen_server implementation
%%%===================================================================
start_link(Name) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, Name, []).
init(Name) ->
io:format("~p is connected with the server...~n", [Name]),
{ok, #message_server_state{
from = atom_to_list(node()),
to = [],
msgsent = [],
msgreceived = []
}}.
stop() ->
gen_server:stop(?MODULE).
send_message(To, Msg) ->
gen_server:call({?MODULE, node()}, {send, To, Msg}).
receive_message(Sender, To, Msg) ->
gen_server:call({?MODULE, list_to_atom(To)}, {reciv, Sender, Msg}).
recv_msg(Msg)->
gen_server:call({?MODULE, node()}, {recive, Msg}).
readyto_send(To)->
gen_server:call({?MODULE, list_to_atom(To)}, {ready, To}).
handle_call({send, To, Msg}, _From, State = #message_server_state{to = Receivers, msgsent = Msgsent, from = Sender}) ->
io:format("Sent message: ~p~n", [Msg]),
%% chat_fsm:message_send(Msg, To),--toDo add later--
receive_message(Sender, To, Msg),
{reply, ok, State#message_server_state{msgsent = [Msg | Msgsent], to = [To | Receivers]}};
handle_call({reciv, Sender, Msg}, _From, State = #message_server_state{msgreceived = Msgreceived}) ->
io:format("Sent by: ~p~n", [Sender]),
io:format("Message: ~p~n", [Msg]),
M = database_server:getalldb(Sender),
io:format("SENDER-DETAILS>>: ~p~n",[M]),
{reply, ok, State#message_server_state{msgreceived = [Msg | Msgreceived]}};
handle_call({recive, Msg}, _From, State = #message_server_state{msgreceived = Msgreceived}) ->
io:format("Message: ~p~n", [Msg]),
{reply, ok, State#message_server_state{msgreceived = [Msg | Msgreceived]}}.
%%--toDo add later--
%%handle_call({ready, To}, _From, State) ->%% chat_fsm:ready_to_send(To),
%% {reply, ok, State}.
handle_cast(_Request, State = #message_server_state{}) ->
{noreply, State}.
handle_info(_Info, State = #message_server_state{}) ->
{noreply, State}.
terminate(_Reason, _State = #message_server_state{}) ->
ok.
code_change(_OldVsn, State = #message_server_state{}, _Extra) ->
{ok, State}.
chat_sup supervisor
-module(chat_sup).
-behaviour(supervisor).
-export([start_link/0, init/1, start_link_shell2/0]).
start_link_shell2()->
{ok, Pid2}= supervisor:start_link({global,?MODULE}, ?MODULE,[]),
unlink(Pid2).
start_link() ->
supervisor:start_link({global, ?MODULE}, ?MODULE, []).
init([]) ->AChild = #{id => 'message_server',
start => {'message_server', start_link, []},
restart => permanent,
shutdown => infinity,
type => worker,
modules => ['message_server']},
{ok, {#{strategy => one_for_all,
intensity => 5,
period => 30},
[AChild]}
}.
I get this error when starting supervisor
(john@DESKTOP-RD414DV)5> chat_sup:start_link_shell2().
=SUPERVISOR REPORT==== 21-Sep-2022::05:49:46.626000 ===
supervisor: {global,chat_sup}
errorContext: start_error
reason: {'EXIT',
{undef,
[{message_server,start_link,[],[]},
{supervisor,do_start_child_i,3,
[{file,"supervisor.erl"},{line,414}]},
{supervisor,do_start_child,2,
[{file,"supervisor.erl"},{line,400}]},
{supervisor,'-start_children/2-fun-0-',3,
[{file,"supervisor.erl"},{line,384}]},
{supervisor,children_map,4,
[{file,"supervisor.erl"},{line,1250}]},
{supervisor,init_children,2,
[{file,"supervisor.erl"},{line,350}]},
{gen_server,init_it,2,
[{file,"gen_server.erl"},{line,848}]},
{gen_server,init_it,6,
[{file,"gen_server.erl"},{line,811}]}]}}
offender: [{pid,undefined},
{id,message_server},
{mfargs,{message_server,start_link,[]}},
{restart_type,permanent},
{significant,false},
{shutdown,infinity},
{child_type,worker}]
** exception exit: {shutdown,
{supervisor,'-start_children/2-fun-0-',3,
[{file,"supervisor.erl"},{line,384}]},
{supervisor,children_map,4,
[{file,"supervisor.erl"},{line,1250}]},
{supervisor,init_children,2,
[{file,"supervisor.erl"},{line,350}]},
{gen_server,init_it,2,
[{file,"gen_server.erl"},{line,848}]},
{gen_server,init_it,6,
[{file,"gen_server.erl"},{line,811}]}]}}}}
The start
mfa (message_server:start_link/0
) does not match message_server:start_link/1
signature
- start => {'message_server', start_link, []}
+ start => {'message_server', start_link, ['message_server_name']}
or implement message_server:start_link/0
as
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, Name, [?MODULE]).