You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2016/08/25 04:49:08 UTC

couch-mrview commit: updated refs/heads/3060-handle-multi-query to 8f59201 [Forced Update!]

Repository: couchdb-couch-mrview
Updated Branches:
  refs/heads/3060-handle-multi-query 0cc75c1db -> 8f592014f (forced update)


Properly handle multi-query streaming of results

After commit:

https://github.com/apache/couchdb-couch-mrview/commit/3ce28641c85af0d5054df47e9ac7de917a9d33cd

In view_cb if rows came before meta, set the row_sent=true flag did not send
meta after that. That made sense for a single query. However, in case of multiple
queries, which could produce this sequence of callbacks:

meta , row, ... , complete, meta, row, ..., complete

Second meta won't be sent because row_sent flag remains true.

So to fix, make sure to reset row_sent=false in after each complete. Also
introduce a `meta_sent` flag, to cover the case when meta was sent for
second request and on first row we don't want to sent `{"rows":[...`.

Jira: COUCHDB-3060


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

Branch: refs/heads/3060-handle-multi-query
Commit: 8f592014f61bd6eb5e8cd8431ea1667ccddc4e95
Parents: 157132c
Author: Nick Vatamaniuc <va...@apache.org>
Authored: Wed Aug 24 23:17:00 2016 -0400
Committer: Nick Vatamaniuc <va...@apache.org>
Committed: Thu Aug 25 00:46:05 2016 -0400

----------------------------------------------------------------------
 src/couch_mrview_http.erl | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-mrview/blob/8f592014/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview_http.erl b/src/couch_mrview_http.erl
index 3a9aa33..c383d6b 100644
--- a/src/couch_mrview_http.erl
+++ b/src/couch_mrview_http.erl
@@ -360,12 +360,16 @@ view_cb({meta, Meta}, #vacc{}=Acc) ->
     end ++ ["\"rows\":["],
     Chunk = [prepend_val(Acc), "{", string:join(Parts, ","), "\r\n"],
     {ok, AccOut} = maybe_flush_response(Acc, Chunk, iolist_size(Chunk)),
-    {ok, AccOut#vacc{prepend=""}};
+    {ok, AccOut#vacc{prepend="", meta_sent=true}};
 view_cb({row, Row}, #vacc{resp=undefined}=Acc) ->
-    % sorted=false and a row arrived before meta, start response.
+    % sorted=false and a row arrived before meta, and response hasn't started
     Pre = "{\"rows\":[\r\n",
     {ok, Resp} = chttpd:start_delayed_json_response(Acc#vacc.req, 200, []),
-    view_cb({row, Row}, Acc#vacc{row_sent=true,resp=Resp, prepend=Pre, should_close=true});
+    view_cb({row, Row}, Acc#vacc{resp=Resp, row_sent=true, prepend=Pre, should_close=true});
+view_cb({row, Row}, #vacc{row_sent=false, meta_sent=false}=Acc) ->
+    % sorted=false and a row arrived before meta, emit a no-meta "rows:" header
+    Pre = prepend_val(Acc) ++ "{\"rows\":[\r\n",
+    view_cb({row, Row}, Acc#vacc{row_sent=true, prepend=Pre});
 view_cb({row, Row}, Acc) ->
     % Adding another row
     Chunk = [prepend_val(Acc), row_to_json(Row)],
@@ -373,16 +377,17 @@ view_cb({row, Row}, Acc) ->
 view_cb(complete, #vacc{resp=undefined}=Acc) ->
     % Nothing in view
     {ok, Resp} = chttpd:send_json(Acc#vacc.req, 200, {[{rows, []}]}),
-    {ok, Acc#vacc{resp=Resp}};
+    {ok, Acc#vacc{resp=Resp, row_sent=false, meta_sent=false}};
 view_cb(complete, #vacc{resp=Resp, buffer=Buf, threshold=Max}=Acc) ->
     % Finish view output and possibly end the response
     {ok, Resp1} = chttpd:close_delayed_json_object(Resp, Buf, "\r\n]}", Max),
-    case Acc#vacc.should_close of
+    Acc1 = Acc#vacc{row_sent=false, meta_sent=false},
+    case Acc1#vacc.should_close of
         true ->
             {ok, Resp2} = chttpd:end_delayed_json_response(Resp1),
-            {ok, Acc#vacc{resp=Resp2}};
+            {ok, Acc1#vacc{resp=Resp2}};
         _ ->
-            {ok, Acc#vacc{resp=Resp1, prepend=",\r\n", buffer=[], bufsize=0}}
+            {ok, Acc1#vacc{resp=Resp1, prepend=",\r\n", buffer=[], bufsize=0}}
     end;
 view_cb({error, Reason}, #vacc{resp=undefined}=Acc) ->
     {ok, Resp} = chttpd:send_error(Acc#vacc.req, Reason),