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).