0

I just happened to read the thesis of Joe Armstrong and don't have much prior knowledge of Erlang. I wonder what happens if a delivery receipt for some message never arrives. What does the sending actor do? It sends the message another time? This could confuse the recipient actor when it receives the same message another time. It has to be able to tell that its receipt was not received and therefore the second message is void.

That kind of problems always kept me away from solutions where message delivery is not transactional. I think I know the answer: the sending actor tells its supervising actor that something must be wrong when it didn't obtain a receipt in reasonable time causing the supervisor to take some action (like restarting the involed actors or something). Is this correct? I see no other solution that doesn't result in theroretically possible infinite message sends.

Thanks for any answer, Oliver

OlliP
  • 1,545
  • 11
  • 22

1 Answers1

2

In Erlang, the sender of a message usually forget it immediately after sending it and continue its job. if an application need an acknowledge of the message reception, you have to build your own protocol (or use an existing one). There are many good reason for that.

One is that most of the time it is not necessary to have this handshake. The higher risk for a message to be ignored is that the receiving process does not exist anymore, or died in the mean time, and the sender in this case has very few chance to do some interesting stuff.

Also, the hand shake is a blocking action, so there is a performance impact, and a risk of deadlock.

The acknowledge should be also a message, but this one should not be acknowledged, otherwise you create a never ending loop of message. Only the application could know what to do (for example using a send with acknowledge or not) and it is really easy to write this kind of function (or use a behavior that implement it). For example:

send_with_ack(To,Mess,TimeOut,Ack) ->
    Ref = make_ref(),
    To ! {Mess,self(),Ref},
    receive
        {Ack,Ref} -> Ack
    after Timeout ->
        {error,timeout}
    end.



receiving_process() ->
    ...
     receive
        {Pattern_matching_Mess,From,Ref} ->
            do_something(),
            From ! {Ack,Ref}, %% Ack for this kind of message is known by the receiver
            do_somethingelse();
        Mess1 -> do_otherthing()
    end,
    ...

with little work, it is even possible to delegate the survey of message delivery to a new process - not blocking check - and using linked process, force a crash of the sender if the timeout is reached.

Pascal
  • 13,977
  • 2
  • 24
  • 32
  • Thanks for sharing your knowledge. Do you know whether there is some document/book that mentions best practices how to deal with that kind of things? – OlliP Jul 05 '13 at 13:23
  • My favorite source of information is http://learnyousomeerlang.com/, the official documentation is worth to get information when you know what you are looking for. You have also some books : programming erlang by Francesco Cesarini and Simon Thompson; Erlang and OTP in action by Martin Logan, Eric Meritt and Richard Carlsson. Finally I liked also a small series of screencasts - because of the progressive approach (by kevin smith: pragmatic screencasts) – Pascal Jul 05 '13 at 16:27