Linking to/from a gen_server?

Jay Nelson jay@REDACTED
Sun Mar 2 09:50:47 CET 2003


Tomorrow (cross fingers) I will post my tutorial showing
the OTP equivalent to Joe's tcp_server.erl.  In it I use
an ets table to keep track of the spawned child processes
and receive Info messages to delete from the ets table
when a process ends.  I haven't yet tested any of the
code below, but in principle it should work (oh, if
programming were that easy...)

 > I'm trying to setup a way to have a client process send
 > a gen_server a message

The way I do it is to introduce a function entry point in
the module implementing the gen_server behaviours:

call_and_link(Server, PingData) ->
	gen_server:call(Server, {msg, PingData}).

 > I want the gen_server to link to the client process so
 > it can remove the term and client pid when the client
 > process exits.

handle_call({msg, PingData}, From, State) when pid(From) ->
	link(From),
	Table = State#state.ets_table,
	ets:insert(Table, {From, erlang:now(), PingData}),
	do_other_stuff(),
	{reply, ok, State}.

This approach means that your client's process calls
call_and_link and waits for a response.  During the
response, gen_server:call runs in the client's process
and sends a message to the gen_server process which
triggers the Module:handle_call method to execute.
When it executes, the From id of the client process
is linked to the server, the ets table kept in the state is
updated, and 'ok' is sent back to the gen_server:call
running in the client process and it is returned as the
result of the call_and_link function.

You could do the same thing with gen_server:cast and
handle_cast if you expect do_other_stuff() to take a
long time, with the handle_cast function calling
gen_server:reply before returning {noreply, State}.

You will see the EXIT message in handle_info when
a linked process dies:

handle_info({'EXIT', Pid, Reason}, State when pid(Pid) ->
	Table = State#state.ets_table,
	ets:delete(Table, Pid),
	{noreply, State}.

 > But it occured to me, gen_server:call/2 links to the
 > gen_server process, sends the message, and waits
 > for the response with a timeout. It then unlinks from
 > the gen_server.

I believe it only _monitors_ the process and then
_demonitors_ it.  This is so it can see if the node is
'DOWN', but AFAIK that is different than linking to
the process.

jay



More information about the erlang-questions mailing list