diff options
author | Andreas Kling <kling@serenityos.org> | 2021-08-26 19:31:43 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-26 23:41:38 +0200 |
commit | 83d3720842d1b31769c05615c7c8eb23471bba79 (patch) | |
tree | 52ca1d3f110e8b4ace7b2144be950d05abe60309 /Userland/Services/ConfigServer | |
parent | 696dbc889f8aefd394e32aafe50e2d166c57cf02 (diff) | |
download | serenity-83d3720842d1b31769c05615c7c8eb23471bba79.zip |
ConfigServer: Monitor opened config files for changes
After opening a domain configuration and putting into our configuration
cache, we now monitor the underlying file for changes and send out
notifications to monitoring clients as needed.
This patch has three FIXME's:
- We create a new Core::FileWatcher for each domain.
- We don't yet detect removed keys.
- We don't know the type of key, so we assume everything is a string.
There are a number of ways we can solve those problems but let's not
hold up this patch while we wait for solutions. :^)
Diffstat (limited to 'Userland/Services/ConfigServer')
-rw-r--r-- | Userland/Services/ConfigServer/ClientConnection.cpp | 27 | ||||
-rw-r--r-- | Userland/Services/ConfigServer/ClientConnection.h | 2 |
2 files changed, 28 insertions, 1 deletions
diff --git a/Userland/Services/ConfigServer/ClientConnection.cpp b/Userland/Services/ConfigServer/ClientConnection.cpp index 246a95e10f..6a2e0194b6 100644 --- a/Userland/Services/ConfigServer/ClientConnection.cpp +++ b/Userland/Services/ConfigServer/ClientConnection.cpp @@ -7,6 +7,7 @@ #include "ClientConnection.h" #include <ConfigServer/ConfigClientEndpoint.h> #include <LibCore/ConfigFile.h> +#include <LibCore/FileWatcher.h> namespace ConfigServer { @@ -15,6 +16,7 @@ static HashMap<int, RefPtr<ClientConnection>> s_connections; struct CachedDomain { String domain; NonnullRefPtr<Core::ConfigFile> config; + RefPtr<Core::FileWatcher> watcher; }; static HashMap<String, NonnullOwnPtr<CachedDomain>> s_cache; @@ -26,7 +28,30 @@ static Core::ConfigFile& ensure_domain_config(String const& domain) return *it->value->config; auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes); - auto cache_entry = make<CachedDomain>(domain, config); + // FIXME: Use a single FileWatcher with multiple watches inside. + auto watcher_or_error = Core::FileWatcher::create(InodeWatcherFlags::Nonblock); + VERIFY(!watcher_or_error.is_error()); + auto result = watcher_or_error.value()->add_watch(config->filename(), Core::FileWatcherEvent::Type::ContentModified); + VERIFY(!result.is_error()); + watcher_or_error.value()->on_change = [config, domain](auto&) { + auto new_config = Core::ConfigFile::open(config->filename()); + // FIXME: Detect removed keys. + // FIXME: Detect type of keys. + for (auto& group : new_config->groups()) { + for (auto& key : new_config->keys(group)) { + auto old_value = config->read_entry(group, key); + auto new_value = new_config->read_entry(group, key); + if (old_value != new_value) { + for (auto& it : s_connections) { + if (it.value->is_monitoring_domain(domain)) { + it.value->async_notify_changed_string_value(domain, group, key, new_value); + } + } + } + } + } + }; + auto cache_entry = make<CachedDomain>(domain, config, watcher_or_error.release_value()); s_cache.set(domain, move(cache_entry)); return *config; } diff --git a/Userland/Services/ConfigServer/ClientConnection.h b/Userland/Services/ConfigServer/ClientConnection.h index 55bd3ebb9c..026f17ff81 100644 --- a/Userland/Services/ConfigServer/ClientConnection.h +++ b/Userland/Services/ConfigServer/ClientConnection.h @@ -20,6 +20,8 @@ public: virtual void die() override; + bool is_monitoring_domain(String const& domain) const { return m_monitored_domains.contains(domain); } + private: explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id); |