couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rnew...@apache.org
Subject [25/49] chttpd commit: updated refs/heads/windsor-merge to 554ef74
Date Fri, 01 Aug 2014 09:06:01 GMT
Try to cancel a replication everywhere

Cancelation requests sometimes omit source and target information in
favor of a replication ID.  When that happens the logic that selects the
owner for the replication picks the wrong node, and the cancelation
fails with a not_found error.  This patch causes the request to be
submitted to all nodes in the cluster.  We report success if at least
one node reports success, otherwise we report (one of) the errors that
we received.

BugzID: 21976


Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/2c4d2b3d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/2c4d2b3d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/2c4d2b3d

Branch: refs/heads/windsor-merge
Commit: 2c4d2b3d201ef33411f6dccde61dfdfa9a028977
Parents: d86f68d
Author: Adam Kocoloski <adam@cloudant.com>
Authored: Wed Oct 16 13:23:14 2013 -0400
Committer: Robert Newson <rnewson@apache.org>
Committed: Tue Jul 29 18:22:24 2014 +0100

----------------------------------------------------------------------
 src/chttpd_misc.erl | 42 +++++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/2c4d2b3d/src/chttpd_misc.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_misc.erl b/src/chttpd_misc.erl
index cb83bc0..fcd8999 100644
--- a/src/chttpd_misc.erl
+++ b/src/chttpd_misc.erl
@@ -171,15 +171,39 @@ handle_replicate_req(Req) ->
     send_method_not_allowed(Req, "POST").
 
 replicate({Props} = PostBody, Ctx) ->
-    Node = choose_node([
-        couch_util:get_value(<<"source">>, Props),
-        couch_util:get_value(<<"target">>, Props)
-    ]),
-    case rpc:call(Node, couch_replicator, replicate, [PostBody, Ctx]) of
-    {badrpc, Reason} ->
-        erlang:error(Reason);
-    Res ->
-        Res
+    case couch_util:get_value(<<"cancel">>, Props) of
+    true ->
+        cancel_replication(PostBody, Ctx);
+    false ->
+        Node = choose_node([
+            couch_util:get_value(<<"source">>, Props),
+            couch_util:get_value(<<"target">>, Props)
+        ]),
+        case rpc:call(Node, couch_replicator, replicate, [PostBody, Ctx]) of
+        {badrpc, Reason} ->
+            erlang:error(Reason);
+        Res ->
+            Res
+        end
+    end.
+
+cancel_replication(PostBody, Ctx) ->
+    {Res, Bad} = rpc:multicall(couch_replicator, replicate, [PostBody, Ctx]),
+    case [X || {ok, {cancelled, _}} = X <- Res] of
+    [Success|_] ->
+        % Report success if at least one node canceled the replication
+        Success;
+    [] ->
+        case lists:usort(Res) of
+        [UniqueReply] ->
+            % Report a universally agreed-upon reply
+            UniqueReply;
+        [] ->
+            {error, badrpc};
+        Else ->
+            % Unclear what to do here -- pick the first error?
+            hd(Else)
+        end
     end.
 
 choose_node(Key) when is_binary(Key) ->


Mime
View raw message