From 0dd8f16e42f4f1d7206cc6d4c7e49b6cf420f725 Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Wed, 24 Feb 2010 04:15:58 +0000 Subject: Allow replication to be cancelled. Closes COUCHDB-664. Patch by Robert Newson. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@915664 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replication.js | 19 +++++++++++++++++++ src/couchdb/couch_httpd_misc_handlers.erl | 4 ++++ src/couchdb/couch_rep.erl | 21 ++++++++++++++++----- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js index d3725a17..a5ed5110 100644 --- a/share/www/script/test/replication.js +++ b/share/www/script/test/replication.js @@ -302,7 +302,26 @@ couchTests.replication = function(debug) { TEquals("test_suite_db_b", dbB.info().db_name, "Target database should exist"); + // continuous + var continuousResult = CouchDB.replicate(dbA.name, "test_suite_db_b", { + body: {"continuous": true} + }); + T(continuousResult.ok) + T(continuousResult._local_id) + var cancelResult = CouchDB.replicate(dbA.name, "test_suite_db_b", { + body: {"cancel": true} + }); + T(cancelResult.ok) + T(continuousResult._local_id == cancelResult._local_id) + + try { + var cancelResult2 = CouchDB.replicate(dbA.name, "test_suite_db_b", { + body: {"cancel": true} + }); + } catch (e) { + T(e.error == "not_found") + } // test replication object option doc_ids var dbA = new CouchDB("test_suite_rep_docs_db_a", {"X-Couch-Full-Commit":"false"}); diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl index a8543306..d58dfacd 100644 --- a/src/couchdb/couch_httpd_misc_handlers.erl +++ b/src/couchdb/couch_httpd_misc_handlers.erl @@ -90,10 +90,14 @@ handle_replicate_req(#httpd{method='POST'}=Req) -> try couch_rep:replicate(PostBody, Req#httpd.user_ctx) of {ok, {continuous, RepId}} -> send_json(Req, 202, {[{ok, true}, {<<"_local_id">>, RepId}]}); + {ok, {cancelled, RepId}} -> + send_json(Req, 200, {[{ok, true}, {<<"_local_id">>, RepId}]}); {ok, {JsonResults}} -> send_json(Req, {[{ok, true} | JsonResults]}); {error, {Type, Details}} -> send_json(Req, 500, {[{error, Type}, {reason, Details}]}); + {error, not_found} -> + send_json(Req, 404, {[{error, not_found}]}); {error, Reason} -> send_json(Req, 500, {[{error, Reason}]}) catch diff --git a/src/couchdb/couch_rep.erl b/src/couchdb/couch_rep.erl index 4e6ad12d..82716809 100644 --- a/src/couchdb/couch_rep.erl +++ b/src/couchdb/couch_rep.erl @@ -68,13 +68,24 @@ replicate({Props}=PostBody, UserCtx) -> [?MODULE] }, - Server = start_replication_server(Replicator), - - case proplists:get_value(<<"continuous">>, Props, false) of + case proplists:get_value(<<"cancel">>, Props, false) of true -> - {ok, {continuous, ?l2b(BaseId)}}; + case supervisor:terminate_child(couch_rep_sup, BaseId ++ Extension) of + {error, not_found} -> + {error, not_found}; + ok -> + ok = supervisor:delete_child(couch_rep_sup, BaseId ++ Extension), + {ok, {cancelled, ?l2b(BaseId)}} + end; false -> - get_result(Server, PostBody, UserCtx) + Server = start_replication_server(Replicator), + + case proplists:get_value(<<"continuous">>, Props, false) of + true -> + {ok, {continuous, ?l2b(BaseId)}}; + false -> + get_result(Server, PostBody, UserCtx) + end end. checkpoint(Server) -> -- cgit v1.2.3