couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kocol...@apache.org
Subject svn commit: r776031 - /couchdb/trunk/src/couchdb/couch_rep.erl
Date Mon, 18 May 2009 18:11:09 GMT
Author: kocolosk
Date: Mon May 18 18:11:09 2009
New Revision: 776031

URL: http://svn.apache.org/viewvc?rev=776031&view=rev
Log:
first crack at binary backoff for failed replicator requests

Modified:
    couchdb/trunk/src/couchdb/couch_rep.erl

Modified: couchdb/trunk/src/couchdb/couch_rep.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_rep.erl?rev=776031&r1=776030&r2=776031&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_rep.erl (original)
+++ couchdb/trunk/src/couchdb/couch_rep.erl Mon May 18 18:11:09 2009
@@ -403,14 +403,14 @@
     {Name, {Type, {RcvFun, Length}}}.
 
 make_attachment_stub_receiver(Url, Headers, Name, Type, Length) ->
-    make_attachment_stub_receiver(Url, Headers, Name, Type, Length, 10).
+    make_attachment_stub_receiver(Url, Headers, Name, Type, Length, 10, 1000).
 
-make_attachment_stub_receiver(Url, _Headers, _Name, _Type, _Length, 0) ->
+make_attachment_stub_receiver(Url, _Headers, _Name, _Type, _Length, 0, _Pause) ->
     ?LOG_ERROR("streaming attachment request failed after 10 retries: ~s", 
         [Url]),
     exit({attachment_request_failed, ?l2b(["failed to replicate ", Url])});
     
-make_attachment_stub_receiver(Url, Headers, Name, Type, Length, Retries) ->
+make_attachment_stub_receiver(Url, Headers, Name, Type, Length, Retries, Pause) ->
     %% start the process that receives attachment data from ibrowse
     #url{host=Host, port=Port} = ibrowse_lib:parse_url(Url),
     {ok, Conn} = ibrowse:spawn_link_worker_process(Host, Port),
@@ -420,22 +420,37 @@
     Opts = [{stream_to, Pid}, {response_format, binary}],
     ReqId = 
     case ibrowse:send_req_direct(Conn, Url, Headers, get, [], Opts, infinity) of
-        {ibrowse_req_id, X} -> X;
-        {error, Reason} ->
-            exit({attachment_request_failed,
-                ?l2b(["ibrowse error on ", Url, " : ", atom_to_list(Reason)])})
+    {ibrowse_req_id, X} -> 
+        X;
+    {error, Reason} ->
+        ?LOG_INFO("retrying couch_rep attachment request in ~p " ++
+            "seconds due to {error, ~p}: ~s", [Pause/1000, Reason, Url]),
+        catch ibrowse:stop_worker_process(Conn),
+        timer:sleep(Pause),
+        make_attachment_stub_receiver(Url, Headers, Name, Type, Length,
+            Retries-1, 2*Pause)
     end,
     
     %% tell our receiver about the ReqId it needs to look for
     Pid ! {self(), {set_req_id, ReqId}},
-    receive {Pid, {ok, ReqId}} -> ok end,
+    receive 
+    {Pid, {ok, ReqId}} -> 
+        ok;
+    {'EXIT', Pid, _Reason} ->
+        catch ibrowse:stop_worker_process(Conn),
+        timer:sleep(Pause),
+        make_attachment_stub_receiver(Url, Headers, Name, Type, Length,
+            Retries-1, 2*Pause)
+    end,
     
     %% wait for headers to ensure that we have a 200 status code
     %% this is where we follow redirects etc
     Pid ! {self(), gimme_status}, 
     receive
     {'EXIT', Pid, attachment_request_failed} ->
-        make_attachment_stub_receiver(Url, Headers, Name, Type, Length, Retries-1);
+        catch ibrowse:stop_worker_process(Conn),
+        make_attachment_stub_receiver(Url, Headers, Name, Type, Length,
+            Retries-1, Pause);
     {Pid, {status, StreamStatus, StreamHeaders}} -> 
         ?LOG_DEBUG("streaming attachment Status ~p Headers ~p",
             [StreamStatus, StreamHeaders]),
@@ -462,8 +477,9 @@
             Pid ! {self(), stop_ok},
             RedirectUrl = mochiweb_headers:get_value("Location", 
                 mochiweb_headers:make(StreamHeaders)),
