From 7be616679cefe6850e9ba7ab0d46b5a9880e5fae Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Mon, 1 Mar 2010 07:46:53 +0000 Subject: Undo accidental revert. Sorry for the mess SVN acted weird on me. Probably due to the LDAP infra issues. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@917411 13f79535-47bb-0310-9956-ffa450edef68 --- THANKS | 1 + src/couchdb/couch_rep_att.erl | 28 ++++++++++++++++++++++++++-- src/couchdb/couch_rep_changes_feed.erl | 6 ++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/THANKS b/THANKS index 78ea2418..c75d1353 100644 --- a/THANKS +++ b/THANKS @@ -50,5 +50,6 @@ suggesting improvements or submitting changes. Some of these people are: * Joel Clark * Matt Lyon * mikeal + * Randall Leeds For a list of authors see the `AUTHORS` file. diff --git a/src/couchdb/couch_rep_att.erl b/src/couchdb/couch_rep_att.erl index 6b576a01..ee4f0184 100644 --- a/src/couchdb/couch_rep_att.erl +++ b/src/couchdb/couch_rep_att.erl @@ -25,7 +25,11 @@ convert_stub(#att{data=stub, name=Name} = Attachment, qs = [{rev, couch_doc:rev_to_str({Pos,RevId})}] }, Ref = make_ref(), - RcvFun = fun() -> attachment_receiver(Ref, Request) end, + RcvFun = fun() -> + Bin = attachment_receiver(Ref, Request), + cleanup(), + Bin + end, Attachment#att{data=RcvFun}. cleanup() -> @@ -34,6 +38,8 @@ cleanup() -> %% TODO maybe log, didn't expect to have data here cleanup(); {ibrowse_async_response_end, _} -> + cleanup(); + {ibrowse_async_headers, _, _, _} -> cleanup() after 0 -> erase(), @@ -43,13 +49,27 @@ cleanup() -> % internal funs attachment_receiver(Ref, Request) -> - case get(Ref) of + try case get(Ref) of undefined -> {ReqId, ContentEncoding} = start_http_request(Request), put(Ref, {ReqId, ContentEncoding}), receive_data(Ref, ReqId, ContentEncoding); {ReqId, ContentEncoding} -> receive_data(Ref, ReqId, ContentEncoding) + end + catch + throw:{attachment_request_failed, timeout} -> + case {Request#http_db.retries, Request#http_db.pause} of + {0, _} -> + ?LOG_INFO("request for ~p failed", [Request#http_db.resource]), + throw({attachment_request_failed, max_retries_reached}); + {N, Pause} when N > 0 -> + ?LOG_INFO("request for ~p timed out, retrying in ~p seconds", + [Request#http_db.resource, Pause/1000]), + timer:sleep(Pause), + cleanup(), + attachment_receiver(Ref, Request#http_db{retries = N-1}) + end end. receive_data(Ref, ReqId, ContentEncoding) -> @@ -71,6 +91,8 @@ receive_data(Ref, ReqId, ContentEncoding) -> {ibrowse_async_response_end, ReqId} -> ?LOG_ERROR("streaming att. ended but more data requested ~p", [ReqId]), throw({attachment_request_failed, premature_end}) + after 31000 -> + throw({attachment_request_failed, timeout}) end. start_http_request(Req) -> @@ -84,6 +106,8 @@ start_http_request(Req) -> {ok, ContentEncoding, NewReqId} -> {NewReqId, ContentEncoding} end + after 10000 -> + throw({attachment_request_failed, timeout}) end. validate_headers(_Req, 200, Headers) -> diff --git a/src/couchdb/couch_rep_changes_feed.erl b/src/couchdb/couch_rep_changes_feed.erl index d6dd6d6a..343b445c 100644 --- a/src/couchdb/couch_rep_changes_feed.erl +++ b/src/couchdb/couch_rep_changes_feed.erl @@ -83,8 +83,7 @@ init([_Parent, #http_db{}=Source, Since, PostProps] = Args) -> resource = "_changes", qs = QS, conn = Pid, - options = [{stream_to, {self(), once}}, {response_format, binary}, - {inactivity_timeout, 31000}], % miss 3 heartbeats, assume death + options = [{stream_to, {self(), once}}, {response_format, binary}], headers = Source#http_db.headers -- [{"Accept-Encoding", "gzip"}] }, {ibrowse_req_id, ReqId} = couch_rep_httpc:request(Req), @@ -203,6 +202,9 @@ handle_info({'EXIT', From, Reason}, #state{changes_loop=From} = State) -> ?LOG_ERROR("changes_loop died with reason ~p", [Reason]), {stop, changes_loop_died, State}; +handle_info({'EXIT', _From, normal}, State) -> + {noreply, State}; + handle_info(Msg, State) -> ?LOG_DEBUG("unexpected message at changes_feed ~p", [Msg]), {noreply, State}. -- cgit v1.2.3