Linking to/from a gen_server?

Ulf Wiger etxuwig@REDACTED
Mon Mar 3 10:26:18 CET 2003


On Sun, 2 Mar 2003, Shawn Pearce wrote:

>Ok, so I'm trying to use OTP stuff as much as I can right
>now, as I haven't really learned it all yet.  :)

That's quite OK; I doubt that anyone can claim to master OTP
fully. (:

>I'm trying to setup a way to have a client process send a
>gen_server a message, where the gen_server stuffs a term
>and the client's pid into an ets table managed by the
>gen_server.  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.

This is _exactly_ the kind of work that erlang:monitor() was
designed for. You do not really want to do it with links,
precisely because of the unlinking problems (the client can
unlink, and the server won't notice; and the server may well
end up in a situation where it has "multiple links" to the
same client, and thus has to maintain a "virtual link
stack". This is all really messy with link.


>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.  This means the gen_server can't link to the
>client process during its handle_call/3 callback, as the
>unlink will be done by the client after the call completes.

Yes, see above, but, gen_server:call() uses monitor() and
demonitor(), which is stackable. It doesn't interfere with
other monitors.

>I could use gen_server:cast/2, but i do need a response to
>be sent back to the client so it knows the operation was
>successful.

If you want a response back, use call(). It is just
confusing to emulate calls with casts. The server can return
{noreply,S'} if it's not possible to respond immediately,
and then use gen_server:reply/2 later. Since
gen_server:reply/2 uses the pid of the caller, it is no big
disaster if you're not using monitors, and the client died
- the reply message will go into the bit bucket.

The big thing that link() can do and monitor() can't, is
cascading exits. Personally, I try as much as possible to
use lots of processes and not trap exits unless I absolutely
have to. This way, I can split a problem into as many
processes as the problem calls for (but not more than
that!), tie them together with links and rely on cascading
exits to clean up if there's a problem.

For monitoring the well-being of another process, I always
use monitor().

/Uffe
-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson AB, Connectivity and Control Nodes




More information about the erlang-questions mailing list