Make sure we don't subscribe multiple times
Check there is no subscription from given Pid in subscribe_for_changes
COUCHDB-3102
diff --git a/src/config_notifier.erl b/src/config_notifier.erl
index c1844e7..52fc4c0 100644
--- a/src/config_notifier.erl
+++ b/src/config_notifier.erl
@@ -33,8 +33,13 @@
subscribe(self(), Subscription).
subscribe(Subscriber, Subscription) ->
- gen_event:add_sup_handler(
- config_event, {?MODULE, Subscriber}, {Subscriber, Subscription}).
+ case lists:member(Subscriber, handlers()) of
+ true ->
+ ok;
+ false ->
+ gen_event:add_sup_handler(
+ config_event, {?MODULE, Subscriber}, {Subscriber, Subscription})
+ end.
init({Subscriber, Subscription}) ->
{ok, {Subscriber, Subscription}}.
@@ -66,3 +71,7 @@
should_notify(Sec, Key, Subscription) ->
lists:any(fun(S) -> S =:= Sec orelse S =:= {Sec, Key} end, Subscription).
+
+handlers() ->
+ AllHandlers = gen_event:which_handlers(config_event),
+ [Id || {?MODULE, Id} <- AllHandlers].
diff --git a/test/config_tests.erl b/test/config_tests.erl
index 854e20e..d3464e1 100644
--- a/test/config_tests.erl
+++ b/test/config_tests.erl
@@ -271,7 +271,8 @@
{[{"section_foo", "key_bar"}], fun should_notify/2},
{["section_foo"], fun should_not_notify/2},
{[{"section_foo", "key_bar"}], fun should_not_notify/2},
- {all, fun should_unsubscribe_when_subscriber_gone/2}
+ {all, fun should_unsubscribe_when_subscriber_gone/2},
+ {all, fun should_not_add_duplicate/2}
]
}
}.
@@ -585,6 +586,20 @@
ok
end).
+should_not_add_duplicate(_, _) ->
+ ?_test(begin
+ ?assertEqual(1, n_notifiers()), %% spawned from setup
+
+ ?assertMatch(ok, config:subscribe_for_changes(all)),
+
+ ?assertEqual(2, n_notifiers()),
+
+ ?assertMatch(ok, config:subscribe_for_changes(all)),
+
+ ?assertEqual(2, n_notifiers()),
+ ok
+ end).
+
spawn_config_listener() ->
Self = self(),