9#include <Ice/Exception.h>
10#include <Ice/LocalException.h>
12#include <SimoxUtility/algorithm/string/string_tools.h>
24#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
53 mns::dto::GetAllRegisteredServersResult result;
56 result = mns->getAllRegisteredServers();
58 catch (
const Ice::NotRegisteredException& e)
65 for (
const auto& [name,
server] : result.servers)
67 auto [it, inserted] = servers.try_emplace(name,
server);
75 auto foo = [](
auto& oldProxy,
const auto& newProxy)
87 catch (
const Ice::Exception& e)
102 oldProxy->ice_ping();
104 if (oldProxy->ice_getIdentity() != newProxy->ice_getIdentity())
110 catch (
const Ice::Exception&)
116 foo(it->second.reading,
server.reading);
117 foo(it->second.writing,
server.writing);
118 foo(it->second.prediction,
server.prediction);
119 foo(it->second.actions,
server.actions);
120 foo(it->second.configuration,
server.configuration);
121 foo(it->second.loading,
server.loading);
122 foo(it->second.readingLtm,
server.readingLtm);
126 for (
auto it = servers.begin(); it != servers.end();)
128 if (result.servers.count(it->first) == 0)
130 it = servers.erase(it);
144 mns::dto::MemoryServerInterfaces
148 if (
auto it = servers.find(memoryID.
memoryName); it != servers.end())
158 mns::dto::MemoryServerInterfaces
159 MemoryNameSystem::waitForServer(
const MemoryID& memoryID)
165 <<
"This will block forever. MemoryID: " << memoryID;
167 if (
auto it = servers.find(memoryID.
memoryName); it != servers.end())
173 mns::dto::WaitForServerInput input;
177 ARMARX_INFO <<
"Waiting for memory server for " << memoryID <<
" ...";
178 mns::dto::WaitForServerResult result = mns->waitForServer(input);
181 ARMARX_INFO <<
"Resolved memory for " << memoryID <<
".";
182 return result.server;
186 throw error::CouldNotResolveMemoryServer(memoryID, result.errorMessage);
191 mns::dto::MemoryServerInterfaces
192 MemoryNameSystem::useServer(
const MemoryID& memoryID)
195 <<
"Owning component not set when using a memory server. \n"
196 <<
"When calling `armem::mns::MemoryNameSystem::useServer()`, the owning component "
198 <<
"receive the dependency to the memory server must be set beforehand. \n\n"
199 <<
"Use `armem::mns::MemoryNameSystem::setComponent()` or pass the component on "
201 <<
"before calling useServer().";
202 return useServer(memoryID, *component);
205 mns::dto::MemoryServerInterfaces
206 MemoryNameSystem::useServer(
const MemoryID& memoryID, ManagedIceObject&
component)
208 mns::dto::MemoryServerInterfaces server = waitForServer(memoryID);
211 component.usingProxy(server.reading->ice_getIdentity().name);
215 mns::dto::MemoryServerInterfaces
216 MemoryNameSystem::useServer(
const std::string& memoryName)
218 return useServer(
MemoryID().withMemoryName(memoryName));
221 mns::dto::MemoryServerInterfaces
222 MemoryNameSystem::useServer(
const std::string& memoryName, ManagedIceObject&
component)
224 return useServer(
MemoryID().withMemoryName(memoryName), component);
237 auto server = useServer(memoryID);
244 auto server = useServer(memoryID, component);
270 auto server = useServer(memoryID);
277 auto server = useServer(memoryID, component);
303 auto server = useServer(memoryID);
310 auto server = useServer(memoryID, component);
326 template <
class ClientT>
327 std::map<std::string, ClientT>
328 MemoryNameSystem::_getAllClients(ClientFactory<ClientT>&& factory)
const
330 std::map<std::string, ClientT> result;
331 for (
const auto& [name,
server] : servers)
335 result[name] =
client.value();
341 std::optional<Configurator>
344 if (
auto config =
server.configuration)
352 std::optional<Loader>
355 if (
auto load =
server.loading)
363 std::optional<Reader>
368 if (
auto predict =
server.prediction)
370 if (
auto readLtm =
server.readingLtm)
385 std::optional<Writer>
388 if (
auto write =
server.writing)
395 std::map<std::string, Loader>
406 std::map<std::string, Loader>
412 std::map<std::string, Configurator>
423 std::map<std::string, Configurator>
429 std::map<std::string, Reader>
440 std::map<std::string, Reader>
455 return Writer(useServer(memoryID).writing);
461 return Writer(useServer(memoryID, component).writing);
476 std::map<std::string, Writer>
486 std::map<std::string, Writer>
492 std::optional<wm::EntityInstance>
496 if (result.size() > 0)
498 return result.begin()->second;
506 std::map<MemoryID, wm::EntityInstance>
509 std::stringstream errors;
510 int errorCounter = 0;
512 std::map<std::string, std::vector<MemoryID>> idsPerMemory;
513 for (
const auto&
id : ids)
515 idsPerMemory[
id.memoryName].push_back(
id);
518 std::map<MemoryID, wm::EntityInstance> result;
519 for (
const auto& [memoryName, ids] : idsPerMemory)
529 if (
id.hasInstanceIndex())
533 else if (
id.hasTimestamp())
537 else if (
id.hasEntityName())
544 std::stringstream ss;
545 ss <<
"MemoryNameSystem::" << __FUNCTION__
546 <<
"requires IDs to be entity, snapshot or instance IDs,"
547 <<
"but ID has no entity name.";
553 errors <<
"\n#" << ++errorCounter <<
"\n"
554 <<
"Failed to retrieve " <<
id <<
" from query result: \n"
561 errors <<
"\n# " << ++errorCounter <<
"\n"
562 <<
"Failed to query '" << memoryName <<
"': \n"
567 if (errors.str().size() > 0)
569 ARMARX_INFO <<
"MemoryNameSystem::" << __FUNCTION__
570 <<
": The following errors may affect your result: "
572 << errors.str() <<
"\n\n"
573 <<
"When querying entity instances: \n- "
574 << simox::alg::join(simox::alg::multi_to_string(ids),
"\n- ");
582 mns::dto::MemoryServerInterfaces
server)
584 mns::dto::RegisterServerInput input;
594 mns::dto::RegisterServerResult result = mns->registerServer(input);
598 "register", memoryID, result.errorMessage);
605 mns::dto::RemoveServerInput input;
609 mns::dto::RemoveServerResult result = mns->removeServer(input);
616 mns::MemoryNameSystemInterfacePrx
632 this->component = component;
The ManagedIceObject is the base class for all ArmarX objects.
Configure a memory server.
void initialize(mns::MemoryNameSystemInterfacePrx mns, ManagedIceObject *component=nullptr)
std::optional< wm::EntityInstance > resolveEntityInstance(const MemoryID &id)
Resolve a memory ID to an EntityInstance.
Loader getLoader(const MemoryID &memoryID)
mns::dto::MemoryServerInterfaces resolveServer(const MemoryID &memoryID)
Resolve the given memory server for the given memory ID.
Configurator useConfigurator(const MemoryID &memoryID)
Use a memory server and get a configurator for it.
std::map< std::string, Reader > getAllReaders() const
Get Readers for all registered servers (without updating).
Reader getReader(const MemoryID &memoryID)
Get a reader to the given memory name.
std::map< std::string, Writer > getAllWriters() const
Get Writers for all registered servers (without updating).
void removeServer(const MemoryID &memoryID)
Remove a memory server from the MNS.
std::map< std::string, Loader > getAllLoaders() const
Get Loaders for all registered servers (without updating).
Loader useLoader(const MemoryID &memoryID)
Use a memory server and get a configurator for it.
Writer useWriter(const MemoryID &memoryID)
Use a memory server and get a writer for it.
std::map< std::string, Configurator > getAllConfigurators() const
Get Configurators for all registered servers (without updating).
Reader useReader(const MemoryID &memoryID)
Use a memory server and get a reader for it.
Configurator getConfigurator(const MemoryID &memoryID)
Get a configurator to the given memory name.
void registerServer(const MemoryID &memoryID, mns::dto::MemoryServerInterfaces server)
Register a memory server in the MNS.
mns::MemoryNameSystemInterfacePrx getMemoryNameSystem() const
void update()
Update the internal registry to the data in the MNS.
void setComponent(ManagedIceObject *component)
std::map< MemoryID, wm::EntityInstance > resolveEntityInstances(const std::vector< MemoryID > &ids)
Writer getWriter(const MemoryID &memoryID)
Get a writer to the given memory name.
Reads data from a memory server.
QueryResult queryMemoryIDs(const std::vector< MemoryID > &ids, armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Query a specific set of memory IDs.
Helps a memory client sending data to a memory.
MemoryListener(ManagedIceObject *component=nullptr)
void setComponent(ManagedIceObject *component)
Base class for all exceptions thrown by the armem library.
Indicates that a query to the Memory Name System failed.
Indicates that a memory ID is invalid, e.g.
Indicates that a query to the Memory Name System failed.
Indicates that a query to the Memory Name System failed.
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file is part of ArmarX.
std::optional< Reader > readerFactory(const mns::dto::MemoryServerInterfaces &server)
std::optional< Configurator > configuratorFactory(const mns::dto::MemoryServerInterfaces &server)
std::optional< Loader > loaderFactory(const mns::dto::MemoryServerInterfaces &server)
std::optional< Writer > writerFactory(const mns::dto::MemoryServerInterfaces &server)
const armem::MemoryID MemoryID
void read(auto &eigen, auto *table)
auto & getEntity(const MemoryID &entityID)
Retrieve an entity.
auto & getInstance(const MemoryID &instanceID)
Retrieve an entity instance.
auto & getSnapshot(const MemoryID &snapshotID)
Retrieve an entity snapshot.
wm::Memory memory
The slice of the memory that matched the query.