gen_server не получает сообщения после вызова httpc

У меня есть один процесс, который отправляет сообщение о паузе на gen_server следующим образом:

Results = [gen_server:cast(Child, pause) || 
      {Id, Child, _Type, _Modules} <- supervisor:which_children(?SERVER),
      ?IGNORE(Id) == false],

В моем gen_server я перехватываю эти сообщения в своем handle_cast следующим образом:

handle_cast(pause, #state{task=#task{server=Serv, 
                 service=Srv, 
                 description=Desc}}=State) ->
    lager:info("Suspending ~s, ~s, ~s.",[Serv, Srv, Desc]),
    {noreply, State#state{suspended=true}};

handle_cast(Msg, State) ->
    lager:error("Url Poller received unexpected cast message: ~p",[Msg]),
    {noreply, State}.

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

Любые идеи о том, что может происходить?

gen_server очень прост, он использует erlang:send_after/3 для отправки самого себе сообщения «опрос». После получения этого сообщения опроса, если оно не приостановлено, оно переходит по URL-адресу, сохраняет ответ в ETS и запускает другой erlang:send_after/3 для повторного опроса через соответствующий интервал. Если он приостановлен, он просто запускает другой erlang:send_after?3

Все, что делает пауза, это устанавливает состояние paused = true

Используя наблюдатель, зависший процесс показывает, что текущая функция — httpc:handle_answer и что очередь сообщений резервируется.

Вкладка Sate: информация "Время ожидания истекло" Совет "системные сообщения, вероятно, не обрабатываются этим процессом"

верхняя часть трассировки стека показывает httpc:handle_answer httpc.erl:636


person Jr0    schedule 04.03.2014    source источник
comment
Вы уверены, что процесс все еще существует? что делает макрос ?IGNORE?, возможно ли, что процесс ожидает вечно в синхронном вызове?   -  person Pascal    schedule 04.03.2014
comment
Он все еще существует, supervisor:what_children перечисляет дочерние элементы, и дочерние элементы могут быть впоследствии уничтожены с помощью supervisor:terminate. Кроме того, весь макрос ?IGNORE проверяет, находится ли идентификатор в списке дочерних элементов, которые никогда не должны быть приостановлены.   -  person Jr0    schedule 04.03.2014
comment
Использовали ли вы такой инструмент, как appmon, для проверки состояния процесса?   -  person Pascal    schedule 05.03.2014
comment
Добавил в ОП то, что я видел с Observer   -  person Jr0    schedule 05.03.2014


Ответы (2)


Я взял код httpc:handle_answer из github erlang. HTTP-клиент otp inets:

(Примечание: это не та версия, что у вас, так как функция переходит из строки 616 в строку 631)

handle_answer(RequestId, false, _) ->
    {ok, RequestId};
handle_answer(RequestId, true, Options) ->
    receive
        {http, {RequestId, saved_to_file}} ->
            ?hcrt("received saved-to-file", [{request_id, RequestId}]),
            {ok, saved_to_file};
        {http, {RequestId, {_,_,_} = Result}} ->
            ?hcrt("received answer", [{request_id, RequestId},
                                      {result, Result}]),
            return_answer(Options, Result);
        {http, {RequestId, {error, Reason}}} ->
            ?hcrt("received error", [{request_id, RequestId},
                                     {reason, Reason}]),
            {error, Reason}
    end.

Итак, процесс ожидает сообщения (пришедшего после вызова httpc_manager:request(Request, profile_name(Profile), который вернул {ok, RequestId}), а это сообщение не приходит или имеет неправильный формат. Можете ли вы проверить значения параметров и очередь сообщений?

person Pascal    schedule 05.03.2014
comment
HTTP-запрос не возвращается и застревает в получении. В моем клиенте я использовал тайм-аут httpc по умолчанию, который равен бесконечности. Я изменил это на 30000, и я думаю, что это решило проблему. - person Jr0; 05.03.2014

заголовки, которые содержали значение, отличное от строки, вызывали выход из httpc_handler. Но после этого вызывающий абонент навсегда завис на «получении» в httpc:handle_answer/3, поскольку вызывающему абоненту не было отправлено никакого сообщения.

вы можете проверить с этим

Request1= {"http://www.google.com",[{"cookie",undefined}, {"test",123}],"application/x-www-form-urlencoded; charset=utf-8", <<"">>}.
httpc:request(post, Request1, [{timeout,1000}], []).
person Alexander Shavelev    schedule 27.08.2018
comment
поздний ответ, но сегодня была эта проблема :) - person Alexander Shavelev; 27.08.2018