From e47fdfb5d79a32075ec10f5549c07a2e8310079f Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 15 Mar 2018 17:09:28 -0700 Subject: utils: Add a class to cache service lookups Currently we are doing interface + path -> service lookups for each ipmi command sent to the daemon. For many types of commands this is not ideal as the daemon is unlikely to change often at runtime. Implement a basic cache with the ability to invalidate the service name at any time. This is used by code in a future commit. Change-Id: I85b04dd17ac19e31d49070f289704b429bd1e577 Signed-off-by: William A. Kennington III --- utils.hpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'utils.hpp') diff --git a/utils.hpp b/utils.hpp index b4f090f..878b05a 100644 --- a/utils.hpp +++ b/utils.hpp @@ -1,7 +1,8 @@ #pragma once +#include +#include #include "types.hpp" -#include namespace ipmi { @@ -20,6 +21,64 @@ constexpr auto METHOD_GET = "Get"; constexpr auto METHOD_GET_ALL = "GetAll"; constexpr auto METHOD_SET = "Set"; +/** @class ServiceCache + * @brief Caches lookups of service names from the object mapper. + * @details Most ipmi commands need to talk to other dbus daemons to perform + * their intended actions on the BMC. This usually means they will + * first look up the service name providing the interface they + * require. This class reduces the number of such calls by caching + * the lookup for a specific service. + */ +class ServiceCache { + public: + /** @brief Creates a new service cache for the given interface + * and path. + * + * @param[in] intf - The interface used for each lookup + * @param[in] path - The path used for each lookup + */ + ServiceCache(const std::string& intf, const std::string& path); + ServiceCache(std::string&& intf, std::string&& path); + + /** @brief Gets the service name from the cache or does in a + * lookup when invalid. + * + * @param[in] bus - The bus associated with and used for looking + * up the service. + */ + const std::string& getService(sdbusplus::bus::bus& bus); + + /** @brief Invalidates the current service name */ + void invalidate(); + + /** @brief A wrapper around sdbusplus bus.new_method_call + * + * @param[in] bus - The bus used for calling the method + * @param[in] intf - The interface containing the method + * @param[in] method - The method name + * @return The message containing the method call. + */ + sdbusplus::message::message newMethodCall(sdbusplus::bus::bus& bus, + const char *intf, + const char *method); + private: + /** @brief DBUS interface provided by the service */ + const std::string intf; + /** @brief DBUS path provided by the service */ + const std::string path; + /** @brief The name of the service if valid */ + std::experimental::optional cachedService; + /** @brief The name of the bus used in the service lookup */ + std::experimental::optional cachedBusName; + + /** @brief Check to see if the current cache is valid + * + * @param[in] bus - The bus used for the service lookup + * @return True if the cache is valid false otherwise. + */ + bool isValid(sdbusplus::bus::bus& bus) const; +}; + /** * @brief Get the DBUS Service name for the input dbus path * -- cgit v1.2.1