Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id AE5B4112AC for ; Fri, 1 Aug 2014 09:09:57 +0000 (UTC) Received: (qmail 11074 invoked by uid 500); 1 Aug 2014 09:09:57 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 10920 invoked by uid 500); 1 Aug 2014 09:09:57 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 10757 invoked by uid 99); 1 Aug 2014 09:09:57 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Aug 2014 09:09:57 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 42BA89BCB46; Fri, 1 Aug 2014 09:09:57 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: rnewson@apache.org To: commits@couchdb.apache.org Date: Fri, 01 Aug 2014 09:09:59 -0000 Message-Id: In-Reply-To: <7ec92bc8976347e8be5a76bf4eac0b9b@git.apache.org> References: <7ec92bc8976347e8be5a76bf4eac0b9b@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [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 Authored: Mon Apr 22 15:48:06 2013 -0500 Committer: Robert Newson 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).