Author: fdmanana
Date: Sun Mar 27 19:20:21 2011
New Revision: 1086008
URL: http://svn.apache.org/viewvc?rev=1086008&view=rev
Log:
Backport fix for COUCHDB-1093 (revision 1086007)
Fix for crashes in continuous and filtered changes feeds
Fixes COUCHDB-1093.
Modified:
couchdb/branches/1.0.x/share/www/script/test/replication.js
couchdb/branches/1.0.x/src/couchdb/couch_changes.erl
Modified: couchdb/branches/1.0.x/share/www/script/test/replication.js
URL:
http://svn.apache.org/viewvc/couchdb/branches/1.0.x/share/www/script/test/replication.js?rev=1086008&r1=1086007&r2=1086008&view=diff
==============================================================================
--- couchdb/branches/1.0.x/share/www/script/test/replication.js (original)
+++ couchdb/branches/1.0.x/share/www/script/test/replication.js Sun Mar 27
19:20:21 2011
@@ -679,6 +679,67 @@ couchTests.replication = function(debug)
run_on_modified_server(server_config, test_fun);
+ // COUCHDB-1093 - filtered and continuous _changes feed dies when the
+ // database is compacted
+ dbA = new CouchDB("test_suite_db_a");
+ dbB = new CouchDB("test_suite_db_b");
+
+ dbA.deleteDb();
+ dbA.createDb();
+ dbB.deleteDb();
+ dbB.createDb();
+
+ var docs = makeDocs(1, 10);
+ docs.push({
+ _id: "_design/foo",
+ language: "javascript",
+ filters: {
+ myfilter: (function(doc, req) { return true; }).toString()
+ }
+ });
+ dbA.bulkSave(docs).ok;
+
+ var repResult = CouchDB.replicate(
+ "http://" + host + "/" + dbA.name,
+ dbB.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, dbA.compact().ok);
+ while (dbA.info().compact_running) {};
+
+ TEquals(true, dbA.save(makeDocs(30, 31)[0]).ok);
+ xhr = CouchDB.request("GET", "/_active_tasks");
+
+ var tasksAfter = JSON.parse(xhr.responseText);
+ TEquals(tasks.length, tasksAfter.length);
+ T(dbB.open("30") !== null);
+
+ repResult = CouchDB.replicate(
+ "http://" + host + "/" + dbA.name,
+ dbB.name,
+ {
+ body: {
+ continuous: true,
+ filter: "foo/myfilter",
+ cancel: true
+ }
+ }
+ );
+ TEquals(true, repResult.ok);
+ TEquals('string', typeof repResult._local_id);
+
+
// cleanup
dbA.deleteDb();
dbB.deleteDb();
Modified: couchdb/branches/1.0.x/src/couchdb/couch_changes.erl
URL:
http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_changes.erl?rev=1086008&r1=1086007&r2=1086008&view=diff
==============================================================================
--- couchdb/branches/1.0.x/src/couchdb/couch_changes.erl (original)
+++ couchdb/branches/1.0.x/src/couchdb/couch_changes.erl Sun Mar 27 19:20:21
2011
@@ -73,7 +73,7 @@ make_filter_fun(FilterName, Style, Req,
case [list_to_binary(couch_httpd:unquote(Part))
|| Part <- string:tokens(FilterName, "/")] of
[] ->
- fun(#doc_info{revs=[#rev_info{rev=Rev}|_]=Revs}) ->
+ fun(_Db2, #doc_info{revs=[#rev_info{rev=Rev}|_]=Revs}) ->
case Style of
main_only ->
[{[{<<"rev">>, couch_doc:rev_to_str(Rev)}]}];
@@ -88,7 +88,7 @@ make_filter_fun(FilterName, Style, Req,
% 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 ->
@@ -97,10 +97,10 @@ make_filter_fun(FilterName, Style, Req,
[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|_]}}}
@@ -207,7 +207,7 @@ changes_enumerator(DocInfo, {Db, _, _, F
Limit, IncludeDocs, Conflicts}) ->
#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
@@ -226,7 +226,7 @@ changes_enumerator(DocInfo, {Db, _, Prep
Limit, IncludeDocs, Conflicts}) ->
#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