Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add db changes hooks

Introduces db hooks to handle changes. For legacy reasons we keep the
gen_event around but instead of executing it directly we are now notifying
hooks via hooks registered for each changes event.

New DB hooks are:

* db_updated(DbName) -> ok: sent when a database is updated
* ddoc_updated(DbName, DDocId) -> ok: when a design document is updated
* db_created(DbName) -> ok: Sent when a database is created
* db_deleted(DbName) -> ok: Sent when a database is deleted
* db_compacted(DbName) -> ok: Sent when a database is compacted
  • Loading branch information...
commit 880e200d5c69b76e04755c9a8f88b071c065a698 1 parent e2641a2
@benoitc benoitc authored
View
36 apps/couch/src/couch_db_update_notifier.erl
@@ -23,12 +23,44 @@
-behaviour(gen_event).
-export([start_link/1, notify/1]).
--export([init/1, terminate/2, handle_event/2, handle_call/2, handle_info/2, code_change/3,stop/1]).
+
+%% gen_server api
+-export([init/1, terminate/2, handle_event/2, handle_call/2, handle_info/2,
+ code_change/3,stop/1]).
+
+%% db changes hooks.
+-export([db_created/1, db_deleted/1, db_updated/1, db_compacted/1,
+ ddoc_updated/2]).
+
-include("couch_db.hrl").
+%%%%%%%%%%%%%%%%%
+%%% db hookks %%%
+%%%%%%%%%%%%%%%%%
+
+db_created(DbName) ->
+ notify({created, DbName}).
+
+db_deleted(DbName) ->
+ notify({deleted, DbName}).
+
+db_updated(DbName) ->
+ notify({updated, DbName}).
+
+db_compacted(DbName) ->
+ notify({compacted, DbName}).
+
+ddoc_updated(DbName, DDocId) ->
+ notify({ddoc_updated, {DbName, DDocId}}).
+
+%%%%%%%%%%%%%%%%%%
+%%% gen_server %%%
+%%%%%%%%%%%%%%%%%%
+
start_link(Exec) ->
- couch_event_sup:start_link(couch_db_update, {couch_db_update_notifier, make_ref()}, Exec).
+ couch_event_sup:start_link(couch_db_update, {couch_db_update_notifier,
+ make_ref()}, Exec).
notify(Event) ->
gen_event:notify(couch_db_update, Event).
View
13 apps/couch/src/couch_db_updater.erl
@@ -15,7 +15,8 @@
-export([btree_by_id_reduce/2,btree_by_seq_reduce/2]).
-export([make_doc_summary/2]).
--export([init/1,terminate/2,handle_call/3,handle_cast/2,code_change/3,handle_info/2]).
+-export([init/1,terminate/2,handle_call/3,handle_cast/2,code_change/3,
+ handle_info/2]).
-include("couch_db.hrl").
@@ -64,7 +65,7 @@ handle_call(full_commit, _From, Db) ->
handle_call(increment_update_seq, _From, Db) ->
Db2 = commit_data(Db#db{update_seq=Db#db.update_seq+1}),
ok = notify_db_updated(Db2),
- couch_db_update_notifier:notify({updated, Db#db.name}),
+ couch_hooks:run(db_udpated, Db#db.name, [Db#db.name]),
{reply, {ok, Db2#db.update_seq}, Db2};
handle_call({set_security, NewSec}, _From, #db{compression = Comp} = Db) ->
@@ -149,7 +150,7 @@ handle_call({purge_docs, IdRevs}, _From, Db) ->
header=Header#db_header{purge_seq=PurgeSeq+1, purged_docs=Pointer}}),
ok = notify_db_updated(Db2),
- couch_db_update_notifier:notify({updated, Db#db.name}),
+ couch_hooks:run(db_updated, Db#db.name, [Db#db.name]),
{reply, {ok, (Db2#db.header)#db_header.purge_seq, IdRevsPurged}, Db2};
handle_call(start_compact, _From, Db) ->
case Db#db.compactor_pid of
@@ -203,7 +204,7 @@ handle_call({compact_done, CompactFilepath}, _From, #db{filepath=Filepath}=Db) -
close_db(Db),
NewDb3 = refresh_validate_doc_funs(NewDb2),
ok = notify_db_updated(NewDb3),
- couch_db_update_notifier:notify({compacted, NewDb3#db.name}),
+ couch_hooks:run(db_compacted, NewDb3#db.name, [NewDb3#db.name]),
?LOG_INFO("Compaction for db \"~s\" completed.", [Db#db.name]),
{reply, ok, NewDb3#db{compactor_pid=nil}};
false ->
@@ -237,12 +238,12 @@ handle_info({update_docs, Client, GroupedDocs, NonRepDocs, MergeConflicts,
{ok, Db2, UpdatedDDocIds} ->
ok = notify_db_updated(Db2),
if Db2#db.update_seq /= Db#db.update_seq ->
- couch_db_update_notifier:notify({updated, Db2#db.name});
+ couch_hooks:run(db_updated, Db2#db.name, [Db2#db.name]);
true -> ok
end,
[catch(ClientPid ! {done, self()}) || ClientPid <- Clients],
lists:foreach(fun(DDocId) ->
- couch_db_update_notifier:notify({ddoc_updated, {Db#db.name, DDocId}})
+ couch_hooks:run(ddoc_updated, Db#db.name, [Db#db.name, DDocId])
end, UpdatedDDocIds),
{noreply, Db2}
catch
View
37 apps/couch/src/couch_server.erl
@@ -163,12 +163,19 @@ init([]) ->
ets:new(couch_dbs_by_name, [ordered_set, protected, named_table]),
ets:new(couch_dbs_by_pid, [set, private, named_table]),
ets:new(couch_sys_dbs, [set, private, named_table]),
+
+ %% ADD db hooks
+ ok = add_db_hooks(),
+
process_flag(trap_exit, true),
{ok, #server{root_dir=RootDir,
dbname_regexp=RegExp,
start_time=couch_util:rfc1123_date()}}.
terminate(_Reason, _Srv) ->
+ %% remove db hooks
+ ok = remove_db_hooks(),
+ %% close opened databases
lists:foreach(
fun({_, Pid}) ->
couch_util:shutdown_sync(Pid)
@@ -212,7 +219,7 @@ do_open_db(DbName, Server, Options, {FromPid, _}) ->
true = ets:insert(couch_dbs_by_pid, {DbPid, DbName}),
case lists:member(create, Options) of
true ->
- couch_db_update_notifier:notify({created, DbName});
+ couch_hooks:run(db_created, DbName, [DbName]);
false ->
ok
end,
@@ -277,7 +284,7 @@ handle_call({delete, DbName, _Options}, _From, Server) ->
case couch_file:delete(Server#server.root_dir, FullFilepath) of
ok ->
- couch_db_update_notifier:notify({deleted, DbName}),
+ couch_hooks:run(db_deleted, DbName, [DbName]),
{reply, ok, Server2};
{error, enoent} ->
{reply, not_found, Server2};
@@ -314,3 +321,29 @@ handle_info({'EXIT', Pid, Reason}, Server) ->
{noreply, Server2};
handle_info(Info, Server) ->
{stop, {unknown_message, Info}, Server}.
+
+
+
+add_db_hooks() ->
+ couch_hooks:add(db_created, '*', couch_db_update_notifier, db_created, 0),
+ couch_hooks:add(db_deleted, '*', couch_db_update_notifier, db_deleted, 0),
+ couch_hooks:add(db_updated, '*', couch_db_update_notifier, db_updated, 0),
+ couch_hooks:add(db_compacted, '*', couch_db_update_notifier,
+ db_compacted, 0),
+ couch_hooks:add(ddoc_updated, '*', couch_db_update_notifier,
+ ddoc_updated, 0),
+ ok.
+
+
+remove_db_hooks() ->
+ couch_hooks:delete(db_created, '*', couch_db_update_notifier,
+ db_created, 0),
+ couch_hooks:delete(db_deleted, '*', couch_db_update_notifier,
+ db_deleted, 0),
+ couch_hooks:delete(db_updated, '*', couch_db_update_notifier,
+ db_updated, 0),
+ couch_hooks:delete(db_compacted, '*', couch_db_update_notifier,
+ db_compacted, 0),
+ couch_hooks:delete(ddoc_updated, '*', couch_db_update_notifier,
+ ddoc_updated, 0),
+ ok.
View
2  tools.mk
@@ -104,7 +104,7 @@ verbose-test: testbuild
@echo "==> test couch_replicator"
@prove -v $(BASE_DIR)/apps/couch_replicator/test/*.t
-core-tests:
+core-tests: testbuild
@echo "==> test couch core"
@prove -v $(COUCHDB_ETAP_DIR)/*.t
Please sign in to comment.
Something went wrong with that request. Please try again.