NVMe: Add constructor of MetricStore to support a range Now the MetricStore can be constructed with iterators of pointer to Metrics. This constructor is needed because the Metric collection can be determined at runtime instead of compile time. Change-Id: I558d235a8d42ac91386a8a0f1df3ac311aa05c27 Signed-off-by: Hao Jiang <jianghao@google.com>
diff --git a/src/NVMeController.cpp b/src/NVMeController.cpp index 3befc25..e4a5ab4 100644 --- a/src/NVMeController.cpp +++ b/src/NVMeController.cpp
@@ -299,11 +299,13 @@ std::chrono::seconds(900))) : std::shared_ptr<HostTelemetryMetric>(); + std::list<std::shared_ptr<MetricBase<SchedulerClockType>>> metrics{ + std::move(identify), std::move(errorInfo), std::move(smart), + std::move(fwSlot), std::move(selfTest), std::move(hostTelemetry)}; + this->metricStore.emplace( this->NVMeController::io, this->NVMeController::conn, - this->NVMeController::path, std::move(identify), std::move(errorInfo), - std::move(smart), std::move(fwSlot), std::move(selfTest), - std::move(hostTelemetry)); + this->NVMeController::path, metrics.begin(), metrics.end()); } void NVMeControllerEnabled::start(
diff --git a/src/NVMeMetricStore.hpp b/src/NVMeMetricStore.hpp index 1d22c39..97ddaa8 100644 --- a/src/NVMeMetricStore.hpp +++ b/src/NVMeMetricStore.hpp
@@ -59,50 +59,44 @@ validFlag(std::make_shared<bool>()) { metricStore.erase(""); - auto vuMetrics = getVendorMatrics(path); - for (auto& metric : vuMetrics) - { - if (!metric) - { - continue; - } - auto [itr, res] = metricStore.try_emplace( - std::string{metric->getIdentifier()}, std::move(metric)); - if (!res) - { - lg2::warning("drop a duplicated vendor metic", "PATH", path, - "METRIC", itr->first); - } - } + insertVUMetrics(); + emit_added(); + } - std::vector<std::string> idCollection; - decltype(validFlag)::weak_type weakFlag = validFlag; - for (auto& [identifier, metric] : metricStore) - { - idCollection.push_back(identifier); - std::weak_ptr<MetricBase<std::chrono::steady_clock>> weakMetric = - metric; - metric->registerCompleteCB([this, weakFlag, identifier, weakMetric, - path{objectPath}](std::error_code ec) { - // use validFlag to protect this call - if (weakFlag.expired()) + template <class Itr> + requires(std::is_base_of_v< + MetricBase<std::chrono::steady_clock>, + typename std::pointer_traits< + typename std::iter_value_t<Itr>>::element_type>) + MetricStore(boost::asio::io_context& io, + const std::shared_ptr<sdbusplus::asio::connection>& conn, + const std::string& objectPath, const Itr& begin, + const Itr& end) : + sdbusplus::xyz::openbmc_project::NVMe::server::MetricStore( + dynamic_cast<sdbusplus::bus_t&>(*conn), objectPath.c_str()), + path(objectPath), io(io), + metricStore([&objectPath](const Itr& begin, const Itr& end) { + std::unordered_map<std::string, std::shared_ptr<MetricBase<>>> temp; + for (auto itr = begin; itr != end; ++itr) + { + auto& metric = *itr; + if (!metric || metric->getIdentifier().empty()) { - lg2::info("MetricStore interface expired, update signal " - "skipped.", - "PATH", path); - return; + continue; } - auto metric = weakMetric.lock(); - if (ec || !metric) + auto [emplaceItr, res] = temp.try_emplace( + std::string{metric->getIdentifier()}, metric); + if (!res) { - // broadcast invalid metric signal - this->signalHelper(identifier, {}); + lg2::warning("drop a duplicated metric", "PATH", objectPath, + "METRIC", emplaceItr->first); } - this->signalHelper(identifier, metric); - }); - metric->refresh({}); - } - metricCollection(std::move(idCollection), true); + } + return temp; + }(begin, end)), + validFlag(std::make_shared<bool>()) + { + insertVUMetrics(); emit_added(); } ~MetricStore() override @@ -147,6 +141,54 @@ const std::shared_ptr<MetricBase<std::chrono::steady_clock>>& metric) noexcept; + inline void insertVUMetrics() + { + auto vuMetrics = getVendorMatrics(path); + for (auto& metric : vuMetrics) + { + if (!metric) + { + continue; + } + auto [itr, res] = metricStore.try_emplace( + std::string{metric->getIdentifier()}, std::move(metric)); + if (!res) + { + lg2::warning("drop a duplicated vendor metric", "PATH", path, + "METRIC", itr->first); + } + } + + std::vector<std::string> idCollection; + decltype(validFlag)::weak_type weakFlag = validFlag; + for (auto& [identifier, metric] : metricStore) + { + idCollection.push_back(identifier); + std::weak_ptr<MetricBase<std::chrono::steady_clock>> weakMetric = + metric; + metric->registerCompleteCB([this, weakFlag, identifier, weakMetric, + path{path}](std::error_code ec) { + // use validFlag to protect this call + if (weakFlag.expired()) + { + lg2::info("MetricStore interface expired, update signal " + "skipped.", + "PATH", path); + return; + } + auto metric = weakMetric.lock(); + if (ec || !metric) + { + // broadcast invalid metric signal + this->signalHelper(identifier, {}); + } + this->signalHelper(identifier, metric); + }); + metric->refresh({}); + } + metricCollection(std::move(idCollection), true); + } + std::string path; boost::asio::io_context& io; std::unordered_map<std::string, std::shared_ptr<MetricBase<>>> metricStore;