Что происходит в Erlang, если квитанция о вручении не приходит?

Я случайно прочитал диссертацию Джо Армстронга и не очень хорошо разбирался в Erlang. Интересно, что будет, если квитанция о доставке какого-то сообщения так и не придет. Что делает отправляющий актер? Он отправляет сообщение в другой раз? Это может сбить с толку актера-получателя, когда он получит то же сообщение в другой раз. Он должен иметь возможность сказать, что его получение не было получено, и поэтому второе сообщение недействительно.

Подобные проблемы всегда удерживали меня от решений, в которых доставка сообщений не является транзакционной. Думаю, я знаю ответ: отправляющий субъект сообщает своему контролирующему субъекту, что что-то должно быть не так, если он не получил квитанцию ​​в разумные сроки, заставляя супервизор предпринять какие-то действия (например, перезапустить задействованных акторов или что-то в этом роде). Это правильно? Я не вижу другого решения, которое не привело бы к теоретически возможным бесконечным отправкам сообщений.

Спасибо за любой ответ, Оливер


person OlliP    schedule 05.07.2013    source источник


Ответы (1)


В Erlang отправитель сообщения обычно забывает его сразу после отправки и продолжает свою работу. если приложению требуется подтверждение получения сообщения, вы должны создать свой собственный протокол (или использовать существующий). Для этого есть много веских причин.

Во-первых, это рукопожатие в большинстве случаев не требуется. Более высокий риск того, что сообщение будет проигнорировано, состоит в том, что процесс получения больше не существует или тем временем умер, а у отправителя в этом случае очень мало шансов сделать что-нибудь интересное.

Кроме того, рукопожатие является блокирующим действием, поэтому это влияет на производительность и риск тупиковой ситуации.

Подтверждение также должно быть сообщением, но это не должно быть подтверждено, иначе вы создадите бесконечный цикл сообщений. Только приложение может знать, что делать (например, использовать отправку с подтверждением или нет), и действительно легко написать такую ​​функцию (или использовать поведение, которое ее реализует). Например:

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,
    ...

приложив немного усилий, можно даже делегировать исследование доставки сообщений новому процессу - не блокируя проверку - и, используя связанный процесс, принудительно завершить работу отправителя, если истечет время ожидания.

person Pascal    schedule 05.07.2013
comment
Спасибо, что поделились своими знаниями. Вы знаете, есть ли какой-нибудь документ / книга, в которых упоминаются передовые методы работы с подобными вещами? - person OlliP; 05.07.2013
comment
Мой любимый источник информации - Learnyousomeerlang.com, официальная документация полезна для получения информации, когда вы знаете, что ищете за. У вас также есть книги: программирование на эрланге Франческо Чезарини и Саймона Томпсона; Erlang и OTP в действии Мартина Логана, Эрика Меритта и Ричарда Карлссона. Наконец, мне понравилась еще небольшая серия скринкастов - из-за прогрессивного подхода (Кевин Смит: прагматичные скринкасты) - person Pascal; 05.07.2013