[erlang-questions] using guards in gen_server

Mazen Harake <>
Mon Aug 30 09:38:08 CEST 2010


  I have as a design principal to never crash inside a gen_server if it 
is a central process. I.e. If the process that is handling these calls 
is some how serving many other processes or is somehow in a "central" 
position then it should be avoided to crash (in general). The reason for 
this is that you shouldn't let one process bring down a central one 
because it will (potentially) propagate to other processes (by calling a 
server that is crashing and/or restarting etc). Note, however, that this 
does not mean that I put useless checks everywhere in the gen_server to 
keep it from crashing but rather treat all data as "safe" as long as I 
have allowed it inside.

I agree that it doesn't seem right to crash inside the gen_server in 
this case and I believe that in general it is best to crash the caller. 
If you have checked the caller at the API function you can (should!) 
assume that it is safe to continue without checking your data.

Sometimes it is the case (as Ulf mentions) that you can't know if the 
call is correct until you are "in" the gen_server but I would argue that 
these tend to be side-effect-based (I'm not sure that is correct English 
:P) and in general should be treated differently then type errors (as 
Robert mentions). In the case of the OP I would suggest the first variant.

/Mazen

On 29/08/2010 18:29, Robert Virding wrote:
> It depends on where you want the error caught and what is to be done.
>
> If you put the guard in the API then the caller will crash, or if you
> add an extra clause return some for of error. I would most definitely
> let it crash as it a clear programming error if it happens.
>
> If you put the guard in the server then the server will crash or the
> error will have to be handled there. This doesn't seem right in this
> case but it does depend on what is right for the application.
>
> It all comes back to the central problem with errors: where are they
> to be detected and "handled". And this is very application dependent.
> I personally feel that type errors, like this one, should be caught as
> early as possible and generate and exception as they are usually
> caused by programming errors.
>
> Robert
>
> On 29 August 2010 11:20, Zvi<>  wrote:
>> Hi,
>>
>> When writing gen_server, do you put validation guards in API functions
>> or in handle_call / cast or in both ? What's the convention?
>>
>> For example:
>>
>> send(Pid) when is_pid(Pid) ->
>>    gen_server:call(?SERVER, {send, Pid}).
>>
>> handle_call({send, Pid}, _From, _State) ->
>>    Resp = do_send(Pid),
>>    {reply,  Resp, State}.
>>
>> OR:
>>
>> send(Pid) ->
>>    gen_server:call(?SERVER, {send, Pid}).
>>
>> handle_call({send, Pid}, _From, _State) when is_pid(Pid) ->
>>    Resp = do_send(Pid),
>>    {reply,  Resp, State}.
>>
>> OR:
>>
>> send(Pid) when is_pid(Pid) ->
>>    gen_server:call(?SERVER, {send, Pid}).
>>
>> handle_call({send, Pid}, _From, _State) when is_pid(Pid) ->
>>    Resp = do_send(Pid),
>>    {reply,  Resp, State}.
>>
>> ________________________________________________________________
>> erlang-questions (at) erlang.org mailing list.
>> See http://www.erlang.org/faq.html
>> To unsubscribe; mailto:
>>
>>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:
>



More information about the erlang-questions mailing list