Updated Branches: refs/heads/1994-merge-rcouch 824869c3c -> 3aca55450
add index update events notifications Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/3aca5545 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/3aca5545 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/3aca5545 Branch: refs/heads/1994-merge-rcouch Commit: 3aca5545026aa630cd1ea2209d94e645f87b8277 Parents: 824869c Author: Benoit Chesneau <[email protected]> Authored: Thu Jan 30 09:21:06 2014 +0100 Committer: Benoit Chesneau <[email protected]> Committed: Thu Jan 30 09:21:06 2014 +0100 ---------------------------------------------------------------------- apps/couch_index/src/couch_index_event.erl | 65 +++++++++++++++++++++ apps/couch_index/src/couch_index_event_sup.erl | 51 ++++++++++++++++ apps/couch_index/src/couch_index_sup.erl | 7 ++- apps/couch_mrview/src/couch_mrview_updater.erl | 7 ++- apps/couch_mrview/test/09-index-events.t | 46 +++++++++++++++ 5 files changed, 174 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/3aca5545/apps/couch_index/src/couch_index_event.erl ---------------------------------------------------------------------- diff --git a/apps/couch_index/src/couch_index_event.erl b/apps/couch_index/src/couch_index_event.erl new file mode 100644 index 0000000..0cd0a6b --- /dev/null +++ b/apps/couch_index/src/couch_index_event.erl @@ -0,0 +1,65 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couch_index_event). +-behaviour(gen_event). + +-export([start_link/1]). +-export([notify/1]). +-export([stop/1]). + +%% gen_event callbacks +-export([init/1, handle_event/2, handle_call/2, handle_info/2, + terminate/2, code_change/3]). + +start_link(Consumer) -> + HandlerId = {?MODULE, make_ref()}, + couch_index_event_sup:start_link(couch_index_events, HandlerId, + Consumer). + +notify(Event) -> + gen_event:notify(couch_index_events, Event). + +stop(Pid) -> + couch_index_event_sup:stop(Pid). + + +init(Consumer) -> + process_flag(trap_exit, true), + {ok, Consumer}. + +handle_event(Event, Consumer) -> + dispatch_event(Event, Consumer). + +handle_call(_Req, Consumer) -> + {reply, ok, Consumer}. + +handle_info({'EXIT', _, _}, _Consumer) -> + remove_handler; +handle_info(_Info, Consumer)-> + {ok, Consumer}. + +code_change(_OldVsn, Consumer, _Extra) -> + {ok, Consumer}. + +terminate(_Reason, _consumer) -> + ok. + +dispatch_event(Event, Fun) when is_function(Fun) -> + Fun(Event), + {ok, Fun}; +dispatch_event(Event, {Fun, Acc}) when is_function(Fun) -> + Acc2 = Fun(Event, Acc), + {ok, {Fun, Acc2}}; +dispatch_event(Event, Pid) when is_pid(Pid) -> + Pid ! Event, + {ok, Pid}. http://git-wip-us.apache.org/repos/asf/couchdb/blob/3aca5545/apps/couch_index/src/couch_index_event_sup.erl ---------------------------------------------------------------------- diff --git a/apps/couch_index/src/couch_index_event_sup.erl b/apps/couch_index/src/couch_index_event_sup.erl new file mode 100644 index 0000000..68cba43 --- /dev/null +++ b/apps/couch_index/src/couch_index_event_sup.erl @@ -0,0 +1,51 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couch_index_event_sup). + +-export([start_link/3]). +-export([stop/1]). + +%% internal gen_server callbacks +-export([init/1, terminate/2, handle_call/3, handle_cast/2, + handle_info/2,code_change/3]). + +start_link(EventMgr, EventHandler, Args) -> + gen_server:start_link(?MODULE, {EventMgr, EventHandler, Args}, []). + +stop(Pid) -> + gen_server:cast(Pid, stop). + +init({EventMgr, EventHandler, Args}) -> + case gen_event:add_sup_handler(EventMgr, EventHandler, Args) of + ok -> + {ok, {EventMgr, EventHandler}}; + {stop, Error} -> + {stop, Error} + end. + +handle_call(_Whatever, _From, State) -> + {ok, State}. + +handle_cast(stop, State) -> + {stop, normal, State}. + +handle_info({gen_event_EXIT, _Handler, Reason}, State) -> + {stop, Reason, State}. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. + + http://git-wip-us.apache.org/repos/asf/couchdb/blob/3aca5545/apps/couch_index/src/couch_index_sup.erl ---------------------------------------------------------------------- diff --git a/apps/couch_index/src/couch_index_sup.erl b/apps/couch_index/src/couch_index_sup.erl index fd97814..8e69016 100644 --- a/apps/couch_index/src/couch_index_sup.erl +++ b/apps/couch_index/src/couch_index_sup.erl @@ -26,4 +26,9 @@ start_link() -> init([]) -> Server = ?CHILD(couch_index_server), - {ok, {{one_for_one, 10, 3600}, [Server]}}. + + EventSup = {couch_index_events, + {gen_event, start_link, [{local, couch_index_events}]}, + permanent, brutal_kill, worker, dynamic}, + + {ok, {{one_for_one, 10, 3600}, [Server, EventSup]}}. http://git-wip-us.apache.org/repos/asf/couchdb/blob/3aca5545/apps/couch_mrview/src/couch_mrview_updater.erl ---------------------------------------------------------------------- diff --git a/apps/couch_mrview/src/couch_mrview_updater.erl b/apps/couch_mrview/src/couch_mrview_updater.erl index be1055c..a23def6 100644 --- a/apps/couch_mrview/src/couch_mrview_updater.erl +++ b/apps/couch_mrview/src/couch_mrview_updater.erl @@ -182,7 +182,7 @@ map_docs(Parent, State0) -> end. -write_results(Parent, State) -> +write_results(Parent, #mrst{db_name=DbName, idx_name=IdxName}=State) -> case couch_work_queue:dequeue(State#mrst.write_queue) of closed -> Parent ! {new_state, State}; @@ -192,6 +192,11 @@ write_results(Parent, State) -> [], dict:new()), NewState = write_kvs(State, Seq, ViewKVs, DocIdKeys, Log), send_partial(NewState#mrst.partial_resp_pid, NewState), + + % notifify the view update + couch_index_event:notify({index_update, {DbName, IdxName, + couch_mrview_index}}), + write_results(Parent, NewState) end. http://git-wip-us.apache.org/repos/asf/couchdb/blob/3aca5545/apps/couch_mrview/test/09-index-events.t ---------------------------------------------------------------------- diff --git a/apps/couch_mrview/test/09-index-events.t b/apps/couch_mrview/test/09-index-events.t new file mode 100644 index 0000000..90654b8 --- /dev/null +++ b/apps/couch_mrview/test/09-index-events.t @@ -0,0 +1,46 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap + +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +main(_) -> + etap:plan(2), + case (catch test()) of + ok -> + etap:end_tests(); + Other -> + etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), + etap:bail(Other) + end, + timer:sleep(300), + ok. + +test() -> + test_util:start_couch(), + {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes), + test_update_event(Db), + test_util:stop_couch(), + ok. + +test_update_event(Db) -> + {ok, Pid} = couch_index_event:start_link(self()), + etap:ok(is_pid(Pid), "event handler added"), + ok = couch_mrview:refresh(Db, <<"_design/bar">>), + Expect = {index_update, {<<"foo">>, <<"_design/bar">>, + couch_mrview_index}}, + receive + Event -> + etap:is(Event, Expect, "index update events OK") + end, + couch_index_event:stop(Pid).
