couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kocol...@apache.org
Subject svn commit: r804436 - in /couchdb/trunk/src/couchdb: couch_httpd_misc_handlers.erl couch_rep.erl couch_rep_httpc.erl
Date Sat, 15 Aug 2009 05:11:45 GMT
Author: kocolosk
Date: Sat Aug 15 05:11:45 2009
New Revision: 804436

URL: http://svn.apache.org/viewvc?rev=804436&view=rev
Log:
better failure modes in replication.  See COUCHDB-193, COUCHDB-416

If you try to replicate a DB to itself, the replication will proceed, but no
checkpoints will be saved, and the logs will say

"checkpoint failure: conflict (are you replicating to yourself?)"

If you try to specify a non-existent DB as source or target, replication will
fail immediately with a 404.  The response body will indicate which DB could
not be opened.

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

Modified: couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl?rev=804436&r1=804435&r2=804436&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl Sat Aug 15 05:11:45 2009
@@ -79,13 +79,16 @@
 
 handle_replicate_req(#httpd{method='POST'}=Req) ->
     PostBody = couch_httpd:json_body_obj(Req),
-    case couch_rep:replicate(PostBody, Req#httpd.user_ctx) of
+    try couch_rep:replicate(PostBody, Req#httpd.user_ctx) of
     {ok, {JsonResults}} ->
         send_json(Req, {[{ok, true} | JsonResults]});
     {error, {Type, Details}} ->
         send_json(Req, 500, {[{error, Type}, {reason, Details}]});
     {error, Reason} ->
         send_json(Req, 500, {[{error, Reason}]})
+    catch
+    throw:{db_not_found, Msg} ->
+        send_json(Req, 404, {[{error, db_not_found}, {reason, Msg}]})
     end;
 handle_replicate_req(Req) ->
     send_method_not_allowed(Req, "POST").

Modified: couchdb/trunk/src/couchdb/couch_rep.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_rep.erl?rev=804436&r1=804435&r2=804436&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_rep.erl (original)
+++ couchdb/trunk/src/couchdb/couch_rep.erl Sat Aug 15 05:11:45 2009
@@ -78,7 +78,11 @@
         replicate(PostBody, UserCtx)
     end.
 
-init([RepId, {PostProps}, UserCtx] = InitArgs) ->
+init(InitArgs) ->
+    try do_init(InitArgs)
+    catch throw:{db_not_found, DbUrl} -> {stop, {db_not_found, DbUrl}} end.
+
+do_init([RepId, {PostProps}, UserCtx] = InitArgs) ->
     process_flag(trap_exit, true),
 
     SourceProps = proplists:get_value(<<"source">>, PostProps),
@@ -177,7 +181,6 @@
     {stop, Reason, State}.
 
 terminate(normal, State) ->
-    % ?LOG_DEBUG("replication terminating normally", []),
     #state{
         checkpoint_history = CheckpointHistory,
         committed_seq = NewSeq,
@@ -252,7 +255,9 @@
         end;
     {error, {already_started, Pid}} ->
         ?LOG_DEBUG("replication ~p already running at ~p", [RepId, Pid]),
-        Pid
+        Pid;
+    {error, {{db_not_found, DbUrl}, _}} ->
+        throw({db_not_found, <<"could not open ", DbUrl/binary>>})
     end.
 
 compare_replication_logs(SrcDoc, TgtDoc) ->
@@ -389,7 +394,7 @@
     },
     case couch_rep_httpc:db_exists(Db) of
     true -> Db;
-    false -> throw({db_not_found, Url})
+    false -> throw({db_not_found, ?l2b(Url)})
     end;
 open_db(<<"http://",_/binary>>=Url, _) ->
     open_db({[{<<"url">>,Url}]}, []);
@@ -446,17 +451,22 @@
         {<<"source_last_seq">>, RecordSeqNum},
         {<<"history">>, lists:sublist([NewHistoryEntry | OldHistory], 50)}
     ]},
-    % ?LOG_DEBUG("updating src doc ~p", [SourceLog]),
+
+    try
     {SrcRevPos,SrcRevId} =
         update_doc(Source, SourceLog#doc{body=NewRepHistory}, []),
-    % ?LOG_DEBUG("updating tgt doc ~p", [TargetLog]),
     {TgtRevPos,TgtRevId} =
         update_doc(Target, TargetLog#doc{body=NewRepHistory}, []),
     State#state{
         checkpoint_history = NewRepHistory,
         source_log = SourceLog#doc{revs={SrcRevPos, [SrcRevId]}},
         target_log = TargetLog#doc{revs={TgtRevPos, [TgtRevId]}}
-    }.
+    }
+    catch throw:conflict ->
+    ?LOG_ERROR("checkpoint failure: conflict (are you replicating to yourself?)",
+        []),
+    State
+    end.
 
 commit_to_both(Source, Target) ->
     % commit the src async

Modified: couchdb/trunk/src/couchdb/couch_rep_httpc.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_rep_httpc.erl?rev=804436&r1=804435&r2=804436&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_rep_httpc.erl (original)
+++ couchdb/trunk/src/couchdb/couch_rep_httpc.erl Sat Aug 15 05:11:45 2009
@@ -96,6 +96,8 @@
         MochiHeaders = mochiweb_headers:make(Headers),
         RedirectUrl = mochiweb_headers:get_value("Location", MochiHeaders),
         do_request(Req#http_db{url = RedirectUrl});
+    Code =:= 409 ->
+        throw(conflict);
     Code >= 400, Code < 500 ->
         ?JSON_DECODE(maybe_decompress(Headers, Body));
     Code =:= 500; Code =:= 502 ->



Mime
View raw message