Merge pull request #29 from apache/notify_on_reload

Raise notify events on reload
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 @@
     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 @@
                 {["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 @@
     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() ->