abhishek ranjan
abhishek ranjan

Reputation: 652

Difficulty adopting gen_server architecture in erlang

I am relatively new to erlang and wrote following modules:

-module(gserver).
-export([start1/0]).
-define(SERVER, gserver).

 start1() ->
 serv_util:start(?SERVER, 
                  { gserver, game_loop, 
                    [dict:new(), dict:new()]}).

serv_util:

-module(serv_util).
-export([start/2]).

 start(ServerName, {Module, Function, Args}) ->
 global:trans({ServerName, ServerName},
            fun() ->
                case global:whereis_name(ServerName) of
                    undefined ->        
                        Pid = spawn(Module, Function, Args),
                        global:register_name(ServerName, Pid);
                _ ->
                    ok
                end
            end).

Then I tried to bring it under gen_server architecture of erlang as below:

-module(s_child).
-behaviour(gen_server).

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


 -import(gserver,[start1/0]).
 -import(gclient,[login/1]).



  start()->
  gserver:start1(),
  gen_server:start_link({global,?MODULE}, ?MODULE, [], []).

   stop()->
   gen_server:cast(?MODULE, {stop}).

  log_in(Name)->
  gen_server:call({global,?MODULE}, {login,Name,self()}).

  init(_Args) ->
   io:format("Hello started ~n"),
   {ok,_Args}.

   handle_call({login,Name},_From,State)->
   State,
   Reply=login(Name),
   {reply, Reply,State}.

But when i call this in the following order

1)s_sup:start_link().

Hello,started {ok,<0.344.0>}

2)s_child:log_in("Abhishek").

** exception exit: {{function_clause,
                        [{s_child,handle_call,
                             [{login,"Abhishek",<0.335.0>},
                              {<0.335.0>,#Ref<0.0.4.457>},
                              []],
                             [{file,"s_child.erl"},{line,61}]},
                         {gen_server,try_handle_call,4,
                             [{file,"gen_server.erl"},{line,615}]},
                         {gen_server,handle_msg,5,
                             [{file,"gen_server.erl"},{line,647}]},
                         {proc_lib,init_p_do_apply,3,
                             [{file,"proc_lib.erl"},{line,247}]}]},
                    {gen_server,call,
                        [{global,s_child},{login,"Abhishek",<0.335.0>}]}}
     in function  gen_server:call/2 (gen_server.erl, line 204)

And I am not able to understand that what exactly is wrong at line 61 in my code.In the complete code at line 61 Following code is present:

handle_call(stop,  _From, State) ->

{stop, normal, ok, State};

i.e the first handle_call is present at line 61

Can anybody help me out here please.

Upvotes: 2

Views: 81

Answers (2)

Pouriya
Pouriya

Reputation: 1626

Legoscia's answer is right.
I recommend to see Understanding gen_server.
This article gives useful information for working with gen_server.

Upvotes: 0

legoscia
legoscia

Reputation: 41648

In the log_in function, you pass {login,Name,self()} as the gen_server call, but the handle_call function only expects {login,Name}. Thus, since there is no matching clause, the call to handle_call fails.

You don't need to pass self(), as you use the reply feature to ensure that the response makes it back to the caller, so just modify log_in to pass {login,Name} to gen_server:call.

Upvotes: 3

Related Questions