This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch notify_on_reload
in repository https://gitbox.apache.org/repos/asf/couchdb-config.git

commit dcf8d0eb56e59443b0dcc265c47a85501ac12329
Author: Will Holley <[email protected]>
AuthorDate: Tue Jan 21 21:58:12 2020 +0000

    Raise notify events on reload
    
    When config is reloaded from disk, raise notification events
    for values that have changed or are deleted.
---
 src/config.erl        | 20 ++++++++++++++++----
 test/config_tests.erl | 25 ++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/src/config.erl b/src/config.erl
index 50d2a5d..f109067 100644
--- a/src/config.erl
+++ b/src/config.erl
@@ -300,17 +300,29 @@ handle_call(reload, _From, Config) ->
     end, dict:new(), Config#config.ini_files),
     % Update ets with anything we just read
     % from disk
-    dict:fold(fun(K, V, _) ->
-        ets:insert(?MODULE, {K, V})
+    dict:fold(fun({Sec, Key} = K, V, _) ->
+        VExisting = get(Sec, Key, V),
+        ets:insert(?MODULE, {K, V}),
+        case V =:= VExisting of
+            true ->
+                ok;
+            false ->
+                couch_log:notice("Reload detected config change ~s.~s = ~p", 
[Sec, Key, V]),
+                Event = {config_change, Sec, Key, V, true},
+                gen_event:sync_notify(config_event, Event)
+        end
     end, nil, DiskKVs),
     % And remove anything in ets that wasn't
     % on disk.
-    ets:foldl(fun({K, _}, _) ->
+    ets:foldl(fun({{Sec, Key} = K, _}, _) ->
         case dict:is_key(K, DiskKVs) of
             true ->
                 ok;
             false ->
-                ets:delete(?MODULE, K)
+                couch_log:notice("Reload deleting in-memory config ~s.~s", 
[Sec, Key]),
+                ets:delete(?MODULE, K),
+                Event = {config_change, Sec, Key, deleted, true},
+                gen_event:sync_notify(config_event, Event)
         end
     end, nil, ?MODULE),
     {reply, ok, Config}.
diff --git a/test/config_tests.erl b/test/config_tests.erl
index ac3c77e..fae0d43 100644
--- a/test/config_tests.erl
+++ b/test/config_tests.erl
@@ -293,7 +293,9 @@ config_notifier_behaviour_test_() ->
                 {["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_not_add_duplicate/2}
+                {all, fun should_not_add_duplicate/2},
+                {all, fun should_notify_on_config_reload/2},
+                {all, fun should_notify_on_config_reload_flush/2}
             ]
         }
     }.
@@ -707,6 +709,27 @@ should_keep_features_on_config_restart() ->
     with_process_restart(config),
     ?assertEqual([snek], config:features()).
 
+should_notify_on_config_reload(Subscription, {_Apps, Pid}) ->
+    {to_string(Subscription), ?_test(begin
+        ?assertEqual(ok, config:set("section_foo", "key_bar", "any", true)),
+        ?assertEqual({config_change,"section_foo", "key_bar", "any", true}, 
getmsg(Pid)),
+        ?assertEqual(ok, config:set("section_foo", "key_bar", "not_any", 
false)),
+        ?assertEqual({config_change,"section_foo", "key_bar", "not_any", 
false}, getmsg(Pid)),
+        ?assertEqual(ok, config:reload()),
+        ?assertEqual({config_change,"section_foo", "key_bar", "any", true}, 
getmsg(Pid)),
+        ok
+    end)}.
+
+should_notify_on_config_reload_flush(Subscription, {_Apps, Pid}) ->
+    {to_string(Subscription), ?_test(begin
+        ?assertEqual(ok, config:set("section_foo_temp", "key_bar", "any", 
false)),
+        ?assertEqual({config_change,"section_foo_temp", "key_bar", "any", 
false}, getmsg(Pid)),
+        ?assertEqual(ok, config:reload()),
+        ?assertEqual({config_change,"section_foo_temp", "key_bar", deleted, 
true}, getmsg(Pid)),
+        ok
+    end)}.
+
+
 spawn_config_listener() ->
     Self = self(),
     Pid = erlang:spawn(fun() ->

Reply via email to