[erlang-questions] Frequent crashes in inets http client (R12B-5)
Oscar Hellström
oscar@REDACTED
Fri Jun 5 16:42:34 CEST 2009
Not to start a flame war, but I would stay away from the inets http
client if I were trying to build something serious. You can find my
reasons here:
http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:43806:200905:gocblgddeplfolmoleep
Best regards
Chris Newcombe wrote:
> Is there a patch for the following issue?
>
>
>
> It was reported a while ago:
> http://groups.google.com/group/erlang-programming/browse_thread/thread/4c497978c75ed6a9/18d9a242df81ba3a?lnk=gst&q=badrecord#18d9a242df81ba3a(but
> I didn't see any replies)
>
>
>
> Here's a bit more detail:
>
>
>
> httpc_handler is crashing with
>
>
>
> {badrecord,request}
>
>
>
> (BTW it would be great if badrecord errors also contained the incorrect
> term, not just the name of the expected record type)
>
>
>
> It’s crashing in
>
>
>
> httpc_handler,handle_info,2
>
>
>
> The last message received by the gen_server is
>
>
>
> {timeout,#Ref<0.0.0.9038>}
>
>
>
> The gen_server #state is
>
>
>
>
> {state,undefined,{tcp_session,{{"my-test-url",8080},<0.709.0>},false,http,#Port<0.1351>,1},undefined,undefined,undefined,undefined,{[],[]},pipeline,[#Ref<0.0.0.5834>],nolimit,nolimit,{options,{undefined,[]},20000,1,100,disabled,enabled,false},{timers,[],#Ref<0.0.0.19293>}
>
>
>
> I think the relevant element is the first one (request).
>
> i.e. request == undefined
>
>
>
> Given the message, it seems almost certain that the crash is in the second
> timeout clause of handle_info,
>
> (marked below with ***).
>
> This clause will fire even if request == undefined, but will try to use
> Request#request.from, which crashes with {badrecord,request}
>
>
>
> %%% Timeouts
>
> %% Internaly, to a request handling process, a request time out is
>
> %% seen as a canceld request.
>
> handle_info({timeout, RequestId}, State =
>
> #state{request = Request = #request{id = RequestId}}) ->
>
> httpc_response:send(Request#request.from,
>
> httpc_response:error(Request,timeout)),
>
> {stop, normal,
>
> State#state{canceled = [RequestId | State#state.canceled],
>
> request = Request#request{from = answer_sent}}};
>
>
>
> *** handle_info({timeout, RequestId}, State = #state{request = Request})
> ->
>
> httpc_response:send(Request#request.from,
>
> httpc_response:error(Request,timeout)),
>
> {noreply, State#state{canceled = [RequestId |
> State#state.canceled]}};
>
>
>
> handle_info(timeout_pipeline, State = #state{request = undefined}) ->
>
> {stop, normal, State};
>
>
>
> It looks like State#state.request is being set to undefined without
> cancelling an in-progress request timer.
>
>
> I've only glanced at the code, but both of the following clauses appear to
> do that.
>
> (But it could easily be something else.)
>
>
>
> %% On a redirect or retry the current request becomes
>
> %% obsolete and the manager will create a new request
>
> %% with the same id as the current.
>
> {redirect, NewRequest, Data}->
>
> ok = httpc_manager:redirect_request(NewRequest, ProfileName),
>
> handle_pipeline(State#state{request = undefined}, Data);
>
> {retry, TimeNewRequest, Data}->
>
> ok = httpc_manager:retry_request(TimeNewRequest, ProfileName),
>
> handle_pipeline(State#state{request = undefined}, Data);
>
>
>
> thanks,
>
>
>
> Chris
>
>
--
Oscar Hellström, oscar@REDACTED
Office: +44 20 7655 0337
Mobile: +44 798 45 44 773
Erlang Training and Consulting Ltd
http://www.erlang-consulting.com/
More information about the erlang-questions
mailing list