From f4c1fd2482f9673ae74b588d90c18a916e9f6806 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/17] 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 4290470a48..3eab6f2a6c 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 50ba1ab8a4230d4520ffccbdbd7fdaba642b18f5 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/17] 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 34705a5949..f0f06f2848 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 8bea5e7268..ac52a9246f 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 ac4a8b1b47..06df8243dc 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 2a229864bf..99b2cc2825 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 0000000000..d93b50fc03 --- /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 9584790546..1908413fb6 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 3cab63bb4c..8803a636da 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 4cc7d1804e..c29b9df3ac 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 f9d2862ba3..ff4e6aa251 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 d23b180b99..974a852438 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 6417eaddac..73fd72d0ec 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 f8caa9f515..59e4e55e59 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 e8cdc0c307..2999e2fef4 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 448bbe4b27..96804a6484 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 228acf5dad..eda6e3178a 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 9ffa87a35d..fb7dc0312f 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 fba3d4a79b..b88ce6d7ec 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", @@ -97,7 +63,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 e2c4c56dd1..0000000000 --- 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 3eab6f2a6c..0000000000 --- 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 23fbf41f23..0000000000 --- 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 bc3f223099..0000000000 --- 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 8909e915cf..d20a2ab92b 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,9 +38,8 @@ 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_(), @@ -49,8 +47,7 @@ ProcessGroupManager::ProcessGroupManager( 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 2926d69dc5..9676eb40c7 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" @@ -33,10 +34,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 @@ -74,9 +73,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. @@ -283,10 +281,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 1a5e5a2134..0b1ac5c715 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 97bd6d036e..0000000000 --- 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 a5a92b0f3d..0000000000 --- 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 3ca37c4e20..0000000000 --- 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 3ae726f533..0000000000 --- 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 c64b8e31cd..0000000000 --- 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 6921fb045c..5c3168e681 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 0000000000..32da6e979d --- /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 f37203578b..0000000000 --- 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 db237840a1..0000000000 --- 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 645c82cf94..0000000000 --- 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 6a06b05aee..0000000000 --- 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 7b6aeb3e3a..0000000000 --- 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 320acc4d70..031e519d88 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 0000000000..bec5a606e4 --- /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 9d25525ca6cdffd425302b1253ea7dd9713ea5b9 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/17] 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 | 6 ++- .../process_group_manager/details/graph.hpp | 3 +- .../details/process_handling.hpp | 4 -- .../details/process_info_node.cpp | 41 +++++++++++-------- .../details/process_info_node.hpp | 10 ++++- .../process_group_manager.cpp | 9 ++-- .../process_group_manager.hpp | 4 +- .../isupervision_factory.hpp | 2 +- .../supervision_handle.hpp | 2 +- 13 files changed, 54 insertions(+), 57 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 8803a636da..eecea02972 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 ff4e6aa251..7e65b1bcdc 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 974a852438..8f2c38f723 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 5161c140ef..38c90d9a44 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 @@ -170,6 +170,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", ], ) @@ -224,6 +225,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 fc4788d102..80594ad2b1 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 @@ -42,6 +42,7 @@ void CreateDependencyGraph( DependencyGraph& graph, configuration::Config& config, ProcessHandling process_handling, + ISupervisionFactory& supervision_factory, std::chrono::milliseconds& off_state_transition_timeout) { std::vector run_targets = config.takeRunTargets(); @@ -59,7 +60,7 @@ void CreateDependencyGraph( auto depends_on = std::move(component_config.component_properties.depends_on); const auto index = graph.try_emplace( - IdentifierHash{name}, std::in_place_type, std::move(component_config), process_handling); + IdentifierHash{name}, std::in_place_type, std::move(component_config), process_handling, supervision_factory); LM_LOG_DEBUG() << "Creating component node:" << name; pending_dependencies.emplace_back(index, std::move(depends_on)); @@ -119,6 +120,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_), @@ -131,7 +133,7 @@ Graph::Graph( last_state_manager_.process_identifier_ = IdentifierHash{""}; // an invalid state manager last_state_manager_.process_group_index_ = 0xFFFFU; cancel_message_.request_or_response_ = ControlClientCode::kNotSet; - CreateDependencyGraph(nodes_, configuration_, process_handling_, off_state_transition_timeout_); + CreateDependencyGraph(nodes_, configuration_, process_handling_, 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 80e7580cce..1591f0c2f0 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 eba560a307..74903dae7f 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 @@ -17,7 +17,6 @@ #include "score/mw/launch_manager/osal/ifile_waiter.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_event_publisher.hpp" #include namespace score::mw::lifecycle::internal @@ -26,9 +25,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 ab943feecf..704e957d23 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 @@ -21,30 +21,37 @@ #include #include #include +#include namespace score::mw::lifecycle::internal { -ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, ProcessHandling process_handling) +ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, ProcessHandling process_handling, + ISupervisionFactory& supervision_factory) : terminator_(), has_semaphore_(false), pid_(0), exit_code_(0), config_(std::move(config)), - process_handling_(std::move(process_handling)), - identifier_(IdentifierHash{{config_.name}}) + 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 uid_t uid = config.deployment_config.sandbox.uid; + + config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(identifier_)); + + state_publisher_ = supervision_factory.constructSupervision(identifier_, uid, app_profile.alive_supervision.value()); + } } IComponent::RequestResult ProcessInfoNode::tryReportCompletion(score::mw::lifecycle::ProcessState new_state) @@ -95,7 +102,7 @@ IComponent::RequestResult ProcessInfoNode::tryReportSuccess() if (auto time = getTimeForReport()) { - process_handling_.state_publisher_.reportActivation(identifier_, time.value()); + state_publisher_->reportActivation(time.value()); } return {RequestState::kSuccess}; @@ -106,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) @@ -471,7 +478,7 @@ IComponent::RequestResult ProcessInfoNode::deactivate(score::cpp::stop_token sto reached_ready_.store(false); if (auto time = getTimeForReport()) { - process_handling_.state_publisher_.reportDeactivation(identifier_, 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 b059ec2466..43637712e0 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,10 @@ 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, ProcessHandling process_handling); + ProcessInfoNode( + configuration::ComponentConfig&& config, + 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,6 +64,7 @@ class ProcessInfoNode final : public IComponent control_client_channel_(std::move(other.control_client_channel_)), sync_(std::move(other.sync_)), process_handling_(std::move(other.process_handling_)), + state_publisher_(std::move(other.state_publisher_)), identifier_(other.identifier_) { } @@ -187,6 +192,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 d20a2ab92b..de448e895b 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)), @@ -95,7 +95,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; @@ -130,7 +130,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 @@ -208,7 +208,8 @@ bool ProcessGroupManager::initializeProcessGroups() configuration_.components().size() + configuration_.runTargets().size() + 2, configuration_, worker_jobs_, - ProcessHandling{*supervision_control_notifier_.get(), &process_interface_, process_map_, &file_waiter_}, + ProcessHandling{&process_interface_, process_map_, &file_waiter_}, + 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 9676eb40c7..6321d61cee 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 @@ -73,7 +73,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); @@ -281,7 +281,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 32da6e979d..4b8a583e79 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 bec5a606e4..4df38f4e77 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 ccb56644c272dc105176bcbfac8dc1f79c29bce3 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/17] 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 06df8243dc..40f65af2b4 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 1908413fb6..6915f07af5 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 eecea02972..bdcf577db8 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 7e65b1bcdc..6b03a020f8 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 8f2c38f723..8bc7a2d99d 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 f84851cf9c..88ebe32be6 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 6d793f7fbf..10b96b6018 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 fb7dc0312f..cf24f72910 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 80594ad2b1..9b1d2a4248 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 @@ -133,7 +133,8 @@ Graph::Graph( last_state_manager_.process_identifier_ = IdentifierHash{""}; // an invalid state manager last_state_manager_.process_group_index_ = 0xFFFFU; cancel_message_.request_or_response_ = ControlClientCode::kNotSet; - CreateDependencyGraph(nodes_, configuration_, process_handling_, supervision_factory, off_state_transition_timeout_); + CreateDependencyGraph( + nodes_, configuration_, process_handling_, supervision_factory, off_state_transition_timeout_); } Graph::~Graph() From d0a26c10e0ba08570c1ff1b3e70b3e16ecba28a7 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/17] 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 | 4 ++-- .../details/process_info_node.hpp | 3 ++- .../isupervision_factory.hpp | 8 +++++--- .../supervision_handle.hpp | 13 ++++++++++++- 11 files changed, 39 insertions(+), 16 deletions(-) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/BUILD index ac52a9246f..030b04a202 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 40f65af2b4..fe31fc6da4 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 6915f07af5..22d36157fc 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 bdcf577db8..1f0502fddb 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 8bc7a2d99d..c46211d56b 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 eda6e3178a..3e46dfb688 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 1591f0c2f0..5ceecdb112 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 704e957d23..fb339c0dfc 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 @@ -21,7 +21,6 @@ #include #include #include -#include namespace score::mw::lifecycle::internal { @@ -45,9 +44,10 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces if (app_profile.alive_supervision.has_value() && app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised) { - std::cout << "setting up alive supervision" << std::endl; const uid_t uid = config.deployment_config.sandbox.uid; + LM_LOG_DEBUG() << "Setting up alive supervision for" << name; + config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(identifier_)); state_publisher_ = supervision_factory.constructSupervision(identifier_, 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 43637712e0..fa175530bc 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, ProcessHandling process_handling, 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 4b8a583e79..493e96f391 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 4df38f4e77..501dabdaa0 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 059727bf643ae09530b3ac17b8c5c2945e1c25e8 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/17] 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 030b04a202..2ceef92c73 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 c46211d56b..d7eb3e86d9 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 0000000000..34ad8e3ae4 --- /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 38c90d9a44..4fc28a125d 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 @@ -184,6 +184,7 @@ lm_cc_test( "//score/launch_manager/src/daemon/src/osal:mock_ifile_waiter", "//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", ], ) @@ -237,6 +238,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", ], ) @@ -354,12 +356,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 3843b68eba..7494babfa0 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 b156a56ad6..336c195ae2 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 0e38a596a3..2657232e0b 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 @@ -16,6 +16,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 @@ -26,8 +27,9 @@ #include using namespace testing; -using namespace score::mw::lifecycle::internal; -using namespace score::mw::lifecycle; + +namespace score::mw::lifecycle::internal +{ // Default process name for testing constexpr std::string_view kProcessName{"test_process"}; @@ -47,8 +49,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. @@ -70,6 +99,13 @@ 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), ProcessHandling{mock_publisher_, &mock_processIf_, process_map_}); } @@ -92,7 +128,7 @@ class ProcessInfoNodeFixture : public ::testing::Test config.deployment_config.shutdown_timeout_ms = shutdown_timeout_ms_; return std::make_unique( - std::move(config), ProcessHandling{mock_publisher_, &mock_processIf_, process_map_, &mock_file_waiter_}); + std::move(config), ProcessHandling{&mock_processIf_, process_map_, &mock_file_waiter_}, mock_factory_); } /// @brief Helper method to create a ProcessInfoNode that is self-terminating. @@ -149,7 +185,7 @@ class ProcessInfoNodeFixture : public ::testing::Test std::shared_ptr process_map_{std::make_shared()}; StrictMock mock_processIf_{}; StrictMock mock_file_waiter_{}; - NiceMock mock_publisher_{}; + NiceMock mock_factory_{}; }; // Bundles different cases for activate() that occur during startup, before the ready condition is reached. @@ -193,10 +229,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{}); @@ -295,12 +331,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{}); @@ -316,7 +352,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(_, _)) @@ -325,7 +362,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{}); @@ -341,9 +377,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) @@ -360,7 +397,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{}); @@ -428,8 +464,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(_, _)) @@ -440,7 +478,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{}); @@ -540,9 +577,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()); @@ -603,7 +640,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)); @@ -717,3 +753,5 @@ TEST_F(ProcessInfoNodeFileStateTest, WaitForFileTimesOut_ReturnsActivationTimedO ASSERT_THAT(result.error(), Eq(IComponent::ComponentError::kActivationTimedOut)); ASSERT_THAT(node->getState(), Eq(score::mw::lifecycle::ProcessState::kTerminated)); } + +} // 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 0b1ac5c715..b4e9568cd5 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 493e96f391..212283c5a5 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 0000000000..0936a7f128 --- /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 0000000000..07107f76f6 --- /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 47b8970b19..8466da100b 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 3325909afc9e09a0cbbd257473519c22a611f41d 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/17] Fix wrong member name --- .../src/process_group_manager/details/process_info_node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 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 fb339c0dfc..f27a9ec9ce 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 @@ -39,12 +39,12 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces 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 uid_t uid = config.deployment_config.sandbox.uid; + const uid_t uid = config_.deployment_config.sandbox.uid; LM_LOG_DEBUG() << "Setting up alive supervision for" << name; From a8f71cadd9695e7a825d5872331840b93d1c9c0b 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/17] 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 d7eb3e86d9..e317f82b71 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 88ebe32be6..556c761cb6 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 10b96b6018..e54323ded5 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 96804a6484..52734a7d2f 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 e339ab946886a7c3faf9a38d73c387fe63ffb389 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/17] Move supervision factory into struct --- .../src/daemon/src/process_group_manager/details/BUILD | 4 +--- .../src/daemon/src/process_group_manager/details/graph.cpp | 6 ++---- .../src/daemon/src/process_group_manager/details/graph.hpp | 3 --- .../daemon/src/process_group_manager/details/graph_UT.cpp | 3 +-- .../src/process_group_manager/details/process_handling.hpp | 6 +++++- .../src/process_group_manager/details/process_info_node.cpp | 6 +++--- .../src/process_group_manager/details/process_info_node.hpp | 4 +--- .../process_group_manager/details/process_info_node_UT.cpp | 2 +- .../src/process_group_manager/process_group_manager.cpp | 3 +-- 9 files changed, 15 insertions(+), 22 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 4fc28a125d..c391c12800 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 @@ -146,7 +146,7 @@ cc_library( ":safe_process_map", "//score/launch_manager/src/daemon/src/osal:ifile_waiter", "//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", ], ) @@ -170,7 +170,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", ], ) @@ -226,7 +225,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 9b1d2a4248..a6a314e4e5 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 @@ -60,7 +60,7 @@ void CreateDependencyGraph( auto depends_on = std::move(component_config.component_properties.depends_on); const auto index = graph.try_emplace( - IdentifierHash{name}, std::in_place_type, std::move(component_config), process_handling, supervision_factory); + IdentifierHash{name}, std::in_place_type, std::move(component_config), process_handling); LM_LOG_DEBUG() << "Creating component node:" << name; pending_dependencies.emplace_back(index, std::move(depends_on)); @@ -120,7 +120,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_), @@ -133,8 +132,7 @@ Graph::Graph( last_state_manager_.process_identifier_ = IdentifierHash{""}; // an invalid state manager last_state_manager_.process_group_index_ = 0xFFFFU; cancel_message_.request_or_response_ = ControlClientCode::kNotSet; - CreateDependencyGraph( - nodes_, configuration_, process_handling_, supervision_factory, off_state_transition_timeout_); + CreateDependencyGraph(nodes_, configuration_, process_handling_, 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 5ceecdb112..89ab3ab587 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 7494babfa0..9372bea1a4 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 74903dae7f..ce3e552c63 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 @@ -17,12 +17,13 @@ #include "score/mw/launch_manager/osal/ifile_waiter.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 { -/// @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. @@ -33,6 +34,9 @@ struct ProcessHandling /// @brief Interface used to wait for a FileState ready condition. osal::IFileWaiter* file_waiter_{nullptr}; + + /// @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 f27a9ec9ce..f230439c15 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 @@ -25,8 +25,7 @@ namespace score::mw::lifecycle::internal { -ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, ProcessHandling process_handling, - ISupervisionFactory& supervision_factory) +ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, ProcessHandling process_handling) : terminator_(), has_semaphore_(false), pid_(0), @@ -50,7 +49,8 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(identifier_)); - state_publisher_ = supervision_factory.constructSupervision(identifier_, uid, app_profile.alive_supervision.value()); + state_publisher_ = process_handling_.supervision_factory.constructSupervision( + identifier_, 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 fa175530bc..83d61a8571 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 @@ -50,8 +49,7 @@ class ProcessInfoNode final : public IComponent /// required. ProcessInfoNode( configuration::ComponentConfig&& config, - ProcessHandling process_handling, - ISupervisionFactory& supervision_factory); + 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 2657232e0b..83e8ccd025 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 @@ -128,7 +128,7 @@ class ProcessInfoNodeFixture : public ::testing::Test config.deployment_config.shutdown_timeout_ms = shutdown_timeout_ms_; return std::make_unique( - std::move(config), ProcessHandling{&mock_processIf_, process_map_, &mock_file_waiter_}, mock_factory_); + std::move(config), ProcessHandling{&mock_processIf_, process_map_, &mock_file_waiter_, 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 de448e895b..037d296681 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 @@ -208,8 +208,7 @@ bool ProcessGroupManager::initializeProcessGroups() configuration_.components().size() + configuration_.runTargets().size() + 2, configuration_, worker_jobs_, - ProcessHandling{&process_interface_, process_map_, &file_waiter_}, - alive_monitor_->getSupervisionFactory(), + ProcessHandling{&process_interface_, process_map_, &file_waiter_, alive_monitor_->getSupervisionFactory()}, this); LM_LOG_DEBUG() << "Process group initialized successfully"; From f5cc8b4b7a0ebc9cedfedc3f918147816d98c164 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/17] 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 1f0502fddb..5cc502bb51 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 f230439c15..69a72f44af 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 @@ -40,9 +40,10 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces 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 uid_t uid = config_.deployment_config.sandbox.uid; LM_LOG_DEBUG() << "Setting up alive supervision for" << name; From 84780eb9259026d86db93d3fa724d48db5f0ca35 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:16:19 +0100 Subject: [PATCH 11/17] Fixes after rebase --- .../daemon/src/process_group_manager/details/graph.cpp | 1 - .../daemon/src/process_group_manager/details/graph_UT.cpp | 2 +- .../process_group_manager/details/process_info_node.cpp | 8 +++++--- .../process_group_manager/details/process_info_node.hpp | 4 +--- .../details/process_info_node_UT.cpp | 5 +---- 5 files changed, 8 insertions(+), 12 deletions(-) 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 a6a314e4e5..fc4788d102 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 @@ -42,7 +42,6 @@ void CreateDependencyGraph( DependencyGraph& graph, configuration::Config& config, ProcessHandling process_handling, - ISupervisionFactory& supervision_factory, std::chrono::milliseconds& off_state_transition_timeout) { std::vector run_targets = config.takeRunTargets(); 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 9372bea1a4..9bfce4e01e 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,7 +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, nullptr, mock_factory_}, &mock_transition_result_publisher_); } 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 69a72f44af..cf2033b607 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 @@ -31,7 +31,8 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces pid_(0), exit_code_(0), config_(std::move(config)), - process_handling_(std::move(process_handling)) + process_handling_(std::move(process_handling)), + identifier_(config_.name) { if (config_.deployment_config.ready_recovery_action.has_value()) { @@ -46,9 +47,10 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces app_profile.alive_supervision.has_value(), "Supervised process did not have alive supervision config"); const uid_t uid = config_.deployment_config.sandbox.uid; - LM_LOG_DEBUG() << "Setting up alive supervision for" << name; + LM_LOG_DEBUG() << "Setting up alive supervision for" << identifier_; - config_.deployment_config.environmental_variables.add("LCM_ALIVE_INTERFACE_PATH", aliveInterfacePath(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()); 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 83d61a8571..7e67b26c94 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 @@ -47,9 +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, - ProcessHandling process_handling); + ProcessInfoNode(configuration::ComponentConfig&& config, 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 83e8ccd025..e1490d993e 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 @@ -107,7 +107,7 @@ class ProcessInfoNodeFixture : public ::testing::Test } return std::make_unique( - std::move(config), ProcessHandling{mock_publisher_, &mock_processIf_, process_map_}); + std::move(config), ProcessHandling{&mock_processIf_, process_map_, nullptr, mock_factory_}); } /// @brief Helper method to create a ProcessInfoNode with a FileState ready condition. @@ -687,7 +687,6 @@ TEST_F(ProcessInfoNodeFileStateTest, ConditionAlreadyMet_ReturnsSuccess) Eq(std::chrono::milliseconds{5}), _)) .WillOnce(Return(osal::OsalReturnType::kSuccess)); - EXPECT_CALL(mock_publisher_, reportActivation); auto result = node->activate(score::cpp::stop_token{}); @@ -708,7 +707,6 @@ TEST_F(ProcessInfoNodeFileStateTest, NotExistingCondition_ReturnsSuccess) EXPECT_CALL(mock_processIf_, ignoreRunning(_)).WillOnce(Return(osal::OsalReturnType::kSuccess)); EXPECT_CALL(mock_file_waiter_, waitForFile(_, Eq(configuration::FileExistenceState::NotExisting), _, _, _)) .WillOnce(Return(osal::OsalReturnType::kSuccess)); - EXPECT_CALL(mock_publisher_, reportActivation); auto result = node->activate(score::cpp::stop_token{}); @@ -745,7 +743,6 @@ TEST_F(ProcessInfoNodeFileStateTest, WaitForFileTimesOut_ReturnsActivationTimedO EXPECT_CALL(mock_file_waiter_, waitForFile(_, _, _, _, _)).WillOnce(Return(osal::OsalReturnType::kTimeout)); // 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{}); From cefd51c39fb65a58dee80e76a02b739e80de71d6 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:41:02 +0100 Subject: [PATCH 12/17] Initial cleanup --- .../src/alive_monitor/details/daemon/AliveMonitorImpl.cpp | 4 ++-- .../src/alive_monitor/details/daemon/AliveMonitorImpl.hpp | 2 +- .../daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp | 8 ++------ .../daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp | 5 +++-- .../alive_monitor/details/daemon/SupervisionManager.cpp | 2 +- .../alive_monitor/details/daemon/SupervisionManager.hpp | 2 +- .../process_group_manager/details/process_info_node.hpp | 3 --- 7 files changed, 10 insertions(+), 16 deletions(-) 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 22d36157fc..1ea5aa233e 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 @@ -25,7 +25,7 @@ AliveMonitorImpl::AliveMonitorImpl( SptrIRecoveryClient recovery_client, const AliveSupervisionConfig& config, const std::size_t supervised_components) - : m_recovery_client(recovery_client), m_config(config) + : m_recovery_client(recovery_client), config_(config) { initResult = init(supervised_components); } @@ -38,7 +38,7 @@ EInitCode AliveMonitorImpl::init(const std::size_t supervised_components) noexce m_osClock.startMeasurement(); m_daemon = std::make_unique(m_osClock, supervised_components); - initResult = m_daemon->init(m_recovery_client, m_config); + initResult = m_daemon->init(m_recovery_client, 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 20729950c2..c075991ad0 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 @@ -64,7 +64,7 @@ class AliveMonitorImpl : public IAliveMonitor SptrIRecoveryClient m_recovery_client{nullptr}; UptrPhmDaemon m_daemon{nullptr}; OsClock m_osClock{}; - const AliveSupervisionConfig& m_config; + const AliveSupervisionConfig& 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 6b03a020f8..28139c54c8 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 @@ -23,16 +23,12 @@ namespace score::mw::lifecycle::internal::saf::daemon { -/* RULECHECKER_comment(0, 6, check_expensive_to_copy_in_parameter, "Move only types cannot be passed by const ref", - 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::size_t supervised_components) : osClock{f_osClock}, cycleTimer{&osClock}, buffer_(std::make_shared()), supervisionManager{std::make_unique()}, - processStateReader{buffer_} + supervisionStateReader_{buffer_} { buffer_->initialize(); supervisionManager.reserve(supervised_components); @@ -48,7 +44,7 @@ void PhmDaemon::performCyclicTriggers(void) syncTimestamp = UINT64_MAX; } - if (processStateReader.distributeChanges(syncTimestamp)) + if (supervisionStateReader_.distributeChanges(syncTimestamp)) { supervisionManager.performCyclicTriggers(syncTimestamp); } 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 93708de8eb..1acafa074c 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 @@ -179,7 +179,7 @@ class PhmDaemon final : public ISupervisionFactory { SCORE_LANGUAGE_FUTURECPP_ASSERT_DBG_MESSAGE( !supervisionManager.full(), "More alive supervisions than expected were constructed"); - supervisionManager.constructWorker(id, config, uid, recoveryClient, processStateReader); + supervisionManager.constructWorker(id, config, uid, recoveryClient, supervisionStateReader_); return std::make_unique(id, buffer_); } @@ -194,6 +194,7 @@ class PhmDaemon final : public ISupervisionFactory /// @brief For fixed time-step execution during the cyclic execution CycleTimer cycleTimer; + /// @brief Buffer that supervision events are pushed to and read from std::shared_ptr buffer_; /// @brief Recovery interface to Launch Manager @@ -203,7 +204,7 @@ class PhmDaemon final : public ISupervisionFactory SupervisionManager supervisionManager; /// @brief Observable Event Reader for PHM daemon - ObservableEventReader processStateReader; + ObservableEventReader supervisionStateReader_; }; } // namespace score::mw::lifecycle::internal::saf::daemon 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 556c761cb6..ececd3d353 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,7 +32,7 @@ SupervisionManager::SupervisionManager(std::unique_ptr fac SupervisionManager::~SupervisionManager() = default; -bool SupervisionManager::full() +bool SupervisionManager::full() const { return aliveSupervisions.size() == capacity; } 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 5d31d0c66c..bade5cb21f 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 @@ -87,7 +87,7 @@ class SupervisionManager void reserve(std::size_t size); /// @brief Returns true if the number of alive supervisions constructed equals the reserved size - bool full(); + bool full() const; /// @brief Construct required worker objects for provided component /// @details Construct the interfaces, checkpoints, supervisions and recovery notifications 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 7e67b26c94..6b2f654175 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 @@ -43,10 +43,7 @@ class ProcessInfoNode final : public IComponent public: /// @brief Constructs a ProcessInfoNode. /// @param config Configuration for the OS process. - /// @param index The process index within its process group. /// @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, ProcessHandling process_handling); /// @brief Explicit move constructor required due to atomics. PIN must be moveable to exist in the graph From 22909505efe6eca17b4d38e8fa298c2df0572a93 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Wed, 2 Sep 2026 11:57:47 +0100 Subject: [PATCH 13/17] Rename supervision_event_publisher --- .../src/alive_monitor/details/daemon/PhmDaemon.hpp | 2 +- .../daemon/src/process_group_manager/details/BUILD | 8 ++++---- .../src/process_group_manager/details/graph_UT.cpp | 8 ++++---- .../details/process_group_manager_UT.cpp | 4 ++-- .../details/process_info_node.hpp | 4 ++-- .../details/process_info_node_UT.cpp | 10 +++++----- .../src/daemon/src/supervision_control_client/BUILD | 12 ++++++------ .../isupervision_factory.hpp | 2 +- ...publisher.hpp => isupervision_state_reporter.hpp} | 10 +++++----- .../mock_supervision_factory.hpp | 2 +- ...isher.hpp => mock_supervision_state_reporter.hpp} | 10 +++++----- .../supervision_control_client_ut.cpp | 2 +- .../supervision_handle.hpp | 4 ++-- 13 files changed, 39 insertions(+), 39 deletions(-) rename score/launch_manager/src/daemon/src/supervision_control_client/{isupervision_event_publisher.hpp => isupervision_state_reporter.hpp} (80%) rename score/launch_manager/src/daemon/src/supervision_control_client/{mock_supervision_event_publisher.hpp => mock_supervision_state_reporter.hpp} (77%) 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 1acafa074c..c1bc38e038 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 @@ -172,7 +172,7 @@ class PhmDaemon final : public ISupervisionFactory } /// @brief @see ISupervisonFactory::constructSupervision - 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/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index c391c12800..d3bfc04c7f 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 @@ -169,7 +169,7 @@ cc_library( "//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/launch_manager/src/daemon/src/supervision_control_client:isupervision_state_reporter", "@score_baselibs//score/language/futurecpp", ], ) @@ -182,8 +182,8 @@ lm_cc_test( ":safe_process_map", "//score/launch_manager/src/daemon/src/osal:mock_ifile_waiter", "//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", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_state_reporter", "@googletest//:gtest_main", ], ) @@ -235,8 +235,8 @@ lm_cc_test( ":graph", "//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", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_state_reporter", "@googletest//:gtest_main", ], ) @@ -358,8 +358,8 @@ lm_cc_test( "//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/supervision_control_client:mock_supervision_state_reporter", "//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 9bfce4e01e..1d1b0b64ec 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 @@ -23,8 +23,8 @@ #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" +#include "score/mw/launch_manager/supervision_control_client/mock_supervision_state_reporter.hpp" namespace score::mw::lifecycle::internal { @@ -53,8 +53,8 @@ class GraphTest : public ::testing::Test RecordProperty("TestType", "interface-test"); RecordProperty("DerivationTechnique", "equivalence-classes"); - ON_CALL(mock_supervision_event_publisher_, reportActivation).WillByDefault(Return(true)); - ON_CALL(mock_supervision_event_publisher_, reportDeactivation).WillByDefault(Return(true)); + ON_CALL(mock_supervision_state_reporter_, reportActivation).WillByDefault(Return(true)); + ON_CALL(mock_supervision_state_reporter_, reportDeactivation).WillByDefault(Return(true)); SetConfig(); @@ -184,7 +184,7 @@ class GraphTest : public ::testing::Test std::shared_ptr job_queue_ = std::make_shared(); StrictMock process_interface_{}; std::shared_ptr mock_process_map = std::make_shared(); - NiceMock mock_supervision_event_publisher_{}; + NiceMock mock_supervision_state_reporter_{}; MockTransitionResultPublisher mock_transition_result_publisher_{}; MockSupervisionFactory mock_factory_{}; std::unique_ptr graph_{}; 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 336c195ae2..223ab0ac89 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 @@ -15,8 +15,8 @@ #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_event_publisher.hpp" #include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" +#include "score/mw/launch_manager/supervision_control_client/mock_supervision_state_reporter.hpp" #include "score/mw/launch_manager/watchdog/mock_IWatchdogIf.hpp" #include @@ -130,7 +130,7 @@ class ProcessGroupManagerWatchdogTest : public Test ON_CALL(*recovery_client_, sendRecoveryRequest(_)).WillByDefault(Return(true)); ON_CALL(factory_, constructSupervision).WillByDefault(InvokeWithoutArgs([]() { - auto publisher = std::make_unique>(); + auto publisher = std::make_unique>(); ON_CALL(*publisher, reportActivation).WillByDefault(Return(true)); ON_CALL(*publisher, reportDeactivation).WillByDefault(Return(true)); return publisher; 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 6b2f654175..da13f7477c 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 @@ -21,7 +21,7 @@ #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 "score/mw/launch_manager/supervision_control_client/isupervision_state_reporter.hpp" #include #include #include @@ -187,7 +187,7 @@ class ProcessInfoNode final : public IComponent ProcessHandling process_handling_; /// @brief Interface for reporting component state to health monitor. - std::unique_ptr state_publisher_; + 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/details/process_info_node_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp index e1490d993e..8fab43902c 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,8 +15,8 @@ #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 "score/mw/launch_manager/supervision_control_client/mock_supervision_state_reporter.hpp" #include #include #include @@ -54,9 +54,9 @@ class ProcessInfoNodeFixture : public ::testing::Test })); } - virtual std::unique_ptr> constructDefaultEventPublisher() const + virtual std::unique_ptr> constructDefaultEventPublisher() const { - auto mock_publisher = std::make_unique>(); + 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; @@ -65,7 +65,7 @@ class ProcessInfoNodeFixture : public ::testing::Test void expectActivationReport(int times = 1) { EXPECT_CALL(mock_factory_, constructSupervision).WillOnce(InvokeWithoutArgs([times]() { - auto mock_publisher = std::make_unique>(); + auto mock_publisher = std::make_unique>(); EXPECT_CALL(*mock_publisher, reportActivation).Times(times).WillRepeatedly(Return(true)); return mock_publisher; })); @@ -74,7 +74,7 @@ class ProcessInfoNodeFixture : public ::testing::Test void expectDeactivationReport(int times = 1) { EXPECT_CALL(mock_factory_, constructSupervision).WillOnce(InvokeWithoutArgs([times]() { - auto mock_publisher = std::make_unique>(); + auto mock_publisher = std::make_unique>(); EXPECT_CALL(*mock_publisher, reportDeactivation).Times(times).WillRepeatedly(Return(true)); return mock_publisher; })); 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 b4e9568cd5..82863f35fc 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD +++ b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD @@ -26,8 +26,8 @@ cc_library( ) cc_library( - name = "isupervision_event_publisher", - hdrs = ["isupervision_event_publisher.hpp"], + name = "isupervision_state_reporter", + hdrs = ["isupervision_state_reporter.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__"], @@ -40,7 +40,7 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", visibility = ["//score:__subpackages__"], deps = [ - ":isupervision_event_publisher", + ":isupervision_state_reporter", ":supervision_event", "//score/launch_manager/src/daemon/src/common:identifier_hash", "//score/launch_manager/src/daemon/src/common:log", @@ -61,14 +61,14 @@ cc_library( ) cc_library( - name = "mock_supervision_event_publisher", + name = "mock_supervision_state_reporter", testonly = True, - hdrs = ["mock_supervision_event_publisher.hpp"], + hdrs = ["mock_supervision_state_reporter.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", + ":isupervision_state_reporter", "@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 212283c5a5..92f3e6bfc8 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/isupervision_event_publisher.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_state_reporter.hpp similarity index 80% rename from score/launch_manager/src/daemon/src/supervision_control_client/isupervision_event_publisher.hpp rename to score/launch_manager/src/daemon/src/supervision_control_client/isupervision_state_reporter.hpp index 236162767e..e691703036 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_state_reporter.hpp @@ -10,22 +10,22 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef ISUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED -#define ISUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED +#ifndef ISUPERVISION_STATE_REPORTER_HPP_INCLUDED +#define ISUPERVISION_STATE_REPORTER_HPP_INCLUDED #include namespace score::mw::lifecycle { -/// @brief ISupervisionEventPublisher interface for forwarding supervision events to the alive monitor. +/// @brief ISupervisionStateReporter 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 the active state or inactive state -class ISupervisionEventPublisher +class ISupervisionStateReporter { public: /// @brief Destructor. - virtual ~ISupervisionEventPublisher() noexcept = default; + virtual ~ISupervisionStateReporter() noexcept = default; /// @brief Report that the calling process has reached the active state at @param time virtual bool reportActivation(timespec time) noexcept = 0; 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 index 07107f76f6..b8913e1c17 100644 --- 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 @@ -24,7 +24,7 @@ class MockSupervisionFactory : public ISupervisionFactory { public: MOCK_METHOD( - std::unique_ptr, + std::unique_ptr, constructSupervision, (const IdentifierHash id, const uid_t uid, const internal::configuration::ComponentAliveSupervision& config), (override)); 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_state_reporter.hpp similarity index 77% rename from score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_event_publisher.hpp rename to score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_state_reporter.hpp index 0936a7f128..e900a4ec8f 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_state_reporter.hpp @@ -10,16 +10,16 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED -#define MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED +#ifndef MOCK_SUPERVISION_STATE_REPORTER_HPP_INCLUDED +#define MOCK_SUPERVISION_STATE_REPORTER_HPP_INCLUDED -#include "score/mw/launch_manager/supervision_control_client/isupervision_event_publisher.hpp" +#include "score/mw/launch_manager/supervision_control_client/isupervision_state_reporter.hpp" #include namespace score::mw::lifecycle { -class MockSupervisionEventPublisher : public ISupervisionEventPublisher +class MockSupervisionStateReporter : public ISupervisionStateReporter { public: MOCK_METHOD(bool, reportActivation, (timespec time), (override, noexcept)); @@ -28,4 +28,4 @@ class MockSupervisionEventPublisher : public ISupervisionEventPublisher } // namespace score::mw::lifecycle -#endif // MOCK_SUPERVISION_EVENT_PUBLISHER_HPP_INCLUDED +#endif // MOCK_SUPERVISION_STATE_REPORTER_HPP_INCLUDED 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 8466da100b..7c23e03ca4 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 @@ -36,7 +36,7 @@ class SupervisionControlClient_UT : public ::testing::Test const IdentifierHash process_{"Process"}; std::shared_ptr buffer_; - std::unique_ptr handle_; + std::unique_ptr handle_; }; TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueOneEvent_Succeeds) 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 501dabdaa0..6222d1906f 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 @@ -15,7 +15,7 @@ #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/isupervision_state_reporter.hpp" #include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" #include @@ -28,7 +28,7 @@ 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 +class SupervisionHandle : public ISupervisionStateReporter { public: /// @brief Construct a new supervision handle. From d590b6d210cc38d763fe675a7067f44fb022c5d5 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Wed, 2 Sep 2026 12:31:46 +0100 Subject: [PATCH 14/17] Handle failed construction --- .../src/alive_monitor/details/daemon/PhmDaemon.hpp | 7 +++++-- .../details/daemon/SupervisionManager.hpp | 2 +- .../details/process_info_node.cpp | 12 +++++++++++- .../details/process_info_node.hpp | 2 +- .../isupervision_factory.hpp | 7 ++++--- 5 files changed, 22 insertions(+), 8 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 c1bc38e038..ac06103487 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 @@ -179,8 +179,11 @@ class PhmDaemon final : public ISupervisionFactory { SCORE_LANGUAGE_FUTURECPP_ASSERT_DBG_MESSAGE( !supervisionManager.full(), "More alive supervisions than expected were constructed"); - supervisionManager.constructWorker(id, config, uid, recoveryClient, supervisionStateReader_); - return std::make_unique(id, buffer_); + if (supervisionManager.constructWorker(id, config, uid, recoveryClient, supervisionStateReader_)) + { + return std::make_unique(id, buffer_); + } + return {}; } private: 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 bade5cb21f..f389d9917b 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 @@ -97,7 +97,7 @@ class SupervisionManager /// @param [in] f_recoveryClient_r Interface to the launch manager for recovery /// @param [in] f_processStateReader_r Process state reader object for PHM daemon /// @return Construction is successful (true), otherwise failure (false) - bool constructWorker( + [[nodiscard]] bool constructWorker( const IdentifierHash& id, const ComponentAliveSupervision& component_config, const uid_t uid, 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 cf2033b607..ebb2e1a949 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 @@ -54,6 +54,15 @@ ProcessInfoNode::ProcessInfoNode(configuration::ComponentConfig&& config, Proces state_publisher_ = process_handling_.supervision_factory.constructSupervision( identifier_, uid, app_profile.alive_supervision.value()); + + if (!state_publisher_) + { + LM_LOG_ERROR() << "Failed to set up alive supervision for" << identifier_; + } + else + { + LM_LOG_DEBUG() << "Successfully set up alive supervision for" << identifier_; + } } } @@ -116,7 +125,8 @@ IComponent::RequestResult ProcessInfoNode::tryReportSuccess() std::optional ProcessInfoNode::getTimeForReport() const { if (config_.component_properties.application_profile.application_type == - score::mw::lifecycle::internal::configuration::ApplicationType::ReportingAndSupervised) + score::mw::lifecycle::internal::configuration::ApplicationType::ReportingAndSupervised && + state_publisher_) { timespec timestamp{}; static_cast(clock_gettime(CLOCK_MONOTONIC, ×tamp)); 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 da13f7477c..787c959cbc 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 @@ -100,7 +100,7 @@ class ProcessInfoNode final : public IComponent /// @brief Helper method to post on the semaphore waiting for kRunning if it exists void unblockSync(); - /// @brief If this process is configured to report to alive monitor, return the current time + /// @brief If this process is successfully configured to report to alive monitor, return the current time [[nodiscard]] std::optional getTimeForReport() const; /// @brief Get the request result corresponding to the new state reached. For example, if the ready state is 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 92f3e6bfc8..3dc667f830 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 @@ -32,12 +32,13 @@ class ISupervisionFactory /// @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. + /// @brief Set up alive supervision for the identified process. Alive supervision is not started until the process + /// reports its activation using the ISupervisionStateReporter. /// @param [in] id Identifier of 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. + /// @returns Nullptr if the construction failed, handle for the process to start and stop its own supervision + /// otherwise. virtual std::unique_ptr constructSupervision( const IdentifierHash id, const uid_t uid, From 587f377f0f610e90d763973612eac7e07b4586fc Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Wed, 2 Sep 2026 13:21:20 +0100 Subject: [PATCH 15/17] Extract init method --- .../src/alive_monitor/IAliveMonitor.hpp | 7 +++++++ .../details/daemon/AliveMonitorImpl.cpp | 20 ++++++------------- .../details/daemon/AliveMonitorImpl.hpp | 10 ++++------ .../src/alive_monitor/mock_alive_monitor.hpp | 1 + .../details/process_group_manager_UT.cpp | 1 + .../process_group_manager.cpp | 5 +++++ 6 files changed, 24 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 5212a1e453..742ff72150 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/IAliveMonitor.hpp @@ -25,13 +25,20 @@ class IAliveMonitor virtual ~IAliveMonitor() = default; /// @brief Start the monitor thread + /// @warning Not valid if @c init() failed virtual bool start() = 0; /// @brief Stop the monitor thread + /// @warning Not valid if @c init() failed virtual void stop() = 0; /// @brief Returns an interface for components to register their alive supervision + /// @warning Not valid if @c init() failed virtual ISupervisionFactory& getSupervisionFactory() const = 0; + + /// @brief Initialize the AliveMonitor functionality + /// @return True if initialization was successful, false otherwise. + virtual bool init() noexcept = 0; }; } // namespace score::mw::lifecycle::internal::saf::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 1ea5aa233e..594093182a 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 @@ -25,25 +25,24 @@ AliveMonitorImpl::AliveMonitorImpl( SptrIRecoveryClient recovery_client, const AliveSupervisionConfig& config, const std::size_t supervised_components) - : m_recovery_client(recovery_client), config_(config) + : m_recovery_client(recovery_client), config_(config), supervised_components_(supervised_components) { - initResult = init(supervised_components); } -EInitCode AliveMonitorImpl::init(const std::size_t supervised_components) noexcept +bool AliveMonitorImpl::init() noexcept { - EInitCode initResult{EInitCode::kGeneralError}; try { m_osClock.startMeasurement(); - m_daemon = std::make_unique(m_osClock, supervised_components); - initResult = m_daemon->init(m_recovery_client, config_); + m_daemon = std::make_unique(m_osClock, supervised_components_); + EInitCode initResult = m_daemon->init(m_recovery_client, config_); if (initResult == EInitCode::kNoError) { const long ms{m_osClock.endMeasurement()}; LM_LOG_DEBUG() << "AliveMonitor: Initialization took " << ms << " ms"; + return true; } else { @@ -53,24 +52,17 @@ EInitCode AliveMonitorImpl::init(const std::size_t supervised_components) noexce catch (const std::exception& e) { std::cerr << "AliveMonitor: Initialization failed due to standard exception: " << e.what() << ".\n"; - initResult = EInitCode::kGeneralError; } catch (...) { std::cerr << "AliveMonitor: Initialization failed due to exception!\n"; - initResult = EInitCode::kGeneralError; } - return initResult; + return false; } bool AliveMonitorImpl::start() noexcept { - if (initResult != EInitCode::kNoError) - { - return false; - } - alive_monitor_thread_ = std::thread([this]() { threadFn(stop_thread_); }); 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 c075991ad0..b9b663a8c6 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,12 +51,10 @@ class AliveMonitorImpl : public IAliveMonitor /// @brief @see IAliveMonitor definition ISupervisionFactory& getSupervisionFactory() const 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 @see IAliveMonitor definition + bool init() 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; @@ -67,7 +65,7 @@ class AliveMonitorImpl : public IAliveMonitor const AliveSupervisionConfig& config_; std::thread alive_monitor_thread_{}; std::atomic_bool stop_thread_{false}; - saf::daemon::EInitCode initResult{saf::daemon::EInitCode::kNotInitialized}; + std::size_t supervised_components_; }; } // namespace internal::saf::daemon 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 34ad8e3ae4..5214234587 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 @@ -25,6 +25,7 @@ class MockAliveMonitor : public IAliveMonitor MOCK_METHOD(bool, start, (), (override)); MOCK_METHOD(void, stop, (), (override)); MOCK_METHOD(ISupervisionFactory&, getSupervisionFactory, (), (const, override)); + MOCK_METHOD(bool, init, (), (noexcept, override)); }; } // namespace score::mw::lifecycle::internal::saf::daemon 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 223ab0ac89..6edc9aaab5 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,6 +107,7 @@ class ProcessGroupManagerWatchdogTest : public Test protected: void expectNormalStartup() { + EXPECT_CALL(*alive_monitor_, init()).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)); 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 037d296681..aaea84b579 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 @@ -87,6 +87,11 @@ bool ProcessGroupManager::initialize() return false; } + if (!alive_monitor_->init()) + { + return false; + } + createProcessComponentsObjects(total_processes); if (!initializeProcessGroups()) From 05759f431ce21a436e601c39af8311442bcebb90 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Wed, 2 Sep 2026 16:05:45 +0100 Subject: [PATCH 16/17] Stop alive config invalidation --- .../details/daemon/AliveMonitorImpl.cpp | 2 +- .../details/daemon/AliveMonitorImpl.hpp | 9 +- score/launch_manager/src/daemon/src/main.cpp | 13 ++- .../process_group_manager/details/graph.cpp | 13 +-- .../process_group_manager/details/graph.hpp | 12 ++- .../details/graph_UT.cpp | 94 ++++++++++++------- .../details/process_group_manager_UT.cpp | 17 +++- .../process_group_manager.cpp | 19 ++-- .../process_group_manager.hpp | 10 +- 9 files changed, 129 insertions(+), 60 deletions(-) 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 594093182a..c0513a7535 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 @@ -23,7 +23,7 @@ namespace score::mw::lifecycle::internal::saf::daemon AliveMonitorImpl::AliveMonitorImpl( SptrIRecoveryClient recovery_client, - const AliveSupervisionConfig& config, + AliveSupervisionConfig config, const std::size_t supervised_components) : m_recovery_client(recovery_client), config_(config), supervised_components_(supervised_components) { 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 b9b663a8c6..e824df089b 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 @@ -36,10 +36,15 @@ using configuration::AliveSupervisionConfig; class AliveMonitorImpl : public IAliveMonitor { + static_assert( + std::is_trivially_copyable_v, + "AliveSupervisionConfig is copied to this object since it is trivially copyable. If this changes, it should be " + "passed by move instead"); + public: AliveMonitorImpl( SptrIRecoveryClient recovery_client, - const AliveSupervisionConfig& config, + AliveSupervisionConfig config, const std::size_t supervised_components); /// @brief @see IAliveMonitor definition @@ -62,7 +67,7 @@ class AliveMonitorImpl : public IAliveMonitor SptrIRecoveryClient m_recovery_client{nullptr}; UptrPhmDaemon m_daemon{nullptr}; OsClock m_osClock{}; - const AliveSupervisionConfig& config_; + AliveSupervisionConfig config_; std::thread alive_monitor_thread_{}; std::atomic_bool stop_thread_{false}; std::size_t supervised_components_; diff --git a/score/launch_manager/src/daemon/src/main.cpp b/score/launch_manager/src/daemon/src/main.cpp index cf24f72910..c9323205c2 100644 --- a/score/launch_manager/src/daemon/src/main.cpp +++ b/score/launch_manager/src/daemon/src/main.cpp @@ -169,9 +169,20 @@ int main(int argc, const char* argv[]) std::unique_ptr healthMonitor{std::make_unique( recoveryClient, config_result.value().takeAliveSupervision(), supervised_components)}; + GraphConfig graph_config = { + config_result.value().takeComponents(), + config_result.value().takeRunTargets(), + config_result.value().takeFallbackRunTarget(), + config_result.value().takeInitialRunTarget(), + }; + auto watchdog = watchdog::createWatchdog(); auto process_group_manager = std::make_unique( - std::move(config_result).value(), std::move(healthMonitor), recoveryClient, std::move(watchdog)); + std::move(graph_config), + std::move(healthMonitor), + recoveryClient, + std::move(watchdog), + config_result.value().takeWatchdog()); if (process_group_manager->initialize()) { 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 fc4788d102..f14cf5a5bb 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 @@ -40,20 +40,17 @@ namespace /// @return A populated dependency graph with all components and run targets. void CreateDependencyGraph( DependencyGraph& graph, - configuration::Config& config, + GraphConfig& config, ProcessHandling process_handling, std::chrono::milliseconds& off_state_transition_timeout) { - std::vector run_targets = config.takeRunTargets(); - std::vector components = config.takeComponents(); - // dependencies can only be wired up once every node exists, so collect // them while creating the nodes std::vector>> pending_dependencies; pending_dependencies.reserve(graph.capacity()); // add all comps - for (auto& component_config : components) + for (auto& component_config : config.components_) { const auto name = component_config.name; auto depends_on = std::move(component_config.component_properties.depends_on); @@ -67,7 +64,7 @@ void CreateDependencyGraph( // add all rts bool off_rt_defined = false; - for (auto& run_target : run_targets) + for (auto& run_target : config.run_targets_) { const auto index = graph.try_emplace( IdentifierHash{run_target.name}, std::in_place_type, IdentifierHash{run_target.name}); @@ -96,7 +93,7 @@ void CreateDependencyGraph( IdentifierHash{Graph::recovery_state_name}, std::in_place_type, IdentifierHash{Graph::recovery_state_name}); - pending_dependencies.emplace_back(fallback_index, config.fallbackRunTarget().depends_on); + pending_dependencies.emplace_back(fallback_index, config.fallback_run_target_.depends_on); // wire up deps for (const auto& [node_identifier, dependencies] : pending_dependencies) @@ -116,7 +113,7 @@ void CreateDependencyGraph( Graph::Graph( uint32_t max_num_nodes, - configuration::Config& configuration, + GraphConfig& configuration, std::shared_ptr job_queue, ProcessHandling process_handling, ITransitionResultPublisher* transition_result_receiver) 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 823062f53d..80b7ace412 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 @@ -47,6 +47,14 @@ namespace score::mw::lifecycle::internal using WorkerQueue = MPMCConcurrentQueue, static_cast(ProcessLimits::kMaxProcesses)>; +struct GraphConfig +{ + std::vector components_; + std::vector run_targets_; + configuration::FallbackRunTargetConfig fallback_run_target_; + std::string initial_run_target_; +}; + /// @brief GraphState - the graph/process group state. /// @details Enumeration representing the state of the graph. /// @note The allowed/disallowed states are managed by @@ -154,7 +162,7 @@ class Graph final /// @param transition_result_receiver Object to notify when the initial transition is complete. Graph( uint32_t max_num_nodes, - configuration::Config& configuration, + GraphConfig& configuration, std::shared_ptr job_queue, ProcessHandling process_handling, ITransitionResultPublisher* transition_result_receiver); @@ -349,7 +357,7 @@ class Graph final mutable std::mutex requested_state_mutex_{}; /// @brief Config pointer to set up graph nodes - configuration::Config& configuration_; + GraphConfig& configuration_; /// @brief Queue to push component tasks to std::shared_ptr job_queue_; 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 1d1b0b64ec..66c734752f 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 @@ -62,7 +62,7 @@ class GraphTest : public ::testing::Test // (fixture-specific) config is in place. graph_ = std::make_unique( 10U, - config_.value(), + graph_config_, job_queue_, ProcessHandling{&process_interface_, mock_process_map, nullptr, mock_factory_}, &mock_transition_result_publisher_); @@ -73,12 +73,18 @@ class GraphTest : public ::testing::Test auto procs = generateProcessComponents(1); auto rts = generateRunTargets(1); rts[1].depends_on = {procs[0].name}; - config_ = ConfigBuilder{} - .setComponents(std::move(procs)) - .setRunTargets(std::move(rts)) - .setInitialRunTarget("Startup") - .setFallbackRunTarget(std::move(fallback)) - .build(); + auto config = ConfigBuilder{} + .setComponents(std::move(procs)) + .setRunTargets(std::move(rts)) + .setInitialRunTarget("Startup") + .setFallbackRunTarget(std::move(fallback)) + .build(); + + graph_config_ = GraphConfig{ + config.takeComponents(), + config.takeRunTargets(), + config.takeFallbackRunTarget(), + config.takeInitialRunTarget()}; } std::vector generateProcessComponents(int count) @@ -180,7 +186,7 @@ class GraphTest : public ::testing::Test ASSERT_EQ(graph_->getProcessGroupState(), target); } - std::optional config_{}; + GraphConfig graph_config_{}; std::shared_ptr job_queue_ = std::make_shared(); StrictMock process_interface_{}; std::shared_ptr mock_process_map = std::make_shared(); @@ -210,12 +216,18 @@ class GraphOrdinaryTransitionTest : public GraphTest auto rts = generateRunTargets(2); rts[1].depends_on = {procs[0].name}; rts[2].depends_on = {procs[1].name}; - config_ = ConfigBuilder{} - .setComponents(std::move(procs)) - .setRunTargets(std::move(rts)) - .setInitialRunTarget("Startup") - .setFallbackRunTarget(std::move(fallback)) - .build(); + auto config = ConfigBuilder{} + .setComponents(std::move(procs)) + .setRunTargets(std::move(rts)) + .setInitialRunTarget("Startup") + .setFallbackRunTarget(std::move(fallback)) + .build(); + + graph_config_ = GraphConfig{ + config.takeComponents(), + config.takeRunTargets(), + config.takeFallbackRunTarget(), + config.takeInitialRunTarget()}; } }; @@ -382,12 +394,18 @@ class GraphImplicitOffTargetTest : public GraphTest rts.push_back(startup); rts.push_back(std::move(rt)); - config_ = ConfigBuilder{} - .setComponents(std::move(procs)) - .setRunTargets(std::move(rts)) - .setInitialRunTarget("Startup") - .setFallbackRunTarget(std::move(fallback)) - .build(); + auto config = ConfigBuilder{} + .setComponents(std::move(procs)) + .setRunTargets(std::move(rts)) + .setInitialRunTarget("Startup") + .setFallbackRunTarget(std::move(fallback)) + .build(); + + graph_config_ = GraphConfig{ + config.takeComponents(), + config.takeRunTargets(), + config.takeFallbackRunTarget(), + config.takeInitialRunTarget()}; } }; @@ -436,12 +454,18 @@ class GraphOffStateTimeoutTest : public GraphTest // The Off run target must be the last entry generateRunTargets() appends. ASSERT_EQ(rts.back().name, "Off"); rts.back().transition_timeout_ms = kOffTimeoutMs; - config_ = ConfigBuilder{} - .setComponents(std::move(procs)) - .setRunTargets(std::move(rts)) - .setInitialRunTarget("Startup") - .setFallbackRunTarget(std::move(fallback)) - .build(); + auto config = ConfigBuilder{} + .setComponents(std::move(procs)) + .setRunTargets(std::move(rts)) + .setInitialRunTarget("Startup") + .setFallbackRunTarget(std::move(fallback)) + .build(); + + graph_config_ = GraphConfig{ + config.takeComponents(), + config.takeRunTargets(), + config.takeFallbackRunTarget(), + config.takeInitialRunTarget()}; } static constexpr std::uint32_t kOffTimeoutMs = 1234; @@ -463,12 +487,18 @@ class GraphHandleComponentEventTest : public GraphTest auto procs = generateProcessComponents(2); auto rts = generateRunTargets(1); rts[1].depends_on = {procs[0].name, procs[1].name}; - config_ = ConfigBuilder{} - .setComponents(std::move(procs)) - .setRunTargets(std::move(rts)) - .setInitialRunTarget("Startup") - .setFallbackRunTarget(std::move(fallback)) - .build(); + auto config = ConfigBuilder{} + .setComponents(std::move(procs)) + .setRunTargets(std::move(rts)) + .setInitialRunTarget("Startup") + .setFallbackRunTarget(std::move(fallback)) + .build(); + + graph_config_ = GraphConfig{ + config.takeComponents(), + config.takeRunTargets(), + config.takeFallbackRunTarget(), + config.takeInitialRunTarget()}; } }; 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 6edc9aaab5..e0fdf88b38 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 @@ -102,6 +102,15 @@ Config makeMinimalConfig() .build(); } +GraphConfig takeGraphConfig(Config& config) +{ + return GraphConfig{ + config.takeComponents(), + config.takeRunTargets(), + config.takeFallbackRunTarget(), + config.takeInitialRunTarget()}; +} + class ProcessGroupManagerWatchdogTest : public Test { protected: @@ -140,8 +149,14 @@ class ProcessGroupManagerWatchdogTest : public Test auto watchdog = std::make_unique>(); watchdog_ = watchdog.get(); + auto config = makeMinimalConfig(); + process_group_manager_ = std::make_unique( - makeMinimalConfig(), std::move(alive_monitor), std::move(recovery_client), std::move(watchdog)); + takeGraphConfig(config), + std::move(alive_monitor), + std::move(recovery_client), + std::move(watchdog), + config.takeWatchdog()); } void TearDown() override 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 aaea84b579..353ec9e5c4 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 @@ -37,11 +37,13 @@ void ProcessGroupManager::cancel() } ProcessGroupManager::ProcessGroupManager( - configuration::Config&& config, + GraphConfig&& config, std::unique_ptr alive_monitor, std::shared_ptr recovery_client, - std::unique_ptr watchdog) + std::unique_ptr watchdog, + std::optional&& watchdog_config) : configuration_(std::move(config)), + watchdog_config_(watchdog_config), process_interface_(), file_waiter_(), process_map_(nullptr), @@ -79,7 +81,7 @@ bool ProcessGroupManager::initialize() return false; } - const std::size_t total_processes = configuration_.components().size(); + const std::size_t total_processes = configuration_.components_.size(); if (total_processes > static_cast(ProcessLimits::kMaxProcesses)) { @@ -105,13 +107,10 @@ bool ProcessGroupManager::initialize() LM_LOG_ERROR() << "Alive monitor thread failed to start"; return false; } - - const auto watchdog_config = configuration_.takeWatchdog(); - // Watchdog config may not be available if no watchdog is configured - if (watchdog_config.has_value()) + if (watchdog_config_.has_value()) { - if (!watchdog_->init(std::move(watchdog_config).value(), score::mw::lifecycle::internal::kMainLoopCycleTimeNs)) + if (!watchdog_->init(std::move(watchdog_config_).value(), score::mw::lifecycle::internal::kMainLoopCycleTimeNs)) { LM_LOG_ERROR() << "Watchdog initialization failed"; return false; @@ -210,7 +209,7 @@ bool ProcessGroupManager::initializeProcessGroups() { graph_ = std::make_shared( // size is +2 for fallback + off - configuration_.components().size() + configuration_.runTargets().size() + 2, + configuration_.components_.size() + configuration_.run_targets_.size() + 2, configuration_, worker_jobs_, ProcessHandling{&process_interface_, process_map_, &file_waiter_, alive_monitor_->getSupervisionFactory()}, @@ -321,7 +320,7 @@ bool ProcessGroupManager::startInitialTransition() { LM_LOG_DEBUG() << "=============STARTING STARTUP STATE============"; SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE(bool(graph_), "Graph not initialized"); - graph_->startInitialTransition(IdentifierHash{configuration_.initialRunTarget()}); + graph_->startInitialTransition(IdentifierHash{configuration_.initial_run_target_}); return true; } 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 6321d61cee..6ff11364db 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,10 +72,11 @@ class ProcessGroupManager final : public ITransitionResultPublisher /// @param watchdog A unique pointer to an IWatchdogIf instance serviced during the main loop. May be nullptr in /// legacy configuration where no watchdog is wired. ProcessGroupManager( - configuration::Config&& config, + GraphConfig&& config, std::unique_ptr alive_monitor, std::shared_ptr recovery_client, - std::unique_ptr watchdog); + std::unique_ptr watchdog, + std::optional&& watchdog_config); /// @brief Initializes the process group manager. /// Sets up a signal handler for SIGINT and SIGTERM so that the main loop of @@ -258,7 +259,10 @@ class ProcessGroupManager final : public ITransitionResultPublisher bool initializeControlClientHandler(); /// @brief The configuration object associated with the ProcessGroupManager. - configuration::Config configuration_; + GraphConfig configuration_; + + /// @brief The configuration object associated with the watchdog. + std::optional watchdog_config_; /// @brief The process interface object associated with the ProcessGroupManager. osal::ProcessLauncher process_interface_; From c79250c1fa493831834af3d679ef8fee49ed62a4 Mon Sep 17 00:00:00 2001 From: William Roebuck <244554584+WilliamRoebuck@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:23:34 +0100 Subject: [PATCH 17/17] Rename supervision state reporter --- .../src/alive_monitor/details/daemon/PhmDaemon.hpp | 2 +- .../daemon/src/process_group_manager/details/BUILD | 8 ++++---- .../src/process_group_manager/details/graph_UT.cpp | 8 ++++---- .../details/process_group_manager_UT.cpp | 4 ++-- .../details/process_info_node.hpp | 4 ++-- .../details/process_info_node_UT.cpp | 10 +++++----- .../src/daemon/src/supervision_control_client/BUILD | 12 ++++++------ ...e_reporter.hpp => iactivation_state_reporter.hpp} | 10 +++++----- .../isupervision_factory.hpp | 4 ++-- ...porter.hpp => mock_activation_state_reporter.hpp} | 10 +++++----- .../mock_supervision_factory.hpp | 2 +- .../supervision_control_client_ut.cpp | 2 +- .../supervision_handle.hpp | 4 ++-- 13 files changed, 40 insertions(+), 40 deletions(-) rename score/launch_manager/src/daemon/src/supervision_control_client/{isupervision_state_reporter.hpp => iactivation_state_reporter.hpp} (80%) rename score/launch_manager/src/daemon/src/supervision_control_client/{mock_supervision_state_reporter.hpp => mock_activation_state_reporter.hpp} (72%) 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 ac06103487..9b022bf58d 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 @@ -172,7 +172,7 @@ class PhmDaemon final : public ISupervisionFactory } /// @brief @see ISupervisonFactory::constructSupervision - 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/process_group_manager/details/BUILD b/score/launch_manager/src/daemon/src/process_group_manager/details/BUILD index d3bfc04c7f..749bc1bf47 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 @@ -169,7 +169,7 @@ cc_library( "//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_state_reporter", + "//score/launch_manager/src/daemon/src/supervision_control_client:iactivation_state_reporter", "@score_baselibs//score/language/futurecpp", ], ) @@ -182,8 +182,8 @@ lm_cc_test( ":safe_process_map", "//score/launch_manager/src/daemon/src/osal:mock_ifile_waiter", "//score/launch_manager/src/daemon/src/process_group_manager:mock_iprocess", + "//score/launch_manager/src/daemon/src/supervision_control_client:mock_activation_state_reporter", "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_state_reporter", "@googletest//:gtest_main", ], ) @@ -235,8 +235,8 @@ lm_cc_test( ":graph", "//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_activation_state_reporter", "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_state_reporter", "@googletest//:gtest_main", ], ) @@ -358,8 +358,8 @@ lm_cc_test( "//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_activation_state_reporter", "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_factory", - "//score/launch_manager/src/daemon/src/supervision_control_client:mock_supervision_state_reporter", "//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 e6721e53ae..bd258adde4 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 @@ -23,8 +23,8 @@ #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_activation_state_reporter.hpp" #include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_state_reporter.hpp" namespace score::mw::lifecycle::internal { @@ -53,8 +53,8 @@ class GraphTest : public ::testing::Test RecordProperty("TestType", "interface-test"); RecordProperty("DerivationTechnique", "equivalence-classes"); - ON_CALL(mock_supervision_state_reporter_, reportActivation).WillByDefault(Return(true)); - ON_CALL(mock_supervision_state_reporter_, reportDeactivation).WillByDefault(Return(true)); + ON_CALL(mock_activation_state_reporter_, reportActivation).WillByDefault(Return(true)); + ON_CALL(mock_activation_state_reporter_, reportDeactivation).WillByDefault(Return(true)); SetConfig(); @@ -190,7 +190,7 @@ class GraphTest : public ::testing::Test std::shared_ptr job_queue_ = std::make_shared(); StrictMock process_interface_{}; std::shared_ptr mock_process_map = std::make_shared(); - NiceMock mock_supervision_state_reporter_{}; + NiceMock mock_activation_state_reporter_{}; MockTransitionResultPublisher mock_transition_result_publisher_{}; MockSupervisionFactory mock_factory_{}; std::unique_ptr graph_{}; 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 e0fdf88b38..18a88acadb 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 @@ -15,8 +15,8 @@ #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_activation_state_reporter.hpp" #include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_state_reporter.hpp" #include "score/mw/launch_manager/watchdog/mock_IWatchdogIf.hpp" #include @@ -140,7 +140,7 @@ class ProcessGroupManagerWatchdogTest : public Test ON_CALL(*recovery_client_, sendRecoveryRequest(_)).WillByDefault(Return(true)); ON_CALL(factory_, constructSupervision).WillByDefault(InvokeWithoutArgs([]() { - auto publisher = std::make_unique>(); + auto publisher = std::make_unique>(); ON_CALL(*publisher, reportActivation).WillByDefault(Return(true)); ON_CALL(*publisher, reportDeactivation).WillByDefault(Return(true)); return publisher; 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 787c959cbc..af6d01a555 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 @@ -21,7 +21,7 @@ #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_state_reporter.hpp" +#include "score/mw/launch_manager/supervision_control_client/iactivation_state_reporter.hpp" #include #include #include @@ -187,7 +187,7 @@ class ProcessInfoNode final : public IComponent ProcessHandling process_handling_; /// @brief Interface for reporting component state to health monitor. - std::unique_ptr state_publisher_; + 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/details/process_info_node_UT.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node_UT.cpp index 8fab43902c..151c2e0017 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,8 +15,8 @@ #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_activation_state_reporter.hpp" #include "score/mw/launch_manager/supervision_control_client/mock_supervision_factory.hpp" -#include "score/mw/launch_manager/supervision_control_client/mock_supervision_state_reporter.hpp" #include #include #include @@ -54,9 +54,9 @@ class ProcessInfoNodeFixture : public ::testing::Test })); } - virtual std::unique_ptr> constructDefaultEventPublisher() const + virtual std::unique_ptr> constructDefaultEventPublisher() const { - auto mock_publisher = std::make_unique>(); + 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; @@ -65,7 +65,7 @@ class ProcessInfoNodeFixture : public ::testing::Test void expectActivationReport(int times = 1) { EXPECT_CALL(mock_factory_, constructSupervision).WillOnce(InvokeWithoutArgs([times]() { - auto mock_publisher = std::make_unique>(); + auto mock_publisher = std::make_unique>(); EXPECT_CALL(*mock_publisher, reportActivation).Times(times).WillRepeatedly(Return(true)); return mock_publisher; })); @@ -74,7 +74,7 @@ class ProcessInfoNodeFixture : public ::testing::Test void expectDeactivationReport(int times = 1) { EXPECT_CALL(mock_factory_, constructSupervision).WillOnce(InvokeWithoutArgs([times]() { - auto mock_publisher = std::make_unique>(); + auto mock_publisher = std::make_unique>(); EXPECT_CALL(*mock_publisher, reportDeactivation).Times(times).WillRepeatedly(Return(true)); return mock_publisher; })); 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 82863f35fc..81ad5eebda 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/BUILD +++ b/score/launch_manager/src/daemon/src/supervision_control_client/BUILD @@ -26,8 +26,8 @@ cc_library( ) cc_library( - name = "isupervision_state_reporter", - hdrs = ["isupervision_state_reporter.hpp"], + name = "iactivation_state_reporter", + hdrs = ["iactivation_state_reporter.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__"], @@ -40,7 +40,7 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/supervision_control_client", visibility = ["//score:__subpackages__"], deps = [ - ":isupervision_state_reporter", + ":iactivation_state_reporter", ":supervision_event", "//score/launch_manager/src/daemon/src/common:identifier_hash", "//score/launch_manager/src/daemon/src/common:log", @@ -61,14 +61,14 @@ cc_library( ) cc_library( - name = "mock_supervision_state_reporter", + name = "mock_activation_state_reporter", testonly = True, - hdrs = ["mock_supervision_state_reporter.hpp"], + hdrs = ["mock_activation_state_reporter.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_state_reporter", + ":iactivation_state_reporter", "@googletest//:gtest_main", ], ) diff --git a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_state_reporter.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/iactivation_state_reporter.hpp similarity index 80% rename from score/launch_manager/src/daemon/src/supervision_control_client/isupervision_state_reporter.hpp rename to score/launch_manager/src/daemon/src/supervision_control_client/iactivation_state_reporter.hpp index e691703036..a81a709b83 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/isupervision_state_reporter.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/iactivation_state_reporter.hpp @@ -10,22 +10,22 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef ISUPERVISION_STATE_REPORTER_HPP_INCLUDED -#define ISUPERVISION_STATE_REPORTER_HPP_INCLUDED +#ifndef IACTIVATION_STATE_REPORTER_HPP_INCLUDED +#define IACTIVATION_STATE_REPORTER_HPP_INCLUDED #include namespace score::mw::lifecycle { -/// @brief ISupervisionStateReporter interface for forwarding supervision events to the alive monitor. +/// @brief IActivationStateReporter 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 the active state or inactive state -class ISupervisionStateReporter +class IActivationStateReporter { public: /// @brief Destructor. - virtual ~ISupervisionStateReporter() noexcept = default; + virtual ~IActivationStateReporter() noexcept = default; /// @brief Report that the calling process has reached the active state at @param time virtual bool reportActivation(timespec time) noexcept = 0; 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 3dc667f830..609a4cfcff 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 @@ -33,13 +33,13 @@ class ISupervisionFactory virtual ~ISupervisionFactory() noexcept = default; /// @brief Set up alive supervision for the identified process. Alive supervision is not started until the process - /// reports its activation using the ISupervisionStateReporter. + /// reports its activation using the IActivationStateReporter. /// @param [in] id Identifier of the process. /// @param [in] uid The configured uid of the process. /// @param [in] config Alive supervision configuration for the process. /// @returns Nullptr if the construction failed, handle for the process to start and stop its own supervision /// otherwise. - 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_state_reporter.hpp b/score/launch_manager/src/daemon/src/supervision_control_client/mock_activation_state_reporter.hpp similarity index 72% rename from score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_state_reporter.hpp rename to score/launch_manager/src/daemon/src/supervision_control_client/mock_activation_state_reporter.hpp index e900a4ec8f..346b33d4d3 100644 --- a/score/launch_manager/src/daemon/src/supervision_control_client/mock_supervision_state_reporter.hpp +++ b/score/launch_manager/src/daemon/src/supervision_control_client/mock_activation_state_reporter.hpp @@ -10,16 +10,16 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef MOCK_SUPERVISION_STATE_REPORTER_HPP_INCLUDED -#define MOCK_SUPERVISION_STATE_REPORTER_HPP_INCLUDED +#ifndef MOCK_ACTIVATION_STATE_REPORTER_HPP_INCLUDED +#define MOCK_ACTIVATION_STATE_REPORTER_HPP_INCLUDED -#include "score/mw/launch_manager/supervision_control_client/isupervision_state_reporter.hpp" +#include "score/mw/launch_manager/supervision_control_client/iactivation_state_reporter.hpp" #include namespace score::mw::lifecycle { -class MockSupervisionStateReporter : public ISupervisionStateReporter +class MockActivationStateReporter : public IActivationStateReporter { public: MOCK_METHOD(bool, reportActivation, (timespec time), (override, noexcept)); @@ -28,4 +28,4 @@ class MockSupervisionStateReporter : public ISupervisionStateReporter } // namespace score::mw::lifecycle -#endif // MOCK_SUPERVISION_STATE_REPORTER_HPP_INCLUDED +#endif // MOCK_ACTIVATION_STATE_REPORTER_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 index b8913e1c17..5ed30d71ea 100644 --- 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 @@ -24,7 +24,7 @@ class MockSupervisionFactory : public ISupervisionFactory { public: MOCK_METHOD( - std::unique_ptr, + std::unique_ptr, constructSupervision, (const IdentifierHash id, const uid_t uid, const internal::configuration::ComponentAliveSupervision& config), (override)); 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 7c23e03ca4..8e5691c9ef 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 @@ -36,7 +36,7 @@ class SupervisionControlClient_UT : public ::testing::Test const IdentifierHash process_{"Process"}; std::shared_ptr buffer_; - std::unique_ptr handle_; + std::unique_ptr handle_; }; TEST_F(SupervisionControlClient_UT, SupervisionControlClient_QueueOneEvent_Succeeds) 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 6222d1906f..ffd56a9225 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 @@ -15,7 +15,7 @@ #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_state_reporter.hpp" +#include "score/mw/launch_manager/supervision_control_client/iactivation_state_reporter.hpp" #include "score/mw/launch_manager/supervision_control_client/supervision_event.hpp" #include @@ -28,7 +28,7 @@ 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 ISupervisionStateReporter +class SupervisionHandle : public IActivationStateReporter { public: /// @brief Construct a new supervision handle.