gen_server:cast/2 vs !

Vance Shipley vances@REDACTED
Sat Oct 4 07:36:17 CEST 2003

On Sat, Oct 04, 2003 at 02:24:56AM +0100, Sean Hinde wrote:
}  I like to use the convention that cast messages to this process are 
}  only sent using the API of this gen_server module:

I'm wondering about more functional differences.  Beyond the code
maintenance aspects how will it behave differently.

}  -module(my_server).
}  -export([send_async_req/2).
}  send_async_req(Pid, Req) ->
}  	gen_server:cast(Pid, Req).

How would it behave differently if you coded it as:


send_async_req(Pid, Req) ->
     Pid ! Req.

I'm thinking about things like SASL.

There are two schools of thought with APIs.  One has the underlying 
messages hidden behind function calls as in your example.  The other 
makes the messages the API.  In my current project I'm implementing
some OSI layers in Erlang.  I want to keep them independent of each
other so you can reuse them and rearrange them.  To do this I'm
providing the "service primitives" as Erlang messages:

   {'N', 'UDATA', request, {CalledPartyAddress, CallingPartyAddress,
         QualityOfServiceParameterSet, UserData}}

This has the major benefit of being already documented.  If you're
reading the specification you will understand what the above is and
how the parameters are encoded.  The API which is used between OSI
layer services is a message passing one so it suits my purposes to
maintain them as such rather than having a unitdata_request/4 function.

Now I'm asking myself if I should have users of a service send service
primitives directly or with a cast.

   gen_server:cast(Pid, {'N', 'UDATA', request, {CalledPartyAddress,
         CallingPartyAddress, QualityOfServiceParameterSet, UserData})

That's not quite as clear as:

   Pid ! {'N', 'UDATA', request, {CalledPartyAddress,
         CallingPartyAddress, QualityOfServiceParameterSet, UserData}

But I can live with it if it's for a purpose.


More information about the erlang-questions mailing list