You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2010/02/27 00:43:38 UTC

svn commit: r916869 - in /couchdb/branches/0.11.x: THANKS src/couchdb/couch_rep_att.erl src/couchdb/couch_rep_changes_feed.erl

Author: jan
Date: Fri Feb 26 23:43:38 2010
New Revision: 916869

URL: http://svn.apache.org/viewvc?rev=916869&view=rev
Log:
Avoid replication task crashes by imporoving timeout handling.

Closes COUCHDB-597.

Patch by Randall Leeds.

Modified:
    couchdb/branches/0.11.x/THANKS
    couchdb/branches/0.11.x/src/couchdb/couch_rep_att.erl
    couchdb/branches/0.11.x/src/couchdb/couch_rep_changes_feed.erl

Modified: couchdb/branches/0.11.x/THANKS
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/THANKS?rev=916869&r1=916868&r2=916869&view=diff
==============================================================================
--- couchdb/branches/0.11.x/THANKS (original)
+++ couchdb/branches/0.11.x/THANKS Fri Feb 26 23:43:38 2010
@@ -50,5 +50,6 @@
  * Joel Clark <un...@yahoo.com>
  * Matt Lyon <ma...@flowerpowered.com>
  * mikeal <mi...@gmail.com>
+ * Randall Leeds <ra...@gmail.com>
 
 For a list of authors see the `AUTHORS` file.

Modified: couchdb/branches/0.11.x/src/couchdb/couch_rep_att.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_rep_att.erl?rev=916869&r1=916868&r2=916869&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_rep_att.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_rep_att.erl Fri Feb 26 23:43:38 2010
@@ -25,7 +25,11 @@
         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 @@
         %% 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 @@
 % 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 @@
     {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 @@
         {ok, ContentEncoding, NewReqId} ->
             {NewReqId, ContentEncoding}
         end
+    after 10000 ->
+        throw({attachment_request_failed, timeout})
     end.
 
 validate_headers(_Req, 200, Headers) ->

Modified: couchdb/branches/0.11.x/src/couchdb/couch_rep_changes_feed.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_rep_changes_feed.erl?rev=916869&r1=916868&r2=916869&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_rep_changes_feed.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_rep_changes_feed.erl Fri Feb 26 23:43:38 2010
@@ -40,7 +40,9 @@
     gen_server:start_link(?MODULE, [Parent, Source, StartSeq, PostProps], []).
 
 next(Server) ->
-    gen_server:call(Server, next_changes, infinity).
+    try gen_server:call(Server, next_changes, 31000)
+    catch exit:{timeout, _Reason} -> throw(changes_timeout)
+    end.
 
 stop(Server) ->
     gen_server:call(Server, stop).
@@ -83,8 +85,7 @@
         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),
@@ -202,6 +203,9 @@
     ?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}.