From 19ea70ebc8bbd387e2b57945fea05638e52a41a6 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 24 Aug 2026 11:30:17 +0100 Subject: [PATCH 01/12] Remove leftover definitions --- .../src/process_group_manager/alive_monitor_thread.hpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp b/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp index 4290470a4..3eab6f2a6 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp @@ -19,6 +19,7 @@ #include #include "score/mw/launch_manager/process_group_manager/ialive_monitor_thread.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" namespace score { @@ -41,11 +42,6 @@ class AliveMonitorThread final : public IAliveMonitorThread void stop() override; private: - void notifyInitializationComplete( - score::mw::lifecycle::internal::saf::daemon::EInitCode& f_init_status_r, - const score::mw::lifecycle::internal::saf::daemon::EInitCode f_init_result); - void waitForInitializationCompleted(score::mw::lifecycle::internal::saf::daemon::EInitCode& f_init_status_r); - std::unique_ptr m_health_monitor{nullptr}; std::thread alive_monitor_thread_{}; std::atomic_bool stop_thread_{false}; From 50b42459f29702005929b2646a323281a3b23e83 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 24 Aug 2026 15:11:39 +0100 Subject: [PATCH 02/12] Alive monitor changes to expose factory --- score/launch_manager/src/daemon/BUILD | 2 - .../src/daemon/src/alive_monitor/BUILD | 12 +++ .../{details/daemon => }/IAliveMonitor.hpp | 13 +-- .../src/alive_monitor/details/common/BUILD | 8 ++ .../details/common/EInitCode.hpp | 34 ++++++++ .../details/daemon/AliveMonitorImpl.cpp | 44 +++++++--- .../details/daemon/AliveMonitorImpl.hpp | 23 ++++-- .../src/alive_monitor/details/daemon/BUILD | 14 +--- .../details/daemon/PhmDaemon.cpp | 7 +- .../details/daemon/PhmDaemon.hpp | 25 +++--- .../src/alive_monitor/details/ifappl/BUILD | 1 + .../details/ifappl/MonitorIfDaemon.cpp | 2 +- .../src/alive_monitor/details/ifexm/BUILD | 5 +- .../details/ifexm/ObservableEventReader.cpp | 38 +++++++-- .../details/ifexm/ObservableEventReader.hpp | 14 ++-- score/launch_manager/src/daemon/src/main.cpp | 17 +--- .../daemon/src/process_group_manager/BUILD | 37 +-------- .../alive_monitor_thread.cpp | 45 ---------- .../alive_monitor_thread.hpp | 54 ------------ .../ialive_monitor_thread.hpp | 35 -------- .../mock_alive_monitor_thread.hpp | 41 ---------- .../process_group_manager.cpp | 7 +- .../process_group_manager.hpp | 11 +-- .../src/supervision_control_client/BUILD | 61 +++----------- .../supervision_control_client/details/BUILD | 27 ------ .../details/supervision_control_receiver.cpp | 54 ------------ .../details/supervision_control_receiver.hpp | 68 --------------- .../isupervision_control_notifier.hpp | 44 ---------- .../isupervision_control_receiver.hpp | 46 ----------- .../isupervision_event_publisher.hpp | 9 +- .../isupervision_factory.hpp | 49 +++++++++++ .../mock_iprocess_state_notifier.hpp | 44 ---------- .../mock_supervision_control_notifier.hpp | 32 -------- .../mock_supervision_event_publisher.hpp | 31 ------- .../supervision_control_notifier.cpp | 64 --------------- .../supervision_control_notifier.hpp | 82 ------------------- .../supervision_event.hpp | 6 ++ .../supervision_handle.hpp | 70 ++++++++++++++++ 38 files changed, 324 insertions(+), 852 deletions(-) rename score/launch_manager/src/daemon/src/alive_monitor/{details/daemon => }/IAliveMonitor.hpp (77%) create mode 100644 score/launch_manager/src/daemon/src/alive_monitor/details/common/EInitCode.hpp delete mode 100644 score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.cpp delete mode 100644 score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp delete mode 100644 score/launch_manager/src/daemon/src/process_group_manager/ialive_monitor_thread.hpp delete mode 100644 score/launch_manager/src/daemon/src/process_group_manager/mock_alive_monitor_thread.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/details/BUILD delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.cpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_notifier.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_receiver.hpp create mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/mock_iprocess_state_notifier.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_control_notifier.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.cpp delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.hpp create mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp diff --git a/score/launch_manager/src/daemon/BUILD b/score/launch_manager/src/daemon/BUILD index 34705a594..f0f06f284 100644 --- a/score/launch_manager/src/daemon/BUILD +++ b/score/launch_manager/src/daemon/BUILD @@ -27,9 +27,7 @@ cc_binary( "//score/launch_manager/src/daemon/src/configuration:flatbuffer_config_loader", "//score/launch_manager/src/daemon/src/osal:ipc_comms", "//score/launch_manager/src/daemon/src/process_group_manager", - "//score/launch_manager/src/daemon/src/process_group_manager:alive_monitor_thread", "//score/launch_manager/src/daemon/src/recovery_client", - "//score/launch_manager/src/daemon/src/supervision_control_client:supervision_control_notifier", "//score/launch_manager/src/daemon/src/watchdog:watchdog_factory", "@score_baselibs//score/language/futurecpp", ], diff --git a/score/launch_manager/src/daemon/src/alive_monitor/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/BUILD index 8bea5e726..ac52a9246 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/BUILD @@ -19,3 +19,15 @@ cc_library( "//score/launch_manager/src/daemon/src/alive_monitor/details/daemon:health_monitor_impl", ], ) + +cc_library( + name = "i_alive_monitor", + hdrs = ["IAliveMonitor.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", + visibility = ["//score:__subpackages__"], + deps = [ + "//score/launch_manager/src/daemon/src/alive_monitor/details/common:einitcode", + "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", + ], +) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/IAliveMonitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp similarity index 77% rename from score/launch_manager/src/daemon/src/alive_monitor/details/daemon/IAliveMonitor.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp index ac4a8b1b4..06df8243d 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/IAliveMonitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp @@ -13,9 +13,8 @@ #ifndef SAF_DAEMON_ALIVE_MONITOR_HPP_INCLUDED #define SAF_DAEMON_ALIVE_MONITOR_HPP_INCLUDED -#include - -#include "score/mw/launch_manager/alive_monitor/details/daemon/PhmDaemon.hpp" +#include "score/mw/launch_manager/alive_monitor/details/common/EInitCode.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" namespace score { @@ -36,9 +35,11 @@ class IAliveMonitor /// @return kNoError if initialization was successful, otherwise an appropriate error code. virtual EInitCode init() noexcept = 0; - /// @brief Run the AliveMonitor functionality in a cyclic manner until cancellation is requested. - /// @param cancel_thread Atomic boolean flag to signal thread cancellation. - virtual bool run(std::atomic_bool& cancel_thread) noexcept = 0; + virtual bool start() = 0; + + virtual void stop() = 0; + + virtual ISupervisionFactory& getSupervisionFactory() = 0; }; } // namespace daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD index 2a229864b..99b2cc282 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD @@ -30,6 +30,14 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], ) +cc_library( + name = "einitcode", + hdrs = ["EInitCode.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor/details/common", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/common", + visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], +) + cc_library( name = "locked_vector", hdrs = ["LockedVector.hpp"], diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/common/EInitCode.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/common/EInitCode.hpp new file mode 100644 index 000000000..d93b50fc0 --- /dev/null +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/common/EInitCode.hpp @@ -0,0 +1,34 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#ifndef E_INIT_CODE_HPP_INCLUDED +#define E_INIT_CODE_HPP_INCLUDED + +#include + +namespace score::mw::lifecycle::internal::saf::daemon +{ + +/// @brief Return codes for PhmDaemon Initialization +enum class EInitCode : std::int8_t +{ + kNoError, ///< Init Successful (no error occurred) + kNotInitialized, ///< Init was not performed + kCycleTimeInitFailed, ///< Cyclic Timer initialization failed + kConstructFlatCfgFactoryFailed, ///< FlatCfgFactory failed loading SWCL configurations + kGeneralError ///< General error +}; + +} // namespace score::mw::lifecycle::internal::saf::daemon + +#endif diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp index 958479054..1908413fb 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp @@ -11,24 +11,20 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ #include - #include #include #include "score/mw/launch_manager/alive_monitor/details/daemon/AliveMonitorImpl.hpp" +#include "score/mw/launch_manager/alive_monitor/details/daemon/PhmDaemon.hpp" namespace score::mw::lifecycle::internal::saf::daemon { -AliveMonitorImpl::AliveMonitorImpl( - SptrIRecoveryClient recovery_client, - UptrISupervisionControlReceiver observable_event_receiver, - const Config& config) - : m_recovery_client(recovery_client), - m_observable_event_receiver(std::move(observable_event_receiver)), - m_config(config) +AliveMonitorImpl::AliveMonitorImpl(SptrIRecoveryClient recovery_client, const Config& config) + : m_recovery_client(recovery_client), m_config(config) { + initResult = init(); } EInitCode AliveMonitorImpl::init() noexcept @@ -38,7 +34,7 @@ EInitCode AliveMonitorImpl::init() noexcept { m_osClock.startMeasurement(); - m_daemon = std::make_unique(m_osClock, std::move(m_observable_event_receiver)); + m_daemon = std::make_unique(m_osClock); initResult = m_daemon->init(m_recovery_client, m_config); if (initResult == EInitCode::kNoError) @@ -65,11 +61,39 @@ EInitCode AliveMonitorImpl::init() noexcept return initResult; } -bool AliveMonitorImpl::run(std::atomic_bool& cancel_thread) noexcept +bool AliveMonitorImpl::start() noexcept +{ + if (initResult != EInitCode::kNoError) + { + return false; + } + + alive_monitor_thread_ = std::thread([this]() { + threadFn(stop_thread_); + }); + + return true; +} + +void AliveMonitorImpl::stop() noexcept +{ + stop_thread_.store(true); + if (alive_monitor_thread_.joinable()) + { + alive_monitor_thread_.join(); + } +} + +bool AliveMonitorImpl::threadFn(std::atomic_bool& cancel_thread) noexcept { SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE( m_daemon != nullptr, "HealthMonitor: Instance is not initialized!"); return m_daemon->startCyclicExec(cancel_thread); } +ISupervisionFactory& AliveMonitorImpl::getSupervisionFactory() noexcept +{ + return *m_daemon; +} + } // namespace score::mw::lifecycle::internal::saf::daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index 3cab63bb4..8803a636d 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -15,8 +15,9 @@ #include #include +#include -#include "score/mw/launch_manager/alive_monitor/details/daemon/IAliveMonitor.hpp" +#include "score/mw/launch_manager/alive_monitor/IAliveMonitor.hpp" #include "score/mw/launch_manager/configuration/config.hpp" namespace score @@ -36,7 +37,6 @@ namespace daemon { using SptrIRecoveryClient = std::shared_ptr; -using UptrISupervisionControlReceiver = std::unique_ptr; using UptrPhmDaemon = std::unique_ptr; using OsClock = score::mw::lifecycle::internal::saf::timers::OsClockInterface; using Config = score::mw::lifecycle::internal::configuration::Config; @@ -45,21 +45,28 @@ using score::mw::lifecycle::internal::configuration::AliveSupervisionConfig; class AliveMonitorImpl : public IAliveMonitor { public: - AliveMonitorImpl( - SptrIRecoveryClient recovery_client, - UptrISupervisionControlReceiver observable_event_receiver, - const Config& config); + AliveMonitorImpl(SptrIRecoveryClient recovery_client, const Config& config); EInitCode init() noexcept override; - bool run(std::atomic_bool& cancel_thread) noexcept override; + bool start() noexcept override; + + void stop() noexcept override; + + ISupervisionFactory& getSupervisionFactory() noexcept override; private: + /// @brief Run the AliveMonitor functionality in a cyclic manner until cancellation is requested. + /// @param cancel_thread Atomic boolean flag to signal thread cancellation. + bool threadFn(std::atomic_bool& cancel_thread) noexcept; + SptrIRecoveryClient m_recovery_client{nullptr}; UptrPhmDaemon m_daemon{nullptr}; OsClock m_osClock{}; - UptrISupervisionControlReceiver m_observable_event_receiver; const Config& m_config; + std::thread alive_monitor_thread_{}; + std::atomic_bool stop_thread_{false}; + saf::daemon::EInitCode initResult{saf::daemon::EInitCode::kNotInitialized}; }; } // namespace daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD index 4cc7d1804..c29b9df3a 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD @@ -51,6 +51,7 @@ cc_library( deps = [ ":phm_daemon_config", ":sw_cluster_handler", + "//score/launch_manager/src/daemon/src/alive_monitor/details/common:einitcode", "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:flat_cfg_factory", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:monitor_if_daemon", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event_reader", @@ -59,18 +60,10 @@ cc_library( "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:cycle_timer", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:log", + "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) -cc_library( - name = "i_health_monitor", - hdrs = ["IAliveMonitor.hpp"], - include_prefix = "score/mw/launch_manager/alive_monitor/details/daemon", - strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/daemon", - visibility = ["//score/launch_manager/src/daemon:__subpackages__"], - deps = [":phm_daemon"], -) - cc_library( name = "health_monitor_impl", srcs = ["AliveMonitorImpl.cpp"], @@ -79,7 +72,8 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/daemon", visibility = ["//score/launch_manager/src/daemon:__subpackages__"], deps = [ - ":i_health_monitor", + ":phm_daemon", + "//score/launch_manager/src/daemon/src/alive_monitor:i_alive_monitor", "//score/launch_manager/src/daemon/src/configuration:config", "@score_baselibs//score/language/futurecpp", ], diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp index f9d2862ba..ff4e6aa25 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp @@ -27,13 +27,14 @@ namespace score::mw::lifecycle::internal::saf::daemon true_no_defect) */ /* RULECHECKER_comment(0, 4, check_incomplete_data_member_construction, "Default constructor is used for\ processStateReader.", true_no_defect) */ -PhmDaemon::PhmDaemon(OsClock& f_osClock, std::unique_ptr f_observable_event_receiver) +PhmDaemon::PhmDaemon(OsClock& f_osClock) : osClock{f_osClock}, cycleTimer{&osClock}, + buffer_(std::make_shared()), supervisionManager{std::make_unique()}, - processStateReader{std::move(f_observable_event_receiver)} + processStateReader{buffer_} { - static_cast(f_osClock); + buffer_->initialize(); } void PhmDaemon::performCyclicTriggers(void) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index d23b180b9..974a85243 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -26,6 +26,7 @@ #include "score/mw/launch_manager/alive_monitor/details/timers/CycleTimer.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/TimeConversion.hpp" #include "score/mw/launch_manager/configuration/config.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" namespace score { @@ -36,24 +37,13 @@ namespace saf namespace daemon { -/// @brief Return codes for PhmDaemon Initialization -enum class EInitCode : std::int8_t -{ - kNoError, ///< Init Successful (no error occurred) - kNotInitialized, ///< Init was not performed - kCycleTimeInitFailed, ///< Cyclic Timer initialization failed - kConstructFlatCfgFactoryFailed, ///< FlatCfgFactory failed loading SWCL configurations - kGeneralError ///< General error -}; - /// @brief PHM daemon main class wraps the functionality for initialization and cyclic execution. /// @details This is the main class responsible to execute the main functionalities of PHM daemon, /// by using the necessary classes from this software component. -class PhmDaemon +class PhmDaemon : public ISupervisionFactory { public: using OsClock = score::mw::lifecycle::internal::saf::timers::OsClockInterface; - using SupervisionControlReceiver = score::mw::lifecycle::ISupervisionControlReceiver; using RecoveryClient = score::mw::lifecycle::IRecoveryClient; using CycleTimer = score::mw::lifecycle::internal::saf::timers::CycleTimer; using CycleTimeValidator = score::mw::lifecycle::internal::saf::timers::CycleTimeValidator; @@ -69,7 +59,7 @@ class PhmDaemon /// in tests) /* RULECHECKER_comment(3,1, check_expensive_to_copy_in_parameter, "Move only types cannot be passed by const ref", true_no_defect) */ - PhmDaemon(OsClock& f_osClock, std::unique_ptr f_observable_event_receiver); + explicit PhmDaemon(OsClock& f_osClock); /* RULECHECKER_comment(0, 4, check_min_instructions, "Default destructor is not provided\ a function body", true_no_defect) */ @@ -193,6 +183,13 @@ class PhmDaemon return true; } + SupervisionHandle + constructSupervision(IdentifierHash id, uid_t uid, configuration::ComponentAliveSupervision config) override + { + supervisionManager.constructWorker(id, config, uid, recoveryClient, processStateReader); + return SupervisionHandle{id, buffer_}; + } + private: /// @brief Create SwCluster objects & Invoke construction of worker objects /// @details Create the SwclusterHandler objects and the workers for the SwclusterHandler @@ -210,6 +207,8 @@ class PhmDaemon /// @brief For fixed time-step execution during the cyclic execution CycleTimer cycleTimer; + std::shared_ptr buffer_; + /// @brief Recovery interface to Launch Manager std::shared_ptr recoveryClient; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/BUILD index 6417eadda..73fd72d0e 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/BUILD @@ -54,6 +54,7 @@ cc_library( ":data_structures", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", + "//score/launch_manager/src/daemon/src/common:log", ], ) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp index f8caa9f51..59e4e55e5 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp @@ -15,8 +15,8 @@ #include -#include "score/launch_manager/src/daemon/src/common/log.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" +#include "score/mw/launch_manager/common/log.hpp" namespace score::mw::lifecycle::internal::saf::ifappl { diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD index e8cdc0c30..2999e2fef 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD @@ -22,7 +22,7 @@ cc_library( deps = [ "//score/launch_manager/src/daemon/src/alive_monitor/details/common:observer", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", - "//score/launch_manager/src/daemon/src/supervision_control_client", + "//score/launch_manager/src/daemon/src/supervision_control_client:supervision_event", ], ) @@ -35,9 +35,10 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ ":observable_event", + "//score/launch_manager:error_event", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:time_conversion", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:log", - "//score/launch_manager/src/daemon/src/supervision_control_client", + "//score/launch_manager/src/daemon/src/supervision_control_client:supervision_event", ], ) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp index 448bbe4b2..96804a648 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp @@ -14,12 +14,13 @@ #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEventReader.hpp" #include "score/launch_manager/src/daemon/src/common/log.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/TimeConversion.hpp" +#include "score/mw/lifecycle/execution_error.h" namespace score::mw::lifecycle::internal::saf::ifexm { -ObservableEventReader::ObservableEventReader(std::unique_ptr f_observable_event_receiver) - : processStateReceiverHM(std::move(f_observable_event_receiver)) +ObservableEventReader::ObservableEventReader(std::shared_ptr f_observable_event_receiver) + : buffer_(f_observable_event_receiver) { } @@ -64,8 +65,7 @@ bool ObservableEventReader::distributeChanges(const timers::NanoSecondType f_syn bool flagContinue{true}; do { - score::Result> resultEvent{ - processStateReceiverHM->getNextSupervisionEvent()}; + score::Result> resultEvent{getNextSupervisionEvent()}; if (resultEvent) { @@ -93,8 +93,36 @@ bool ObservableEventReader::distributeChanges(const timers::NanoSecondType f_syn return flagSuccess; } +score::Result> ObservableEventReader::getNextSupervisionEvent() noexcept +{ + score::mw::lifecycle::SupervisionEvent event; + if (buffer_->getOverflowFlag()) + { + LM_LOG_ERROR() << "ObservableEventReader::getNextSupervisionEvent: Overflow occurred, " + "will be reported as kCommunicationError"; + return score::Result>{ + score::MakeUnexpected(score::mw::lifecycle::ExecErrc::kCommunicationError)}; + } + + if (buffer_->empty()) + { + return score::Result>{std::nullopt}; + } + + auto res = buffer_->tryDequeue(event); + if (res) + { + return score::Result>{event}; + } + else + { + return score::Result>{ + score::MakeUnexpected(score::mw::lifecycle::ExecErrc::kGeneralError)}; + } +} + bool ObservableEventReader::pushUpdateTill( - const LcmSupervisionEvent& f_event, + const SupervisionEvent& f_event, const timers::NanoSecondType f_syncTimestamp) noexcept { bool isSyncTimestampReached{false}; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp index 228acf5da..eda6e3178 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp @@ -18,9 +18,10 @@ #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_control_receiver.hpp" #include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" +#include "score/result/result.h" + namespace score { namespace mw::lifecycle::internal @@ -36,12 +37,9 @@ namespace ifexm class ObservableEventReader { public: - using LcmSupervisionEvent = score::mw::lifecycle::SupervisionEvent; - using LcmSupervisionControlReceiver = score::mw::lifecycle::ISupervisionControlReceiver; - /// @brief Constructor /// @param [in] f_observable_event_receiver Process state receiver implementation - ObservableEventReader(std::unique_ptr f_observable_event_receiver); + explicit ObservableEventReader(std::shared_ptr f_observable_event_receiver); /// @brief No Copy Constructor ObservableEventReader(const ObservableEventReader&) = delete; @@ -76,10 +74,12 @@ class ObservableEventReader /// @param [in] f_event Supervision event for which push update is needed /// @param [in] f_syncTimestamp Timestamp for cyclic synchronization /// @return true (sync timestamp is reached), false (sync timestamp is not yet reached) - bool pushUpdateTill(const LcmSupervisionEvent& f_event, const timers::NanoSecondType f_syncTimestamp) noexcept; + bool pushUpdateTill(const SupervisionEvent& f_event, const timers::NanoSecondType f_syncTimestamp) noexcept; + + score::Result> getNextSupervisionEvent() noexcept; /// @brief Process state receiver for HM thread - std::unique_ptr processStateReceiverHM; + std::shared_ptr buffer_; /// @brief Map for process id and observable event object std::map processStateMap{}; diff --git a/score/launch_manager/src/daemon/src/main.cpp b/score/launch_manager/src/daemon/src/main.cpp index 9ffa87a35..fb7dc0312 100644 --- a/score/launch_manager/src/daemon/src/main.cpp +++ b/score/launch_manager/src/daemon/src/main.cpp @@ -20,10 +20,8 @@ #include "score/mw/launch_manager/alive_monitor/details/daemon/AliveMonitorImpl.hpp" #include "score/mw/launch_manager/common/log.hpp" #include "score/mw/launch_manager/configuration/flatbuffer_config_loader.hpp" -#include "score/mw/launch_manager/process_group_manager/alive_monitor_thread.hpp" #include "score/mw/launch_manager/process_group_manager/process_group_manager.hpp" #include "score/mw/launch_manager/recovery_client/recovery_client.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_control_notifier.hpp" #include "score/mw/launch_manager/watchdog/WatchdogFactory.hpp" using namespace std; @@ -161,23 +159,14 @@ int main(int argc, const char* argv[]) std::shared_ptr recoveryClient{std::make_shared()}; - auto supervision_control_notifier = std::make_unique(); - // currently this is copying the config. - std::unique_ptr healthMonitor{std::make_unique( - recoveryClient, supervision_control_notifier->constructReceiver(), *config_result)}; + std::unique_ptr healthMonitor{ + std::make_unique(recoveryClient, *config_result)}; static_cast(config_result.value().takeAliveSupervision()); - std::unique_ptr aliveMonitorThread{ - std::make_unique(std::move(healthMonitor))}; - auto watchdog = watchdog::createWatchdog(); auto process_group_manager = std::make_unique( - std::move(config_result).value(), - std::move(aliveMonitorThread), - recoveryClient, - std::move(supervision_control_notifier), - std::move(watchdog)); + std::move(config_result).value(), std::move(healthMonitor), recoveryClient, std::move(watchdog)); if (process_group_manager->initialize()) { diff --git a/score/launch_manager/src/daemon/src/process_group_manager/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/BUILD index 707cb5202..c7fe705f3 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/BUILD +++ b/score/launch_manager/src/daemon/src/process_group_manager/BUILD @@ -38,40 +38,6 @@ cc_library( ], ) -cc_library( - name = "ialive_monitor_thread", - hdrs = ["ialive_monitor_thread.hpp"], - include_prefix = "score/mw/launch_manager/process_group_manager", - strip_include_prefix = "/score/launch_manager/src/daemon/src/process_group_manager", - visibility = ["//score:__subpackages__"], -) - -cc_library( - name = "mock_ialive_monitor_thread", - testonly = True, - hdrs = ["mock_alive_monitor_thread.hpp"], - include_prefix = "score/mw/launch_manager/process_group_manager", - strip_include_prefix = "/score/launch_manager/src/daemon/src/process_group_manager", - visibility = ["//score:__subpackages__"], - deps = [ - ":ialive_monitor_thread", - "@googletest//:gtest", - ], -) - -cc_library( - name = "alive_monitor_thread", - srcs = ["alive_monitor_thread.cpp"], - hdrs = ["alive_monitor_thread.hpp"], - include_prefix = "score/mw/launch_manager/process_group_manager", - strip_include_prefix = "/score/launch_manager/src/daemon/src/process_group_manager", - visibility = ["//score:__subpackages__"], - deps = [ - ":ialive_monitor_thread", - "//score/launch_manager/src/daemon/src/alive_monitor", - ], -) - cc_library( name = "process_group_manager", srcs = ["process_group_manager.cpp"], @@ -80,8 +46,8 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/process_group_manager", visibility = ["//score:__subpackages__"], deps = [ - ":ialive_monitor_thread", ":iprocess", + "//score/launch_manager/src/daemon/src/alive_monitor:i_alive_monitor", "//score/launch_manager/src/daemon/src/common:identifier_hash", "//score/launch_manager/src/daemon/src/common/concurrency:mpmc_concurrent_queue", "//score/launch_manager/src/daemon/src/common/concurrency:thread_pool", @@ -96,7 +62,6 @@ cc_library( "//score/launch_manager/src/daemon/src/process_group_manager/details:process_monitor", "//score/launch_manager/src/daemon/src/process_group_manager/details:safe_process_map", "//score/launch_manager/src/daemon/src/recovery_client", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_control_notifier", "//score/launch_manager/src/daemon/src/watchdog:i_watchdog_if", "@score_baselibs//score/language/futurecpp", ], diff --git a/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.cpp b/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.cpp deleted file mode 100644 index e2c4c56dd..000000000 --- a/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#include "score/mw/launch_manager/process_group_manager/alive_monitor_thread.hpp" - -namespace score::mw::lifecycle::internal -{ - -AliveMonitorThread::AliveMonitorThread(std::unique_ptr health_monitor) - : m_health_monitor(std::move(health_monitor)) -{ - initResult = m_health_monitor->init(); -} - -bool AliveMonitorThread::start() -{ - alive_monitor_thread_ = std::thread([this]() { - if (initResult == saf::daemon::EInitCode::kNoError) - { - m_health_monitor->run(stop_thread_); - } - }); - - return initResult == saf::daemon::EInitCode::kNoError; -} - -void AliveMonitorThread::stop() -{ - stop_thread_.store(true); - if (alive_monitor_thread_.joinable()) - { - alive_monitor_thread_.join(); - } -} - -} // namespace score::mw::lifecycle::internal diff --git a/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp b/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp deleted file mode 100644 index 3eab6f2a6..000000000 --- a/score/launch_manager/src/daemon/src/process_group_manager/alive_monitor_thread.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#ifndef SCORE_LCM_ALIVE_MONITOR_THREAD_HPP_INCLUDED -#define SCORE_LCM_ALIVE_MONITOR_THREAD_HPP_INCLUDED - -#include "score/mw/launch_manager/alive_monitor/details/daemon/IAliveMonitor.hpp" -#include -#include -#include - -#include "score/mw/launch_manager/process_group_manager/ialive_monitor_thread.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" - -namespace score -{ -namespace mw::lifecycle -{ -namespace internal -{ - -/// @brief AliveMonitor manages the lifecycle of the alive monitoring daemon in a separate thread. -class AliveMonitorThread final : public IAliveMonitorThread -{ - public: - explicit AliveMonitorThread(std::unique_ptr health_monitor); - - /// @brief Starts the Alive Monitor thread. - /// @return true if the Alive Monitor started successfully, false otherwise. - bool start() override; - - /// @brief Stops the Alive Monitor thread. - void stop() override; - - private: - std::unique_ptr m_health_monitor{nullptr}; - std::thread alive_monitor_thread_{}; - std::atomic_bool stop_thread_{false}; - saf::daemon::EInitCode initResult{saf::daemon::EInitCode::kNotInitialized}; -}; - -} // namespace internal -} // namespace mw::lifecycle -} // namespace score -#endif diff --git a/score/launch_manager/src/daemon/src/process_group_manager/ialive_monitor_thread.hpp b/score/launch_manager/src/daemon/src/process_group_manager/ialive_monitor_thread.hpp deleted file mode 100644 index 23fbf41f2..000000000 --- a/score/launch_manager/src/daemon/src/process_group_manager/ialive_monitor_thread.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#ifndef SCORE_LCM_IALIVE_MONITOR_THREAD_HPP_INCLUDED -#define SCORE_LCM_IALIVE_MONITOR_THREAD_HPP_INCLUDED - -namespace score -{ -namespace mw::lifecycle -{ -namespace internal -{ -class IAliveMonitorThread -{ - public: - virtual bool start() = 0; - virtual void stop() = 0; - - virtual ~IAliveMonitorThread() = default; -}; -} // namespace internal -} // namespace mw::lifecycle -} // namespace score - -#endif diff --git a/score/launch_manager/src/daemon/src/process_group_manager/mock_alive_monitor_thread.hpp b/score/launch_manager/src/daemon/src/process_group_manager/mock_alive_monitor_thread.hpp deleted file mode 100644 index bc3f22309..000000000 --- a/score/launch_manager/src/daemon/src/process_group_manager/mock_alive_monitor_thread.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#ifndef SCORE_LCM_IALIVE_MONITOR_THREAD_MOCK_HPP_INCLUDED -#define SCORE_LCM_IALIVE_MONITOR_THREAD_MOCK_HPP_INCLUDED - -#include "score/mw/launch_manager/process_group_manager/ialive_monitor_thread.hpp" - -#include - -namespace score -{ -namespace mw::lifecycle -{ -namespace internal -{ - -/// @brief Reusable gmock mock for IAliveMonitorThread, for use by tests of components that own an alive monitor -/// thread. -class MockAliveMonitorThread : public IAliveMonitorThread -{ - public: - MOCK_METHOD(bool, start, (), (override)); - MOCK_METHOD(void, stop, (), (override)); -}; - -} // namespace internal -} // namespace mw::lifecycle -} // namespace score - -#endif // SCORE_LCM_IALIVE_MONITOR_THREAD_MOCK_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp index ceb4f1ff6..b992d1959 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp @@ -19,7 +19,6 @@ #include "score/mw/launch_manager/common/log.hpp" #include "score/mw/launch_manager/process_group_manager/details/process_monitor.hpp" -#include "score/mw/launch_manager/process_group_manager/ialive_monitor_thread.hpp" #include "score/mw/launch_manager/process_group_manager/process_group_manager.hpp" namespace score::mw::lifecycle::internal @@ -39,17 +38,15 @@ void ProcessGroupManager::cancel() ProcessGroupManager::ProcessGroupManager( configuration::Config&& config, - std::unique_ptr alive_monitor_thread, + std::unique_ptr alive_monitor, std::shared_ptr recovery_client, - std::unique_ptr supervision_control_notifier, std::unique_ptr watchdog) : configuration_(std::move(config)), process_interface_(), process_map_(nullptr), thread_pool_(nullptr), worker_jobs_(nullptr), - supervision_control_notifier_(std::move(supervision_control_notifier)), - alive_monitor_thread_(std::move(alive_monitor_thread)), + alive_monitor_(std::move(alive_monitor)), recovery_client_(recovery_client), watchdog_(std::move(watchdog)) { diff --git a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp index 811cff93a..51d065bbd 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp @@ -18,6 +18,7 @@ #include #include +#include "score/mw/launch_manager/alive_monitor/IAliveMonitor.hpp" #include "score/mw/launch_manager/common/concurrency/mpmc_concurrent_queue.hpp" #include "score/mw/launch_manager/common/concurrency/thread_pool.hpp" #include "score/mw/launch_manager/common/constants.hpp" @@ -32,10 +33,8 @@ #include "score/mw/launch_manager/process_group_manager/details/process_launcher.hpp" #include "score/mw/launch_manager/process_group_manager/details/process_monitor.hpp" #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" -#include "score/mw/launch_manager/process_group_manager/ialive_monitor_thread.hpp" #include "score/mw/launch_manager/process_group_manager/iprocess.hpp" #include "score/mw/launch_manager/recovery_client/recovery_client.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_control_notifier.hpp" #include "score/mw/launch_manager/watchdog/IWatchdogIf.hpp" namespace score::mw::lifecycle::internal @@ -73,9 +72,8 @@ class ProcessGroupManager final : public ITransitionResultPublisher /// legacy configuration where no watchdog is wired. ProcessGroupManager( configuration::Config&& config, - std::unique_ptr alive_monitor_thread, + std::unique_ptr alive_monitor, std::shared_ptr recovery_client, - std::unique_ptr supervision_control_notifier, std::unique_ptr watchdog); /// @brief Initializes the process group manager. @@ -279,10 +277,7 @@ class ProcessGroupManager final : public ITransitionResultPublisher /// @brief Pointer to the gaph. std::shared_ptr graph_{nullptr}; - /// @brief Process state notifier object used to send data to PHM - std::unique_ptr supervision_control_notifier_; - - std::unique_ptr alive_monitor_thread_; + std::unique_ptr alive_monitor_; std::unique_ptr process_monitor_; diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD index 1a5e5a213..0b1ac5c71 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD +++ b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD @@ -20,44 +20,43 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", visibility = ["//score:__subpackages__"], deps = [ + "//externals/ipc_dropin", "//score/launch_manager/src/daemon/src/common:identifier_hash", ], ) cc_library( - name = "isupervision_control_receiver", - hdrs = ["isupervision_control_receiver.hpp"], + name = "isupervision_event_publisher", + hdrs = ["isupervision_event_publisher.hpp"], include_prefix = "score/mw/launch_manager/supervision_control_client", strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", visibility = ["//score:__subpackages__"], - deps = [ - ":supervision_event", - "//score/launch_manager:error", - "@score_baselibs//score/result", - ], ) cc_library( - name = "isupervision_control_notifier", - hdrs = ["isupervision_control_notifier.hpp"], + name = "supervision_handle", + hdrs = ["supervision_handle.hpp"], include_prefix = "score/mw/launch_manager/supervision_control_client", strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", visibility = ["//score:__subpackages__"], deps = [ - ":isupervision_control_receiver", ":isupervision_event_publisher", ":supervision_event", + "//score/launch_manager/src/daemon/src/common:identifier_hash", + "//score/launch_manager/src/daemon/src/common:log", ], ) cc_library( - name = "isupervision_event_publisher", - hdrs = ["isupervision_event_publisher.hpp"], + name = "isupervision_factory", + hdrs = ["isupervision_factory.hpp"], include_prefix = "score/mw/launch_manager/supervision_control_client", strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", visibility = ["//score:__subpackages__"], deps = [ + ":supervision_handle", "//score/launch_manager/src/daemon/src/common:identifier_hash", + "//score/launch_manager/src/daemon/src/configuration:component_config", ], ) @@ -74,49 +73,11 @@ cc_library( ], ) -cc_library( - name = "mock_supervision_control_notifier", - testonly = True, - hdrs = ["mock_supervision_control_notifier.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":isupervision_control_notifier", - "@googletest//:gtest_main", - ], -) - -cc_library( - name = "supervision_control_notifier", - srcs = ["supervision_control_notifier.cpp"], - hdrs = ["supervision_control_notifier.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":isupervision_control_notifier", - "//externals/ipc_dropin", - "//score/launch_manager/src/daemon/src/common:log", - "//score/launch_manager/src/daemon/src/supervision_control_client/details:supervision_control_receiver", - ], -) - -cc_library( - name = "supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":supervision_control_notifier", - "//score/launch_manager/src/daemon/src/supervision_control_client/details:supervision_control_receiver", - ], -) - lm_cc_test( name = "supervision_control_client_ut", srcs = ["supervision_control_client_ut.cpp"], deps = [ ":supervision_control_client", - "//score/launch_manager/src/daemon/src/supervision_control_client/details:supervision_control_receiver", "@googletest//:gtest_main", ], ) diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/details/BUILD b/score/launch_manager/src/daemon/src/supervision_control_client/details/BUILD deleted file mode 100644 index 97bd6d036..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/details/BUILD +++ /dev/null @@ -1,27 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2026 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Apache License Version 2.0 which is available at -# https://www.apache.org/licenses/LICENSE-2.0 -# -# SPDX-License-Identifier: Apache-2.0 -# ******************************************************************************* -load("@rules_cc//cc:defs.bzl", "cc_library") - -cc_library( - name = "supervision_control_receiver", - srcs = ["supervision_control_receiver.cpp"], - hdrs = ["supervision_control_receiver.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client/details", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client/details", - visibility = ["//score/launch_manager/src/daemon/src/supervision_control_client:__pkg__"], - deps = [ - "//externals/ipc_dropin", - "//score/launch_manager/src/daemon/src/common:log", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_control_receiver", - ], -) diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.cpp b/score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.cpp deleted file mode 100644 index a5a92b0f3..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#include "score/mw/launch_manager/supervision_control_client/details/supervision_control_receiver.hpp" -#include "score/mw/launch_manager/common/log.hpp" - -namespace score::mw::lifecycle -{ -SupervisionControlReceiver::SupervisionControlReceiver(BufferP ring_buffer) noexcept : ring_buffer_(ring_buffer) -{ -} - -SupervisionControlReceiver::~SupervisionControlReceiver() noexcept -{ -} - -score::Result> SupervisionControlReceiver::getNextSupervisionEvent() noexcept -{ - score::mw::lifecycle::SupervisionEvent event; - if (ring_buffer_->getOverflowFlag()) - { - LM_LOG_ERROR() << "SupervisionControlReceiver::getNextSupervisionEvent: Overflow occurred, " - "will be reported as kCommunicationError"; - return score::Result>{ - score::MakeUnexpected(score::mw::lifecycle::ExecErrc::kCommunicationError)}; - } - - if (ring_buffer_->empty()) - { - return score::Result>{std::nullopt}; - } - - auto res = ring_buffer_->tryDequeue(event); - if (res) - { - return score::Result>{event}; - } - else - { - return score::Result>{ - score::MakeUnexpected(score::mw::lifecycle::ExecErrc::kGeneralError)}; - } -} -} // namespace score::mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.hpp deleted file mode 100644 index 3ca37c4e2..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/details/supervision_control_receiver.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#ifndef SUPERVISION_CONTROL_RECEIVER_HPP_INCLUDED -#define SUPERVISION_CONTROL_RECEIVER_HPP_INCLUDED - -#include "ipc_dropin/ringbuffer.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_control_receiver.hpp" - -namespace score -{ - -namespace mw::lifecycle -{ - -/// @brief SupervisionControlReceiver implementation for receiving supervision events from the Launch Manager. -class SupervisionControlReceiver final : public ISupervisionControlReceiver -{ - public: - using BufferP = std::shared_ptr(score::mw::lifecycle::BufferConstants::BUFFER_QUEUE_SIZE), - static_cast(score::mw::lifecycle::BufferConstants::BUFFER_MAXPAYLOAD)>>; - - /// @brief Constructor that creates the SupervisionControlReceiver - /// @param ring_buffer Shared pointer to the ring buffer used to receive supervision events - SupervisionControlReceiver(BufferP ring_buffer) noexcept; - - /// @brief Copy constructor is disabled. - SupervisionControlReceiver(const SupervisionControlReceiver&) noexcept = delete; - - /// @brief Move constructor is disabled. - SupervisionControlReceiver(SupervisionControlReceiver&&) noexcept = delete; - - /// @brief Copy-assign is disabled. - SupervisionControlReceiver& operator=(const SupervisionControlReceiver& other) = delete; - - /// @brief Move-assign is disabled. - SupervisionControlReceiver& operator=(SupervisionControlReceiver&& other) = delete; - - /// @brief Destructor. - ~SupervisionControlReceiver() noexcept; - - /// @brief Returns the queued SupervisionEvent, which the alive monitor has not yet parsed. - /// @returns Returns the queued SupervisionEvent. - /// "std::nullopt" is returned in case there is no new information. - /// "score::mw::lifecycle::ExecErrc::kGeneralError" is returned in case of any other error. - score::Result> getNextSupervisionEvent() noexcept override; - - private: - /// @brief Ring buffer through which supervision events are received from the Launch Manager - BufferP ring_buffer_{}; -}; - -} // namespace mw::lifecycle - -} // namespace score - -#endif // SUPERVISION_CONTROL_RECEIVER_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_notifier.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_notifier.hpp deleted file mode 100644 index 3ae726f53..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_notifier.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#ifndef ISUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED -#define ISUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED - -#include "score/mw/launch_manager/supervision_control_client/isupervision_control_receiver.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" - -namespace score -{ - -namespace mw::lifecycle -{ - -/// @brief ISupervisionControlNotifier interface for forwarding supervision events to the alive monitor. -/// The Launch Manager uses this interface to notify the alive monitor whenever a supervised -/// process reaches running state (activation) or starts terminating (deactivation). -class ISupervisionControlNotifier : public ISupervisionEventPublisher -{ - public: - /// @brief Destructor. - virtual ~ISupervisionControlNotifier() noexcept = default; - - /// @brief Construct and return the receiver instance used to receive supervision events. - /// @return Supervision control receiver instance - virtual std::unique_ptr constructReceiver() = 0; -}; - -} // namespace mw::lifecycle - -} // namespace score - -#endif diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_receiver.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_receiver.hpp deleted file mode 100644 index c64b8e31c..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_control_receiver.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#ifndef ISUPERVISION_CONTROL_RECEIVER_HPP_INCLUDED -#define ISUPERVISION_CONTROL_RECEIVER_HPP_INCLUDED - -#include "score/mw/lifecycle/execution_error.h" -#include "score/result/result.h" -#include -#include - -#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" - -namespace score -{ - -namespace mw::lifecycle -{ - -/// @brief ISupervisionControlReceiver interface for receiving supervision events. -/// The alive monitor uses this interface to receive supervision events (activation/deactivation) -/// forwarded by the Launch Manager. -class ISupervisionControlReceiver -{ - public: - virtual ~ISupervisionControlReceiver() noexcept = default; - - /// @brief Returns a queued SupervisionEvent that has not yet been parsed. - /// @returns Result containing SupervisionEvent in case of success, or ExecError in case of failure. - virtual score::Result> getNextSupervisionEvent() noexcept = 0; -}; - -} // namespace mw::lifecycle - -} // namespace score - -#endif diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp index 6921fb045..5c3168e68 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp @@ -13,7 +13,6 @@ #ifndef ISUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED #define ISUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED -#include "score/mw/launch_manager/common/identifier_hash.hpp" #include namespace score @@ -31,11 +30,11 @@ class ISupervisionEventPublisher /// @brief Destructor. virtual ~ISupervisionEventPublisher() noexcept = default; - /// @brief Report that process with @param id has reached the active state at @param time - virtual bool reportActivation(IdentifierHash id, timespec time) noexcept = 0; + /// @brief Report that the calling process has reached the active state at @param time + virtual bool reportActivation(timespec time) noexcept = 0; - /// @brief Report that process with @param id has changed from the active state at @param time - virtual bool reportDeactivation(IdentifierHash id, timespec time) noexcept = 0; + /// @brief Report that the calling process has changed from the active state at @param time + virtual bool reportDeactivation(timespec time) noexcept = 0; }; } // namespace mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp new file mode 100644 index 000000000..32da6e979 --- /dev/null +++ b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp @@ -0,0 +1,49 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#ifndef ISUPERVISION_FACTORY_HPP_INCLUDED +#define ISUPERVISION_FACTORY_HPP_INCLUDED + +#include +#include + +#include "score/mw/launch_manager/common/identifier_hash.hpp" +#include "score/mw/launch_manager/configuration/component_config.hpp" +#include "score/mw/launch_manager/supervision_control_client/supervision_handle.hpp" + +namespace score +{ + +namespace mw::lifecycle +{ + +class ISupervisionFactory +{ + public: + /// @brief Destructor. + virtual ~ISupervisionFactory() noexcept = default; + + /// @brief Set up alive supervision for the identified process. Alive supervision is not started until the publisher + /// is notified. + /// @param [in] id Identifier of the process. + /// @param [in] config Alive supervision configuration for the process. + /// @param [in] uid The configured uid of the process. + /// @returns Handle for the process to start and stop its own supervision. + virtual SupervisionHandle + constructSupervision(IdentifierHash id, uid_t uid, internal::configuration::ComponentAliveSupervision config) = 0; +}; + +} // namespace mw::lifecycle + +} // namespace score + +#endif diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_iprocess_state_notifier.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_iprocess_state_notifier.hpp deleted file mode 100644 index f37203578..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_iprocess_state_notifier.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#ifndef IPROCESSSTATE_NOTIFIER_MOCK_HPP_INCLUDED -#define IPROCESSSTATE_NOTIFIER_MOCK_HPP_INCLUDED - -#include "score/mw/launch_manager/process_state_client/iprocess_state_notifier.hpp" - -#include - -#include - -namespace score -{ -namespace mw::lifecycle -{ - -/// @brief Reusable gmock mock for IProcessStateNotifier, for use by tests of components that notify PHM of process -/// state changes. -class MockProcessStateNotifier : public IProcessStateNotifier -{ - public: - MOCK_METHOD(std::unique_ptr, constructReceiver, (), (override)); - MOCK_METHOD( - bool, - queuePosixProcess, - (const score::mw::lifecycle::PosixProcess& f_posixProcess), - (noexcept, override)); -}; - -} // namespace mw::lifecycle -} // namespace score - -#endif // IPROCESSSTATE_NOTIFIER_MOCK_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_control_notifier.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_control_notifier.hpp deleted file mode 100644 index db237840a..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_control_notifier.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#ifndef MOCK_SUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED -#define MOCK_SUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED - -#include "score/mw/launch_manager/supervision_control_client/isupervision_control_notifier.hpp" -#include - -namespace score::mw::lifecycle -{ - -class MockSupervisionControlNotifier : public ISupervisionControlNotifier -{ - public: - MOCK_METHOD(bool, reportActivation, (IdentifierHash id, timespec time), (override, noexcept)); - MOCK_METHOD(bool, reportDeactivation, (IdentifierHash id, timespec time), (override, noexcept)); - MOCK_METHOD(std::unique_ptr, constructReceiver, (), (override)); -}; - -} // namespace score::mw::lifecycle - -#endif // MOCK_SUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp deleted file mode 100644 index 645c82cf9..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#ifndef MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED -#define MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED - -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" -#include - -namespace score::mw::lifecycle -{ - -class MockSupervisionEventPublisher : public ISupervisionEventPublisher -{ - public: - MOCK_METHOD(bool, reportActivation, (IdentifierHash id, timespec time), (override, noexcept)); - MOCK_METHOD(bool, reportDeactivation, (IdentifierHash id, timespec time), (override, noexcept)); -}; - -} // namespace score::mw::lifecycle - -#endif // MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.cpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.cpp deleted file mode 100644 index 6a06b05ae..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#include "score/mw/launch_manager/supervision_control_client/supervision_control_notifier.hpp" -#include "score/mw/launch_manager/common/log.hpp" -#include "score/mw/launch_manager/supervision_control_client/details/supervision_control_receiver.hpp" - -namespace score::mw::lifecycle::internal -{ - -SupervisionControlNotifier::SupervisionControlNotifier() noexcept -{ - ring_buffer_ = std::make_shared(score::mw::lifecycle::BufferConstants::BUFFER_QUEUE_SIZE), - static_cast(score::mw::lifecycle::BufferConstants::BUFFER_MAXPAYLOAD)>>(); - - ring_buffer_->initialize(); -} - -SupervisionControlNotifier::~SupervisionControlNotifier() noexcept -{ -} - -bool SupervisionControlNotifier::reportActivation(IdentifierHash id, timespec time) noexcept -{ - return queueSupervisionEvent({id, SupervisionEventType::kActivation, time}); -} - -bool SupervisionControlNotifier::reportDeactivation(IdentifierHash id, timespec time) noexcept -{ - return queueSupervisionEvent({id, SupervisionEventType::kDeactivation, time}); -} - -bool SupervisionControlNotifier::queueSupervisionEvent(const score::mw::lifecycle::SupervisionEvent& f_event) noexcept -{ - bool ret = true; - if (ring_buffer_->tryEnqueue(f_event)) - { - // nothing - } - else - { - LM_LOG_ERROR() << "Failed to queue supervision event"; - ret = false; - } - return ret; -} - -std::unique_ptr SupervisionControlNotifier::constructReceiver() -{ - return std::make_unique(ring_buffer_); -} - -} // namespace score::mw::lifecycle::internal diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.hpp deleted file mode 100644 index 7b6aeb3e3..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_notifier.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#ifndef SUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED -#define SUPERVISION_CONTROL_NOTIFIER_HPP_INCLUDED - -#include "ipc_dropin/ringbuffer.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_control_notifier.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" - -namespace score -{ - -namespace mw::lifecycle -{ - -namespace internal -{ - -/// @brief SupervisionControlNotifier implementation for forwarding supervision events to the alive monitor. -/// The Launch Manager creates an instance of this class to queue supervision events -/// (activation/deactivation) for the alive monitor to consume via the receiver. -class SupervisionControlNotifier final : public ISupervisionControlNotifier -{ - public: - /// @brief Constructor that creates the SupervisionControlNotifier. - SupervisionControlNotifier() noexcept; - - /// @brief Copy constructor is disabled. - SupervisionControlNotifier(const SupervisionControlNotifier&) noexcept = delete; - - /// @brief Move constructor is disabled. - SupervisionControlNotifier(SupervisionControlNotifier&&) noexcept = delete; - - /// @brief Copy-assign is disabled. - SupervisionControlNotifier& operator=(const SupervisionControlNotifier& other) = delete; - - /// @brief Move-assign is disabled. - SupervisionControlNotifier& operator=(SupervisionControlNotifier&& other) = delete; - - /// @brief Destructor. - ~SupervisionControlNotifier() noexcept; - - /// @brief Construct and return the receiver instance used to receive supervision events. - /// @return Supervision control receiver instance - std::unique_ptr constructReceiver() override; - - /// @brief Report that process with @param id has reached the active state at @param time - bool reportActivation(IdentifierHash id, timespec time) noexcept override; - - /// @brief Report that process with @param id has changed from the active state at @param time - bool reportDeactivation(IdentifierHash id, timespec time) noexcept override; - - private: - /// @brief Writes via IPC the latest supervision event, so that the alive monitor can be informed about it. - /// @param[in] f_event The SupervisionEvent to be queued - /// @returns True on success, false for failure - bool queueSupervisionEvent(const score::mw::lifecycle::SupervisionEvent& f_event) noexcept; - - /// @brief Ring buffer through which supervision events are forwarded to the alive monitor - std::shared_ptr(score::mw::lifecycle::BufferConstants::BUFFER_QUEUE_SIZE), - static_cast(score::mw::lifecycle::BufferConstants::BUFFER_MAXPAYLOAD)>> - ring_buffer_{}; -}; - -} // namespace internal - -} // namespace mw::lifecycle - -} // namespace score -#endif diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_event.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_event.hpp index 320acc4d7..031e519d8 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_event.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_event.hpp @@ -14,9 +14,11 @@ #ifndef SUPERVISION_EVENT_HPP_INCLUDED #define SUPERVISION_EVENT_HPP_INCLUDED +#include "ipc_dropin/ringbuffer.hpp" #include "score/mw/launch_manager/common/identifier_hash.hpp" #include #include +#include namespace score { @@ -55,6 +57,10 @@ constexpr std::size_t BUFFER_QUEUE_SIZE = 4096UL; } // namespace BufferConstants +using SupervisionBufferType = ipc_dropin::RingBuffer< + static_cast(score::mw::lifecycle::BufferConstants::BUFFER_QUEUE_SIZE), + static_cast(score::mw::lifecycle::BufferConstants::BUFFER_MAXPAYLOAD)>; + } // namespace mw::lifecycle } // namespace score diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp new file mode 100644 index 000000000..bec5a606e --- /dev/null +++ b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp @@ -0,0 +1,70 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#ifndef SUPERVISION_HANDLE_HPP_INCLUDED +#define SUPERVISION_HANDLE_HPP_INCLUDED + +#include "score/mw/launch_manager/common/identifier_hash.hpp" +#include "score/mw/launch_manager/common/log.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" +#include + +namespace score +{ + +namespace mw::lifecycle +{ + +class SupervisionHandle : ISupervisionEventPublisher +{ + public: + explicit SupervisionHandle(IdentifierHash process_id, std::shared_ptr buffer) + : process_id_(process_id), buffer_(buffer) + { + } + + /// @brief Report that the calling process has reached the active state at @param time + bool reportActivation(timespec time) noexcept override + { + return queueSupervisionEvent({process_id_, SupervisionEventType::kActivation, time}); + } + + /// @brief Report that the calling process has changed from the active state at @param time + bool reportDeactivation(timespec time) noexcept override + { + return queueSupervisionEvent({process_id_, SupervisionEventType::kDeactivation, time}); + } + + private: + bool queueSupervisionEvent(const score::mw::lifecycle::SupervisionEvent& f_event) noexcept + { + if (buffer_->tryEnqueue(f_event)) + { + return true; + } + else + { + LM_LOG_ERROR() << "Failed to queue supervision event"; + return false; + } + } + + IdentifierHash process_id_; + std::shared_ptr buffer_; +}; + +} // namespace mw::lifecycle + +} // namespace score + +#endif From c1e9a8a7b7437aefb8ee156c57b13618c1317950 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 24 Aug 2026 17:00:43 +0100 Subject: [PATCH 03/12] PIN uses factory, integration tests pass --- .../details/daemon/AliveMonitorImpl.hpp | 1 + .../details/daemon/PhmDaemon.cpp | 22 ----------- .../details/daemon/PhmDaemon.hpp | 5 ++- .../src/process_group_manager/details/BUILD | 2 + .../process_group_manager/details/graph.cpp | 7 +++- .../process_group_manager/details/graph.hpp | 3 +- .../details/process_handling.hpp | 4 -- .../details/process_info_node.cpp | 39 ++++++++++++------- .../details/process_info_node.hpp | 13 ++++++- .../process_group_manager.cpp | 9 +++-- .../process_group_manager.hpp | 4 +- .../isupervision_factory.hpp | 2 +- .../supervision_handle.hpp | 2 +- 13 files changed, 57 insertions(+), 56 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index 8803a636d..eecea0297 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -18,6 +18,7 @@ #include #include "score/mw/launch_manager/alive_monitor/IAliveMonitor.hpp" +#include "score/mw/launch_manager/alive_monitor/details/daemon/PhmDaemon.hpp" #include "score/mw/launch_manager/configuration/config.hpp" namespace score diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp index ff4e6aa25..7e65b1bcd 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp @@ -67,28 +67,6 @@ bool PhmDaemon::construct(const std::vector& con supervisionManager.reserve(supervised_components); - // In a later refactoring step, components will register their own alive supervision and provide their identifier. - // For now, we iterate through them all here. - - LM_LOG_DEBUG() << "Supervision manager starts constructing workers"; - - for (const auto& comp : config) - { - if (!comp.component_properties.application_profile.alive_supervision.has_value()) - { - continue; - } - const auto& alive = comp.component_properties.application_profile.alive_supervision.value(); - const IdentifierHash name{comp.name}; - const auto uid = comp.deployment_config.sandbox.uid; - if (!supervisionManager.constructWorker(name, alive, uid, recoveryClient, processStateReader)) - { - - LM_LOG_ERROR() << "Supervision manager is unable to construct the required worker objects."; - return false; - } - } - return true; } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index 974a85243..8f2c38f72 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -19,6 +19,7 @@ #include #include "score/launch_manager/src/daemon/src/common/log.hpp" +#include "score/mw/launch_manager/alive_monitor/details/common/EInitCode.hpp" #include "score/mw/launch_manager/alive_monitor/details/daemon/PhmDaemonConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/daemon/SupervisionManager.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEventReader.hpp" @@ -183,11 +184,11 @@ class PhmDaemon : public ISupervisionFactory return true; } - SupervisionHandle + std::unique_ptr constructSupervision(IdentifierHash id, uid_t uid, configuration::ComponentAliveSupervision config) override { supervisionManager.constructWorker(id, config, uid, recoveryClient, processStateReader); - return SupervisionHandle{id, buffer_}; + return std::make_unique(id, buffer_); } private: diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index de31199ee..c67aa8b49 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD @@ -167,6 +167,7 @@ cc_library( "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", "//score/launch_manager/src/daemon/src/process_group_manager:process_state", "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_event_publisher", + "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", "@score_baselibs//score/language/futurecpp", ], ) @@ -220,6 +221,7 @@ cc_library( "//score/launch_manager/src/daemon/src/control:control_client_channel", "//score/launch_manager/src/daemon/src/osal:semaphore", "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", + "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp index 2d8eeb15b..a3ae13225 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp @@ -43,6 +43,7 @@ void CreateDependencyGraph( configuration::Config& config, ProcessHandling process_handling, std::unordered_map& run_target_map, + ISupervisionFactory& supervision_factory, std::chrono::milliseconds& off_state_transition_timeout) { // this is a temporary (bad) implementation, all shall be cleandup @@ -70,7 +71,8 @@ void CreateDependencyGraph( std::in_place_type, std::move(component_config), static_cast(graph.size()), - process_handling); + process_handling, + supervision_factory); LM_LOG_DEBUG() << "Creating component node:" << name << "at index:" << index; name_to_index[name] = index; @@ -132,6 +134,7 @@ Graph::Graph( configuration::Config& configuration, std::shared_ptr job_queue, ProcessHandling process_handling, + ISupervisionFactory& supervision_factory, ITransitionResultPublisher* transition_result_receiver) : nodes_(max_num_nodes), transition_builder_(nodes_), @@ -144,7 +147,7 @@ Graph::Graph( last_state_manager_.process_index_ = 0xFFFFU; // an invalid state manager last_state_manager_.process_group_index_ = 0xFFFFU; cancel_message_.request_or_response_ = ControlClientCode::kNotSet; - CreateDependencyGraph(nodes_, configuration_, process_handling_, run_targets_, off_state_transition_timeout_); + CreateDependencyGraph(nodes_, configuration_, process_handling_, run_targets_, supervision_factory, off_state_transition_timeout_); } Graph::~Graph() diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp index 4cb0ec443..87e511b6b 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp @@ -39,7 +39,7 @@ #include "score/mw/launch_manager/process_group_manager/details/run_target.hpp" #include "score/mw/launch_manager/process_group_manager/details/transition.hpp" #include "score/mw/launch_manager/process_group_manager/iprocess.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" #include namespace score @@ -161,6 +161,7 @@ class Graph final configuration::Config& configuration, std::shared_ptr job_queue, ProcessHandling process_handling, + ISupervisionFactory& supervision_factory, ITransitionResultPublisher* transition_result_receiver); /// @brief Destructor to clean up resources used by the Graph object. diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp index 50cfbb37d..6ef5744e5 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp @@ -16,7 +16,6 @@ #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/iprocess.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" #include namespace score::mw::lifecycle::internal @@ -25,9 +24,6 @@ namespace score::mw::lifecycle::internal /// @brief Collection of interfaces required to control a OS process. struct ProcessHandling { - /// @brief Interface for reporting component state to health monitor. - ISupervisionEventPublisher& state_publisher_; - /// @brief Handle to manage the underlying posix process. osal::IProcess* process_interface_{nullptr}; diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp index 754e9b1bf..7d7dc802a 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace score::mw::lifecycle::internal { @@ -27,7 +28,8 @@ namespace score::mw::lifecycle::internal ProcessInfoNode::ProcessInfoNode( configuration::ComponentConfig&& config, uint32_t index, - ProcessHandling process_handling) + ProcessHandling process_handling, + ISupervisionFactory& supervision_factory) : terminator_(), has_semaphore_(false), process_index_(index), @@ -36,17 +38,24 @@ ProcessInfoNode::ProcessInfoNode( config_(std::move(config)), process_handling_(std::move(process_handling)) { - - if (config.component_properties.application_profile.application_type == - configuration::ApplicationType::ReportingAndSupervised) - { - config_.deployment_config.environmental_variables.add( - "LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(IdentifierHash{config_.name})); - } if (config_.deployment_config.ready_recovery_action.has_value()) { start_tries_ = config_.deployment_config.ready_recovery_action->number_of_attempts + 1; } + + const configuration::ApplicationProfile& app_profile = config.component_properties.application_profile; + + if (app_profile.alive_supervision.has_value() && + app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised) + { + std::cout << "setting up alive supervision" << std::endl; + const IdentifierHash name{config.name}; + const uid_t uid = config.deployment_config.sandbox.uid; + + config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(name)); + + state_publisher_ = supervision_factory.constructSupervision(name, uid, app_profile.alive_supervision.value()); + } } IComponent::RequestResult ProcessInfoNode::tryReportCompletion(score::mw::lifecycle::ProcessState new_state) @@ -93,7 +102,7 @@ IComponent::RequestResult ProcessInfoNode::tryReportSuccess() if (auto time = getTimeForReport()) { - process_handling_.state_publisher_.reportActivation(IdentifierHash{config_.name}, time.value()); + state_publisher_->reportActivation(time.value()); } return {RequestState::kSuccess}; @@ -104,14 +113,14 @@ IComponent::RequestResult ProcessInfoNode::tryReportSuccess() std::optional ProcessInfoNode::getTimeForReport() const { if (config_.component_properties.application_profile.application_type == - score::mw::lifecycle::internal::configuration::ApplicationType::Native) + score::mw::lifecycle::internal::configuration::ApplicationType::ReportingAndSupervised) { - return std::nullopt; + timespec timestamp{}; + static_cast(clock_gettime(CLOCK_MONOTONIC, ×tamp)); + return timestamp; } - timespec timestamp{}; - static_cast(clock_gettime(CLOCK_MONOTONIC, ×tamp)); - return timestamp; + return std::nullopt; } IComponent::RequestResult ProcessInfoNode::tryReportError(ComponentError error) @@ -428,7 +437,7 @@ IComponent::RequestResult ProcessInfoNode::deactivate(score::cpp::stop_token sto reached_ready_.store(false); if (auto time = getTimeForReport()) { - process_handling_.state_publisher_.reportDeactivation(IdentifierHash{config_.name}, time.value()); + state_publisher_->reportDeactivation(time.value()); } terminateProcess(stop_token); setState(ProcessState::kIdle); diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp index 49fc16671..c1828eb6b 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp @@ -22,6 +22,7 @@ #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/process_state.hpp" #include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" #include #include #include @@ -46,7 +47,11 @@ class ProcessInfoNode final : public IComponent /// @param index The process index within its process group. /// @param ready_condition Whether this process is considered ready when running or when terminated. /// @param process_handling The interfaces used to start, stop and report on the OS process. - ProcessInfoNode(configuration::ComponentConfig&& config, uint32_t index, ProcessHandling process_handling); + ProcessInfoNode( + configuration::ComponentConfig&& config, + uint32_t index, + ProcessHandling process_handling, + ISupervisionFactory& supervision_factory); /// @brief Explicit move constructor required due to atomics. PIN must be moveable to exist in the graph ProcessInfoNode(ProcessInfoNode&& other) noexcept @@ -60,7 +65,8 @@ class ProcessInfoNode final : public IComponent config_(std::move(other.config_)), control_client_channel_(std::move(other.control_client_channel_)), sync_(std::move(other.sync_)), - process_handling_(std::move(other.process_handling_)) + process_handling_(std::move(other.process_handling_)), + state_publisher_(std::move(other.state_publisher_)) { } @@ -190,6 +196,9 @@ class ProcessInfoNode final : public IComponent /// @brief The interfaces used to control a OS process. ProcessHandling process_handling_; + /// @brief Interface for reporting component state to health monitor. + std::unique_ptr state_publisher_; + /// @brief Number ot times to try run the process. std::uint8_t start_tries_{1U}; }; diff --git a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp index b992d1959..7e03809e6 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp @@ -38,7 +38,7 @@ void ProcessGroupManager::cancel() ProcessGroupManager::ProcessGroupManager( configuration::Config&& config, - std::unique_ptr alive_monitor, + std::unique_ptr alive_monitor, std::shared_ptr recovery_client, std::unique_ptr watchdog) : configuration_(std::move(config)), @@ -94,7 +94,7 @@ bool ProcessGroupManager::initialize() } LM_LOG_DEBUG() << "Process Group initialization done"; - if (!alive_monitor_thread_->start()) + if (!alive_monitor_->start()) { LM_LOG_ERROR() << "Alive monitor thread failed to start"; return false; @@ -129,7 +129,7 @@ void ProcessGroupManager::deinitialize() event_queue_->stop(); } os_handler_.reset(); - alive_monitor_thread_->stop(); + alive_monitor_->stop(); // Join the worker threads before destroying the process groups: a worker may // still be (de)activating a ProcessInfoNode owned by a graph, so tearing the @@ -207,7 +207,8 @@ bool ProcessGroupManager::initializeProcessGroups() configuration_.components().size() + configuration_.runTargets().size() + 2, configuration_, worker_jobs_, - ProcessHandling{*supervision_control_notifier_.get(), &process_interface_, process_map_}, + ProcessHandling{&process_interface_, process_map_}, + alive_monitor_->getSupervisionFactory(), this); LM_LOG_DEBUG() << "Process group initialized successfully"; diff --git a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp index 51d065bbd..e74e9330b 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.hpp @@ -72,7 +72,7 @@ class ProcessGroupManager final : public ITransitionResultPublisher /// legacy configuration where no watchdog is wired. ProcessGroupManager( configuration::Config&& config, - std::unique_ptr alive_monitor, + std::unique_ptr alive_monitor, std::shared_ptr recovery_client, std::unique_ptr watchdog); @@ -277,7 +277,7 @@ class ProcessGroupManager final : public ITransitionResultPublisher /// @brief Pointer to the gaph. std::shared_ptr graph_{nullptr}; - std::unique_ptr alive_monitor_; + std::unique_ptr alive_monitor_; std::unique_ptr process_monitor_; diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp index 32da6e979..4b8a583e7 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp @@ -38,7 +38,7 @@ class ISupervisionFactory /// @param [in] config Alive supervision configuration for the process. /// @param [in] uid The configured uid of the process. /// @returns Handle for the process to start and stop its own supervision. - virtual SupervisionHandle + virtual std::unique_ptr constructSupervision(IdentifierHash id, uid_t uid, internal::configuration::ComponentAliveSupervision config) = 0; }; diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp index bec5a606e..4df38f4e7 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp @@ -25,7 +25,7 @@ namespace score namespace mw::lifecycle { -class SupervisionHandle : ISupervisionEventPublisher +class SupervisionHandle : public ISupervisionEventPublisher { public: explicit SupervisionHandle(IdentifierHash process_id, std::shared_ptr buffer) From 510adc51101d1eb536e15101e739cbbe120e2fa7 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Thu, 27 Aug 2026 10:42:46 +0100 Subject: [PATCH 04/12] Remove construct method --- .../src/alive_monitor/IAliveMonitor.hpp | 4 --- .../details/daemon/AliveMonitorImpl.cpp | 11 ++++--- .../details/daemon/AliveMonitorImpl.hpp | 17 ++++++---- .../details/daemon/PhmDaemon.cpp | 15 ++------- .../details/daemon/PhmDaemon.hpp | 33 +++++++------------ .../details/daemon/SupervisionManager.cpp | 5 +++ .../details/daemon/SupervisionManager.hpp | 3 ++ score/launch_manager/src/daemon/src/main.cpp | 13 +++++--- .../process_group_manager/details/graph.cpp | 3 +- 9 files changed, 50 insertions(+), 54 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp index 06df8243d..40f65af2b 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp @@ -31,10 +31,6 @@ class IAliveMonitor public: virtual ~IAliveMonitor() = default; - /// @brief Initialize the AliveMonitor functionality - /// @return kNoError if initialization was successful, otherwise an appropriate error code. - virtual EInitCode init() noexcept = 0; - virtual bool start() = 0; virtual void stop() = 0; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp index 1908413fb..6915f07af 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp @@ -21,20 +21,23 @@ namespace score::mw::lifecycle::internal::saf::daemon { -AliveMonitorImpl::AliveMonitorImpl(SptrIRecoveryClient recovery_client, const Config& config) +AliveMonitorImpl::AliveMonitorImpl( + SptrIRecoveryClient recovery_client, + const AliveSupervisionConfig& config, + const std::size_t supervised_components) : m_recovery_client(recovery_client), m_config(config) { - initResult = init(); + initResult = init(supervised_components); } -EInitCode AliveMonitorImpl::init() noexcept +EInitCode AliveMonitorImpl::init(const std::size_t supervised_components) noexcept { EInitCode initResult{EInitCode::kGeneralError}; try { m_osClock.startMeasurement(); - m_daemon = std::make_unique(m_osClock); + m_daemon = std::make_unique(m_osClock, supervised_components); initResult = m_daemon->init(m_recovery_client, m_config); if (initResult == EInitCode::kNoError) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index eecea0297..bdcf577db 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -40,15 +40,15 @@ namespace daemon using SptrIRecoveryClient = std::shared_ptr; using UptrPhmDaemon = std::unique_ptr; using OsClock = score::mw::lifecycle::internal::saf::timers::OsClockInterface; -using Config = score::mw::lifecycle::internal::configuration::Config; -using score::mw::lifecycle::internal::configuration::AliveSupervisionConfig; +using configuration::AliveSupervisionConfig; class AliveMonitorImpl : public IAliveMonitor { public: - AliveMonitorImpl(SptrIRecoveryClient recovery_client, const Config& config); - - EInitCode init() noexcept override; + AliveMonitorImpl( + SptrIRecoveryClient recovery_client, + const AliveSupervisionConfig& config, + const std::size_t supervised_components); bool start() noexcept override; @@ -57,6 +57,11 @@ class AliveMonitorImpl : public IAliveMonitor ISupervisionFactory& getSupervisionFactory() noexcept override; private: + /// @brief Initialize the AliveMonitor functionality + /// @param supervised_components Number of components we expect to register alive supervision + /// @return kNoError if initialization was successful, otherwise an appropriate error code. + EInitCode init(const std::size_t supervised_components) noexcept; + /// @brief Run the AliveMonitor functionality in a cyclic manner until cancellation is requested. /// @param cancel_thread Atomic boolean flag to signal thread cancellation. bool threadFn(std::atomic_bool& cancel_thread) noexcept; @@ -64,7 +69,7 @@ class AliveMonitorImpl : public IAliveMonitor SptrIRecoveryClient m_recovery_client{nullptr}; UptrPhmDaemon m_daemon{nullptr}; OsClock m_osClock{}; - const Config& m_config; + const AliveSupervisionConfig& m_config; std::thread alive_monitor_thread_{}; std::atomic_bool stop_thread_{false}; saf::daemon::EInitCode initResult{saf::daemon::EInitCode::kNotInitialized}; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp index 7e65b1bcd..6b03a020f 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp @@ -27,7 +27,7 @@ namespace score::mw::lifecycle::internal::saf::daemon true_no_defect) */ /* RULECHECKER_comment(0, 4, check_incomplete_data_member_construction, "Default constructor is used for\ processStateReader.", true_no_defect) */ -PhmDaemon::PhmDaemon(OsClock& f_osClock) +PhmDaemon::PhmDaemon(OsClock& f_osClock, std::size_t supervised_components) : osClock{f_osClock}, cycleTimer{&osClock}, buffer_(std::make_shared()), @@ -35,6 +35,7 @@ PhmDaemon::PhmDaemon(OsClock& f_osClock) processStateReader{buffer_} { buffer_->initialize(); + supervisionManager.reserve(supervised_components); } void PhmDaemon::performCyclicTriggers(void) @@ -58,16 +59,4 @@ void PhmDaemon::performCyclicTriggers(void) } } -bool PhmDaemon::construct(const std::vector& config) noexcept(false) -{ - const std::size_t supervised_components = - std::count_if(config.begin(), config.end(), [](const configuration::ComponentConfig& component) { - return component.component_properties.application_profile.alive_supervision.has_value(); - }); - - supervisionManager.reserve(supervised_components); - - return true; -} - } // namespace score::mw::lifecycle::internal::saf::daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index 8f2c38f72..8bc7a2d99 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -41,7 +41,7 @@ namespace daemon /// @brief PHM daemon main class wraps the functionality for initialization and cyclic execution. /// @details This is the main class responsible to execute the main functionalities of PHM daemon, /// by using the necessary classes from this software component. -class PhmDaemon : public ISupervisionFactory +class PhmDaemon final : public ISupervisionFactory { public: using OsClock = score::mw::lifecycle::internal::saf::timers::OsClockInterface; @@ -52,20 +52,16 @@ class PhmDaemon : public ISupervisionFactory using ObservableEventReader = score::mw::lifecycle::internal::saf::ifexm::ObservableEventReader; using Config = score::mw::lifecycle::internal::configuration::Config; - /* RULECHECKER_comment(0, 4, check_expensive_to_copy_in_parameter, "f_supervisionErrorInfo name is passed by value\ - as same as generated function", true_no_defect) */ /// @brief Set the OS clock interface /// @param[in] f_osClock Access to the system clock (dependency injection possible in tests) - /// @param[in] f_observable_event_receiver observable event receiver implementation (dependency injection possible + /// @param[in] supervised_components Number of components that will register alive supervision /// in tests) /* RULECHECKER_comment(3,1, check_expensive_to_copy_in_parameter, "Move only types cannot be passed by const ref", true_no_defect) */ - explicit PhmDaemon(OsClock& f_osClock); + explicit PhmDaemon(OsClock& f_osClock, std::size_t supervised_components); - /* RULECHECKER_comment(0, 4, check_min_instructions, "Default destructor is not provided\ - a function body", true_no_defect) */ /// @brief Destroys the workers - virtual ~PhmDaemon() = default; + ~PhmDaemon() override = default; /// @brief No Copy Constructor PhmDaemon(const PhmDaemon&) = delete; @@ -81,17 +77,14 @@ class PhmDaemon : public ISupervisionFactory /// @param[in] recovery_client Shared pointer to recovery client /// @param[in] config Config holding alive monitor and component configuration /// @return See EInitCode definition - EInitCode init(std::shared_ptr recovery_client, const Config& config) noexcept(false) + EInitCode init( + std::shared_ptr recovery_client, + const configuration::AliveSupervisionConfig& config) noexcept(false) { recoveryClient = recovery_client; - if (!construct(config.components())) - { - return EInitCode::kConstructFlatCfgFactoryFailed; - } - - int64_t cycleTimeModified{static_cast( - timers::TimeConversion::convertMilliSecToNanoSec(config.aliveSupervision().evaluation_cycle_ms))}; + int64_t cycleTimeModified{ + static_cast(timers::TimeConversion::convertMilliSecToNanoSec(config.evaluation_cycle_ms))}; cycleTimeModified = CycleTimeValidator::adjustCycleTimeOnClockAccuracy(cycleTimeModified, osClock); @@ -187,17 +180,13 @@ class PhmDaemon : public ISupervisionFactory std::unique_ptr constructSupervision(IdentifierHash id, uid_t uid, configuration::ComponentAliveSupervision config) override { + SCORE_LANGUAGE_FUTURECPP_ASSERT_DBG_MESSAGE( + !supervisionManager.full(), "More alive supervisions than expected were constructed"); supervisionManager.constructWorker(id, config, uid, recoveryClient, processStateReader); return std::make_unique(id, buffer_); } private: - /// @brief Create SwCluster objects & Invoke construction of worker objects - /// @details Create the SwclusterHandler objects and the workers for the SwclusterHandler - /// @param[in] config Config for all components - /// @return bool true if workers creation succeeded, false otherwise - bool construct(const std::vector& config) noexcept(false); - /// @brief Perform cyclic execution of Phm daemon /// @details Perform cyclic execution of Phm daemon functionalities, for e.g., evaluation of supervisions. void performCyclicTriggers(void); diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp index f84851cf9..88ebe32be 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp @@ -32,6 +32,11 @@ SupervisionManager::SupervisionManager(std::unique_ptr fac SupervisionManager::~SupervisionManager() = default; +bool SupervisionManager::full() +{ + return aliveSupervisions.size() == aliveSupervisions.capacity(); +} + void SupervisionManager::reserve(std::size_t size) { processStates.reserve(size); diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp index 6d793f7fb..10b96b601 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp @@ -91,6 +91,9 @@ class SupervisionManager /// @param[in] size Number of supervised components void reserve(std::size_t size); + /// @brief Returns true if the number of alive supervisions constructed equals the reserved size + bool full(); + /// @brief Construct required worker objects for provided component /// @details Construct the interfaces, checkpoints, supervisions and recovery notifications /// @param [in] id Identifier of the component diff --git a/score/launch_manager/src/daemon/src/main.cpp b/score/launch_manager/src/daemon/src/main.cpp index fb7dc0312..cf24f7291 100644 --- a/score/launch_manager/src/daemon/src/main.cpp +++ b/score/launch_manager/src/daemon/src/main.cpp @@ -159,10 +159,15 @@ int main(int argc, const char* argv[]) std::shared_ptr recoveryClient{std::make_shared()}; - // currently this is copying the config. - std::unique_ptr healthMonitor{ - std::make_unique(recoveryClient, *config_result)}; - static_cast(config_result.value().takeAliveSupervision()); + const std::size_t supervised_components = std::count_if( + config_result.value().components().begin(), + config_result.value().components().end(), + [](const configuration::ComponentConfig& component) { + return component.component_properties.application_profile.alive_supervision.has_value(); + }); + + std::unique_ptr healthMonitor{std::make_unique( + recoveryClient, config_result.value().takeAliveSupervision(), supervised_components)}; auto watchdog = watchdog::createWatchdog(); auto process_group_manager = std::make_unique( diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp index a3ae13225..5866bb784 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp @@ -147,7 +147,8 @@ Graph::Graph( last_state_manager_.process_index_ = 0xFFFFU; // an invalid state manager last_state_manager_.process_group_index_ = 0xFFFFU; cancel_message_.request_or_response_ = ControlClientCode::kNotSet; - CreateDependencyGraph(nodes_, configuration_, process_handling_, run_targets_, supervision_factory, off_state_transition_timeout_); + CreateDependencyGraph( + nodes_, configuration_, process_handling_, run_targets_, supervision_factory, off_state_transition_timeout_); } Graph::~Graph() From 7e1b642a193a475bede07e32e3edb2cd7705d6a4 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:19:04 +0100 Subject: [PATCH 05/12] Cleanup --- .../src/daemon/src/alive_monitor/BUILD | 1 - .../src/daemon/src/alive_monitor/IAliveMonitor.hpp | 6 ++++-- .../details/daemon/AliveMonitorImpl.cpp | 2 +- .../details/daemon/AliveMonitorImpl.hpp | 2 +- .../src/alive_monitor/details/daemon/PhmDaemon.hpp | 6 ++++-- .../details/ifexm/ObservableEventReader.hpp | 6 ++++-- .../src/process_group_manager/details/graph.hpp | 4 ++++ .../details/process_info_node.cpp | 5 ++--- .../details/process_info_node.hpp | 3 ++- .../isupervision_factory.hpp | 8 +++++--- .../supervision_handle.hpp | 13 ++++++++++++- 11 files changed, 39 insertions(+), 17 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/BUILD index ac52a9246..030b04a20 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/BUILD @@ -27,7 +27,6 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", visibility = ["//score:__subpackages__"], deps = [ - "//score/launch_manager/src/daemon/src/alive_monitor/details/common:einitcode", "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp index 40f65af2b..fe31fc6da 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp @@ -13,7 +13,6 @@ #ifndef SAF_DAEMON_ALIVE_MONITOR_HPP_INCLUDED #define SAF_DAEMON_ALIVE_MONITOR_HPP_INCLUDED -#include "score/mw/launch_manager/alive_monitor/details/common/EInitCode.hpp" #include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" namespace score @@ -31,11 +30,14 @@ class IAliveMonitor public: virtual ~IAliveMonitor() = default; + /// @brief Start the monitor thread virtual bool start() = 0; + /// @brief Stop the monitor thread virtual void stop() = 0; - virtual ISupervisionFactory& getSupervisionFactory() = 0; + /// @brief Returns an interface for components to register their alive supervision + virtual ISupervisionFactory& getSupervisionFactory() const = 0; }; } // namespace daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp index 6915f07af..22d36157f 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp @@ -94,7 +94,7 @@ bool AliveMonitorImpl::threadFn(std::atomic_bool& cancel_thread) noexcept return m_daemon->startCyclicExec(cancel_thread); } -ISupervisionFactory& AliveMonitorImpl::getSupervisionFactory() noexcept +ISupervisionFactory& AliveMonitorImpl::getSupervisionFactory() const noexcept { return *m_daemon; } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index bdcf577db..1f0502fdd 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -54,7 +54,7 @@ class AliveMonitorImpl : public IAliveMonitor void stop() noexcept override; - ISupervisionFactory& getSupervisionFactory() noexcept override; + ISupervisionFactory& getSupervisionFactory() const noexcept override; private: /// @brief Initialize the AliveMonitor functionality diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index 8bc7a2d99..c46211d56 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -177,8 +177,10 @@ class PhmDaemon final : public ISupervisionFactory return true; } - std::unique_ptr - constructSupervision(IdentifierHash id, uid_t uid, configuration::ComponentAliveSupervision config) override + std::unique_ptr constructSupervision( + const IdentifierHash id, + const uid_t uid, + const configuration::ComponentAliveSupervision& config) override { SCORE_LANGUAGE_FUTURECPP_ASSERT_DBG_MESSAGE( !supervisionManager.full(), "More alive supervisions than expected were constructed"); diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp index eda6e3178..3e46dfb68 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp @@ -38,7 +38,7 @@ class ObservableEventReader { public: /// @brief Constructor - /// @param [in] f_observable_event_receiver Process state receiver implementation + /// @param [in] f_observable_event_receiver Shared pointer to the ring buffer used to receive supervision events explicit ObservableEventReader(std::shared_ptr f_observable_event_receiver); /// @brief No Copy Constructor @@ -76,9 +76,11 @@ class ObservableEventReader /// @return true (sync timestamp is reached), false (sync timestamp is not yet reached) bool pushUpdateTill(const SupervisionEvent& f_event, const timers::NanoSecondType f_syncTimestamp) noexcept; + /// @brief Returns a queued SupervisionEvent that has not yet been parsed. + /// @returns Result containing SupervisionEvent in case of success, or ExecError in case of failure. score::Result> getNextSupervisionEvent() noexcept; - /// @brief Process state receiver for HM thread + /// @brief Ring buffer through which supervision events are received from the Launch Manager std::shared_ptr buffer_; /// @brief Map for process id and observable event object diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp index 87e511b6b..d820ce0e9 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp @@ -155,7 +155,11 @@ class Graph final /// @brief Constructor to initialize a Graph object. /// @param max_num_nodes Maximum number of nodes this graph can hold. + /// @param configuration Configuration containing run target and component information. + /// @param job_queue Queue to push component jobs to for multithreaded processing. /// @param process_handling The interfaces used to start, stop and report on the OS processes. + /// @param supervision_factory Factory to construct component supervisions with. + /// @param transition_result_receiver Object to notify when the initial transition is complete. Graph( uint32_t max_num_nodes, configuration::Config& configuration, diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp index 7d7dc802a..e93c676d6 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp @@ -20,7 +20,6 @@ #include #include #include -#include namespace score::mw::lifecycle::internal { @@ -48,12 +47,12 @@ ProcessInfoNode::ProcessInfoNode( if (app_profile.alive_supervision.has_value() && app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised) { - std::cout << "setting up alive supervision" << std::endl; const IdentifierHash name{config.name}; const uid_t uid = config.deployment_config.sandbox.uid; - config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(name)); + LM_LOG_DEBUG() << "Setting up alive supervision for" << name; + config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(name)); state_publisher_ = supervision_factory.constructSupervision(name, uid, app_profile.alive_supervision.value()); } } diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp index c1828eb6b..e4a143510 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp @@ -45,8 +45,9 @@ class ProcessInfoNode final : public IComponent /// @brief Constructs a ProcessInfoNode. /// @param config Configuration for the OS process. /// @param index The process index within its process group. - /// @param ready_condition Whether this process is considered ready when running or when terminated. /// @param process_handling The interfaces used to start, stop and report on the OS process. + /// @param supervision_factory Temporary reference to a factory this node can use to construct its supervision if + /// required. ProcessInfoNode( configuration::ComponentConfig&& config, uint32_t index, diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp index 4b8a583e7..493e96f39 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp @@ -35,11 +35,13 @@ class ISupervisionFactory /// @brief Set up alive supervision for the identified process. Alive supervision is not started until the publisher /// is notified. /// @param [in] id Identifier of the process. - /// @param [in] config Alive supervision configuration for the process. /// @param [in] uid The configured uid of the process. + /// @param [in] config Alive supervision configuration for the process. /// @returns Handle for the process to start and stop its own supervision. - virtual std::unique_ptr - constructSupervision(IdentifierHash id, uid_t uid, internal::configuration::ComponentAliveSupervision config) = 0; + virtual std::unique_ptr constructSupervision( + const IdentifierHash id, + const uid_t uid, + const internal::configuration::ComponentAliveSupervision& config) = 0; }; } // namespace mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp index 4df38f4e7..501dabdaa 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp @@ -25,9 +25,15 @@ namespace score namespace mw::lifecycle { +/// @brief A supervision handle can be used by a process to manage its own alive supervision. It should be constructed +/// by the alive monitor and provided to a process so that the process need not have access to the supervision buffer. +/// The process can then report its own activation and deactivation. class SupervisionHandle : public ISupervisionEventPublisher { public: + /// @brief Construct a new supervision handle. + /// @param process_id Identifier of the process being supervised. + /// @param buffer Buffer to push supervision events to. explicit SupervisionHandle(IdentifierHash process_id, std::shared_ptr buffer) : process_id_(process_id), buffer_(buffer) { @@ -46,6 +52,9 @@ class SupervisionHandle : public ISupervisionEventPublisher } private: + /// @brief Attempts to push a supervision event so that the alive monitor can be informed about it. + /// @param[in] f_event The SupervisionEvent to be queued + /// @returns True on success, false for failure bool queueSupervisionEvent(const score::mw::lifecycle::SupervisionEvent& f_event) noexcept { if (buffer_->tryEnqueue(f_event)) @@ -59,7 +68,9 @@ class SupervisionHandle : public ISupervisionEventPublisher } } - IdentifierHash process_id_; + /// @brief Identifier of the process being supervised. + const IdentifierHash process_id_; + /// @brief Buffer to push supervision events to std::shared_ptr buffer_; }; From 7dc15dda539f40735910d92d3a88543b2b51d369 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Thu, 27 Aug 2026 17:06:27 +0100 Subject: [PATCH 06/12] Fix UTs --- .../src/daemon/src/alive_monitor/BUILD | 13 +++ .../details/daemon/PhmDaemon.hpp | 2 +- .../src/alive_monitor/mock_alive_monitor.hpp | 32 ++++++ .../src/process_group_manager/details/BUILD | 8 +- .../details/graph_UT.cpp | 5 +- .../details/process_group_manager_UT.cpp | 65 +++++-------- .../details/process_info_node_UT.cpp | 76 +++++++++++---- .../src/supervision_control_client/BUILD | 15 ++- .../isupervision_factory.hpp | 2 +- .../mock_supervision_event_publisher.hpp | 31 ++++++ .../mock_supervision_factory.hpp | 35 +++++++ .../supervision_control_client_ut.cpp | 97 +++++++------------ 12 files changed, 252 insertions(+), 129 deletions(-) create mode 100644 score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp create mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp create mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp diff --git a/score/launch_manager/src/daemon/src/alive_monitor/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/BUILD index 030b04a20..2ceef92c7 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/BUILD @@ -30,3 +30,16 @@ cc_library( "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) + +cc_library( + name = "mock_alive_monitor", + testonly = True, + hdrs = ["mock_alive_monitor.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", + visibility = ["//score:__subpackages__"], + deps = [ + ":i_alive_monitor", + "@googletest//:gtest_main", + ], +) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index c46211d56..d7eb3e86d 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -177,7 +177,7 @@ class PhmDaemon final : public ISupervisionFactory return true; } - std::unique_ptr constructSupervision( + std::unique_ptr constructSupervision( const IdentifierHash id, const uid_t uid, const configuration::ComponentAliveSupervision& config) override diff --git a/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp new file mode 100644 index 000000000..34ad8e3ae --- /dev/null +++ b/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp @@ -0,0 +1,32 @@ +/******************************************************************************** + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#ifndef MOCK_ALIVE_MONITOR_HPP_INCLUDED +#define MOCK_ALIVE_MONITOR_HPP_INCLUDED + +#include "score/mw/launch_manager/alive_monitor/IAliveMonitor.hpp" +#include + +namespace score::mw::lifecycle::internal::saf::daemon +{ + +class MockAliveMonitor : public IAliveMonitor +{ + public: + MOCK_METHOD(bool, start, (), (override)); + MOCK_METHOD(void, stop, (), (override)); + MOCK_METHOD(ISupervisionFactory&, getSupervisionFactory, (), (const, override)); +}; + +} // namespace score::mw::lifecycle::internal::saf::daemon + +#endif diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index c67aa8b49..aa6201298 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD @@ -180,6 +180,7 @@ lm_cc_test( ":safe_process_map", "//score/launch_manager/src/daemon/src/process_group_manager:mock_iprocess", "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_event_publisher", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", "@googletest//:gtest_main", ], ) @@ -233,6 +234,7 @@ lm_cc_test( "//score/launch_manager/src/daemon/src/configuration:config", "//score/launch_manager/src/daemon/src/process_group_manager:mock_iprocess", "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_event_publisher", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", "@googletest//:gtest_main", ], ) @@ -349,12 +351,12 @@ lm_cc_test( name = "process_group_manager_UT", srcs = ["process_group_manager_UT.cpp"], deps = [ + "//score/launch_manager/src/daemon/src/alive_monitor:mock_alive_monitor", "//score/launch_manager/src/daemon/src/configuration:config", "//score/launch_manager/src/daemon/src/process_group_manager", - "//score/launch_manager/src/daemon/src/process_group_manager:mock_ialive_monitor_thread", "//score/launch_manager/src/daemon/src/recovery_client:mock_recovery_client", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_control_notifier", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_control_notifier", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_event_publisher", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", "//score/launch_manager/src/daemon/src/watchdog:mock_i_watchdog_if", "@googletest//:gtest_main", ], diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp index c61c6d35c..ae9aabbd4 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp @@ -24,6 +24,7 @@ #include "score/mw/launch_manager/process_group_manager/details/graph.hpp" #include "score/mw/launch_manager/process_group_manager/mock_iprocess.hpp" #include "score/mw/launch_manager/supervision_control_client/mock_supervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" namespace score::mw::lifecycle::internal { @@ -63,7 +64,8 @@ class GraphTest : public ::testing::Test 10U, config_.value(), job_queue_, - ProcessHandling{mock_supervision_event_publisher_, &process_interface_, mock_process_map}, + ProcessHandling{&process_interface_, mock_process_map}, + mock_factory_, &mock_transition_result_publisher_); } @@ -185,6 +187,7 @@ class GraphTest : public ::testing::Test std::shared_ptr mock_process_map = std::make_shared(); NiceMock mock_supervision_event_publisher_{}; MockTransitionResultPublisher mock_transition_result_publisher_{}; + MockSupervisionFactory mock_factory_{}; std::unique_ptr graph_{}; static constexpr std::string_view pg_string{"MainPG"}; diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp index b156a56ad..336c195ae 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp @@ -13,9 +13,10 @@ #include "score/mw/launch_manager/process_group_manager/process_group_manager.hpp" -#include "score/mw/launch_manager/process_group_manager/mock_alive_monitor_thread.hpp" +#include "score/mw/launch_manager/alive_monitor/mock_alive_monitor.hpp" #include "score/mw/launch_manager/recovery_client/mock_irecovery_client.h" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_control_notifier.hpp" +#include "score/mw/launch_manager/supervision_control_client/mock_supervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" #include "score/mw/launch_manager/watchdog/mock_IWatchdogIf.hpp" #include @@ -36,20 +37,9 @@ namespace score::mw::lifecycle::internal namespace { -using score::mw::lifecycle::MockRecoveryClient; -using score::mw::lifecycle::MockSupervisionControlNotifier; -using score::mw::lifecycle::internal::watchdog::MockWatchdogIf; - -using score::mw::lifecycle::internal::configuration::AliveSupervisionConfig; -using score::mw::lifecycle::internal::configuration::ApplicationType; -using score::mw::lifecycle::internal::configuration::ComponentConfig; -using score::mw::lifecycle::internal::configuration::Config; -using score::mw::lifecycle::internal::configuration::ConfigBuilder; -using score::mw::lifecycle::internal::configuration::FallbackRunTargetConfig; -using score::mw::lifecycle::internal::configuration::ProcessState; -using score::mw::lifecycle::internal::configuration::ReadyCondition; -using score::mw::lifecycle::internal::configuration::RunTargetConfig; -using score::mw::lifecycle::internal::configuration::WatchdogConfig; +using namespace configuration; +using namespace watchdog; +using saf::daemon::MockAliveMonitor; Config makeMinimalConfig() { @@ -117,7 +107,7 @@ class ProcessGroupManagerWatchdogTest : public Test protected: void expectNormalStartup() { - EXPECT_CALL(*alive_monitor_thread_, start()).WillOnce(Return(true)); + EXPECT_CALL(*alive_monitor_, start()).WillOnce(Return(true)); EXPECT_CALL(*watchdog_, init(_, _)).WillOnce(Return(true)); EXPECT_CALL(*watchdog_, enable()).WillOnce(Return(true)); } @@ -127,9 +117,10 @@ class ProcessGroupManagerWatchdogTest : public Test RecordProperty("TestType", "unit-test"); RecordProperty("DerivationTechnique", "explorative-testing"); - auto alive_monitor_thread = std::make_unique>(); - alive_monitor_thread_ = alive_monitor_thread.get(); - ON_CALL(*alive_monitor_thread_, start()).WillByDefault(Return(true)); + auto alive_monitor = std::make_unique>(); + alive_monitor_ = alive_monitor.get(); + ON_CALL(*alive_monitor_, start()).WillByDefault(Return(true)); + ON_CALL(*alive_monitor_, getSupervisionFactory).WillByDefault(ReturnRef(factory_)); auto recovery_client = std::make_shared>(); recovery_client_ = recovery_client.get(); @@ -138,22 +129,18 @@ class ProcessGroupManagerWatchdogTest : public Test ON_CALL(*recovery_client_, setRecoveryRequestCallback(_)).WillByDefault(SaveArg<0>(&recovery_callback_)); ON_CALL(*recovery_client_, sendRecoveryRequest(_)).WillByDefault(Return(true)); - auto supervision_control_notifier = std::make_unique>(); - supervision_control_notifier_ = supervision_control_notifier.get(); - ON_CALL(*supervision_control_notifier_, constructReceiver()) - .WillByDefault(Return(ByMove(std::unique_ptr{}))); - ON_CALL(*supervision_control_notifier_, reportActivation(_, _)).WillByDefault(Return(true)); - ON_CALL(*supervision_control_notifier_, reportDeactivation(_, _)).WillByDefault(Return(true)); + ON_CALL(factory_, constructSupervision).WillByDefault(InvokeWithoutArgs([]() { + auto publisher = std::make_unique>(); + ON_CALL(*publisher, reportActivation).WillByDefault(Return(true)); + ON_CALL(*publisher, reportDeactivation).WillByDefault(Return(true)); + return publisher; + })); auto watchdog = std::make_unique>(); watchdog_ = watchdog.get(); process_group_manager_ = std::make_unique( - makeMinimalConfig(), - std::move(alive_monitor_thread), - std::move(recovery_client), - std::move(supervision_control_notifier), - std::move(watchdog)); + makeMinimalConfig(), std::move(alive_monitor), std::move(recovery_client), std::move(watchdog)); } void TearDown() override @@ -161,11 +148,11 @@ class ProcessGroupManagerWatchdogTest : public Test process_group_manager_->deinitialize(); } - MockAliveMonitorThread* alive_monitor_thread_{}; + MockAliveMonitor* alive_monitor_{}; MockRecoveryClient* recovery_client_{}; - score::mw::lifecycle::IRecoveryClient::RecoveryRequestCallback recovery_callback_{}; - MockSupervisionControlNotifier* supervision_control_notifier_{}; + IRecoveryClient::RecoveryRequestCallback recovery_callback_{}; MockWatchdogIf* watchdog_{}; + NiceMock factory_{}; std::unique_ptr process_group_manager_; }; @@ -178,7 +165,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogMethods InSequence sequence; expectNormalStartup(); EXPECT_CALL(*watchdog_, disable()).Times(1); - EXPECT_CALL(*alive_monitor_thread_, stop()).Times(1); + EXPECT_CALL(*alive_monitor_, stop()).Times(1); // When auto initialize_result = process_group_manager_->initialize(); @@ -197,7 +184,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogService }); // Called in deinitialize() after run() returns EXPECT_CALL(*watchdog_, disable()).Times(1); - EXPECT_CALL(*alive_monitor_thread_, stop()).Times(1); + EXPECT_CALL(*alive_monitor_, stop()).Times(1); // When ASSERT_TRUE(process_group_manager_->initialize()); @@ -221,7 +208,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogFired_W process_group_manager_->cancel(); }); EXPECT_CALL(*watchdog_, disable()).Times(1); - EXPECT_CALL(*alive_monitor_thread_, stop()).Times(1); + EXPECT_CALL(*alive_monitor_, stop()).Times(1); // When ASSERT_TRUE(process_group_manager_->initialize()); @@ -232,7 +219,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogFired_W ASSERT_TRUE(recovery_callback_); for (int i = 0; i < kNumRecoveryRequests; ++i) { - recovery_callback_(score::mw::lifecycle::IdentifierHash{"overflow_probe"}); + recovery_callback_(IdentifierHash{"overflow_probe"}); } auto run_result = process_group_manager_->run(); @@ -248,7 +235,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogDisable // We are explicitly calling deinitialize() in this test for readability, // so disable() and stop() are expected to be called twice: once in deinitialize() and once in TearDown(). EXPECT_CALL(*watchdog_, disable()).Times(2); - EXPECT_CALL(*alive_monitor_thread_, stop()).Times(2); + EXPECT_CALL(*alive_monitor_, stop()).Times(2); // When ASSERT_TRUE(process_group_manager_->initialize()); diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp index 6c176d40a..71702c8f1 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp @@ -15,6 +15,7 @@ #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/mock_iprocess.hpp" #include "score/mw/launch_manager/supervision_control_client/mock_supervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" #include #include #include @@ -24,8 +25,9 @@ #include using namespace testing; -using namespace score::mw::lifecycle::internal; -using namespace score::mw::lifecycle; + +namespace score::mw::lifecycle::internal +{ // Default ProcessIndex for testing constexpr uint32_t kProcessIndex = 111; @@ -44,8 +46,35 @@ class ProcessInfoNodeFixture : public ::testing::Test RecordProperty("TestType", "interface-test"); RecordProperty("DerivationTechnique", "equivalence-classes"); - ON_CALL(mock_publisher_, reportActivation).WillByDefault(Return(true)); - ON_CALL(mock_publisher_, reportDeactivation).WillByDefault(Return(true)); + ON_CALL(mock_factory_, constructSupervision).WillByDefault(InvokeWithoutArgs([this]() { + return constructDefaultEventPublisher(); + })); + } + + virtual std::unique_ptr> constructDefaultEventPublisher() const + { + auto mock_publisher = std::make_unique>(); + ON_CALL(*mock_publisher, reportActivation).WillByDefault(Return(true)); + ON_CALL(*mock_publisher, reportDeactivation).WillByDefault(Return(true)); + return mock_publisher; + } + + void expectActivationReport(int times = 1) + { + EXPECT_CALL(mock_factory_, constructSupervision).WillOnce(InvokeWithoutArgs([times]() { + auto mock_publisher = std::make_unique>(); + EXPECT_CALL(*mock_publisher, reportActivation).Times(times).WillRepeatedly(Return(true)); + return mock_publisher; + })); + } + + void expectDeactivationReport(int times = 1) + { + EXPECT_CALL(mock_factory_, constructSupervision).WillOnce(InvokeWithoutArgs([times]() { + auto mock_publisher = std::make_unique>(); + EXPECT_CALL(*mock_publisher, reportDeactivation).Times(times).WillRepeatedly(Return(true)); + return mock_publisher; + })); } /// @brief Helper method to create a ProcessInfoNode with the given parameters. @@ -67,8 +96,15 @@ class ProcessInfoNodeFixture : public ::testing::Test config.deployment_config.ready_recovery_action = configuration::RestartAction{restart_attempts, 0U}; config.deployment_config.shutdown_timeout_ms = shutdown_timeout_ms_; + if (application_type == configuration::ApplicationType::ReportingAndSupervised) + { + configuration::ComponentAliveSupervision alive{ + .reporting_cycle_ms = 10, .failed_cycles_tolerance = 1, .min_indications = 0, .max_indications = 0}; + config.component_properties.application_profile.alive_supervision = alive; + } + return std::make_unique( - std::move(config), kProcessIndex, ProcessHandling{mock_publisher_, &mock_processIf_, process_map_}); + std::move(config), kProcessIndex, ProcessHandling{&mock_processIf_, process_map_}, mock_factory_); } /// @brief Helper method to create a ProcessInfoNode that is self-terminating. @@ -124,7 +160,7 @@ class ProcessInfoNodeFixture : public ::testing::Test score::cpp::stop_source stop_source_{}; std::shared_ptr process_map_{std::make_shared()}; StrictMock mock_processIf_{}; - NiceMock mock_publisher_{}; + NiceMock mock_factory_{}; }; // Bundles different cases for activate() that occur during startup, before the ready condition is reached. @@ -168,10 +204,10 @@ TEST_F(ProcessInfoNodeStartupTest, CanStartReportingProcess_ReportsRunningInTime { RecordProperty("Description", "Can start a reporting process and check that the state transitions to kRunning."); - auto node = createProcessInfoNode(configuration::ApplicationType::Reporting); + expectActivationReport(); + auto node = createProcessInfoNode(configuration::ApplicationType::ReportingAndSupervised); expectSuccessfulProcessLaunch(); EXPECT_CALL(mock_processIf_, waitForkRunning(_, _)).WillOnce(Return(osal::OsalReturnType::kSuccess)); - EXPECT_CALL(mock_publisher_, reportActivation); auto result = node->activate(score::cpp::stop_token{}); @@ -270,12 +306,12 @@ TEST_F(ProcessInfoNodeStartupCrashTest, ProcesssTerminated_OnWaitForkRunningTime "Description", "If waitForkRunning times out, the process reports kActivationTimedOut and ends up in state kTerminated."); - auto node = createProcessInfoNode(configuration::ApplicationType::Reporting); + expectActivationReport(0); + auto node = createProcessInfoNode(configuration::ApplicationType::ReportingAndSupervised); expectSuccessfulProcessLaunch(); EXPECT_CALL(mock_processIf_, waitForkRunning(_, _)).WillOnce(Return(osal::OsalReturnType::kFail)); // Simulate the OS handler reporting the killed process's exit once termination is requested. expectOsAcknowledgesTermination(node.get()); - EXPECT_CALL(mock_publisher_, reportActivation).Times(0); auto result = node->activate(score::cpp::stop_token{}); @@ -291,7 +327,8 @@ TEST_F(ProcessInfoNodeStartupCrashTest, ReportingProcess_CrashesBeforeReady_NoRe "Process returns kErrorBeforeReady when crashing before reaching its ready condition (kRunning) with 0 restart " "attempts"); - auto node = createProcessInfoNode(configuration::ApplicationType::Reporting); + expectActivationReport(0); + auto node = createProcessInfoNode(configuration::ApplicationType::ReportingAndSupervised); expectSuccessfulProcessLaunch(); // Simulate the OS handler detecting the crash while the process is still waiting to reach kRunning. EXPECT_CALL(mock_processIf_, waitForkRunning(_, _)) @@ -300,7 +337,6 @@ TEST_F(ProcessInfoNodeStartupCrashTest, ReportingProcess_CrashesBeforeReady_NoRe static_cast(node->tryHandleTermination(-1)); }), Return(osal::OsalReturnType::kFail))); - EXPECT_CALL(mock_publisher_, reportActivation).Times(0); auto result = node->activate(score::cpp::stop_token{}); @@ -316,9 +352,10 @@ TEST_F(ProcessInfoNodeStartupCrashTest, ReportingProcess_CrashesBeforeReady_With "Process returns kErrorBeforeReady when crashing before reaching its ready condition (kRunning) with 3 restart " "attempts"); + expectActivationReport(0); constexpr uint32_t kRestartAttempts = 3; constexpr uint32_t kTotalAttempts = kRestartAttempts + 1; - auto node = createProcessInfoNode(configuration::ApplicationType::Reporting, kRestartAttempts); + auto node = createProcessInfoNode(configuration::ApplicationType::ReportingAndSupervised, kRestartAttempts); EXPECT_CALL(mock_processIf_, startProcess(_, _, _)) .Times(kTotalAttempts) @@ -335,7 +372,6 @@ TEST_F(ProcessInfoNodeStartupCrashTest, ReportingProcess_CrashesBeforeReady_With static_cast(node->tryHandleTermination(-1)); }), Return(osal::OsalReturnType::kFail))); - EXPECT_CALL(mock_publisher_, reportActivation).Times(0); auto result = node->activate(score::cpp::stop_token{}); @@ -403,8 +439,10 @@ TEST_F(ProcessInfoNodeStartupCrashTest, TimeoutThenSuccess_WithRestarts) "Description", "A reporting process that times out on the first attempt but reports kRunning on the retry returns kSuccess."); + expectActivationReport(); + constexpr uint32_t kRestartAttempts = 1; - auto node = createProcessInfoNode(configuration::ApplicationType::Reporting, kRestartAttempts); + auto node = createProcessInfoNode(configuration::ApplicationType::ReportingAndSupervised, kRestartAttempts); EXPECT_CALL(mock_processIf_, startProcess(_, _, _)).Times(2).WillRepeatedly(Return(osal::OsalReturnType::kSuccess)); EXPECT_CALL(*process_map_, insertIfNotTerminated(_, _)) @@ -415,7 +453,6 @@ TEST_F(ProcessInfoNodeStartupCrashTest, TimeoutThenSuccess_WithRestarts) .WillOnce(Return(osal::OsalReturnType::kSuccess)); // Simulate the OS handler reporting the killed process's exit on the first (timed-out) attempt. expectOsAcknowledgesTermination(node.get()); - EXPECT_CALL(mock_publisher_, reportActivation); auto result = node->activate(score::cpp::stop_token{}); @@ -515,9 +552,9 @@ TEST_F(ProcessInfoNodeDeactivationTest, CanTerminateNonSelfTerminatingProcess) "to kTerminated."); EXPECT_CALL(mock_processIf_, waitForkRunning(_, _)).WillOnce(Return(osal::OsalReturnType::kSuccess)); - EXPECT_CALL(mock_publisher_, reportDeactivation); + expectDeactivationReport(); - auto node = createRunningProcessInfoNode(configuration::ApplicationType::Reporting); + auto node = createRunningProcessInfoNode(configuration::ApplicationType::ReportingAndSupervised); // Simulate the OS handler reporting the process's exit once termination is requested. expectOsAcknowledgesTermination(node.get()); @@ -578,7 +615,6 @@ TEST_F(ProcessInfoNodeDeactivationTest, ProcessIgnoresSigterm_ForcedWithSigkill) "SIGKILL."); EXPECT_CALL(mock_processIf_, waitForkRunning(_, _)).WillOnce(Return(osal::OsalReturnType::kSuccess)); - EXPECT_CALL(mock_publisher_, reportDeactivation); auto node = createRunningProcessInfoNode_TermTimeout(std::chrono::milliseconds{0}); EXPECT_CALL(mock_processIf_, requestTermination(_)).WillOnce(Return(osal::OsalReturnType::kSuccess)); @@ -597,3 +633,5 @@ TEST_F(ProcessInfoNodeDeactivationTest, ProcessIgnoresSigterm_ForcedWithSigkill) ASSERT_THAT(node->active(), IsFalse()); ASSERT_THAT(node->getState(), Eq(score::mw::lifecycle::ProcessState::kIdle)); } + +} // namespace score::mw::lifecycle::internal diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD index 0b1ac5c71..b4e9568cd 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD +++ b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD @@ -73,11 +73,24 @@ cc_library( ], ) +cc_library( + name = "mock_supervision_factory", + testonly = True, + hdrs = ["mock_supervision_factory.hpp"], + include_prefix = "score/mw/launch_manager/supervision_control_client", + strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", + visibility = ["//score:__subpackages__"], + deps = [ + ":isupervision_factory", + "@googletest//:gtest_main", + ], +) + lm_cc_test( name = "supervision_control_client_ut", srcs = ["supervision_control_client_ut.cpp"], deps = [ - ":supervision_control_client", + ":supervision_handle", "@googletest//:gtest_main", ], ) diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp index 493e96f39..212283c5a 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp @@ -38,7 +38,7 @@ class ISupervisionFactory /// @param [in] uid The configured uid of the process. /// @param [in] config Alive supervision configuration for the process. /// @returns Handle for the process to start and stop its own supervision. - virtual std::unique_ptr constructSupervision( + virtual std::unique_ptr constructSupervision( const IdentifierHash id, const uid_t uid, const internal::configuration::ComponentAliveSupervision& config) = 0; diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp new file mode 100644 index 000000000..0936a7f12 --- /dev/null +++ b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp @@ -0,0 +1,31 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#ifndef MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED +#define MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED + +#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" +#include + +namespace score::mw::lifecycle +{ + +class MockSupervisionEventPublisher : public ISupervisionEventPublisher +{ + public: + MOCK_METHOD(bool, reportActivation, (timespec time), (override, noexcept)); + MOCK_METHOD(bool, reportDeactivation, (timespec time), (override, noexcept)); +}; + +} // namespace score::mw::lifecycle + +#endif // MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp new file mode 100644 index 000000000..07107f76f --- /dev/null +++ b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp @@ -0,0 +1,35 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#ifndef MOCK_SUPERVISION_FACTORY_HPP_INCLUDED +#define MOCK_SUPERVISION_FACTORY_HPP_INCLUDED + +#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" +#include + +namespace score::mw::lifecycle +{ + +class MockSupervisionFactory : public ISupervisionFactory +{ + public: + MOCK_METHOD( + std::unique_ptr, + constructSupervision, + (const IdentifierHash id, const uid_t uid, const internal::configuration::ComponentAliveSupervision& config), + (override)); +}; + +} // namespace score::mw::lifecycle + +#endif diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp index 47b8970b1..8466da100 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp @@ -10,17 +10,13 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#include "score/mw/launch_manager/supervision_control_client/details/supervision_control_receiver.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_control_notifier.hpp" +#include "score/mw/launch_manager/supervision_control_client/supervision_handle.hpp" #include #include using namespace testing; using namespace score::mw::lifecycle; -using score::mw::lifecycle::SupervisionControlReceiver; -using score::mw::lifecycle::internal::SupervisionControlNotifier; - class SupervisionControlClient_UT : public ::testing::Test { protected: @@ -28,27 +24,20 @@ class SupervisionControlClient_UT : public ::testing::Test { RecordProperty("TestType", "interface-test"); RecordProperty("DerivationTechnique", "explorative-testing "); - notifier_ = std::make_unique(); - receiver_ = notifier_->constructReceiver(); + buffer_ = std::make_shared(); + handle_ = std::make_unique(process_, buffer_); } + void TearDown() override { - receiver_.reset(); - notifier_.reset(); + handle_.reset(); + buffer_.reset(); } - std::unique_ptr notifier_; - std::unique_ptr receiver_; -}; -TEST_F(SupervisionControlClient_UT, SupervisionControlClient_ConstructReceiver_Succeeds) -{ - RecordProperty( - "Description", - "This test verifies that the SupervisionControlNotifier can successfully construct a " - "SupervisionControlReceiver instance."); - ASSERT_NE(notifier_, nullptr); - ASSERT_NE(receiver_, nullptr); -} + const IdentifierHash process_{"Process"}; + std::shared_ptr buffer_; + std::unique_ptr handle_; +}; TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueOneEvent_Succeeds) { @@ -56,26 +45,22 @@ TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueOneEvent_Succe "Description", "This test verifies that a single SupervisionEvent can be successfully queued using the " "SupervisionControlNotifier and retrieved using the SupervisionControlReceiver."); - SupervisionEvent event1{ - .id = score::mw::lifecycle::IdentifierHash("Process1"), - .eventType = score::mw::lifecycle::SupervisionEventType::kActivation, - .systemClockTimestamp = {}}; + SupervisionEvent event1{.id = process_, .eventType = SupervisionEventType::kActivation, .systemClockTimestamp = {}}; clock_gettime(CLOCK_MONOTONIC, &event1.systemClockTimestamp); - bool queued = notifier_->reportActivation(event1.id, event1.systemClockTimestamp); + bool queued = handle_->reportActivation(event1.systemClockTimestamp); ASSERT_TRUE(queued); - auto result = receiver_->getNextSupervisionEvent(); - ASSERT_TRUE(result.has_value()); - ASSERT_TRUE(result->has_value()); - EXPECT_EQ(result->value().id, event1.id); - EXPECT_EQ(result->value().eventType, event1.eventType); - EXPECT_EQ(result->value().systemClockTimestamp.tv_nsec, event1.systemClockTimestamp.tv_nsec); + SupervisionEvent result; + ASSERT_TRUE(buffer_->tryDequeue(result)); + + EXPECT_EQ(result.id, event1.id); + EXPECT_EQ(result.eventType, event1.eventType); + EXPECT_EQ(result.systemClockTimestamp.tv_nsec, event1.systemClockTimestamp.tv_nsec); - auto no_more = receiver_->getNextSupervisionEvent(); - ASSERT_TRUE(no_more.has_value()); - ASSERT_FALSE(no_more->has_value()); + bool items_remaining = buffer_->tryDequeue(result); + ASSERT_FALSE(items_remaining); } TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueMaxNumberOfEvents_Succeeds) @@ -85,27 +70,25 @@ TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueMaxNumberOfEve "This test verifies that the SupervisionControlNotifier can successfully queue the maximum number of " "SupervisionEvent " "instances defined by the buffer size, and that they can be retrieved using the SupervisionControlReceiver."); + + SupervisionEvent event{.id = process_, .eventType = SupervisionEventType::kActivation, .systemClockTimestamp = {}}; + for (size_t i = 0; i < static_cast(BufferConstants::BUFFER_QUEUE_SIZE); ++i) { - SupervisionEvent event{ - .id = score::mw::lifecycle::IdentifierHash("Process" + std::to_string(i)), - .eventType = score::mw::lifecycle::SupervisionEventType::kActivation, - .systemClockTimestamp = {}}; - bool queued = notifier_->reportActivation(event.id, event.systemClockTimestamp); + bool queued = handle_->reportActivation(event.systemClockTimestamp); ASSERT_TRUE(queued) << "Failed to queue event at index " << i; } + SupervisionEvent result; + for (size_t i = 0; i < static_cast(BufferConstants::BUFFER_QUEUE_SIZE); ++i) { - auto result = receiver_->getNextSupervisionEvent(); - ASSERT_TRUE(result.has_value()); - ASSERT_TRUE(result->has_value()); - EXPECT_EQ(result->value().id, score::mw::lifecycle::IdentifierHash("Process" + std::to_string(i))); + ASSERT_TRUE(buffer_->tryDequeue(result)); + EXPECT_EQ(result.id, event.id); } - auto no_more = receiver_->getNextSupervisionEvent(); - ASSERT_TRUE(no_more.has_value()); - ASSERT_FALSE(no_more->has_value()); + bool items_remaining = buffer_->tryDequeue(result); + ASSERT_FALSE(items_remaining); } TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueOneEventTooMany_Fails) @@ -114,28 +97,14 @@ TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueOneEventTooMan "Description", "This test verifies that attempting to queue a SupervisionEvent when the buffer is already at maximum capacity " "results in a failure, and that no additional events can be retrieved from the receiver."); - SupervisionEvent event1{ - .id = score::mw::lifecycle::IdentifierHash("Process1"), - .eventType = score::mw::lifecycle::SupervisionEventType::kActivation, - .systemClockTimestamp = {}}; + SupervisionEvent event{.id = process_, .eventType = SupervisionEventType::kActivation, .systemClockTimestamp = {}}; for (size_t i = 0; i < static_cast(BufferConstants::BUFFER_QUEUE_SIZE); ++i) { - SupervisionEvent event{ - .id = score::mw::lifecycle::IdentifierHash("Process" + std::to_string(i)), - .eventType = score::mw::lifecycle::SupervisionEventType::kActivation, - .systemClockTimestamp = {}}; - bool queued = notifier_->reportActivation(event.id, event.systemClockTimestamp); + bool queued = handle_->reportActivation(event.systemClockTimestamp); ASSERT_TRUE(queued) << "Failed to queue event at index " << i; } - bool queued = notifier_->reportActivation(event1.id, event1.systemClockTimestamp); + bool queued = handle_->reportActivation(event.systemClockTimestamp); ASSERT_FALSE(queued) << "Expected queuing to fail due to full buffer"; - - auto result = receiver_->getNextSupervisionEvent(); - ASSERT_FALSE(result.has_value()) << "Expected no events to be retrievable"; - - EXPECT_EQ( - static_cast(*result.error()), - score::mw::lifecycle::ExecErrc::kCommunicationError); } From 5abca27298757c65bcc46d2878c77c6483c67676 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Fri, 28 Aug 2026 09:56:37 +0100 Subject: [PATCH 07/12] Fix wrong member name --- .../src/process_group_manager/details/process_info_node.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp index e93c676d6..35483a7e4 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp @@ -42,13 +42,13 @@ ProcessInfoNode::ProcessInfoNode( start_tries_ = config_.deployment_config.ready_recovery_action->number_of_attempts + 1; } - const configuration::ApplicationProfile& app_profile = config.component_properties.application_profile; + const configuration::ApplicationProfile& app_profile = config_.component_properties.application_profile; if (app_profile.alive_supervision.has_value() && app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised) { - const IdentifierHash name{config.name}; - const uid_t uid = config.deployment_config.sandbox.uid; + const IdentifierHash name{config_.name}; + const uid_t uid = config_.deployment_config.sandbox.uid; LM_LOG_DEBUG() << "Setting up alive supervision for" << name; From f6a281a2798dae69fe41cb99acaaa8b45e480fd6 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:28:24 +0100 Subject: [PATCH 08/12] Superficial cleanup --- .../src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp | 1 + .../src/alive_monitor/details/daemon/SupervisionManager.cpp | 3 ++- .../src/alive_monitor/details/daemon/SupervisionManager.hpp | 3 +++ .../src/alive_monitor/details/ifexm/ObservableEventReader.cpp | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index d7eb3e86d..e317f82b7 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -177,6 +177,7 @@ class PhmDaemon final : public ISupervisionFactory return true; } + /// @brief @see ISupervisonFactory::constructSupervision std::unique_ptr constructSupervision( const IdentifierHash id, const uid_t uid, diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp index 88ebe32be..556c761cb 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.cpp @@ -34,11 +34,12 @@ SupervisionManager::~SupervisionManager() = default; bool SupervisionManager::full() { - return aliveSupervisions.size() == aliveSupervisions.capacity(); + return aliveSupervisions.size() == capacity; } void SupervisionManager::reserve(std::size_t size) { + capacity = size; processStates.reserve(size); aliveIfIpcs.reserve(size); aliveInterfaces.reserve(size); diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp index 10b96b601..e54323ded 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SupervisionManager.hpp @@ -145,6 +145,9 @@ class SupervisionManager std::vector aliveSupervisions; std::unique_ptr flatCfgFactory; + + /// @brief The number of alive supervisions we expect to successfully construct + std::size_t capacity{0}; }; } // namespace daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp index 96804a648..52734a7d2 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.cpp @@ -98,8 +98,8 @@ score::Result> ObservableEventReader::getNextSup score::mw::lifecycle::SupervisionEvent event; if (buffer_->getOverflowFlag()) { - LM_LOG_ERROR() << "ObservableEventReader::getNextSupervisionEvent: Overflow occurred, " - "will be reported as kCommunicationError"; + LM_LOG_ERROR() + << "Supervision event buffer overflow has occurred, this will be reported as a communication error"; return score::Result>{ score::MakeUnexpected(score::mw::lifecycle::ExecErrc::kCommunicationError)}; } From 24f4c0d697daad876c4e4456c1afc78fa4924158 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:44:04 +0100 Subject: [PATCH 09/12] Move supervision factory into struct --- .../src/daemon/src/process_group_manager/details/BUILD | 4 +--- .../daemon/src/process_group_manager/details/graph.cpp | 8 ++------ .../daemon/src/process_group_manager/details/graph.hpp | 3 --- .../daemon/src/process_group_manager/details/graph_UT.cpp | 3 +-- .../process_group_manager/details/process_handling.hpp | 6 +++++- .../process_group_manager/details/process_info_node.cpp | 6 +++--- .../process_group_manager/details/process_info_node.hpp | 7 +------ .../details/process_info_node_UT.cpp | 2 +- .../src/process_group_manager/process_group_manager.cpp | 3 +-- 9 files changed, 15 insertions(+), 27 deletions(-) diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index aa6201298..ed06e0f5e 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD @@ -144,7 +144,7 @@ cc_library( deps = [ ":safe_process_map", "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_event_publisher", + "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) @@ -167,7 +167,6 @@ cc_library( "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", "//score/launch_manager/src/daemon/src/process_group_manager:process_state", "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_event_publisher", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", "@score_baselibs//score/language/futurecpp", ], ) @@ -222,7 +221,6 @@ cc_library( "//score/launch_manager/src/daemon/src/control:control_client_channel", "//score/launch_manager/src/daemon/src/osal:semaphore", "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp index 5866bb784..2d8eeb15b 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.cpp @@ -43,7 +43,6 @@ void CreateDependencyGraph( configuration::Config& config, ProcessHandling process_handling, std::unordered_map& run_target_map, - ISupervisionFactory& supervision_factory, std::chrono::milliseconds& off_state_transition_timeout) { // this is a temporary (bad) implementation, all shall be cleandup @@ -71,8 +70,7 @@ void CreateDependencyGraph( std::in_place_type, std::move(component_config), static_cast(graph.size()), - process_handling, - supervision_factory); + process_handling); LM_LOG_DEBUG() << "Creating component node:" << name << "at index:" << index; name_to_index[name] = index; @@ -134,7 +132,6 @@ Graph::Graph( configuration::Config& configuration, std::shared_ptr job_queue, ProcessHandling process_handling, - ISupervisionFactory& supervision_factory, ITransitionResultPublisher* transition_result_receiver) : nodes_(max_num_nodes), transition_builder_(nodes_), @@ -147,8 +144,7 @@ Graph::Graph( last_state_manager_.process_index_ = 0xFFFFU; // an invalid state manager last_state_manager_.process_group_index_ = 0xFFFFU; cancel_message_.request_or_response_ = ControlClientCode::kNotSet; - CreateDependencyGraph( - nodes_, configuration_, process_handling_, run_targets_, supervision_factory, off_state_transition_timeout_); + CreateDependencyGraph(nodes_, configuration_, process_handling_, run_targets_, off_state_transition_timeout_); } Graph::~Graph() diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp index d820ce0e9..71f6c893e 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph.hpp @@ -39,7 +39,6 @@ #include "score/mw/launch_manager/process_group_manager/details/run_target.hpp" #include "score/mw/launch_manager/process_group_manager/details/transition.hpp" #include "score/mw/launch_manager/process_group_manager/iprocess.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" #include namespace score @@ -158,14 +157,12 @@ class Graph final /// @param configuration Configuration containing run target and component information. /// @param job_queue Queue to push component jobs to for multithreaded processing. /// @param process_handling The interfaces used to start, stop and report on the OS processes. - /// @param supervision_factory Factory to construct component supervisions with. /// @param transition_result_receiver Object to notify when the initial transition is complete. Graph( uint32_t max_num_nodes, configuration::Config& configuration, std::shared_ptr job_queue, ProcessHandling process_handling, - ISupervisionFactory& supervision_factory, ITransitionResultPublisher* transition_result_receiver); /// @brief Destructor to clean up resources used by the Graph object. diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp index ae9aabbd4..ee07d21dc 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp @@ -64,8 +64,7 @@ class GraphTest : public ::testing::Test 10U, config_.value(), job_queue_, - ProcessHandling{&process_interface_, mock_process_map}, - mock_factory_, + ProcessHandling{&process_interface_, mock_process_map, mock_factory_}, &mock_transition_result_publisher_); } diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp index 6ef5744e5..b9c283b6c 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp @@ -16,12 +16,13 @@ #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/iprocess.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" #include namespace score::mw::lifecycle::internal { -/// @brief Collection of interfaces required to control a OS process. +/// @brief Collection of interfaces required to control an OS process. struct ProcessHandling { /// @brief Handle to manage the underlying posix process. @@ -29,6 +30,9 @@ struct ProcessHandling /// @brief Map to store the state of the process. std::shared_ptr process_map_; + + /// @brief Factory to construct component supervisions with. + ISupervisionFactory& supervision_factory; }; } // namespace score::mw::lifecycle::internal diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp index 35483a7e4..f9d6a5ce5 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp @@ -27,8 +27,7 @@ namespace score::mw::lifecycle::internal ProcessInfoNode::ProcessInfoNode( configuration::ComponentConfig&& config, uint32_t index, - ProcessHandling process_handling, - ISupervisionFactory& supervision_factory) + ProcessHandling process_handling) : terminator_(), has_semaphore_(false), process_index_(index), @@ -53,7 +52,8 @@ ProcessInfoNode::ProcessInfoNode( LM_LOG_DEBUG() << "Setting up alive supervision for" << name; config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(name)); - state_publisher_ = supervision_factory.constructSupervision(name, uid, app_profile.alive_supervision.value()); + state_publisher_ = process_handling_.supervision_factory.constructSupervision( + name, uid, app_profile.alive_supervision.value()); } } diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp index e4a143510..099255763 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp @@ -22,7 +22,6 @@ #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/process_state.hpp" #include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" #include #include #include @@ -48,11 +47,7 @@ class ProcessInfoNode final : public IComponent /// @param process_handling The interfaces used to start, stop and report on the OS process. /// @param supervision_factory Temporary reference to a factory this node can use to construct its supervision if /// required. - ProcessInfoNode( - configuration::ComponentConfig&& config, - uint32_t index, - ProcessHandling process_handling, - ISupervisionFactory& supervision_factory); + ProcessInfoNode(configuration::ComponentConfig&& config, uint32_t index, ProcessHandling process_handling); /// @brief Explicit move constructor required due to atomics. PIN must be moveable to exist in the graph ProcessInfoNode(ProcessInfoNode&& other) noexcept diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp index 71702c8f1..4eb1ce310 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp @@ -104,7 +104,7 @@ class ProcessInfoNodeFixture : public ::testing::Test } return std::make_unique( - std::move(config), kProcessIndex, ProcessHandling{&mock_processIf_, process_map_}, mock_factory_); + std::move(config), kProcessIndex, ProcessHandling{&mock_processIf_, process_map_, mock_factory_}); } /// @brief Helper method to create a ProcessInfoNode that is self-terminating. diff --git a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp index 7e03809e6..5dba0b35a 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp @@ -207,8 +207,7 @@ bool ProcessGroupManager::initializeProcessGroups() configuration_.components().size() + configuration_.runTargets().size() + 2, configuration_, worker_jobs_, - ProcessHandling{&process_interface_, process_map_}, - alive_monitor_->getSupervisionFactory(), + ProcessHandling{&process_interface_, process_map_, alive_monitor_->getSupervisionFactory()}, this); LM_LOG_DEBUG() << "Process group initialized successfully"; From f412534535117aa9db40c5197f2b791624d19a27 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 31 Aug 2026 10:51:16 +0100 Subject: [PATCH 10/12] Apply suggestions --- .../src/alive_monitor/details/daemon/AliveMonitorImpl.hpp | 3 +++ .../src/process_group_manager/details/process_info_node.cpp | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index 1f0502fdd..5cc502bb5 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -50,10 +50,13 @@ class AliveMonitorImpl : public IAliveMonitor const AliveSupervisionConfig& config, const std::size_t supervised_components); + /// @brief @see IAliveMonitor definition bool start() noexcept override; + /// @brief @see IAliveMonitor definition void stop() noexcept override; + /// @brief @see IAliveMonitor definition ISupervisionFactory& getSupervisionFactory() const noexcept override; private: diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp index f9d6a5ce5..983c8e437 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp @@ -43,9 +43,10 @@ ProcessInfoNode::ProcessInfoNode( const configuration::ApplicationProfile& app_profile = config_.component_properties.application_profile; - if (app_profile.alive_supervision.has_value() && - app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised) + if (app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised) { + SCORE_LANGUAGE_FUTURECPP_ASSERT_DBG_MESSAGE( + app_profile.alive_supervision.has_value(), "Supervised process did not have alive supervision config"); const IdentifierHash name{config_.name}; const uid_t uid = config_.deployment_config.sandbox.uid; From 432e8398b879eea9576b2a1967948047ccefc850 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 31 Aug 2026 10:46:53 +0100 Subject: [PATCH 11/12] Cleanup --- .../src/daemon/src/alive_monitor/IAliveMonitor.hpp | 5 +++-- .../details/daemon/AliveMonitorImpl.cpp | 4 ++-- .../details/daemon/AliveMonitorImpl.hpp | 4 ++-- .../daemon/src/alive_monitor/mock_alive_monitor.hpp | 4 ++-- .../daemon/src/process_group_manager/details/BUILD | 1 - .../details/process_group_manager_UT.cpp | 12 ++++++------ .../details/process_info_node.cpp | 5 ++--- .../process_group_manager/process_group_manager.cpp | 4 ++-- .../src/daemon/src/supervision_control_client/BUILD | 1 + .../isupervision_event_publisher.hpp | 4 ++++ .../mock_supervision_event_publisher.hpp | 1 + .../supervision_handle.hpp | 11 +++++++++++ 12 files changed, 36 insertions(+), 20 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp index fe31fc6da..107b75592 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp @@ -31,10 +31,11 @@ class IAliveMonitor virtual ~IAliveMonitor() = default; /// @brief Start the monitor thread - virtual bool start() = 0; + /// @returns False if monitoring failed to start, true otherwise + virtual bool startMonitoring() = 0; /// @brief Stop the monitor thread - virtual void stop() = 0; + virtual void stopMonitoring() = 0; /// @brief Returns an interface for components to register their alive supervision virtual ISupervisionFactory& getSupervisionFactory() const = 0; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp index 22d36157f..d673215e4 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp @@ -64,7 +64,7 @@ EInitCode AliveMonitorImpl::init(const std::size_t supervised_components) noexce return initResult; } -bool AliveMonitorImpl::start() noexcept +bool AliveMonitorImpl::startMonitoring() noexcept { if (initResult != EInitCode::kNoError) { @@ -78,7 +78,7 @@ bool AliveMonitorImpl::start() noexcept return true; } -void AliveMonitorImpl::stop() noexcept +void AliveMonitorImpl::stopMonitoring() noexcept { stop_thread_.store(true); if (alive_monitor_thread_.joinable()) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index 5cc502bb5..aceb34eae 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -51,10 +51,10 @@ class AliveMonitorImpl : public IAliveMonitor const std::size_t supervised_components); /// @brief @see IAliveMonitor definition - bool start() noexcept override; + bool startMonitoring() noexcept override; /// @brief @see IAliveMonitor definition - void stop() noexcept override; + void stopMonitoring() noexcept override; /// @brief @see IAliveMonitor definition ISupervisionFactory& getSupervisionFactory() const noexcept override; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp index 34ad8e3ae..915379fc9 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/mock_alive_monitor.hpp @@ -22,8 +22,8 @@ namespace score::mw::lifecycle::internal::saf::daemon class MockAliveMonitor : public IAliveMonitor { public: - MOCK_METHOD(bool, start, (), (override)); - MOCK_METHOD(void, stop, (), (override)); + MOCK_METHOD(bool, startMonitoring, (), (override)); + MOCK_METHOD(void, stopMonitoring, (), (override)); MOCK_METHOD(ISupervisionFactory&, getSupervisionFactory, (), (const, override)); }; diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index 2696a7dd9..3718585ef 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD @@ -160,7 +160,6 @@ cc_library( ":icomponent", ":process_handling", ":safe_process_map", - "//score/launch_manager/src/daemon/src/common:alive_interface_path", "//score/launch_manager/src/daemon/src/configuration:component_config", "//score/launch_manager/src/daemon/src/control:control_client_channel", "//score/launch_manager/src/daemon/src/osal:ipc_comms", diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp index 336c195ae..c4899d0a0 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp @@ -107,7 +107,7 @@ class ProcessGroupManagerWatchdogTest : public Test protected: void expectNormalStartup() { - EXPECT_CALL(*alive_monitor_, start()).WillOnce(Return(true)); + EXPECT_CALL(*alive_monitor_, startMonitoring()).WillOnce(Return(true)); EXPECT_CALL(*watchdog_, init(_, _)).WillOnce(Return(true)); EXPECT_CALL(*watchdog_, enable()).WillOnce(Return(true)); } @@ -119,7 +119,7 @@ class ProcessGroupManagerWatchdogTest : public Test auto alive_monitor = std::make_unique>(); alive_monitor_ = alive_monitor.get(); - ON_CALL(*alive_monitor_, start()).WillByDefault(Return(true)); + ON_CALL(*alive_monitor_, startMonitoring()).WillByDefault(Return(true)); ON_CALL(*alive_monitor_, getSupervisionFactory).WillByDefault(ReturnRef(factory_)); auto recovery_client = std::make_shared>(); @@ -165,7 +165,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogMethods InSequence sequence; expectNormalStartup(); EXPECT_CALL(*watchdog_, disable()).Times(1); - EXPECT_CALL(*alive_monitor_, stop()).Times(1); + EXPECT_CALL(*alive_monitor_, stopMonitoring()).Times(1); // When auto initialize_result = process_group_manager_->initialize(); @@ -184,7 +184,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogService }); // Called in deinitialize() after run() returns EXPECT_CALL(*watchdog_, disable()).Times(1); - EXPECT_CALL(*alive_monitor_, stop()).Times(1); + EXPECT_CALL(*alive_monitor_, stopMonitoring()).Times(1); // When ASSERT_TRUE(process_group_manager_->initialize()); @@ -208,7 +208,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogFired_W process_group_manager_->cancel(); }); EXPECT_CALL(*watchdog_, disable()).Times(1); - EXPECT_CALL(*alive_monitor_, stop()).Times(1); + EXPECT_CALL(*alive_monitor_, stopMonitoring()).Times(1); // When ASSERT_TRUE(process_group_manager_->initialize()); @@ -235,7 +235,7 @@ TEST_F(ProcessGroupManagerWatchdogTest, GivenMinimalConfig_ExpectWatchdogDisable // We are explicitly calling deinitialize() in this test for readability, // so disable() and stop() are expected to be called twice: once in deinitialize() and once in TearDown(). EXPECT_CALL(*watchdog_, disable()).Times(2); - EXPECT_CALL(*alive_monitor_, stop()).Times(2); + EXPECT_CALL(*alive_monitor_, stopMonitoring()).Times(2); // When ASSERT_TRUE(process_group_manager_->initialize()); diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp index 8d6c5fe83..21eba6733 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp @@ -13,7 +13,6 @@ #include "process_info_node.hpp" #include "score/launch_manager/src/daemon/src/configuration/component_config.hpp" -#include "score/mw/launch_manager/common/alive_interface_path.hpp" #include "score/mw/launch_manager/common/log.hpp" #include "score/mw/launch_manager/osal/ipc_comms.hpp" #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" @@ -48,10 +47,10 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces LM_LOG_DEBUG() << "Setting up alive supervision for" << identifier_; - config_.deployment_config.environmental_variables.add( - "LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(identifier_)); state_publisher_ = process_handling_.supervision_factory.constructSupervision( identifier_, uid, app_profile.alive_supervision.value()); + config_.deployment_config.environmental_variables.add( + "LCM_ALIVE_INTERFACE_PATH", state_publisher_->getConnectionId()); } } diff --git a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp index c4661fe08..89ca29a7a 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/process_group_manager.cpp @@ -94,7 +94,7 @@ bool ProcessGroupManager::initialize() } LM_LOG_DEBUG() << "Process Group initialization done"; - if (!alive_monitor_->start()) + if (!alive_monitor_->startMonitoring()) { LM_LOG_ERROR() << "Alive monitor thread failed to start"; return false; @@ -129,7 +129,7 @@ void ProcessGroupManager::deinitialize() event_queue_->stop(); } os_handler_.reset(); - alive_monitor_->stop(); + alive_monitor_->stopMonitoring(); // Join the worker threads before destroying the process groups: a worker may // still be (de)activating a ProcessInfoNode owned by a graph, so tearing the diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD index b4e9568cd..bef74dd4a 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD +++ b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD @@ -42,6 +42,7 @@ cc_library( deps = [ ":isupervision_event_publisher", ":supervision_event", + "//score/launch_manager/src/daemon/src/common:alive_interface_path", "//score/launch_manager/src/daemon/src/common:identifier_hash", "//score/launch_manager/src/daemon/src/common:log", ], diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp index 5c3168e68..ff30af4e4 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp @@ -14,6 +14,7 @@ #define ISUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED #include +#include namespace score { @@ -35,6 +36,9 @@ class ISupervisionEventPublisher /// @brief Report that the calling process has changed from the active state at @param time virtual bool reportDeactivation(timespec time) noexcept = 0; + + /// @brief Get the name of the IPC file alive indications are sent to. + virtual std::string_view getConnectionId() const noexcept = 0; }; } // namespace mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp index 0936a7f12..284289b3a 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp @@ -24,6 +24,7 @@ class MockSupervisionEventPublisher : public ISupervisionEventPublisher public: MOCK_METHOD(bool, reportActivation, (timespec time), (override, noexcept)); MOCK_METHOD(bool, reportDeactivation, (timespec time), (override, noexcept)); + MOCK_METHOD(std::string_view, getConnectionId, (), (const, override, noexcept)); }; } // namespace score::mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp index 501dabdaa..b10208235 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp @@ -13,10 +13,12 @@ #ifndef SUPERVISION_HANDLE_HPP_INCLUDED #define SUPERVISION_HANDLE_HPP_INCLUDED +#include "score/mw/launch_manager/common/alive_interface_path.hpp" #include "score/mw/launch_manager/common/identifier_hash.hpp" #include "score/mw/launch_manager/common/log.hpp" #include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" #include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" + #include namespace score @@ -37,6 +39,7 @@ class SupervisionHandle : public ISupervisionEventPublisher explicit SupervisionHandle(IdentifierHash process_id, std::shared_ptr buffer) : process_id_(process_id), buffer_(buffer) { + ipc_path_ = std::move(internal::aliveInterfacePath(process_id_)); } /// @brief Report that the calling process has reached the active state at @param time @@ -51,6 +54,12 @@ class SupervisionHandle : public ISupervisionEventPublisher return queueSupervisionEvent({process_id_, SupervisionEventType::kDeactivation, time}); } + /// @brief Get the name of the IPC file alive indications are sent to. + std::string_view getConnectionId() const noexcept override + { + return ipc_path_; + } + private: /// @brief Attempts to push a supervision event so that the alive monitor can be informed about it. /// @param[in] f_event The SupervisionEvent to be queued @@ -72,6 +81,8 @@ class SupervisionHandle : public ISupervisionEventPublisher const IdentifierHash process_id_; /// @brief Buffer to push supervision events to std::shared_ptr buffer_; + /// @brief IPC path for alive indications + std::string ipc_path_; }; } // namespace mw::lifecycle From 9d9cbe8faf280181d75f8a2fb29e175202919450 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 31 Aug 2026 11:43:30 +0100 Subject: [PATCH 12/12] Reorganise supervision control client --- .../src/daemon/src/alive_monitor/BUILD | 49 +++++++++- .../src/alive_monitor/IAliveMonitor.hpp | 2 +- .../src/alive_monitor/details/daemon/BUILD | 2 +- .../details/daemon/PhmDaemon.hpp | 2 +- .../src/alive_monitor/details/ifexm/BUILD | 41 +++++++- .../details/ifexm/ObservableEvent.hpp | 2 +- .../details/ifexm/ObservableEventReader.hpp | 2 +- .../ifexm}/supervision_control_client_ut.cpp | 2 +- .../details/ifexm}/supervision_event.hpp | 0 .../details/ifexm}/supervision_handle.hpp | 4 +- .../isupervision_event_publisher.hpp | 0 .../isupervision_factory.hpp | 2 +- .../mock_supervision_event_publisher.hpp | 2 +- .../mock_supervision_factory.hpp | 2 +- .../src/process_group_manager/details/BUILD | 16 +-- .../details/graph_UT.cpp | 4 +- .../details/process_group_manager_UT.cpp | 4 +- .../details/process_handling.hpp | 2 +- .../details/process_info_node.hpp | 2 +- .../details/process_info_node_UT.cpp | 4 +- .../src/supervision_control_client/BUILD | 97 ------------------- 21 files changed, 114 insertions(+), 127 deletions(-) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor/details/ifexm}/supervision_control_client_ut.cpp (98%) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor/details/ifexm}/supervision_event.hpp (100%) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor/details/ifexm}/supervision_handle.hpp (94%) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor}/isupervision_event_publisher.hpp (100%) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor}/isupervision_factory.hpp (95%) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor}/mock_supervision_event_publisher.hpp (92%) rename score/launch_manager/src/daemon/src/{supervision_control_client => alive_monitor}/mock_supervision_factory.hpp (92%) delete mode 100644 score/launch_manager/src/daemon/src/supervision_control_client/BUILD diff --git a/score/launch_manager/src/daemon/src/alive_monitor/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/BUILD index 2ceef92c7..afa8bc526 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/BUILD @@ -27,7 +27,7 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", visibility = ["//score:__subpackages__"], deps = [ - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", + "//score/launch_manager/src/daemon/src/alive_monitor:isupervision_factory", ], ) @@ -43,3 +43,50 @@ cc_library( "@googletest//:gtest_main", ], ) + +cc_library( + name = "isupervision_event_publisher", + hdrs = ["isupervision_event_publisher.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", + visibility = ["//score:__subpackages__"], +) + +cc_library( + name = "isupervision_factory", + hdrs = ["isupervision_factory.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", + visibility = ["//score:__subpackages__"], + deps = [ + "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:supervision_handle", + "//score/launch_manager/src/daemon/src/common:identifier_hash", + "//score/launch_manager/src/daemon/src/configuration:component_config", + ], +) + +cc_library( + name = "mock_supervision_event_publisher", + testonly = True, + hdrs = ["mock_supervision_event_publisher.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", + visibility = ["//score:__subpackages__"], + deps = [ + ":isupervision_event_publisher", + "@googletest//:gtest_main", + ], +) + +cc_library( + name = "mock_supervision_factory", + testonly = True, + hdrs = ["mock_supervision_factory.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor", + visibility = ["//score:__subpackages__"], + deps = [ + ":isupervision_factory", + "@googletest//:gtest_main", + ], +) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp index 107b75592..9ee72a01b 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp @@ -13,7 +13,7 @@ #ifndef SAF_DAEMON_ALIVE_MONITOR_HPP_INCLUDED #define SAF_DAEMON_ALIVE_MONITOR_HPP_INCLUDED -#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" +#include "score/mw/launch_manager/alive_monitor/isupervision_factory.hpp" namespace score { diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD index c29b9df3a..2014d0723 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD @@ -51,6 +51,7 @@ cc_library( deps = [ ":phm_daemon_config", ":sw_cluster_handler", + "//score/launch_manager/src/daemon/src/alive_monitor:isupervision_factory", "//score/launch_manager/src/daemon/src/alive_monitor/details/common:einitcode", "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:flat_cfg_factory", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:monitor_if_daemon", @@ -60,7 +61,6 @@ cc_library( "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:cycle_timer", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:log", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index e317f82b7..bd823268c 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -26,8 +26,8 @@ #include "score/mw/launch_manager/alive_monitor/details/timers/CycleTimeValidator.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/CycleTimer.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/TimeConversion.hpp" +#include "score/mw/launch_manager/alive_monitor/isupervision_factory.hpp" #include "score/mw/launch_manager/configuration/config.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" namespace score { diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD index 2999e2fef..a30d5fa03 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/BUILD @@ -11,6 +11,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* load("@rules_cc//cc:defs.bzl", "cc_library") +load("//tests/utils/bazel:unit_test.bzl", "lm_cc_test") cc_library( name = "observable_event", @@ -20,9 +21,9 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm", visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ + ":supervision_event", "//score/launch_manager/src/daemon/src/alive_monitor/details/common:observer", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", - "//score/launch_manager/src/daemon/src/supervision_control_client:supervision_event", ], ) @@ -35,10 +36,46 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ ":observable_event", + ":supervision_event", "//score/launch_manager:error_event", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:time_conversion", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:log", - "//score/launch_manager/src/daemon/src/supervision_control_client:supervision_event", + ], +) + +cc_library( + name = "supervision_event", + hdrs = ["supervision_event.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor/details/ifexm", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm", + visibility = ["//score:__subpackages__"], + deps = [ + "//externals/ipc_dropin", + "//score/launch_manager/src/daemon/src/common:identifier_hash", + ], +) + +cc_library( + name = "supervision_handle", + hdrs = ["supervision_handle.hpp"], + include_prefix = "score/mw/launch_manager/alive_monitor/details/ifexm", + strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm", + visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], + deps = [ + ":supervision_event", + "//score/launch_manager/src/daemon/src/alive_monitor:isupervision_event_publisher", + "//score/launch_manager/src/daemon/src/common:alive_interface_path", + "//score/launch_manager/src/daemon/src/common:identifier_hash", + "//score/launch_manager/src/daemon/src/common:log", + ], +) + +lm_cc_test( + name = "supervision_control_client_ut", + srcs = ["supervision_control_client_ut.cpp"], + deps = [ + ":supervision_handle", + "@googletest//:gtest_main", ], ) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEvent.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEvent.hpp index f43cd5aaf..1575bb97e 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEvent.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEvent.hpp @@ -18,7 +18,7 @@ #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" #include -#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" +#include "score/mw/launch_manager/alive_monitor/details/ifexm/supervision_event.hpp" namespace score { diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp index 3e46dfb68..a14b33ae7 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/ObservableEventReader.hpp @@ -17,8 +17,8 @@ #include #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" +#include "score/mw/launch_manager/alive_monitor/details/ifexm/supervision_event.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" #include "score/result/result.h" diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_control_client_ut.cpp similarity index 98% rename from score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp rename to score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_control_client_ut.cpp index 8466da100..c089dabac 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_control_client_ut.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_control_client_ut.cpp @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#include "score/mw/launch_manager/supervision_control_client/supervision_handle.hpp" +#include "score/mw/launch_manager/alive_monitor/details/ifexm/supervision_handle.hpp" #include #include diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_event.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_event.hpp similarity index 100% rename from score/launch_manager/src/daemon/src/supervision_control_client/supervision_event.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_event.hpp diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_handle.hpp similarity index 94% rename from score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_handle.hpp index b10208235..9c60dd516 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/supervision_handle.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifexm/supervision_handle.hpp @@ -13,11 +13,11 @@ #ifndef SUPERVISION_HANDLE_HPP_INCLUDED #define SUPERVISION_HANDLE_HPP_INCLUDED +#include "score/mw/launch_manager/alive_monitor/details/ifexm/supervision_event.hpp" +#include "score/mw/launch_manager/alive_monitor/isupervision_event_publisher.hpp" #include "score/mw/launch_manager/common/alive_interface_path.hpp" #include "score/mw/launch_manager/common/identifier_hash.hpp" #include "score/mw/launch_manager/common/log.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" #include diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/alive_monitor/isupervision_event_publisher.hpp similarity index 100% rename from score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/isupervision_event_publisher.hpp diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp b/score/launch_manager/src/daemon/src/alive_monitor/isupervision_factory.hpp similarity index 95% rename from score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/isupervision_factory.hpp index 212283c5a..f40ab6de9 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_factory.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/isupervision_factory.hpp @@ -16,9 +16,9 @@ #include #include +#include "score/mw/launch_manager/alive_monitor/details/ifexm/supervision_handle.hpp" #include "score/mw/launch_manager/common/identifier_hash.hpp" #include "score/mw/launch_manager/configuration/component_config.hpp" -#include "score/mw/launch_manager/supervision_control_client/supervision_handle.hpp" namespace score { diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/alive_monitor/mock_supervision_event_publisher.hpp similarity index 92% rename from score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/mock_supervision_event_publisher.hpp index 284289b3a..c34b8b370 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/mock_supervision_event_publisher.hpp @@ -13,7 +13,7 @@ #ifndef MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED #define MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" +#include "score/mw/launch_manager/alive_monitor/isupervision_event_publisher.hpp" #include namespace score::mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp b/score/launch_manager/src/daemon/src/alive_monitor/mock_supervision_factory.hpp similarity index 92% rename from score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp rename to score/launch_manager/src/daemon/src/alive_monitor/mock_supervision_factory.hpp index 07107f76f..025b49e6e 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_factory.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/mock_supervision_factory.hpp @@ -14,7 +14,7 @@ #ifndef MOCK_SUPERVISION_FACTORY_HPP_INCLUDED #define MOCK_SUPERVISION_FACTORY_HPP_INCLUDED -#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" +#include "score/mw/launch_manager/alive_monitor/isupervision_factory.hpp" #include namespace score::mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index 3718585ef..b91d398c9 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD @@ -144,8 +144,8 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/process_group_manager:__pkg__"], deps = [ ":safe_process_map", + "//score/launch_manager/src/daemon/src/alive_monitor:isupervision_factory", "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_factory", ], ) @@ -160,13 +160,13 @@ cc_library( ":icomponent", ":process_handling", ":safe_process_map", + "//score/launch_manager/src/daemon/src/alive_monitor:isupervision_event_publisher", "//score/launch_manager/src/daemon/src/configuration:component_config", "//score/launch_manager/src/daemon/src/control:control_client_channel", "//score/launch_manager/src/daemon/src/osal:ipc_comms", "//score/launch_manager/src/daemon/src/osal:semaphore", "//score/launch_manager/src/daemon/src/process_group_manager:iprocess", "//score/launch_manager/src/daemon/src/process_group_manager:process_state", - "//score/launch_manager/src/daemon/src/supervision_control_client:isupervision_event_publisher", "@score_baselibs//score/language/futurecpp", ], ) @@ -177,9 +177,9 @@ lm_cc_test( deps = [ ":process_info_node", ":safe_process_map", + "//score/launch_manager/src/daemon/src/alive_monitor:mock_supervision_event_publisher", + "//score/launch_manager/src/daemon/src/alive_monitor:mock_supervision_factory", "//score/launch_manager/src/daemon/src/process_group_manager:mock_iprocess", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_event_publisher", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", "@googletest//:gtest_main", ], ) @@ -229,10 +229,10 @@ lm_cc_test( srcs = ["graph_UT.cpp"], deps = [ ":graph", + "//score/launch_manager/src/daemon/src/alive_monitor:mock_supervision_event_publisher", + "//score/launch_manager/src/daemon/src/alive_monitor:mock_supervision_factory", "//score/launch_manager/src/daemon/src/configuration:config", "//score/launch_manager/src/daemon/src/process_group_manager:mock_iprocess", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_event_publisher", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", "@googletest//:gtest_main", ], ) @@ -351,11 +351,11 @@ lm_cc_test( srcs = ["process_group_manager_UT.cpp"], deps = [ "//score/launch_manager/src/daemon/src/alive_monitor:mock_alive_monitor", + "//score/launch_manager/src/daemon/src/alive_monitor:mock_supervision_event_publisher", + "//score/launch_manager/src/daemon/src/alive_monitor:mock_supervision_factory", "//score/launch_manager/src/daemon/src/configuration:config", "//score/launch_manager/src/daemon/src/process_group_manager", "//score/launch_manager/src/daemon/src/recovery_client:mock_recovery_client", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_event_publisher", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", "//score/launch_manager/src/daemon/src/watchdog:mock_i_watchdog_if", "@googletest//:gtest_main", ], diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp index 9372bea1a..bf4cb26da 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/graph_UT.cpp @@ -20,11 +20,11 @@ #include #include +#include "score/mw/launch_manager/alive_monitor/mock_supervision_event_publisher.hpp" +#include "score/mw/launch_manager/alive_monitor/mock_supervision_factory.hpp" #include "score/mw/launch_manager/configuration/config.hpp" #include "score/mw/launch_manager/process_group_manager/details/graph.hpp" #include "score/mw/launch_manager/process_group_manager/mock_iprocess.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_event_publisher.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" namespace score::mw::lifecycle::internal { diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp index c4899d0a0..45c02a4fd 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager_UT.cpp @@ -14,9 +14,9 @@ #include "score/mw/launch_manager/process_group_manager/process_group_manager.hpp" #include "score/mw/launch_manager/alive_monitor/mock_alive_monitor.hpp" +#include "score/mw/launch_manager/alive_monitor/mock_supervision_event_publisher.hpp" +#include "score/mw/launch_manager/alive_monitor/mock_supervision_factory.hpp" #include "score/mw/launch_manager/recovery_client/mock_irecovery_client.h" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_event_publisher.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" #include "score/mw/launch_manager/watchdog/mock_IWatchdogIf.hpp" #include diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp index b9c283b6c..0c1794034 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_handling.hpp @@ -14,9 +14,9 @@ #ifndef _INCLUDED_PROCESSHANDLING_ #define _INCLUDED_PROCESSHANDLING_ +#include "score/mw/launch_manager/alive_monitor/isupervision_factory.hpp" #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/iprocess.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_factory.hpp" #include namespace score::mw::lifecycle::internal diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp index 510bc3771..cec061c3e 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.hpp @@ -15,13 +15,13 @@ #define _INCLUDED_PROCESSINFONODE_ #include "score/launch_manager/src/daemon/src/configuration/component_config.hpp" +#include "score/mw/launch_manager/alive_monitor/isupervision_event_publisher.hpp" #include "score/mw/launch_manager/configuration/component_config.hpp" #include "score/mw/launch_manager/control/control_client_channel.hpp" #include "score/mw/launch_manager/process_group_manager/details/icomponent.hpp" #include "score/mw/launch_manager/process_group_manager/details/process_handling.hpp" #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/process_state.hpp" -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" #include #include #include diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp index c68d25564..1cb4b24ba 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp @@ -11,11 +11,11 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +#include "score/mw/launch_manager/alive_monitor/mock_supervision_event_publisher.hpp" +#include "score/mw/launch_manager/alive_monitor/mock_supervision_factory.hpp" #include "score/mw/launch_manager/process_group_manager/details/process_info_node.hpp" #include "score/mw/launch_manager/process_group_manager/details/safe_process_map.hpp" #include "score/mw/launch_manager/process_group_manager/mock_iprocess.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_event_publisher.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" #include #include #include diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD deleted file mode 100644 index bef74dd4a..000000000 --- a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD +++ /dev/null @@ -1,97 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2026 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Apache License Version 2.0 which is available at -# https://www.apache.org/licenses/LICENSE-2.0 -# -# SPDX-License-Identifier: Apache-2.0 -# ******************************************************************************* -load("@rules_cc//cc:defs.bzl", "cc_library") -load("//tests/utils/bazel:unit_test.bzl", "lm_cc_test") - -cc_library( - name = "supervision_event", - hdrs = ["supervision_event.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - "//externals/ipc_dropin", - "//score/launch_manager/src/daemon/src/common:identifier_hash", - ], -) - -cc_library( - name = "isupervision_event_publisher", - hdrs = ["isupervision_event_publisher.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], -) - -cc_library( - name = "supervision_handle", - hdrs = ["supervision_handle.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":isupervision_event_publisher", - ":supervision_event", - "//score/launch_manager/src/daemon/src/common:alive_interface_path", - "//score/launch_manager/src/daemon/src/common:identifier_hash", - "//score/launch_manager/src/daemon/src/common:log", - ], -) - -cc_library( - name = "isupervision_factory", - hdrs = ["isupervision_factory.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":supervision_handle", - "//score/launch_manager/src/daemon/src/common:identifier_hash", - "//score/launch_manager/src/daemon/src/configuration:component_config", - ], -) - -cc_library( - name = "mock_supervision_event_publisher", - testonly = True, - hdrs = ["mock_supervision_event_publisher.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":isupervision_event_publisher", - "@googletest//:gtest_main", - ], -) - -cc_library( - name = "mock_supervision_factory", - testonly = True, - hdrs = ["mock_supervision_factory.hpp"], - include_prefix = "score/mw/launch_manager/supervision_control_client", - strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", - visibility = ["//score:__subpackages__"], - deps = [ - ":isupervision_factory", - "@googletest//:gtest_main", - ], -) - -lm_cc_test( - name = "supervision_control_client_ut", - srcs = ["supervision_control_client_ut.cpp"], - deps = [ - ":supervision_handle", - "@googletest//:gtest_main", - ], -)