вернуть {noreply,NewState} и потом позвать gen_server:reply/2. С этим всё понятно. Я правильно понимаю, что нет способа узнать, ждут ещё ответ, или gen_server:call уже завершился по таймауту?
кстати хороший вопрос. Ведь теперь есть алиасы пидов, так что можно сделать очень плохое — подсмотреть в структуру {From, Ref} и попробовать проверить, живой From или уже нет
можно глянуть жив ли процесс что запросил, но в целом нет.
Но процесс может быть жив, просто расстроился и пошёл другие дела делать
Способа узнать нет. А зачем так делать вообще? У gen_server есть же send_request, который вообще на стороне клиента способен асинхронно ожидать ответа
это его проблемы, отошли ему результат работы, в случае чего это задача получателя отфильтровать ответ который ему уже не интересен
Там после таймаута алиас обнуляется же, может можно это проверить
https://github.com/erlang/otp/blob/master/lib/stdlib/src/gen.erl#L230 да, там везде self(), не проверишь
Так а от этой проверки смысла всё равно нет. Если проверишь, а потом пошлёшь ответ, то между проверкой процесс уже может и перестать ждать
можно ещё reply позвать до таймаута, а сообщение придет позже
А почему плохо отправить ответ в любом случае?
В норме вызывающий должен сдохнуть. Т.е. по идее ты перед тяжелой работой можешь спросить его состояние и мы так кое где делаем.
если вдруг вычисление ответа тяжелая операция
плохо не отправить, плохо начать делать что-то, если HTTP клиент уже отвалился
Звучит логично, но тогда видимо прямой gencall не проходит, и можно спавнить слинкованные процессы
Чтобы не задаваться такими вопросами теперь можно пользоваться парой send_request/receive_response. Они на алиасах, позволяют таймаут без exit и чистят алиас после себя, так что безопасно.
А ещё можно с запросом слать атомик, который по мере выполнения долгой работы чекать - если там выставят значение, например 1 - это отмена, прекращаем считать
Обсуждают сегодня