incubator-couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Davis <paul.joseph.da...@gmail.com>
Subject Re: git commit: add Server-Sent Events protocol to db changes API. close #COUCHDB-986
Date Wed, 16 May 2012 05:42:39 GMT
That JS test looks broken for JS environments that don't support
EventSource. Notably the CLI test suite but also browsers that don't
implement it. I'd either move the entire test into the conditional or
reimplement it by parsing the actual data sent across.

On Wed, May 16, 2012 at 12:36 AM,  <benoitc@apache.org> wrote:
> Updated Branches:
>  refs/heads/master af7441d8d -> 093d2aa65
>
>
> add Server-Sent Events protocol to db changes API. close #COUCHDB-986
>
> This patch add support for the new specification of w3c by adding a new
> feed type named `eventsource`:
>
> http://www.w3.org/TR/2009/WD-eventsource-20090423/
>
> This patch is based on @indutny patch with edits.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
> Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/093d2aa6
> Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/093d2aa6
> Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/093d2aa6
>
> Branch: refs/heads/master
> Commit: 093d2aa6544546a95f6133f1db3c4f4179793f3c
> Parents: af7441d
> Author: benoitc <benoitc@apache.org>
> Authored: Wed May 16 07:30:19 2012 +0200
> Committer: benoitc <benoitc@apache.org>
> Committed: Wed May 16 07:30:19 2012 +0200
>
> ----------------------------------------------------------------------
>  share/www/script/test/changes.js |   28 ++++++++++++++++++++++++++++
>  src/couchdb/couch_changes.erl    |   15 ++++++++++-----
>  src/couchdb/couch_httpd_db.erl   |   24 ++++++++++++++++++++++--
>  3 files changed, 60 insertions(+), 7 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/couchdb/blob/093d2aa6/share/www/script/test/changes.js
> ----------------------------------------------------------------------
> diff --git a/share/www/script/test/changes.js b/share/www/script/test/changes.js
> index 19e22fd..c529b21 100644
> --- a/share/www/script/test/changes.js
> +++ b/share/www/script/test/changes.js
> @@ -139,6 +139,34 @@ couchTests.changes = function(debug) {
>     // otherwise we'll continue to receive heartbeats forever
>     xhr.abort();
>
> +    // test Server Sent Event (eventsource)
> +    if (window.EventSource) {
> +      var source = new EventSource(
> +              "/test_suite_db/_changes?feed=eventsource");
> +      var results = [];
> +      var sourceListener = function(e) {
> +        var data = JSON.parse(e.data);
> +        results.push(data);
> +
> +      };
> +
> +      source.addEventListener('message', sourceListener , false);
> +
> +      waitForSuccess(function() {
> +        if (results.length != 3)
> +          throw "bad seq, try again";
> +      });
> +
> +      source.removeEventListener('message', sourceListener, false);
> +
> +      T(results[0].seq == 1);
> +      T(results[0].id == "foo");
> +
> +      T(results[1].seq == 2);
> +      T(results[1].id == "bar");
> +      T(results[1].changes[0].rev == docBar._rev);
> +    }
> +
>     // test longpolling
>     xhr = CouchDB.newXhr();
>
>
> http://git-wip-us.apache.org/repos/asf/couchdb/blob/093d2aa6/src/couchdb/couch_changes.erl
> ----------------------------------------------------------------------
> diff --git a/src/couchdb/couch_changes.erl b/src/couchdb/couch_changes.erl
> index aec7873..85c9e54 100644
> --- a/src/couchdb/couch_changes.erl
> +++ b/src/couchdb/couch_changes.erl
> @@ -63,7 +63,8 @@ handle_changes(Args1, Req, Db0) ->
>         put(last_changes_heartbeat, now())
>     end,
>
> -    if Feed == "continuous" orelse Feed == "longpoll" ->
> +    case lists:member(Feed, ["continuous", "longpoll", "eventsource"]) of
> +    true ->
>         fun(CallbackAcc) ->
>             {Callback, UserAcc} = get_callback_acc(CallbackAcc),
>             Self = self(),
> @@ -89,7 +90,7 @@ handle_changes(Args1, Req, Db0) ->
>                 get_rest_db_updated(ok) % clean out any remaining update messages
>             end
>         end;
> -    true ->
> +    false ->
>         fun(CallbackAcc) ->
>             {Callback, UserAcc} = get_callback_acc(CallbackAcc),
>             UserAcc2 = start_sending_changes(Callback, UserAcc, Feed),
> @@ -261,7 +262,9 @@ get_changes_timeout(Args, Callback) ->
>             fun(UserAcc) -> {ok, Callback(timeout, ResponseType, UserAcc)} end}
>     end.
>
> -start_sending_changes(_Callback, UserAcc, "continuous") ->
> +start_sending_changes(_Callback, UserAcc, ResponseType)
> +        when ResponseType =:= "continuous"
> +        orelse ResponseType =:= "eventsource" ->
>     UserAcc;
>  start_sending_changes(Callback, UserAcc, ResponseType) ->
>     Callback(start, ResponseType, UserAcc).
> @@ -434,7 +437,9 @@ keep_sending_changes(Args, Acc0, FirstRound) ->
>  end_sending_changes(Callback, UserAcc, EndSeq, ResponseType) ->
>     Callback({stop, EndSeq}, ResponseType, UserAcc).
>
> -changes_enumerator(DocInfo, #changes_acc{resp_type = "continuous"} = Acc) ->
> +changes_enumerator(DocInfo, #changes_acc{resp_type = ResponseType} = Acc)
> +        when ResponseType =:= "continuous"
> +        orelse ResponseType =:= "eventsource" ->
>     #changes_acc{
>         filter = FilterFun, callback = Callback,
>         user_acc = UserAcc, limit = Limit, db = Db,
> @@ -456,7 +461,7 @@ changes_enumerator(DocInfo, #changes_acc{resp_type = "continuous"}
= Acc) ->
>         end;
>     _ ->
>         ChangesRow = changes_row(Results, DocInfo, Acc),
> -        UserAcc2 = Callback({change, ChangesRow, <<>>}, "continuous",
UserAcc),
> +        UserAcc2 = Callback({change, ChangesRow, <<>>}, ResponseType,
UserAcc),
>         reset_heartbeat(),
>         {Go, Acc#changes_acc{seq = Seq, user_acc = UserAcc2, limit = Limit - 1}}
>     end;
>
> http://git-wip-us.apache.org/repos/asf/couchdb/blob/093d2aa6/src/couchdb/couch_httpd_db.erl
> ----------------------------------------------------------------------
> diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
> index de39b9e..0920014 100644
> --- a/src/couchdb/couch_httpd_db.erl
> +++ b/src/couchdb/couch_httpd_db.erl
> @@ -76,14 +76,23 @@ handle_changes_req1(Req, #db{name=DbName}=Db) ->
>
>  handle_changes_req2(Req, Db) ->
>     MakeCallback = fun(Resp) ->
> -        fun({change, Change, _}, "continuous") ->
> +        fun({change, {ChangeProp}=Change, _}, "eventsource") ->
> +            Seq = proplists:get_value(<<"seq">>, ChangeProp),
> +            send_chunk(Resp, ["data: ", ?JSON_ENCODE(Change),
> +                              "\n", "id: ", ?JSON_ENCODE(Seq),
> +                              "\n\n"]);
> +        ({change, Change, _}, "continuous") ->
>             send_chunk(Resp, [?JSON_ENCODE(Change) | "\n"]);
>         ({change, Change, Prepend}, _) ->
>             send_chunk(Resp, [Prepend, ?JSON_ENCODE(Change)]);
> +        (start, "eventsource") ->
> +            ok;
>         (start, "continuous") ->
>             ok;
>         (start, _) ->
>             send_chunk(Resp, "{\"results\":[\n");
> +        ({stop, _EndSeq}, "eventsource") ->
> +            end_json_response(Resp);
>         ({stop, EndSeq}, "continuous") ->
>             send_chunk(
>                 Resp,
> @@ -118,6 +127,15 @@ handle_changes_req2(Req, Db) ->
>                 end
>             )
>         end;
> +    "eventsource" ->
> +        Headers = [
> +            {"Content-Type", "text/event-stream"},
> +            {"Cache-Control", "no-cache"}
> +        ],
> +        {ok, Resp} = couch_httpd:start_json_response(Req, 200, Headers),
> +        fun(FeedChangesFun) ->
> +            FeedChangesFun(MakeCallback(Resp))
> +        end;
>     _ ->
>         % "longpoll" or "continuous"
>         {ok, Resp} = couch_httpd:start_json_response(Req, 200),
> @@ -1097,13 +1115,15 @@ parse_doc_query(Req) ->
>
>  parse_changes_query(Req) ->
>     lists:foldl(fun({Key, Value}, Args) ->
> -        case {Key, Value} of
> +        case {string:to_lower(Key), Value} of
>         {"feed", _} ->
>             Args#changes_args{feed=Value};
>         {"descending", "true"} ->
>             Args#changes_args{dir=rev};
>         {"since", _} ->
>             Args#changes_args{since=list_to_integer(Value)};
> +        {"last-event-id", _} ->
> +            Args#changes_args{since=list_to_integer(Value)};
>         {"limit", _} ->
>             Args#changes_args{limit=list_to_integer(Value)};
>         {"style", _} ->
>

Mime
View raw message