[erlang-questions] Generic server and selective receives
Siraaj Khandkar
siraaj@REDACTED
Mon Feb 17 08:40:44 CET 2014
With gen_server, you have no choice but to handle a message. Once you
have it, you can defer processing by stashing it in your process' state.
If you want to reject messages when client_pid=undefined, then you may
want to consider a protocol with receipt acknowledgements, notifying the
sender if the message was accepted or discarded.
On 2/16/14, 6:55 PM, ludovic@REDACTED wrote:
> Hi,
>
> I would like some help to implement a message-buffer in erlang. This
> process can be sent messages, and stores them in mailbox. A buffer can
> have one client, or can have no client. When there's no client, I
> would prevent the process to do anything but accept a new client or
> timeout after a small amount of time. So I have two sets of receive
> clauses.
>
> Now, I would like to implement this as a gen_server. But I don't know
> how. The Idea is to timeout quickly if no message of the expected
> clauses-set comes.
>
> * I thought of a gen_fsm but it will crash if it's sent a message when
> in the "no client" state, right ? (Plus i may want to handle more
> receive clauses in the "no client" part)
> * I thougt about time calculations but it's seems too complicated for
> no reason ; I prefer use the simple gen_* timeouts.
> * I could keep my current implementation and adapt the module to fit
> in a supervision tree but I believe I willll miss common OTP features.
>
> So, I hope this is a common pattern and that someone will tell me a
> good solution.
>
> Thank you.
>
> -- lud
>
> This is my current implementation (but not the actual code).
>
> loop(#state{client_pid=undefined}) ->
> receive
> {set_client,Pid} ->
> loop(State#state{client_pid=Pid})
> after 10000 ->
> io:fwrite("Terminating\n")
> end;
>
> loop(State=#state{client_pid=Client,mailbox=Mailbox}) ->
> receive
> {set_client,Pid} ->
> %% here we can change the client or set it to undefined
> loop(State#state{client_pid=Pid});
> {message,M} ->
> Client ! you_have_messages,
> loop(State#state{mailbox=[M|Mailbox]});
> %% A handful of other clauses
> ...
> ...
> ...
> after way more time than 1000 ->
> io:fwrite("Terminating too\n")
> end;
>
>
> Now i'll pray for this mail to be seen in the current huge amount of
> emails (and very intersting by the way) on the list.
More information about the erlang-questions
mailing list