Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 24239 invoked from network); 2 Jun 2010 12:25:53 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 2 Jun 2010 12:25:53 -0000 Received: (qmail 22453 invoked by uid 500); 2 Jun 2010 12:25:53 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 22336 invoked by uid 500); 2 Jun 2010 12:25:52 -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 22329 invoked by uid 99); 2 Jun 2010 12:25:52 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Jun 2010 12:25:52 +0000 X-ASF-Spam-Status: No, hits=-1685.5 required=10.0 tests=ALL_TRUSTED,AWL 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; Wed, 02 Jun 2010 12:25:52 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id D238F2388AD6; Wed, 2 Jun 2010 12:25:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r950534 - in /couchdb/branches/0.11.x: share/www/script/test/changes.js share/www/script/test/uuids.js src/couchdb/couch_changes.erl Date: Wed, 02 Jun 2010 12:25:31 -0000 To: commits@couchdb.apache.org From: jan@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100602122531.D238F2388AD6@eris.apache.org> Author: jan Date: Wed Jun 2 12:25:31 2010 New Revision: 950534 URL: http://svn.apache.org/viewvc?rev=950534&view=rev Log: Merge r931407 from trunk: changes is less likely to miss updates, and changes test is more robust Modified: couchdb/branches/0.11.x/share/www/script/test/changes.js couchdb/branches/0.11.x/share/www/script/test/uuids.js couchdb/branches/0.11.x/src/couchdb/couch_changes.erl Modified: couchdb/branches/0.11.x/share/www/script/test/changes.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/script/test/changes.js?rev=950534&r1=950533&r2=950534&view=diff ============================================================================== --- couchdb/branches/0.11.x/share/www/script/test/changes.js (original) +++ couchdb/branches/0.11.x/share/www/script/test/changes.js Wed Jun 2 12:25:31 2010 @@ -17,7 +17,7 @@ function jsonp(obj) { } couchTests.changes = function(debug) { - var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"}); + var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"true"}); db.deleteDb(); db.createDb(); if (debug) debugger; @@ -29,11 +29,13 @@ couchTests.changes = function(debug) { var docFoo = {_id:"foo", bar:1}; T(db.save(docFoo).ok); T(db.ensureFullCommit().ok); + T(db.open(docFoo._id)._id == docFoo._id); req = CouchDB.request("GET", "/test_suite_db/_changes"); var resp = JSON.parse(req.responseText); - T(resp.results.length == 1 && resp.last_seq==1, "one doc db") + T(resp.last_seq == 1); + T(resp.results.length == 1, "one doc db") T(resp.results[0].changes[0].rev == docFoo._rev) // test with callback @@ -76,7 +78,7 @@ couchTests.changes = function(debug) { // WebKit (last checked on nightly #47686) does fail on processing // the async-request properly while javascript is executed. - xhr.open("GET", "/test_suite_db/_changes?feed=continuous", true); + xhr.open("GET", "/test_suite_db/_changes?feed=continuous&timeout=500", true); xhr.send(""); var docBar = {_id:"bar", bar:1}; @@ -114,7 +116,7 @@ couchTests.changes = function(debug) { xhr = CouchDB.newXhr(); //verify the hearbeat newlines are sent - xhr.open("GET", "/test_suite_db/_changes?feed=continuous&heartbeat=10", true); + xhr.open("GET", "/test_suite_db/_changes?feed=continuous&heartbeat=10&timeout=500", true); xhr.send(""); var str; @@ -128,6 +130,8 @@ couchTests.changes = function(debug) { T(str.charAt(str.length - 1) == "\n") T(str.charAt(str.length - 2) == "\n") + // otherwise we'll continue to receive heartbeats forever + xhr.abort(); // test longpolling xhr = CouchDB.newXhr(); @@ -186,6 +190,14 @@ couchTests.changes = function(debug) { return doc.user && (doc.user == req.userCtx.name); }), "conflicted" : "function(doc, req) { return (doc._conflicts);}", + }, + options : { + local_seq : true + }, + views : { + local_seq : { + map : "function(doc) {emit(doc._local_seq, null)}" + } } } @@ -200,7 +212,7 @@ couchTests.changes = function(debug) { var req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/bop"); var resp = JSON.parse(req.responseText); - T(resp.results.length == 1); + T(resp.results.length == 1, "filtered/bop"); req = CouchDB.request("GET", "/test_suite_db/_changes?filter=changes_filter/dynamic&field=woox"); resp = JSON.parse(req.responseText); @@ -231,21 +243,46 @@ couchTests.changes = function(debug) { T(resp.last_seq == 9); T(resp.results && resp.results.length > 0 && resp.results[0]["id"] == "bingo", "filter the correct update"); - - // filter with continuous - xhr = CouchDB.newXhr(); - xhr.open("GET", "/test_suite_db/_changes?feed=continuous&filter=changes_filter/bop&timeout=200", true); - xhr.send(""); - db.save({"_id":"rusty", "bop" : "plankton"}); + xhr.abort(); - waitForSuccess(function() { + timeout = 500; + last_seq = 10 + while (true) { + + // filter with continuous + xhr = CouchDB.newXhr(); + xhr.open("GET", "/test_suite_db/_changes?feed=continuous&filter=changes_filter/bop&timeout="+timeout, true); + xhr.send(""); + + db.save({"_id":"rusty", "bop" : "plankton"}); + T(xhr.readyState != 4, "test client too slow"); + var rusty = db.open("rusty", {cache_bust : new Date()}); + T(rusty._id == "rusty"); + + waitForSuccess(function() { // throws an error after 5 seconds + if (xhr.readyState != 4) { + throw("still waiting") + } + }, "continuous-rusty"); lines = xhr.responseText.split("\n"); - JSON.parse(lines[3]); - }, "continuous-timeout"); - - T(JSON.parse(lines[1]).id == "bingo", lines[1]); - T(JSON.parse(lines[2]).id == "rusty", lines[2]); - T(JSON.parse(lines[3]).last_seq == 10, lines[3]); + try { + JSON.parse(lines[3]) + good = true; + } catch(e) { + good = false; + } + if (good) { + T(JSON.parse(lines[1]).id == "bingo", lines[1]); + T(JSON.parse(lines[2]).id == "rusty", lines[2]); + T(JSON.parse(lines[3]).last_seq == last_seq, lines[3]); + break; + } else { + xhr.abort(); + db.deleteDoc(rusty); + timeout = timeout * 2; + last_seq = last_seq + 2; + } + } } // error conditions Modified: couchdb/branches/0.11.x/share/www/script/test/uuids.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/script/test/uuids.js?rev=950534&r1=950533&r2=950534&view=diff ============================================================================== --- couchdb/branches/0.11.x/share/www/script/test/uuids.js (original) +++ couchdb/branches/0.11.x/share/www/script/test/uuids.js Wed Jun 2 12:25:31 2010 @@ -97,7 +97,7 @@ couchTests.uuids = function(debug) { T(result.uuids[i].length == 32); var u1 = result.uuids[i-1].substr(0, 13); var u2 = result.uuids[i].substr(0, 13); - T(u1 < u2, "UTC uuids are roughly ordered."); + T(u1 < u2, "UTC uuids are only roughly ordered, so this assertion may fail occasionally. Don't sweat it."); } }; Modified: couchdb/branches/0.11.x/src/couchdb/couch_changes.erl URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_changes.erl?rev=950534&r1=950533&r2=950534&view=diff ============================================================================== --- couchdb/branches/0.11.x/src/couchdb/couch_changes.erl (original) +++ couchdb/branches/0.11.x/src/couchdb/couch_changes.erl Wed Jun 2 12:25:31 2010 @@ -17,7 +17,7 @@ %% @type Req -> #httpd{} | {json_req, JsonObj()} handle_changes(#changes_args{}=Args1, Req, Db) -> - Args = Args1#changes_args{filter=make_filter_fun(Args1, Req, Db)}, + Args = Args1#changes_args{filter=make_filter_fun(Args1#changes_args.filter, Req, Db)}, StartSeq = case Args#changes_args.dir of rev -> couch_db:get_update_seq(Db); @@ -27,7 +27,6 @@ handle_changes(#changes_args{}=Args1, Re if Args#changes_args.feed == "continuous" orelse Args#changes_args.feed == "longpoll" -> fun(Callback) -> - start_sending_changes(Callback, Args#changes_args.feed), Self = self(), {ok, Notify} = couch_db_update_notifier:start_link( fun({_, DbName}) when DbName == Db#db.name -> @@ -36,6 +35,7 @@ handle_changes(#changes_args{}=Args1, Re ok end ), + start_sending_changes(Callback, Args#changes_args.feed), {Timeout, TimeoutFun} = get_changes_timeout(Args, Callback), couch_stats_collector:track_process_count( Self, @@ -72,7 +72,7 @@ handle_changes(#changes_args{}=Args1, Re end. %% @type Req -> #httpd{} | {json_req, JsonObj()} -make_filter_fun(#changes_args{filter=FilterName}, Req, Db) -> +make_filter_fun(FilterName, Req, Db) -> case [list_to_binary(couch_httpd:unquote(Part)) || Part <- string:tokens(FilterName, "/")] of [] -> @@ -94,6 +94,7 @@ make_filter_fun(#changes_args{filter=Fil {ok, Passes} = couch_query_servers:filter_docs( Req, Db, DDoc, FName, Docs ), + % ?LOG_INFO("filtering ~p ~w",[FName, [DI#doc_info.high_seq || DI <- DocInfos]]), [{[{<<"rev">>, couch_doc:rev_to_str(Rev)}]} || #doc_info{revs=[#rev_info{rev=Rev}|_]} <- DocInfos, Pass <- Passes, Pass == true] @@ -155,20 +156,22 @@ send_changes(Args, Callback, Db, StartSe keep_sending_changes(Args, Callback, Db, StartSeq, Prepend, Timeout, TimeoutFun) -> - #changes_args{ feed = ResponseType, limit = Limit } = Args, + % ?LOG_INFO("send_changes start ~p",[StartSeq]), {ok, {_, EndSeq, Prepend2, _, _, _, NewLimit, _}} = send_changes( Args#changes_args{dir=fwd}, Callback, Db, StartSeq, Prepend ), + % ?LOG_INFO("send_changes last ~p",[EndSeq]), couch_db:close(Db), if Limit > NewLimit, ResponseType == "longpoll" -> end_sending_changes(Callback, EndSeq, ResponseType); true -> case wait_db_updated(Timeout, TimeoutFun) of updated -> + % ?LOG_INFO("wait_db_updated updated ~p",[{Db#db.name, EndSeq}]), case couch_db:open(Db#db.name, [{user_ctx, Db#db.user_ctx}]) of {ok, Db2} -> keep_sending_changes( @@ -184,6 +187,7 @@ keep_sending_changes(Args, Callback, Db, end_sending_changes(Callback, EndSeq, ResponseType) end; stop -> + % ?LOG_INFO("wait_db_updated stop ~p",[{Db#db.name, EndSeq}]), end_sending_changes(Callback, EndSeq, ResponseType) end end.