RemoteObjectNode.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore
19 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl.txt
22 * GNU General Public License
23 */
24#include "ArmarXCore/interface/core/RemoteObjectNode.h"
25
26#include <algorithm> // for move, max
27#include <ostream> // for operator<<, etc
28#include <thread> // for thread
29#include <thread>
30#include <utility> // for pair
31
32#include <Ice/Object.h> // for Object
33#include <Ice/ObjectAdapter.h> // for ObjectAdapter
34#include <Ice/PropertiesAdmin.h> // for PropertyDict
35#include <IceUtil/Handle.h> // for HandleBase, Handle
36
37#include "ArmarXCore/core/Component.h" // for Component
38#include "ArmarXCore/core/logging/LogSender.h" // for LogSender
39#include "ArmarXCore/core/logging/Logging.h" // for ARMARX_DEBUG_S, etc
41#include "ArmarXCore/interface/core/UserException.h"
42#include "ArmarXCore/interface/core/util/distributed/RemoteHandle/RemoteHandleControlBlock.h"
43#include <ArmarXCore/core/ArmarXManager.h> // for ArmarXManager
44#include <ArmarXCore/core/ComponentFactories.h> // for ComponentFactory
45
46#include "RemoteObjectNode.h"
47
48namespace armarx
49{
50 /**
51 * @brief The processor thread count according to std. (in libstd shipped with gcc 4.6 this is 0)
52 */
53 static const unsigned CORE_COUNT_STD = std::thread::hardware_concurrency();
54 /**
55 * @brief The minimal used processor thread count. (in case both boost and std return 0)
56 */
57 static const unsigned CORE_COUNT_MIN = 1;
58 /**
59 * @brief Used core count. (in case both boost and std return 0 we will still use 1)
60 */
61 static const unsigned CORE_COUNT_DEFAULT = std::max(CORE_COUNT_STD, CORE_COUNT_MIN);
62
63 unsigned
65 {
66 return CORE_COUNT_DEFAULT;
67 }
68
69 void
71 {
72 coreCountUsed = newCount < 1 ? getDefaultCoreCount() : newCount;
73 ARMARX_DEBUG_S << "processor core count according to (std/requested from user) : "
74 << CORE_COUNT_STD << "/" << newCount;
75 ARMARX_VERBOSE_S << "processor core count used: " << coreCountUsed;
76 }
77
78 void
84
85 Ice::Long
86 RemoteObjectNode::getNumberOfObjects(const Ice::Current&) const
87 {
88 std::lock_guard<std::mutex> lock{dataMutex};
91 }
92
93 Ice::Long
95 {
96 std::lock_guard<std::mutex> lock{dataMutex};
98 }
99
100 Ice::Long
102 {
103 std::lock_guard<std::mutex> lock{dataMutex};
104 return remoteHandledObjects.size();
105 }
106
107 Ice::StringSeq
109 {
111 }
112
113 Ice::ObjectPrx
114 RemoteObjectNode::createPersistentComponent(const std::string& componentFactoryName,
115 const std::string& registrationName,
116 const ComponentParameter& params,
117 const Ice::Current&)
118 {
119 if (shuttingDown)
120 {
121 throw ServerShuttingDown{};
122 }
124 setupComponent(componentFactoryName, registrationName, params));
125 }
126
127 ClientSideRemoteHandleControlBlockBasePtr
128 RemoteObjectNode::createRemoteHandledComponent(const std::string& componentFactoryName,
129 const std::string& registrationName,
130 const ComponentParameter& params,
131 const Ice::Current&)
132 {
133 if (shuttingDown)
134 {
135 throw ServerShuttingDown{};
136 }
138 setupComponent(componentFactoryName, registrationName, params));
139 }
140
141 Ice::ObjectPrx
143 const Ice::ObjectPtr& registree,
144 const Ice::Current&)
145 {
146 if (shuttingDown)
147 {
148 throw ServerShuttingDown{};
149 }
150 auto mioPtr = ManagedIceObjectPtr::dynamicCast(registree);
151
152 if (mioPtr)
153 {
155 setupManagedIceObject(std::move(mioPtr), ident.category + ident.name));
156 }
157 return doRegisterPersistentIceObjectAtRON(setupIceObject(registree, ident));
158 }
159
160 ClientSideRemoteHandleControlBlockBasePtr
162 const Ice::ObjectPtr& registree,
163 const Ice::Current&)
164 {
165 if (shuttingDown)
166 {
167 throw ServerShuttingDown{};
168 }
169 auto mioPtr = ManagedIceObjectPtr::dynamicCast(registree);
170
171 if (mioPtr)
172 {
174 setupManagedIceObject(std::move(mioPtr), ident.category + ident.name));
175 }
177 }
178
179 Ice::ObjectPrx
180 RemoteObjectNode::registerPersistentObject(const std::string& registrationName,
181 const Ice::ObjectPtr& registree,
182 const Ice::Current&)
183 {
184 if (shuttingDown)
185 {
186 throw ServerShuttingDown{};
187 }
188 auto mioPtr = ManagedIceObjectPtr::dynamicCast(registree);
189
190 if (mioPtr)
191 {
193 setupManagedIceObject(std::move(mioPtr), registrationName));
194 }
195 Ice::Identity ident;
196 ident.name = registrationName;
197 return doRegisterPersistentIceObjectAtRON(setupIceObject(registree, std::move(ident)));
198 }
199
200 ClientSideRemoteHandleControlBlockBasePtr
201 RemoteObjectNode::registerRemoteHandledObject(const std::string& registrationName,
202 const Ice::ObjectPtr& registree,
203 const Ice::Current&)
204 {
205 if (shuttingDown)
206 {
207 throw ServerShuttingDown{};
208 }
209 auto mioPtr = ManagedIceObjectPtr::dynamicCast(registree);
210
211 if (mioPtr)
212 {
214 setupManagedIceObject(std::move(mioPtr), registrationName));
215 }
216 Ice::Identity ident;
217 ident.name = registrationName;
218 return doRegisterRemoteHandledIceObjectAtRON(setupIceObject(registree, std::move(ident)));
219 }
220
223 std::string registrationName)
224 {
225 getArmarXManager()->addObject(mioPtr, true, registrationName);
226 //the self proxy could still be null => wait for it
227 auto mioPrx = mioPtr->getProxy(-1);
228 return {std::move(mioPtr), std::move(mioPrx)};
229 }
230
232 RemoteObjectNode::setupComponent(const std::string& componentFactoryName,
233 const std::string& registrationName,
234 const ComponentParameter& params)
235 {
236 if (!ComponentFactory::has(componentFactoryName))
237 {
238 throw NoSuchComponentFactory{"There is no component factory for the name " +
239 componentFactoryName};
240 }
241 return setupManagedIceObject(ComponentFactory::get(componentFactoryName)(
242 params.prop, params.configName, params.configDomain),
243 registrationName);
244 }
245
247 RemoteObjectNode::setupIceObject(const Ice::ObjectPtr& ptr, Ice::Identity ident)
248 {
249 auto ioPrx = getArmarXManager()->getAdapter()->add(ptr, ident);
250 return {std::move(ident), std::move(ioPrx)};
251 }
252
253 ClientSideRemoteHandleControlBlockBasePtr
256 {
257 auto mioPtr = std::move(mio.ptr);
258 auto axManager = getArmarXManager();
259
260 auto id = nextRemoteHandledObjectId++;
261 RemoteObjectNodePtr ron = this;
262
263 auto mioRH =
265 std::move(mio.prx),
266 [axManager, mioPtr, ron, id]
267 {
268 axManager->removeObjectNonBlocking(mioPtr);
269 ron->removeRemoteHandledObject(id);
270 });
271 {
272 std::lock_guard<std::mutex> lock(dataMutex);
273 if (shuttingDown)
274 {
275 mioRH.directHandle->forceDeletion();
276 throw ServerShuttingDown{};
277 }
278 remoteHandledObjects[id] = std::move(mioRH.directHandle);
279 }
280 return mioRH.clientSideRemoteHandleControlBlock;
281 }
282
283 ClientSideRemoteHandleControlBlockBasePtr
286 {
287 auto ioIdent = std::move(io.ident);
288 auto objAdapter = getArmarXManager()->getAdapter();
289
290 auto id = nextRemoteHandledObjectId++;
291 RemoteObjectNodePtr ron = this;
292
294 std::move(io.prx),
295 [objAdapter, ioIdent, ron, id]
296 {
297 objAdapter->remove(ioIdent);
298 ron->removeRemoteHandledObject(id);
299 });
300 {
301 std::lock_guard<std::mutex> lock(dataMutex);
302 if (shuttingDown)
303 {
304 ioRH.directHandle->forceDeletion();
305 throw ServerShuttingDown{};
306 }
307 remoteHandledObjects[id] = std::move(ioRH.directHandle);
308 }
309 return ioRH.clientSideRemoteHandleControlBlock;
310 }
311
312 Ice::ObjectPrx
315 {
316 {
317 std::lock_guard<std::mutex> lock(dataMutex);
318 if (shuttingDown)
319 {
320 getArmarXManager()->removeObjectBlocking(mio.ptr);
321 throw ServerShuttingDown{};
322 }
323 persistentManagedIceObjects.emplace_back(std::move(mio.ptr));
324 }
325 return mio.prx;
326 }
327
328 Ice::ObjectPrx
331 {
332 {
333 std::lock_guard<std::mutex> lock(dataMutex);
334 if (shuttingDown)
335 {
336 getArmarXManager()->getAdapter()->remove(io.ident);
337 throw ServerShuttingDown{};
338 }
339 persistentIceObjectIdentities.emplace_back(std::move(io.ident));
340 }
341 return io.prx;
342 }
343
344 void
346 {
347 std::lock_guard<std::mutex> lock(dataMutex);
348 auto it = remoteHandledObjects.find(id);
349 if (it == remoteHandledObjects.end())
350 {
351 ARMARX_ERROR_S << "RON " << getName() << " has no object with id " << id;
352 return;
353 }
354 //just to be safe
355 it->second->forceDeletion();
356 remoteHandledObjects.erase(it);
357 }
358
359 void
361 {
362 shuttingDown = true;
363 std::lock_guard<std::mutex> lock(dataMutex);
364 for (auto& elem : remoteHandledObjects)
365 {
366 elem.second->forceDeletion();
367 }
368
369 auto axManager = getArmarXManager();
370 for (auto& obj : persistentManagedIceObjects)
371 {
372 axManager->removeObjectBlocking(obj);
373 }
375
376 auto adapter = axManager->getAdapter();
377 for (auto& ident : persistentIceObjectIdentities)
378 {
379 adapter->remove(ident);
380 }
382 }
383} // namespace armarx
std::string getName() const
Retrieve name of object.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
static bool has(const std::string &key)
Definition Registrar.h:96
static const ComponentCreatorObject & get(const std::string &key)
Definition Registrar.h:85
static std::vector< std::string > getKeys()
Definition Registrar.h:119
static ManagementData create(ArmarXManagerPtr manager, Ice::ObjectPrx managedObjectPrx, Deleter deleter)
Creates a new RemoteHandleControlBlock.
Ice::ObjectPrx registerPersistentObjectWithIdentity(const Ice::Identity &ident, const Ice::ObjectPtr &registree, const Ice::Current &=Ice::emptyCurrent) override
ClientSideRemoteHandleControlBlockBasePtr createRemoteHandledComponent(const std::string &componentFactoryName, const std::string &registrationName, const ComponentParameter &params, const Ice::Current &=Ice::emptyCurrent) override
Ice::ObjectPrx doRegisterPersistentManagedIceObjectAtRON(ManagedIceObjectPtrAndPrx mio)
IceObjectIdentityAndPrx setupIceObject(const Ice::ObjectPtr &ptr, Ice::Identity ident)
Ice::ObjectPrx doRegisterPersistentIceObjectAtRON(IceObjectIdentityAndPrx io)
std::vector< ManagedIceObjectPtr > persistentManagedIceObjects
The persistent managed ice objects.
Ice::Long getNumberOfRemoteHandledObjects(const Ice::Current &=Ice::emptyCurrent) const override
Ice::Long getNumberOfObjects(const Ice::Current &=Ice::emptyCurrent) const override
Ice::ObjectPrx registerPersistentObject(const std::string &registrationName, const Ice::ObjectPtr &registree, const Ice::Current &=Ice::emptyCurrent) override
ClientSideRemoteHandleControlBlockBasePtr doRegisterRemoteHandledIceObjectAtRON(IceObjectIdentityAndPrx io)
ClientSideRemoteHandleControlBlockBasePtr doRegisterRemoteHandledManagedIceObjectAtRON(ManagedIceObjectPtrAndPrx mio)
ClientSideRemoteHandleControlBlockBasePtr registerRemoteHandledObjectWithIdentity(const Ice::Identity &ident, const Ice::ObjectPtr &registree, const Ice::Current &=Ice::emptyCurrent) override
std::atomic_bool shuttingDown
static unsigned getDefaultCoreCount()
std::atomic< Ice::Long > nextRemoteHandledObjectId
Ice::IdentitySeq persistentIceObjectIdentities
The identities of persistent ice objects.
std::size_t coreCountUsed
The nuber of cores returned, when querried for it.
Ice::Long getNumberOfPersistentObjects(const Ice::Current &=Ice::emptyCurrent) const override
virtual void setCoreCount(int newCount)
Ice::StringSeq getKnownComponentFactories(const Ice::Current &=Ice::emptyCurrent) const override
ManagedIceObjectPtrAndPrx setupComponent(const std::string &componentFactoryName, const std::string &registrationName, const ComponentParameter &params)
ClientSideRemoteHandleControlBlockBasePtr registerRemoteHandledObject(const std::string &registrationName, const Ice::ObjectPtr &registree, const Ice::Current &=Ice::emptyCurrent) override
std::mutex dataMutex
mutex to protect the map
void removeRemoteHandledObject(Ice::Long id)
void onExitComponent() override
Removes all remote objects.
std::unordered_map< Ice::Long, RemoteHandleControlBlockPtr > remoteHandledObjects
the map of running objects
ManagedIceObjectPtrAndPrx setupManagedIceObject(ManagedIceObjectPtr mioPtr, std::string registrationName)
Ice::ObjectPrx createPersistentComponent(const std::string &componentFactoryName, const std::string &registrationName, const ComponentParameter &params, const Ice::Current &=Ice::emptyCurrent) override
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:205
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_VERBOSE_S
Definition Logging.h:207
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< ManagedIceObject > ManagedIceObjectPtr
Definition ArmarXFwd.h:42
IceInternal::Handle< RemoteObjectNode > RemoteObjectNodePtr
An ice handle for a RemoteObjectNodeComponent.