[erlang-questions] net_kernel:handle_call

bile <>
Sun Feb 21 23:43:02 CET 2010


Your example is fine... but doesn't represent what is happening here.
Your code would cause the client to error... net_kernel, the server, is
dying in this case. We are talking about a major component of the
system which will bring down the entire system if you happen to send it
a message it doesn't understand. Kernel_sup is setup to die should any
of it's children die and that brings down BEAM. rex is in the same pool
of services yet it just ignores the messages and refuses to reply. As
do others. Behaviors are inconsistent and in some cases contradictory.
Like rex having a public stop function that due to being configured in
kernel_sup as permanent leads to the entire system going down should
you stop it. And this for an ultimately optional component. Don't reply
or reply with an error, crash or ignore. They have different strengths
and weaknesses... but pick a paradigm and use it consistency. Generally
you want general components to be flexible and stable. Currently some of
these base services are neither.

I've submitted some patches to clean up a few of these inconsistencies
but I've yet to hear any comments on them.


On Sun, 21 Feb 2010 17:13:52 -0500
Vance Shipley <> wrote:

> On Fri, Feb 19, 2010 at 11:23:08AM -0500, Musumeci, Antonio S wrote:
> }  While not directly comparable... in other languages when you ask 
> }  for an invalid service (method, function, etc) the caller not the 
> }  called errors.
> 
> The proper thing to do when a server receives an incorrect
> call depends on the relationship between the server and the
> client.
> 
> The Erlang way of handling programming errors is to fail
> immediately and leave a stack trace pointing directly at
> the problem so that someone can fix the code.  So if your
> client and server are two parts of a single program you would
> want to have no clause to handle an unknown call.
> 
> On the other hand if the server repesents a service access
> point and the client is a user of that service from another
> program you would want to guard against it's errors.  I use
> the following:
> 
>     %% @spec (SAP, Request) -> ok
>     %%    SAP = Name | {Name,Node} | {global,GlobalName} | pid()
>     %%    Node = atom()
>     %%    GlobalName = term()
>     %%    Request = term()
>     %%
>     %% @doc Public API function for a service request.
>     %%
>     call(SAP, Request) ->
>          case gen_server:call(SAP, Request) of
>              {ok, Result} ->
>                  Result;
>              {error, Reason} ->
>                  exit(Reason)
>          end.
> 
>     %% @spec (Request, From, State) -> Result
>     %%     Request = term()
>     %%     From = {pid(), Tag}
>     %%     State = term()
>     %% @doc Private callback to handle a request sent with call/2.
>     %%
>     handle_call(Request, _, State) ->
>         ...
>         {reply, {ok, Result}, State};
>     handle_call(Other, _, State) ->
>         {reply, {error, badarg}, State}.
> 
> 
> I have in the past used something like this:
> 
>     handle_call(Other, {Pid, _Tag}, State) ->
>         exit(Pid, badarg),
>         {noreply, State}.
> 
> ... however I've come to find the former more appropriate.
> 



More information about the erlang-questions mailing list