From f533dda4935d69c1de3124667b435e6384b8243b Mon Sep 17 00:00:00 2001 From: Marcos Bento Date: Mon, 11 Nov 2024 16:39:27 +0000 Subject: [PATCH] Enable reloading of Mirror configuration Mirror attribute is reset with the latest configuration when "reload" is used as value on a Alter Mirror command Re ECFLOW-1986 --- libs/base/src/ecflow/base/cts/user/AlterCmd.cpp | 2 +- libs/node/src/ecflow/node/MirrorAttr.cpp | 15 ++++++++++++--- libs/node/src/ecflow/node/MirrorAttr.hpp | 9 +++++++++ libs/node/src/ecflow/node/NodeChange.cpp | 14 +++++++++----- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/libs/base/src/ecflow/base/cts/user/AlterCmd.cpp b/libs/base/src/ecflow/base/cts/user/AlterCmd.cpp index 517c736cc..6b4c64b2a 100644 --- a/libs/base/src/ecflow/base/cts/user/AlterCmd.cpp +++ b/libs/base/src/ecflow/base/cts/user/AlterCmd.cpp @@ -613,7 +613,7 @@ const char* AlterCmd::desc() { " For change:\n" " [ variable | clock_type | clock_gain | clock_date | clock_sync | event | meter | label |\n" " trigger | complete | repeat | limit_max | limit_value | defstatus | late | time |\n" - " today, aviso, mirror ]\n" + " today | aviso | mirror ]\n" " *NOTE* If the clock is changed, then the suite will need to be re-queued in order for\n" " the change to take effect fully.\n" " For add:\n" diff --git a/libs/node/src/ecflow/node/MirrorAttr.cpp b/libs/node/src/ecflow/node/MirrorAttr.cpp index bce3abbcd..d8c3134c6 100644 --- a/libs/node/src/ecflow/node/MirrorAttr.cpp +++ b/libs/node/src/ecflow/node/MirrorAttr.cpp @@ -74,6 +74,14 @@ void MirrorAttr::reset() { start_controller(); } +void MirrorAttr::reload() { + if (controller_) { + state_change_no_ = Ecf::incr_state_change_no(); + stop_controller(); + start_controller(); + } +} + void MirrorAttr::finish() { stop_controller(); } @@ -190,7 +198,7 @@ std::string MirrorAttr::resolve_cfg(const std::string& value, } void MirrorAttr::start_controller() { - if (controller_ == nullptr) { + if (!controller_) { // Resolve variables in configuration // In the case of the 'remote_host', we have to resolve the configuration @@ -217,7 +225,8 @@ void MirrorAttr::start_controller() { SLOG(D, "MirrorAttr: start polling Mirror attribute '" << absolute_name() << "', from " << remote_path_ << " @ " - << remote_host << ':' << remote_port << ")"); + << remote_host << ':' << remote_port << ") using polling: " + << polling << " s"); std::uint32_t polling_value; try { @@ -247,7 +256,7 @@ void MirrorAttr::start_controller() { } void MirrorAttr::stop_controller() { - if (controller_ != nullptr) { + if (controller_) { SLOG(D, "MirrorAttr: finishing polling for Mirror attribute \"" << parent_->absNodePath() << ":" << name_ << "\", from host: " << remote_host_ diff --git a/libs/node/src/ecflow/node/MirrorAttr.hpp b/libs/node/src/ecflow/node/MirrorAttr.hpp index 45786fa7f..199bc73a3 100644 --- a/libs/node/src/ecflow/node/MirrorAttr.hpp +++ b/libs/node/src/ecflow/node/MirrorAttr.hpp @@ -59,6 +59,8 @@ class MirrorAttr { static constexpr const char* fallback_polling = "120"; static constexpr const char* fallback_remote_auth = ""; + static constexpr const char* reload_option_value = "reload"; + static bool is_valid_name(const std::string& name); /** @@ -104,8 +106,15 @@ class MirrorAttr { /** * Initialises the Mirror procedure, which effectively starts the background polling mechanism. + * Typically, called when traversing the tree -- does nothing if Mirror service is already set up. */ void reset(); + /** + * Restarts the Mirror procedure, which effectively stops before restarting the background polling mechanism. + * Typicallly, called explicitly via Alter command -- forces the reinitialisation of the Mirror service, + * guaranteeing that parameters, given as ECF variables, are reevaluated. + */ + void reload(); void finish(); /** diff --git a/libs/node/src/ecflow/node/NodeChange.cpp b/libs/node/src/ecflow/node/NodeChange.cpp index 8abbe8e4d..8befadb15 100644 --- a/libs/node/src/ecflow/node/NodeChange.cpp +++ b/libs/node/src/ecflow/node/NodeChange.cpp @@ -201,11 +201,15 @@ void Node::changeMirror(const std::string& name, const std::string& value) { throw std::runtime_error("Node::changeMirror: Could not find mirror " + name); } - auto attr = MirrorParser::parse_mirror_line(value, name, this); - - // The following delete/add enforces the reconfiguration of the attribute backend thread - this->deleteMirror(name); // delete the mirror if it exists (to avoid duplicates - this->addMirror(attr); + if (value == MirrorAttr::reload_option_value) { + found->reload(); + } else { + auto attr = MirrorParser::parse_mirror_line(value, name, this); + + // The following delete/add enforces the reconfiguration of the attribute backend thread + this->deleteMirror(name); // delete the mirror if it exists (to avoid duplicates + this->addMirror(attr); + } state_change_no_ = Ecf::incr_state_change_no(); }