diff options
author | Jan Lehnardt <jan@apache.org> | 2009-08-01 13:50:38 +0000 |
---|---|---|
committer | Jan Lehnardt <jan@apache.org> | 2009-08-01 13:50:38 +0000 |
commit | a613317745c9b88e2c0d01e9a24f8b5d7b5b242e (patch) | |
tree | 7380e04e579d83e904165bf46e008ab651b20138 /src | |
parent | 2cf4fec22fa7214b11363eb7430c411e0afa6221 (diff) |
implement longpolling for _changes, unify _changes-mode parameters, patch by Benoit Chesneau, closes COUCHDB-241
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@799862 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/couchdb/couch_httpd_db.erl | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl index 7498a521..63ae5563 100644 --- a/src/couchdb/couch_httpd_db.erl +++ b/src/couchdb/couch_httpd_db.erl @@ -64,12 +64,13 @@ get_changes_timeout(Req, Resp) -> fun() -> send_chunk(Resp, "\n"), ok end} end. + handle_changes_req(#httpd{method='GET',path_parts=[DbName|_]}=Req, Db) -> StartSeq = list_to_integer(couch_httpd:qs_value(Req, "since", "0")), {ok, Resp} = start_json_response(Req, 200), send_chunk(Resp, "{\"results\":[\n"), - case couch_httpd:qs_value(Req, "continuous", "false") of - "true" -> + case couch_httpd:qs_value(Req, "feed", "normal") of + ResponseType when ResponseType == "continuous" orelse ResponseType == "longpoll"-> Self = self(), {ok, Notify} = couch_db_update_notifier:start_link( fun({_, DbName0}) when DbName0 == DbName -> @@ -81,16 +82,15 @@ handle_changes_req(#httpd{method='GET',path_parts=[DbName|_]}=Req, Db) -> couch_stats_collector:track_process_count(Self, {httpd, clients_requesting_changes}), try - keep_sending_changes(Req, Resp, Db, StartSeq, <<"">>, Timeout, TimeoutFun) + keep_sending_changes(Req, Resp, Db, StartSeq, <<"">>, Timeout, TimeoutFun, ResponseType) after couch_db_update_notifier:stop(Notify), get_rest_db_updated() % clean out any remaining update messages end; - "false" -> + "normal" -> {ok, {LastSeq, _Prepend}} = send_changes(Req, Resp, Db, StartSeq, <<"">>), - send_chunk(Resp, io_lib:format("\n],\n\"last_seq\":~w}\n", [LastSeq])), - end_json_response(Resp) + end_sending_changes(Resp, LastSeq) end; handle_changes_req(#httpd{path_parts=[_,<<"_changes">>]}=Req, _Db) -> @@ -110,17 +110,25 @@ get_rest_db_updated() -> receive db_updated -> get_rest_db_updated() after 0 -> updated end. + +end_sending_changes(Resp, EndSeq) -> + send_chunk(Resp, io_lib:format("\n],\n\"last_seq\":~w}\n", [EndSeq])), + end_json_response(Resp). -keep_sending_changes(#httpd{user_ctx=UserCtx,path_parts=[DbName|_]}=Req, Resp, Db, StartSeq, Prepend, Timeout, TimeoutFun) -> +keep_sending_changes(#httpd{user_ctx=UserCtx,path_parts=[DbName|_]}=Req, Resp, Db, StartSeq, Prepend, Timeout, TimeoutFun, ResponseType) -> {ok, {EndSeq, Prepend2}} = send_changes(Req, Resp, Db, StartSeq, Prepend), couch_db:close(Db), - case wait_db_updated(Timeout, TimeoutFun) of - updated -> - {ok, Db2} = couch_db:open(DbName, [{user_ctx, UserCtx}]), - keep_sending_changes(Req, Resp, Db2, EndSeq, Prepend2, Timeout, TimeoutFun); - stop -> - send_chunk(Resp, io_lib:format("\n],\n\"last_seq\":~w}\n", [EndSeq])), - end_json_response(Resp) + if + EndSeq > StartSeq, ResponseType == "longpoll" -> + end_sending_changes(Resp, EndSeq); + true -> + case wait_db_updated(Timeout, TimeoutFun) of + updated -> + {ok, Db2} = couch_db:open(DbName, [{user_ctx, UserCtx}]), + keep_sending_changes(Req, Resp, Db2, EndSeq, Prepend2, Timeout, TimeoutFun, ResponseType); + stop -> + end_sending_changes(Resp, EndSeq) + end end. send_changes(Req, Resp, Db, StartSeq, Prepend0) -> |