You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2013/07/20 16:51:41 UTC

git commit: updated refs/heads/master to dfd2199

Updated Branches:
  refs/heads/master c40b25dfc -> dfd2199a4


Support Last-Event-ID header for eventsource changes feeds

COUCHDB-1852


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

Branch: refs/heads/master
Commit: dfd2199a4c6f67b76018eccfdd00b4fd4190e392
Parents: c40b25d
Author: Damjan Georgievski <gd...@gmail.com>
Authored: Sat Jul 20 15:46:04 2013 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Sat Jul 20 15:46:04 2013 +0100

----------------------------------------------------------------------
 share/doc/src/changes.rst        |  3 ++-
 share/www/script/test/changes.js | 26 ++++++++++++++++++++++++++
 src/couchdb/couch_httpd_db.erl   | 18 ++++++++++++++++--
 3 files changed, 44 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/dfd2199a/share/doc/src/changes.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/changes.rst b/share/doc/src/changes.rst
index f806559..cfec5cd 100644
--- a/share/doc/src/changes.rst
+++ b/share/doc/src/changes.rst
@@ -187,7 +187,8 @@ Event Source
 
 The `eventsource` feed provides push notifications that can be consumed in
 the form of DOM events in the browser. Refer to the `W3C eventsource
-specification`_ for further details.
+specification`_ for further details. CouchDB honors the ``Last-Event-ID`` header,
+and if it's present it will take precedence over the ``since`` query parameter.
 
 .. code-block:: text
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/dfd2199a/share/www/script/test/changes.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/changes.js b/share/www/script/test/changes.js
index 00944f7..fcd8306 100644
--- a/share/www/script/test/changes.js
+++ b/share/www/script/test/changes.js
@@ -620,6 +620,32 @@ couchTests.changes = function(debug) {
   TEquals(1, resp.results.length);
   TEquals(2, resp.results[0].changes.length);
 
+  // COUCHDB-1852
+  T(db.deleteDb());
+  T(db.createDb());
+
+  // create 4 documents... this assumes the update sequnce will start from 0 and get to 4
+  db.save({"bop" : "foom"});
+  db.save({"bop" : "foom"});
+  db.save({"bop" : "foom"});
+  db.save({"bop" : "foom"});
+
+  // simulate an EventSource request with a Last-Event-ID header
+  req = CouchDB.request("GET", "/test_suite_db/_changes?feed=eventsource&timeout=0&since=0",
+        {"headers": {"Accept": "text/event-stream", "Last-Event-ID": "2"}});
+
+  // "parse" the eventsource response and collect only the "id: ..." lines
+  var changes = req.responseText.split('\n')
+     .map(function (el) {
+        return el.split(":").map(function (el) { return el.trim()});
+     })
+     .filter(function (el) { return (el[0] === "id"); })
+
+  // make sure we only got 2 changes, and they are update_seq=3 and update_seq=4
+  T(changes.length === 2);
+  T(changes[0][1] === "3");
+  T(changes[1][1] === "4");
+
   // cleanup
   db.deleteDb();
 };

http://git-wip-us.apache.org/repos/asf/couchdb/blob/dfd2199a/src/couchdb/couch_httpd_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index f270fef..f5fe483 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -1114,7 +1114,7 @@ parse_doc_query(Req) ->
     end, #doc_query_args{}, couch_httpd:qs(Req)).
 
 parse_changes_query(Req, Db) ->
-    lists:foldl(fun({Key, Value}, Args) ->
+    ChangesArgs = lists:foldl(fun({Key, Value}, Args) ->
         case {string:to_lower(Key), Value} of
         {"feed", _} ->
             Args#changes_args{feed=Value};
@@ -1148,7 +1148,21 @@ parse_changes_query(Req, Db) ->
         _Else -> % unknown key value pair, ignore.
             Args
         end
-    end, #changes_args{}, couch_httpd:qs(Req)).
+    end, #changes_args{}, couch_httpd:qs(Req)),
+    %% if it's an EventSource request with a Last-event-ID header
+    %% that should override the `since` query string, since it's
+    %% probably the browser reconnecting.
+    case ChangesArgs#changes_args.feed of
+        "eventsource" ->
+            case couch_httpd:header_value(Req, "last-event-id") of
+                undefined ->
+                    ChangesArgs;
+                Value ->
+                    ChangesArgs#changes_args{since=list_to_integer(Value)}
+            end;
+        _ ->
+            ChangesArgs
+    end.
 
 extract_header_rev(Req, ExplicitRev) when is_binary(ExplicitRev) or is_list(ExplicitRev)->
     extract_header_rev(Req, couch_doc:parse_rev(ExplicitRev));