1

我有一个进程向 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 向自己发送“poll”消息。收到此轮询消息后,如果没有暂停,它会点击一个 url 并将响应保存到 ETS 并触发另一个 erlang:send_after/3 在适当的时间间隔后再次轮询。如果它暂停,它只会触发另一个 erlang:send_after?3

所有 pause 都将状态设置为 paused = true

使用观察者,卡住的进程显示当前函数是 httpc:handle_answer 并且消息队列正在备份

状态选项卡:信息“超时”提示“系统消息可能未被此进程处理”

堆栈跟踪的顶部显示 httpc:handle_answer httpc.erl:636

4

2 回答 2

0

我从github erlang otp inets http client中选择了 httpc:handle_answer 的代码:

(注意:它与您的版本不同,因为该函数从第 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} 的调用之后到来),这个消息没有到来或者它的格式错误。你能检查参数和消息队列的值吗?

于 2014-03-05T17:08:43.093 回答
0

包含字符串以外的值的标头导致 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}], []).
于 2018-08-27T11:35:52.053 回答