Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
Use khash for tracking event listeners
After doing some testing locally it became apparent that ets is a bit of
a bottleneck when used as a bag with many duplicate keys. Theoretically
this new approach could be accomplished by nesting ets tables but the
ets table limit makes that approach untenable in the long run.

This just replaces the use of ets with khash as well as runs a nested
hash table structure to store the list of pids for each database name.
  • Loading branch information
davisp authored and rnewson committed Jul 30, 2014
1 parent 1deb3d4 commit 8e6797a2db00813d62d0bf3054153de6618022b3
Showing 6 changed files with 168 additions and 261 deletions.
@@ -26,17 +26,15 @@
register/2,
register_many/2,
register_all/1,
unregister/2,
unregister_many/2,
unregister_all/1
unregister/1
]).

-define(REGISTRY, couch_event_registry).
-define(DIST, couch_event_dist).

-define(SERVER, couch_event_server).


notify(DbName, Event) ->
gen_server:cast(?DIST, {DbName, Event}).
gen_server:cast(?SERVER, {notify, DbName, Event}).


listen(Module, Function, State, Options) ->
@@ -52,24 +50,16 @@ stop_listener(Pid) ->


register(Pid, DbName) ->
gen_server:call(?REGISTRY, {register, Pid, [DbName]}).
gen_server:call(?SERVER, {register, Pid, [DbName]}).


register_many(Pid, DbNames) when is_list(DbNames) ->
gen_server:call(?REGISTRY, {register, Pid, DbNames}).
gen_server:call(?SERVER, {register, Pid, DbNames}).


register_all(Pid) ->
gen_server:call(?REGISTRY, {register, Pid, [all_dbs]}).


unregister(Pid, DbName) ->
gen_server:call(?REGISTRY, {unregister, Pid, [DbName]}).


unregister_many(Pid, DbNames) when is_list(DbNames) ->
gen_server:call(?REGISTRY, {unregister, Pid, DbNames}).
gen_server:call(?SERVER, {register, Pid, [all_dbs]}).


unregister_all(Pid) ->
gen_server:call(?REGISTRY, {unregister, Pid}).
unregister(Pid) ->
gen_server:call(?SERVER, {unregister, Pid}).

This file was deleted.

@@ -179,10 +179,10 @@ do_info(#st{module=Module, state=State}=St, Message) ->

do_terminate(Reason, #st{module=Module, state=State}) ->
% Order matters. We want to make sure Module:terminate/1
% is called even if couch_event:unregister_all/1 hangs
% is called even if couch_event:unregister/1 hangs
% indefinitely.
catch Module:terminate(Reason, State),
catch couch_event:unregister_all(self()),
catch couch_event:unregister(self()),
Status = case Reason of
normal -> normal;
shutdown -> normal;

This file was deleted.

0 comments on commit 8e6797a

Please sign in to comment.