Vineet,
Using standard OTP behaviours for handling processes is not a bad practice.
It helps to always have unified predictable behaviour of the processes you spawn.
I will just enumerate several examples hoping those would be helpful for you:
* process A queries process B for something:
[in A]
{ok, Result} = gen_server:call( B, {request, Something}, CallTimeout ).
* procerss A asks B to do something but does not expect any response on this action:
[in A]
ok = gen_server:cast( B, {ack, ID} ).
* process A queries B for some results.
Yet the query cannot be satisfied but will be once some event will be reported to B
[in A]
it_occurred = gen_server:call( B, i_will_wait_for_a_while, infinity ).
[in B]
handle_call( i_will_wait_for_a_while, From, State = #s{ reply_queue = Q } ) ->
{no_reply, State #s{reply_queue = queue:in( From , Q )} };
…
handle_cast( the_event_i_told_you_about, State = #s{ reply_queue = Q }) ->
{ReplyTo, NewQ} = queue:out( Q ),
_Ignored = gen_server:reply( ReplyTo, it_occured ),
{no_reply, State #s{ reply_queue = NewQ }};
...
In this very case it's probably better to think about employing gen_fsm behaviour - to handle the states like probably 'starving', 'caught_up', 'lagging' etc…
* Say we are handling some named resources each with one process.
A client code if wants to interact with the resource needs to get the pid of the process owning the resource.
A client code knows the name of the resource only.
resource_owner.erl:
maybe_start_resource_owner( ResourceName ) ->
case catch supervisor:start_link( resource_owners_sup , { ResourceName }) of
{ ok, Pid } -> ok;
ignore -> ok
end.
init({ ResourceName }) ->
case catch gproc:add_local_name( {resource_owner, ResourceName} ) of
true ->
{ok, #s{ resource_name = ResourceName }};
_ ->
ignore
end.
client_code.erl:
get_owner_pid_by_resource_name( ResourceName ) ->
ok = resource_owner:maybe_start_resource_owner( ResourceName ),
{ResourceOwnerPid, _} = gproc:await( {n, l, {resource_owner, ResourceName} } ),
{ok, ResourceOwnerPid}.
The main moral here - use the standard behaviours when spawning your processes.
The OTP team has solved most of the potential problems for you already :)
--
RG