-            make_attachment_stub_receiver(RedirectUrl, Headers, Name, Type, Length, 
-                Retries - 1);
+            catch ibrowse:stop_worker_process(Conn),
+            make_attachment_stub_receiver(RedirectUrl, Headers, Name, Type,
+                Length, Retries - 1, Pause);
         ResponseCode >= 400, ResponseCode < 500 -> 
             % an error... log and fail
             ?LOG_ERROR("streaming attachment failed with code ~p: ~s", 
@@ -472,10 +488,13 @@
             exit(attachment_request_failed);
         ResponseCode == 500 ->
             % an error... log and retry
-            ?LOG_INFO("retrying streaming attachment request due to 500 error: ~s", [Url]),
+            ?LOG_INFO("retrying couch_rep attachment request in ~p " ++ 
+                "seconds due to 500 response: ~s", [Pause/1000, Url]),
             Pid ! {self(), fail},
+            catch ibrowse:stop_worker_process(Conn),
+            timer:sleep(Pause),
             make_attachment_stub_receiver(Url, Headers, Name, Type, Length, 
-                Retries - 1)
+                Retries - 1, 2*Pause)
         end
     end.
 
@@ -588,15 +607,15 @@
     do_http_request(Url, Action, Headers, []).
 
 do_http_request(Url, Action, Headers, JsonBody) ->
-    do_http_request(Url, Action, Headers, JsonBody, 10).
+    do_http_request(Url, Action, Headers, JsonBody, 10, 1000).
 
-do_http_request(Url, Action, Headers, Body, Retries) when is_binary(Url) ->
-    do_http_request(?b2l(Url), Action, Headers, Body, Retries);
-do_http_request(Url, Action, _Headers, _JsonBody, 0) ->
+do_http_request(Url, Action, Headers, Body, Retries, Pause) when is_binary(Url) ->
+    do_http_request(?b2l(Url), Action, Headers, Body, Retries, Pause);
+do_http_request(Url, Action, _Headers, _JsonBody, 0, _Pause) ->
     ?LOG_ERROR("couch_rep HTTP ~p request failed after 10 retries: ~s", 
         [Action, Url]),
     exit({http_request_failed, ?l2b(["failed to replicate ", Url])});
-do_http_request(Url, Action, Headers, JsonBody, Retries) ->
+do_http_request(Url, Action, Headers, JsonBody, Retries, Pause) ->
     ?LOG_DEBUG("couch_rep HTTP ~p request: ~s", [Action, Url]),
     Body =
     case JsonBody of
@@ -622,18 +641,21 @@
         ResponseCode >= 300, ResponseCode < 400 ->
             RedirectUrl = mochiweb_headers:get_value("Location", 
                 mochiweb_headers:make(ResponseHeaders)),
-            do_http_request(RedirectUrl, Action, Headers, JsonBody, Retries-1);
+            do_http_request(RedirectUrl, Action, Headers, JsonBody, Retries-1,
+                Pause);
         ResponseCode >= 400, ResponseCode < 500 -> 
             ?JSON_DECODE(ResponseBody);        
         ResponseCode == 500 ->
-            ?LOG_INFO("retrying couch_rep HTTP ~p request due to 500 error: ~s",
-                [Action, Url]),
-            do_http_request(Url, Action, Headers, JsonBody, Retries - 1)
+            ?LOG_INFO("retrying couch_rep HTTP ~p request in ~p seconds " ++ 
+                "due to 500 error: ~s", [Action, Pause/1000, Url]),
+            timer:sleep(Pause),
+            do_http_request(Url, Action, Headers, JsonBody, Retries - 1, 2*Pause)
         end;
     {error, Reason} ->
-        ?LOG_INFO("retrying couch_rep HTTP ~p request due to {error, ~p}: ~s", 
-            [Action, Reason, Url]),
-        do_http_request(Url, Action, Headers, JsonBody, Retries - 1)
+        ?LOG_INFO("retrying couch_rep HTTP ~p request in ~p seconds due to " ++ 
+            "{error, ~p}: ~s", [Action, Pause/1000, Reason, Url]),
+        timer:sleep(Pause),
+        do_http_request(Url, Action, Headers, JsonBody, Retries - 1, 2*Pause)
     end.
 
 ensure_full_commit(#http_db{uri=DbUrl, headers=Headers}) ->



Mime
View raw message