Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 88023 invoked from network); 27 Mar 2011 19:19:16 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 27 Mar 2011 19:19:16 -0000 Received: (qmail 64266 invoked by uid 500); 27 Mar 2011 19:19:16 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 64231 invoked by uid 500); 27 Mar 2011 19:19:16 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 64224 invoked by uid 99); 27 Mar 2011 19:19:16 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 27 Mar 2011 19:19:16 +0000 X-ASF-Spam-Status: No, hits=-1996.4 required=5.0 tests=ALL_TRUSTED,FS_REPLICA X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 27 Mar 2011 19:19:13 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 77DB123889EB; Sun, 27 Mar 2011 19:18:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1086007 - in /couchdb/trunk: share/www/script/test/replication.js src/couchdb/couch_changes.erl Date: Sun, 27 Mar 2011 19:18:51 -0000 To: commits@couchdb.apache.org From: fdmanana@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110327191851.77DB123889EB@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fdmanana Date: Sun Mar 27 19:18:51 2011 New Revision: 1086007 URL: http://svn.apache.org/viewvc?rev=1086007&view=rev Log: Fix for crashes in continuous and filtered changes feeds Fixes COUCHDB-1093. Modified: couchdb/trunk/share/www/script/test/replication.js couchdb/trunk/src/couchdb/couch_changes.erl Modified: couchdb/trunk/share/www/script/test/replication.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/replication.js?rev=1086007&r1=1086006&r2=1086007&view=diff ============================================================================== --- couchdb/trunk/share/www/script/test/replication.js (original) +++ couchdb/trunk/share/www/script/test/replication.js Sun Mar 27 19:18:51 2011 @@ -999,7 +999,10 @@ couchTests.replication = function(debug) docs = makeDocs(1, 25); docs.push({ _id: "_design/foo", - language: "javascript" + language: "javascript", + filters: { + myfilter: (function(doc, req) { return true; }).toString() + } }); for (i = 0; i < dbPairs.length; i++) { @@ -1204,6 +1207,60 @@ couchTests.replication = function(debug) TEquals(null, copy); } + // COUCHDB-1093 - filtered and continuous _changes feed dies when the + // database is compacted + docs = makeDocs(1, 10); + docs.push({ + _id: "_design/foo", + language: "javascript", + filters: { + myfilter: (function(doc, req) { return true; }).toString() + } + }); + populateDb(sourceDb, docs); + populateDb(targetDb, []); + + repResult = CouchDB.replicate( + CouchDB.protocol + host + "/" + sourceDb.name, + targetDb.name, + { + body: { + continuous: true, + filter: "foo/myfilter" + } + } + ); + TEquals(true, repResult.ok); + TEquals('string', typeof repResult._local_id); + + var xhr = CouchDB.request("GET", "/_active_tasks"); + var tasks = JSON.parse(xhr.responseText); + + TEquals(true, sourceDb.compact().ok); + while (sourceDb.info().compact_running) {}; + + TEquals(true, sourceDb.save(makeDocs(30, 31)[0]).ok); + xhr = CouchDB.request("GET", "/_active_tasks"); + + var tasksAfter = JSON.parse(xhr.responseText); + TEquals(tasks.length, tasksAfter.length); + T(sourceDb.open("30") !== null); + + // cancel replication + repResult = CouchDB.replicate( + CouchDB.protocol + host + "/" + sourceDb.name, + targetDb.name, + { + body: { + continuous: true, + filter: "foo/myfilter", + cancel: true + } + } + ); + TEquals(true, repResult.ok); + TEquals('string', typeof repResult._local_id); + // // test replication of compressed attachments Modified: couchdb/trunk/src/couchdb/couch_changes.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_changes.erl?rev=1086007&r1=1086006&r2=1086007&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_changes.erl (original) +++ couchdb/trunk/src/couchdb/couch_changes.erl Sun Mar 27 19:18:51 2011 @@ -100,7 +100,7 @@ os_filter_fun(FilterName, Style, Req, Db case [list_to_binary(couch_httpd:unquote(Part)) || Part <- string:tokens(FilterName, "/")] of [] -> - fun(#doc_info{revs=Revs}) -> + fun(_Db2, #doc_info{revs=Revs}) -> builtin_results(Style, Revs) end; [DName, FName] -> @@ -109,7 +109,7 @@ os_filter_fun(FilterName, Style, Req, Db % validate that the ddoc has the filter fun #doc{body={Props}} = DDoc, couch_util:get_nested_json_value({Props}, [<<"filters">>, FName]), - fun(DocInfo) -> + fun(Db2, DocInfo) -> DocInfos = case Style of main_only -> @@ -118,10 +118,10 @@ os_filter_fun(FilterName, Style, Req, Db [DocInfo#doc_info{revs=[Rev]}|| Rev <- DocInfo#doc_info.revs] end, Docs = [Doc || {ok, Doc} <- [ - couch_db:open_doc(Db, DocInfo2, [deleted, conflicts]) + couch_db:open_doc(Db2, DocInfo2, [deleted, conflicts]) || DocInfo2 <- DocInfos]], {ok, Passes} = couch_query_servers:filter_docs( - Req, Db, DDoc, FName, Docs + Req, Db2, DDoc, FName, Docs ), [{[{<<"rev">>, couch_doc:rev_to_str({RevPos,RevId})}]} || {Pass, #doc{revs={RevPos,[RevId|_]}}} @@ -150,7 +150,7 @@ builtin_filter_fun(_FilterName, _Style, throw({bad_request, "unknown builtin filter name"}). filter_docids(DocIds, Style) when is_list(DocIds)-> - fun(#doc_info{id=DocId, revs=Revs}) -> + fun(_Db, #doc_info{id=DocId, revs=Revs}) -> case lists:member(DocId, DocIds) of true -> builtin_results(Style, Revs); @@ -161,7 +161,7 @@ filter_docids(_, _) -> throw({bad_request, "`doc_ids` filter parameter is not a list."}). filter_designdoc(Style) -> - fun(#doc_info{id=DocId, revs=Revs}) -> + fun(_Db, #doc_info{id=DocId, revs=Revs}) -> case DocId of <<"_design", _/binary>> -> builtin_results(Style, Revs); @@ -182,7 +182,7 @@ filter_view(ViewName, Style, Db) -> % validate that the ddoc has the filter fun #doc{body={Props}} = DDoc, couch_util:get_nested_json_value({Props}, [<<"views">>, VName]), - fun(DocInfo) -> + fun(Db2, DocInfo) -> DocInfos = case Style of main_only -> @@ -191,9 +191,8 @@ filter_view(ViewName, Style, Db) -> [DocInfo#doc_info{revs=[Rev]}|| Rev <- DocInfo#doc_info.revs] end, Docs = [Doc || {ok, Doc} <- [ - couch_db:open_doc(Db, DocInfo2, [deleted, conflicts]) + couch_db:open_doc(Db2, DocInfo2, [deleted, conflicts]) || DocInfo2 <- DocInfos]], - {ok, Passes} = couch_query_servers:filter_view( DDoc, VName, Docs ), @@ -325,10 +324,10 @@ end_sending_changes(Callback, UserAcc, E changes_enumerator(DocInfo, #changes_acc{resp_type = "continuous"} = Acc) -> #changes_acc{ filter = FilterFun, callback = Callback, - user_acc = UserAcc, limit = Limit + user_acc = UserAcc, limit = Limit, db = Db } = Acc, #doc_info{high_seq = Seq} = DocInfo, - Results0 = FilterFun(DocInfo), + Results0 = FilterFun(Db, DocInfo), Results = [Result || Result <- Results0, Result /= null], Go = if Limit =< 1 -> stop; true -> ok end, case Results of @@ -342,10 +341,10 @@ changes_enumerator(DocInfo, #changes_acc changes_enumerator(DocInfo, Acc) -> #changes_acc{ filter = FilterFun, callback = Callback, prepend = Prepend, - user_acc = UserAcc, limit = Limit, resp_type = ResponseType + user_acc = UserAcc, limit = Limit, resp_type = ResponseType, db = Db } = Acc, #doc_info{high_seq = Seq} = DocInfo, - Results0 = FilterFun(DocInfo), + Results0 = FilterFun(Db, DocInfo), Results = [Result || Result <- Results0, Result /= null], Go = if (Limit =< 1) andalso Results =/= [] -> stop; true -> ok end, case Results of