You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by fd...@apache.org on 2011/05/20 10:52:39 UTC

svn commit: r1125282 - in /couchdb/trunk: etc/couchdb/default.ini.tpl.in src/couchdb/couch_replication_manager.erl

Author: fdmanana
Date: Fri May 20 08:52:39 2011
New Revision: 1125282

URL: http://svn.apache.org/viewvc?rev=1125282&view=rev
Log:
Replication manager: allow max_replication_retry_count to be set to "infinity"

Modified:
    couchdb/trunk/etc/couchdb/default.ini.tpl.in
    couchdb/trunk/src/couchdb/couch_replication_manager.erl

Modified: couchdb/trunk/etc/couchdb/default.ini.tpl.in
URL: http://svn.apache.org/viewvc/couchdb/trunk/etc/couchdb/default.ini.tpl.in?rev=1125282&r1=1125281&r2=1125282&view=diff
==============================================================================
--- couchdb/trunk/etc/couchdb/default.ini.tpl.in (original)
+++ couchdb/trunk/etc/couchdb/default.ini.tpl.in Fri May 20 08:52:39 2011
@@ -153,6 +153,7 @@ compressible_types = text/*, application
 
 [replicator]
 db = _replicator
+; Maximum replicaton retry count can be a non-negative integer or "infinity".
 max_replication_retry_count = 10
 ; More worker processes can give higher network throughput but can also
 ; imply more disk and network IO.

Modified: couchdb/trunk/src/couchdb/couch_replication_manager.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_replication_manager.erl?rev=1125282&r1=1125281&r2=1125282&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_replication_manager.erl (original)
+++ couchdb/trunk/src/couchdb/couch_replication_manager.erl Fri May 20 08:52:39 2011
@@ -26,13 +26,15 @@
 
 -define(DOC_TO_REP, couch_rep_doc_id_to_rep_id).
 -define(REP_TO_STATE, couch_rep_id_to_rep_state).
--define(INITIAL_WAIT, 5).
+-define(INITIAL_WAIT, 2.5). % seconds
+-define(MAX_WAIT, 600).     % seconds
 
 -record(rep_state, {
     rep,
     starting,
     retries_left,
-    max_retries
+    max_retries,
+    wait = ?INITIAL_WAIT
 }).
 
 -import(couch_replicator_utils, [
@@ -102,9 +104,8 @@ init(_) ->
     ok = couch_config:register(
         fun("replicator", "db", NewName) ->
             ok = gen_server:cast(Server, {rep_db_changed, ?l2b(NewName)});
-        ("replicator", "max_replication_retry_count", NewMaxRetries1) ->
-            NewMaxRetries = list_to_integer(NewMaxRetries1),
-            ok = gen_server:cast(Server, {set_max_retries, NewMaxRetries})
+        ("replicator", "max_replication_retry_count", V) ->
+            ok = gen_server:cast(Server, {set_max_retries, retries_value(V)})
         end
     ),
     {Loop, RepDbName} = changes_feed_loop(),
@@ -112,7 +113,7 @@ init(_) ->
         changes_feed_loop = Loop,
         rep_db_name = RepDbName,
         db_notifier = db_update_notifier(),
-        max_retries = list_to_integer(
+        max_retries = retries_value(
             couch_config:get("replicator", "max_replication_retry_count", "10"))
     }}.
 
@@ -125,8 +126,13 @@ handle_call({rep_started, RepId}, _From,
     nil ->
         ok;
     RepState ->
-        true = ets:insert(
-            ?REP_TO_STATE, {RepId, RepState#rep_state{starting = false}})
+        NewRepState = RepState#rep_state{
+            starting = false,
+            retries_left = State#state.max_retries,
+            max_retries = State#state.max_retries,
+            wait = ?INITIAL_WAIT
+        },
+        true = ets:insert(?REP_TO_STATE, {RepId, NewRepState})
     end,
     {reply, ok, State};
 
@@ -416,12 +422,10 @@ maybe_retry_replication(#rep_state{retri
 
 maybe_retry_replication(RepState, Error, State) ->
     #rep_state{
-        rep = #rep{id = RepId, doc_id = DocId} = Rep,
-        retries_left = RetriesLeft
+        rep = #rep{id = RepId, doc_id = DocId} = Rep
     } = RepState,
-    NewRepState = RepState#rep_state{retries_left = RetriesLeft - 1},
+    #rep_state{wait = Wait} = NewRepState = state_after_error(RepState),
     true = ets:insert(?REP_TO_STATE, {RepId, NewRepState}),
-    Wait = wait_period(NewRepState),
     ?LOG_ERROR("Error in replication `~s` (triggered by document `~s`): ~s"
         "~nRestarting replication in ~p seconds.",
         [pp_rep_id(RepId), DocId, to_binary(error_reason(Error)), Wait]),
@@ -529,10 +533,17 @@ error_reason(Reason) ->
     Reason.
 
 
-wait_period(#rep_state{max_retries = Max, retries_left = Left}) ->
-    wait_period(Max - Left, ?INITIAL_WAIT).
+retries_value("infinity") ->
+    infinity;
+retries_value(Value) ->
+    list_to_integer(Value).
 
-wait_period(1, T) ->
-    T;
-wait_period(N, T) when N > 1 ->
-    wait_period(N - 1, 2 * T).
+
+state_after_error(#rep_state{retries_left = Left, wait = Wait} = State) ->
+    Wait2 = erlang:min(trunc(Wait * 2), ?MAX_WAIT),
+    case Left of
+    infinity ->
+        State#rep_state{wait = Wait2};
+    _ ->
+        State#rep_state{retries_left = Left - 1, wait = Wait2}
+    end.