From 112f61175fef6d3995fc9f86b3b8b7216a7ca9aa Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Thu, 10 Jun 2021 08:59:17 +0200
Subject: [PATCH] Add owning component (for use with dependency). Add
 useReader() and useWriter() Improve doc

---
 .../RobotAPI/libraries/armem/mns/Client.cpp   | 73 +++++++++++++++++--
 source/RobotAPI/libraries/armem/mns/Client.h  | 53 +++++++++++---
 2 files changed, 109 insertions(+), 17 deletions(-)

diff --git a/source/RobotAPI/libraries/armem/mns/Client.cpp b/source/RobotAPI/libraries/armem/mns/Client.cpp
index cb308f79a..5eedec3b5 100644
--- a/source/RobotAPI/libraries/armem/mns/Client.cpp
+++ b/source/RobotAPI/libraries/armem/mns/Client.cpp
@@ -16,7 +16,8 @@ namespace armarx::armem::mns
     }
 
 
-    Client::Client(MemoryNameSystemInterfacePrx mns) : mns(mns)
+    Client::Client(MemoryNameSystemInterfacePrx mns, ManagedIceObject* component) :
+        mns(mns), component(component)
     {
     }
 
@@ -24,12 +25,11 @@ namespace armarx::armem::mns
     void Client::update()
     {
         ARMARX_CHECK_NOT_NULL(mns);
-
         data::GetAllRegisteredMemoriesResult result = mns->getAllRegisteredMemories();
 
         if (result.success)
         {
-            this->memoryMap = result.proxies;
+            this->servers = result.proxies;
         }
         else
         {
@@ -40,14 +40,14 @@ namespace armarx::armem::mns
 
     server::MemoryInterfacePrx Client::resolveServer(const MemoryID& memoryID)
     {
-        if (auto it = memoryMap.find(memoryID.memoryName); it != memoryMap.end())
+        if (auto it = servers.find(memoryID.memoryName); it != servers.end())
         {
             return it->second;
         }
         else
         {
             update();
-            if (auto it = memoryMap.find(memoryID.memoryName); it != memoryMap.end())
+            if (auto it = servers.find(memoryID.memoryName); it != servers.end())
             {
                 return it->second;
             }
@@ -61,7 +61,7 @@ namespace armarx::armem::mns
 
     server::MemoryInterfacePrx Client::waitForServer(const MemoryID& memoryID, Time timeout)
     {
-        if (auto it = memoryMap.find(memoryID.memoryName); it != memoryMap.end())
+        if (auto it = servers.find(memoryID.memoryName); it != servers.end())
         {
             return it->second;
         }
@@ -71,6 +71,7 @@ namespace armarx::armem::mns
             input.name = memoryID.memoryName;
             input.timeoutMilliSeconds = timeout.toMilliSeconds();
 
+            ARMARX_CHECK_NOT_NULL(mns);
             armem::data::WaitForMemoryResult result = mns->waitForMemory(input);
             if (result.success)
             {
@@ -83,6 +84,17 @@ namespace armarx::armem::mns
         }
     }
 
+    server::MemoryInterfacePrx Client::useServer(const MemoryID& memoryID)
+    {
+        ARMARX_CHECK_NOT_NULL(component)
+                << "Owning component not set when using a memory server. \n"
+                << "When calling `armem::mns::Client::useServer()`, the owning component which should "
+                << "receive the dependency to the memory server must be set beforehand. \n\n"
+                << "Use `armem::mns::Client::setComponent()` or pass the component on construction "
+                << "before calling useServer().";
+        return useServer(memoryID, *component);
+    }
+
 
     server::MemoryInterfacePrx Client::useServer(const MemoryID& memoryID, ManagedIceObject& component)
     {
@@ -97,12 +109,32 @@ namespace armarx::armem::mns
         return client::Reader(resolveServer(memoryID));
     }
 
+    client::Reader Client::useReader(const MemoryID& memoryID)
+    {
+        return client::Reader(useServer(memoryID));
+    }
+
+    client::Reader Client::useReader(const MemoryID& memoryID, ManagedIceObject& component)
+    {
+        return client::Reader(useServer(memoryID, component));
+    }
+
+    client::Reader Client::useReader(const std::string& memoryName)
+    {
+        return useReader(MemoryID().withMemoryName(memoryName));
+    }
+
+    client::Reader Client::useReader(const std::string& memoryName, ManagedIceObject& component)
+    {
+        return useReader(MemoryID().withMemoryName(memoryName), component);
+    }
+
 
     template <class ClientT>
     std::map<std::string, ClientT> Client::_getAllClients() const
     {
         std::map<std::string, ClientT> result;
-        for (const auto& [name, server] : memoryMap)
+        for (const auto& [name, server] : servers)
         {
             result[name] = ClientT(server);
         }
@@ -138,6 +170,26 @@ namespace armarx::armem::mns
         return client::Writer(resolveServer(memoryID));
     }
 
+    client::Writer Client::useWriter(const MemoryID& memoryID)
+    {
+        return client::Writer(useServer(memoryID));
+    }
+
+    client::Writer Client::useWriter(const MemoryID& memoryID, ManagedIceObject& component)
+    {
+        return client::Writer(useServer(memoryID, component));
+    }
+
+    client::Writer Client::useWriter(const std::string& memoryName)
+    {
+        return useWriter(MemoryID().withMemoryName(memoryName));
+    }
+
+    client::Writer Client::useWriter(const std::string& memoryName, ManagedIceObject& component)
+    {
+        return useWriter(MemoryID().withMemoryName(memoryName), component);
+    }
+
 
     std::map<std::string, client::Writer> Client::getAllWriters(bool update)
     {
@@ -158,6 +210,7 @@ namespace armarx::armem::mns
         input.proxy = proxy;
         ARMARX_CHECK_NOT_NULL(input.proxy);
 
+        ARMARX_CHECK_NOT_NULL(mns);
         data::RegisterMemoryResult result = mns->registerMemory(input);
         if (!result.success)
         {
@@ -171,6 +224,7 @@ namespace armarx::armem::mns
         data::RemoveMemoryInput input;
         input.name = memoryID.memoryName;
 
+        ARMARX_CHECK_NOT_NULL(mns);
         data::RemoveMemoryResult result = mns->removeMemory(input);
         if (!result.success)
         {
@@ -190,6 +244,11 @@ namespace armarx::armem::mns
         this->mns = mns;
     }
 
+    void Client::setComponent(ManagedIceObject* component)
+    {
+        this->component = component;
+    }
+
 }
 
 
diff --git a/source/RobotAPI/libraries/armem/mns/Client.h b/source/RobotAPI/libraries/armem/mns/Client.h
index 5979a6cab..8ceb4984d 100644
--- a/source/RobotAPI/libraries/armem/mns/Client.h
+++ b/source/RobotAPI/libraries/armem/mns/Client.h
@@ -44,25 +44,40 @@ namespace armarx::armem::mns
     /**
      * @brief The memory name system (MNS) client.
      *
-     * This client class has a proxy to the MNS and can be used to construct
-     * (single) Memory Clients as well as fetch the data for any Memory IDs.
-     * Like in DNS, it stores a map from memory names to proxies which is used
-     * if the respective entry exists. Otherwise, it queries the MNS.
-     * Provides the other interface functions of the MNS.
-     * Can be used to query arbitrary Memory IDs (resolving the memory name,
-     * then sending a query to that memory, returning the result).
+     * This client class serves provides the MNS interface and is a local cache
+     * of the MNS registry. It can be used to resolve memory servers by their
+     * memory ID and to construct `client::Readers` and `client::Writers`.
+     *
+     * During server resolution, it first consults the locally cached registry.
+     * If the memory server is not known locally, the local registry is
+     * updated to that of the remote MNS before trying again.
+     *
+     * In addition, the MNS client can be used to send queries over multiple
+     * memory servers, as well as retrieving the data for arbitrary entity or
+     * entity snapshot IDs.
      */
     class Client
     {
     public:
 
         Client();
-        Client(MemoryNameSystemInterfacePrx mns);
+
+        /**
+         * @brief Construct an MNS client.
+         *
+         * @param mns The MNS proxy.
+         * @param component The owning component. When `using` a memory server,
+         *  dependencies will be added to this component.
+         */
+        Client(MemoryNameSystemInterfacePrx mns,
+               ManagedIceObject* component = nullptr);
 
 
         mns::MemoryNameSystemInterfacePrx getMemoryNameSystem() const;
         void getMemoryNameSystem(mns::MemoryNameSystemInterfacePrx mns);
 
+        void setComponent(ManagedIceObject* component);
+
 
         // Name Resolution
 
@@ -103,6 +118,7 @@ namespace armarx::armem::mns
         *
         * @throw `error::CouldNotResolveMemoryServer` If the memory name could not be resolved.
         */
+        server::MemoryInterfacePrx useServer(const MemoryID& memoryID);
         server::MemoryInterfacePrx useServer(const MemoryID& memoryID, ManagedIceObject& component);
 
 
@@ -118,6 +134,11 @@ namespace armarx::armem::mns
          */
         client::Reader getReader(const MemoryID& memoryID);
 
+        client::Reader useReader(const MemoryID& memoryID);
+        client::Reader useReader(const MemoryID& memoryID, ManagedIceObject& component);
+        client::Reader useReader(const std::string& memoryName);
+        client::Reader useReader(const std::string& memoryName, ManagedIceObject& component);
+
         /**
          * @brief Get Readers for all registered servers.
          *
@@ -144,6 +165,11 @@ namespace armarx::armem::mns
          */
         client::Writer getWriter(const MemoryID& memoryID);
 
+        client::Writer useWriter(const MemoryID& memoryID);
+        client::Writer useWriter(const MemoryID& memoryID, ManagedIceObject& component);
+        client::Writer useWriter(const std::string& memoryName);
+        client::Writer useWriter(const std::string& memoryName, ManagedIceObject& component);
+
         /**
          * @brief Get Writers for all registered servers.
          *
@@ -159,6 +185,10 @@ namespace armarx::armem::mns
         std::map<std::string, client::Writer> getAllWriters() const;
 
 
+        // ToDo: commit() and query()
+
+
+
         // Registration - only for memory servers
 
         /**
@@ -199,10 +229,13 @@ namespace armarx::armem::mns
         std::map<std::string, ClientT> _getAllClients() const;
 
 
+        /// The MNS proxy.
         MemoryNameSystemInterfacePrx mns = nullptr;
+        /// The component to which dependencies will be added.
+        ManagedIceObject* component = nullptr;
 
-        std::map<std::string, server::MemoryInterfacePrx> memoryMap;
-
+        /// The registered memory servers.
+        std::map<std::string, server::MemoryInterfacePrx> servers;
 
     };
 
-- 
GitLab