From 89d645539cd230336337b5982016f90eba687e31 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Tue, 11 Oct 2016 07:54:03 +0200 Subject: [PATCH] refactor: Drop modules on failure If a module error occur, just stop the failing module and let the application keep running. --- include/components/controller.hpp | 22 +++++++- include/modules/meta.hpp | 93 +++++++++++++++++++------------ include/modules/text.hpp | 15 ++--- 3 files changed, 85 insertions(+), 45 deletions(-) diff --git a/include/components/controller.hpp b/include/components/controller.hpp index 75354657..6b5c0c3b 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -67,6 +67,7 @@ class controller { for (auto&& block : m_modules) { for (auto&& module : block.second) { module->on_update.disconnect(this, &controller::on_module_update); + module->on_stop.disconnect(this, &controller::on_module_stop); module->stop(); } } @@ -95,6 +96,7 @@ class controller { for (auto&& block : m_modules) { for (auto&& module : block.second) { module->on_update.disconnect(this, &controller::on_module_update); + module->on_stop.disconnect(this, &controller::on_module_stop); module->stop(); } } @@ -203,7 +205,13 @@ class controller { for (auto&& block : m_modules) { for (auto&& module : block.second) { module->on_update.connect(this, &controller::on_module_update); - module->start(); + module->on_stop.connect(this, &controller::on_module_stop); + + try { + module->start(); + } catch (const application_error& err) { + m_log.err("Failed to start '%s' (reason: %s)", module->name(), err.what()); + } } } @@ -463,6 +471,18 @@ class controller { m_bar->parse(contents); } + void on_module_stop(string module_name) { + for (auto&& block : m_modules) { + for (auto&& module : block.second) { + if (module->running()) + return; + } + } + + m_log.warn("No running modules, raising SIGTERM"); + kill(getpid(), SIGTERM); + } + void on_module_click(string input) { if (!m_mutex.try_lock()) return; diff --git a/include/modules/meta.hpp b/include/modules/meta.hpp index 97353c21..8b4768df 100644 --- a/include/modules/meta.hpp +++ b/include/modules/meta.hpp @@ -148,6 +148,7 @@ namespace modules { virtual ~module_interface() {} virtual string name() const = 0; + virtual bool running() const = 0; virtual void setup() = 0; virtual void start() = 0; @@ -159,6 +160,7 @@ namespace modules { virtual bool receive_events() const = 0; delegate::Signal1 on_update; + delegate::Signal1 on_stop; }; // }}} @@ -195,17 +197,23 @@ namespace modules { return m_name; } + bool running() const { + return enabled(); + } + void setup() { m_log.trace("%s: Setup", name()); CAST_MODULE(Impl)->setup(); } void stop() { - // std::lock_guard lck(this->broadcast_lock); - // std::lock_guard lck(this->update_lock); + if (!enabled()) + return; m_log.trace("%s: Stop", name()); enable(false); wakeup(); + if (!on_stop.empty()) + on_stop.emit(name()); } void refresh() { @@ -265,8 +273,6 @@ namespace modules { } string get_output() { - // std::lock_guard lck(this->output_lock); - if (!enabled()) { m_log.trace("%s: Module is disabled", name()); return ""; @@ -332,7 +338,7 @@ namespace modules { void start() { CAST_MODULE(Impl)->setup(); CAST_MODULE(Impl)->enable(true); - CAST_MODULE(Impl)->m_threads.emplace_back(thread(&static_module::broadcast, this)); + CAST_MODULE(Impl)->broadcast(); } bool build(builder*, string) { @@ -359,15 +365,21 @@ namespace modules { interval_t m_interval = 1s; void runner() { - CAST_MODULE(Impl)->setup(); + try { + CAST_MODULE(Impl)->setup(); - while (CONST_CAST_MODULE(Impl).enabled()) { - { - std::lock_guard lck(this->update_lock); - if (CAST_MODULE(Impl)->update()) - CAST_MODULE(Impl)->broadcast(); + while (CONST_CAST_MODULE(Impl).enabled()) { + { + std::lock_guard lck(this->update_lock); + if (CAST_MODULE(Impl)->update()) + CAST_MODULE(Impl)->broadcast(); + } + CAST_MODULE(Impl)->sleep(m_interval); } - CAST_MODULE(Impl)->sleep(m_interval); + } catch (const application_error& err) { + this->m_log.err("%s: %s", this->name(), err.what()); + this->m_log.warn("Stopping '%s'...", this->name()); + CAST_MODULE(Impl)->stop(); } } }; @@ -387,25 +399,31 @@ namespace modules { protected: void runner() { - CAST_MODULE(Impl)->setup(); - - // warmup - CAST_MODULE(Impl)->update(); - CAST_MODULE(Impl)->broadcast(); - - while (CONST_CAST_MODULE(Impl).enabled()) { - std::unique_lock lck(this->update_lock); - - if (!CAST_MODULE(Impl)->has_event()) - continue; - - if (!CAST_MODULE(Impl)->update()) - continue; + try { + CAST_MODULE(Impl)->setup(); + // warmup + CAST_MODULE(Impl)->update(); CAST_MODULE(Impl)->broadcast(); - lck.unlock(); - CAST_MODULE(Impl)->idle(); + while (CONST_CAST_MODULE(Impl).enabled()) { + std::unique_lock lck(this->update_lock); + + if (!CAST_MODULE(Impl)->has_event()) + continue; + + if (!CAST_MODULE(Impl)->update()) + continue; + + CAST_MODULE(Impl)->broadcast(); + + lck.unlock(); + CAST_MODULE(Impl)->idle(); + } + } catch (const application_error& err) { + this->m_log.err("%s: %s", this->name(), err.what()); + this->m_log.warn("Stopping '%s'...", this->name()); + CAST_MODULE(Impl)->stop(); } } }; @@ -425,18 +443,19 @@ namespace modules { protected: void runner() { - CAST_MODULE(Impl)->setup(); - CAST_MODULE(Impl)->on_event(nullptr); // warmup - CAST_MODULE(Impl)->broadcast(); + try { + CAST_MODULE(Impl)->setup(); + CAST_MODULE(Impl)->on_event(nullptr); // warmup + CAST_MODULE(Impl)->broadcast(); - while (CAST_MODULE(Impl)->enabled()) { - std::lock_guard lck(this->update_lock); - try { + while (CAST_MODULE(Impl)->enabled()) { + std::lock_guard lck(this->update_lock); CAST_MODULE(Impl)->poll_events(); - } catch (const system_error& e) { - this->m_log.err("%s: Error while polling for events (what: %s)", this->name(), e.what()); - return; } + } catch (const application_error& err) { + this->m_log.err("%s: %s", this->name(), err.what()); + this->m_log.warn("Stopping '%s'...", this->name()); + CAST_MODULE(Impl)->stop(); } } diff --git a/include/modules/text.hpp b/include/modules/text.hpp index 74f1aa2e..98768f60 100644 --- a/include/modules/text.hpp +++ b/include/modules/text.hpp @@ -10,13 +10,17 @@ namespace modules { using static_module::static_module; void setup() { - m_formatter->add(FORMAT, "", {}); - if (m_formatter->get(FORMAT)->value.empty()) - throw undefined_format(FORMAT); + m_formatter->add("content", "", {}); + + if (m_formatter->get("content")->value.empty()) + throw module_error(name() + ".content is empty or undefined"); + + m_formatter->get("content")->value = + string_util::replace_all(m_formatter->get("content")->value, " ", BUILDER_SPACE_TOKEN); } string get_format() { - return FORMAT; + return "content"; } string get_output() { @@ -41,9 +45,6 @@ namespace modules { return m_builder->flush(); } - - private: - static constexpr auto FORMAT = "content"; }; }