You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/08/01 11:09:59 UTC
[03/35] git commit: Minimize message from monitors
Minimize message from monitors
I wasn't deduping monitors before. That bugged me enough to add an extra
ets table so that we can dedupe those messages and avoid the extra work
done by couch_event_registry.
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-event/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-event/commit/f4c80d73
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-event/tree/f4c80d73
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-event/diff/f4c80d73
Branch: refs/heads/windsor-merge
Commit: f4c80d73e8b6c09ff9bdf300875fb2d501209e66
Parents: cc616a7
Author: Paul J. Davis <pa...@gmail.com>
Authored: Mon Apr 22 15:48:06 2013 -0500
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 17:35:26 2014 +0100
----------------------------------------------------------------------
src/couch_event_int.hrl | 4 +--
src/couch_event_registry.erl | 64 ++++++++++++++++++++++-----------------
2 files changed, 39 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch-event/blob/f4c80d73/src/couch_event_int.hrl
----------------------------------------------------------------------
diff --git a/src/couch_event_int.hrl b/src/couch_event_int.hrl
index dc4739e..f837e1d 100644
--- a/src/couch_event_int.hrl
+++ b/src/couch_event_int.hrl
@@ -11,9 +11,9 @@
% the License.
-define(REGISTRY_TABLE, couch_event_registry).
+-define(MONITOR_TABLE, couch_event_registry_monitors).
-record(client, {
dbname,
- pid,
- ref
+ pid
}).
http://git-wip-us.apache.org/repos/asf/couchdb-couch-event/blob/f4c80d73/src/couch_event_registry.erl
----------------------------------------------------------------------
diff --git a/src/couch_event_registry.erl b/src/couch_event_registry.erl
index 65fa160..e956a83 100644
--- a/src/couch_event_registry.erl
+++ b/src/couch_event_registry.erl
@@ -36,13 +36,19 @@ start_link() ->
init(_) ->
- EtsOpts = [
+ RegistryOpts = [
protected,
named_table,
bag,
{keypos, #client.dbname}
],
- ets:new(?REGISTRY_TABLE, EtsOpts),
+ MonitorOpts = [
+ protected,
+ named_table,
+ set
+ ],
+ ets:new(?REGISTRY_TABLE, RegistryOpts),
+ ets:new(?MONITOR_TABLE, MonitorOpts),
{ok, nil}.
@@ -53,36 +59,24 @@ terminate(_Reason, _St) ->
handle_call({register, Pid, DbName}, _From, St) ->
Client = #client{
dbname = DbName,
- pid = Pid,
- ref = erlang:monitor(process, Pid)
+ pid = Pid
},
ets:insert(?REGISTRY_TABLE, Client),
+ case ets:lookup(?MONITOR_TABLE, Pid) of
+ [] ->
+ Ref = erlang:monitor(process, Pid),
+ ets:insert(?MONITOR_TABLE, {Pid, Ref});
+ [{Pid, _}] ->
+ ok
+ end,
{reply, ok, St};
handle_call({unregister, Pid, DbName}, _From, St) ->
- Pattern = #client{dbname=DbName, pid=Pid, _='_'},
- case ets:match_object(?REGISTRY_TABLE, Pattern) of
- [] ->
- ok;
- [#client{ref=Ref}=Cli] ->
- erlang:demonitor(Ref, [flush]),
- ets:delete_object(?REGISTRY_TABLE, Cli)
- end,
+ unregister_pattern(#client{dbname=DbName, pid=Pid, _='_'}),
{reply, ok, St};
handle_call({unregister_all, Pid}, _From, St) ->
- Pattern = #client{pid=Pid, _='_'},
- case ets:match_object(?REGISTRY_TABLE, Pattern) of
- [] ->
- ok;
- Clients ->
- lists:foreach(fun(Cli) ->
- erlang:demonitor(Cli#client.ref, [flush]),
- % I wonder if match_delete/2 is faster
- % than repeated calls to delete_object.
- ets:delete_object(Cli)
- end, Clients)
- end,
+ unregister_pattern(#client{pid=Pid, _='_'}),
{reply, ok, St};
handle_call(Msg, From, St) ->
@@ -95,9 +89,8 @@ handle_cast(Msg, St) ->
{noreply, St, 0}.
-handle_info({'DOWN', Ref, process, Pid, _Reason}, St) ->
- Pattern = #client{pid=Pid, ref=Ref, _='_'},
- ets:match_delete(?REGISTRY_TABLE, Pattern),
+handle_info({'DOWN', _Ref, process, Pid, _Reason}, St) ->
+ unregister_pattern(#client{pid=Pid, _='_'}),
{noreply, St};
handle_info(Msg, St) ->
@@ -107,3 +100,20 @@ handle_info(Msg, St) ->
code_change(_OldVsn, St, _Extra) ->
{ok, St}.
+
+
+unregister_pattern(Pattern) ->
+ Clients = ets:match_object(?REGISTRY_TABLE, Pattern),
+ Refs = lists:foldl(fun(#client{pid=Pid}=Cli, Acc) ->
+ ets:delete_object(?REGISTRY_TABLE, Cli),
+ case ets:lookup(?MONITOR_TABLE, Pid) of
+ [{Pid, Ref}] ->
+ ets:delete(?MONITOR_TABLE, Pid),
+ [Ref | Acc];
+ [] ->
+ Acc
+ end
+ end, [], Clients),
+ lists:foreach(fun(Ref) ->
+ erlang:demonitor(Ref, [flush])
+ end, Refs).