summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-06-09 09:56:37 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-06-09 09:56:37 +0000
commita6d51aa0ea13510e4eca6b9646be5ae1d917aa3f (patch)
tree4bc2e711e1fc32ecb7943fb3c7c6d94226c47507
parentproperties updates (diff)
downloadice-a6d51aa0ea13510e4eca6b9646be5ae1d917aa3f.tar.bz2
ice-a6d51aa0ea13510e4eca6b9646be5ae1d917aa3f.tar.xz
ice-a6d51aa0ea13510e4eca6b9646be5ae1d917aa3f.zip
Added support for allocatable objects.
-rw-r--r--cpp/demo/IceGrid/allocate/application-multiple.xml2
-rw-r--r--cpp/demo/IceGrid/allocate/application-single.xml2
-rw-r--r--cpp/demo/IceGrid/sessionActivation/application.xml2
-rw-r--r--cpp/slice/IceGrid/Descriptor.ice9
-rw-r--r--cpp/src/IceGrid/AllocatableObjectCache.cpp352
-rw-r--r--cpp/src/IceGrid/AllocatableObjectCache.h121
-rw-r--r--cpp/src/IceGrid/Database.cpp20
-rw-r--r--cpp/src/IceGrid/Database.h2
-rw-r--r--cpp/src/IceGrid/DescriptorBuilder.cpp9
-rw-r--r--cpp/src/IceGrid/DescriptorBuilder.h1
-rw-r--r--cpp/src/IceGrid/DescriptorHelper.cpp39
-rw-r--r--cpp/src/IceGrid/DescriptorHelper.h2
-rw-r--r--cpp/src/IceGrid/DescriptorParser.cpp33
-rw-r--r--cpp/src/IceGrid/Makefile1
-rw-r--r--cpp/src/IceGrid/ObjectCache.cpp231
-rw-r--r--cpp/src/IceGrid/ObjectCache.h64
-rw-r--r--cpp/src/IceGrid/ServerCache.cpp40
-rw-r--r--cpp/src/IceGrid/ServerCache.h7
-rw-r--r--cpp/test/IceGrid/activation/application.xml1
-rw-r--r--cpp/test/IceGrid/allocation/AllTests.cpp19
-rw-r--r--cpp/test/IceGrid/allocation/application.xml37
21 files changed, 637 insertions, 357 deletions
diff --git a/cpp/demo/IceGrid/allocate/application-multiple.xml b/cpp/demo/IceGrid/allocate/application-multiple.xml
index 3a7dc481cea..7e5ea863bdd 100644
--- a/cpp/demo/IceGrid/allocate/application-multiple.xml
+++ b/cpp/demo/IceGrid/allocate/application-multiple.xml
@@ -17,7 +17,7 @@
<parameter name="index"/>
<server id="AllocateServer-${index}" exe="./server" activation="on-demand">
<adapter name="Hello" endpoints="tcp" register-process="true">
- <object identity="hello-${index}" type="::Demo::Hello"/>
+ <allocatable identity="hello-${index}" type="::Demo::Hello"/>
</adapter>
<property name="Identity" value="hello-${index}"/>
</server>
diff --git a/cpp/demo/IceGrid/allocate/application-single.xml b/cpp/demo/IceGrid/allocate/application-single.xml
index 70fb67398a7..e2d2d6f4c61 100644
--- a/cpp/demo/IceGrid/allocate/application-single.xml
+++ b/cpp/demo/IceGrid/allocate/application-single.xml
@@ -16,7 +16,7 @@
<node name="localhost">
<server id="AllocateServer" exe="./server" activation="on-demand">
<adapter name="Hello" endpoints="tcp" register-process="true">
- <object identity="hello" type="::Demo::Hello"/>
+ <allocatable identity="hello" type="::Demo::Hello"/>
</adapter>
<property name="Identity" value="hello"/>
</server>
diff --git a/cpp/demo/IceGrid/sessionActivation/application.xml b/cpp/demo/IceGrid/sessionActivation/application.xml
index 617a1bfdedc..1d049c45b35 100644
--- a/cpp/demo/IceGrid/sessionActivation/application.xml
+++ b/cpp/demo/IceGrid/sessionActivation/application.xml
@@ -16,7 +16,7 @@
<node name="localhost">
<server id="SessionServer" exe="./server" activation="session">
<adapter name="Hello" endpoints="tcp" register-process="true">
- <object identity="hello" type="::Demo::Hello"/>
+ <allocatable identity="hello"/>
</adapter>
<property name="Identity" value="hello"/>
</server>
diff --git a/cpp/slice/IceGrid/Descriptor.ice b/cpp/slice/IceGrid/Descriptor.ice
index 7b658893832..18f938e3678 100644
--- a/cpp/slice/IceGrid/Descriptor.ice
+++ b/cpp/slice/IceGrid/Descriptor.ice
@@ -134,10 +134,17 @@ struct AdapterDescriptor
/**
*
- * The object descriptors associated to this object adapter.
+ * The well-known object descriptors associated to this object adapter.
*
**/
ObjectDescriptorSeq objects;
+
+ /**
+ *
+ * The allocatable object descriptors associated to this object adapter.
+ *
+ **/
+ ObjectDescriptorSeq allocatables;
};
/**
diff --git a/cpp/src/IceGrid/AllocatableObjectCache.cpp b/cpp/src/IceGrid/AllocatableObjectCache.cpp
new file mode 100644
index 00000000000..78bac949bbf
--- /dev/null
+++ b/cpp/src/IceGrid/AllocatableObjectCache.cpp
@@ -0,0 +1,352 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Random.h>
+#include <Ice/Communicator.h>
+#include <Ice/LoggerUtil.h>
+#include <Ice/LocalException.h>
+#include <IceGrid/AllocatableObjectCache.h>
+#include <IceGrid/SessionI.h>
+
+using namespace std;
+using namespace IceGrid;
+
+pointer_to_unary_function<int, int> AllocatableObjectCache::_rand(IceUtil::random);
+
+namespace IceGrid
+{
+
+struct AllocatableObjectEntryCI : binary_function<AllocatableObjectEntryPtr&, AllocatableObjectEntryPtr&, bool>
+{
+
+ bool
+ operator()(const AllocatableObjectEntryPtr& lhs, const AllocatableObjectEntryPtr& rhs)
+ {
+ return ::Ice::proxyIdentityLess(lhs->getProxy(), rhs->getProxy());
+ }
+};
+
+};
+
+AllocatableObjectCache::TypeEntry::TypeEntry()
+{
+}
+
+void
+AllocatableObjectCache::TypeEntry::add(const AllocatableObjectEntryPtr& obj)
+{
+ //
+ // No mutex protection here, this is called with the cache locked.
+ //
+ _objects.insert(lower_bound(_objects.begin(), _objects.end(), obj, AllocatableObjectEntryCI()), obj);
+ if(!_requests.empty())
+ {
+ canTryAllocate(obj, false);
+ }
+}
+
+bool
+AllocatableObjectCache::TypeEntry::remove(const AllocatableObjectEntryPtr& obj)
+{
+ //
+ // No mutex protection here, this is called with the cache locked.
+ //
+ vector<AllocatableObjectEntryPtr>::iterator q;
+ q = lower_bound(_objects.begin(), _objects.end(), obj, AllocatableObjectEntryCI());
+ assert(q->get() == obj.get());
+ _objects.erase(q);
+
+ if(!_requests.empty() && _objects.empty())
+ {
+ for(list<ObjectAllocationRequestPtr>::const_iterator p = _requests.begin(); p != _requests.end(); ++p)
+ {
+ (*p)->cancel(AllocationException("no allocatable objects with type `" + obj->getType() + "' registered"));
+ }
+ }
+ return _objects.empty();
+}
+
+void
+AllocatableObjectCache::TypeEntry::addAllocationRequest(const ObjectAllocationRequestPtr& request)
+{
+ //
+ // No mutex protection here, this is called with the cache locked.
+ //
+ if(request->pending())
+ {
+ _requests.push_back(request);
+ }
+}
+
+bool
+AllocatableObjectCache::TypeEntry::canTryAllocate(const AllocatableObjectEntryPtr& entry, bool fromRelease)
+{
+ //
+ // No mutex protection here, this is called with the cache locked.
+ //
+ list<ObjectAllocationRequestPtr>::iterator p = _requests.begin();
+ while(p != _requests.end())
+ {
+ AllocationRequestPtr request = *p;
+ try
+ {
+ if(request->isCanceled()) // If the request has been canceled, we just remove it.
+ {
+ p = _requests.erase(p);
+ }
+ else if(entry->tryAllocate(request, fromRelease))
+ {
+ p = _requests.erase(p);
+ return true; // The request successfully allocated the entry!
+ }
+ else if(entry->getSession()) // If entry is allocated, we're done
+ {
+ return false;
+ }
+ else
+ {
+ ++p;
+ }
+ }
+ catch(const SessionDestroyedException&)
+ {
+ p = _requests.erase(p);
+ }
+ }
+ return false;
+}
+
+AllocatableObjectCache::AllocatableObjectCache(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator)
+{
+}
+
+void
+AllocatableObjectCache::add(const ObjectInfo& info, const AllocatablePtr& parent)
+{
+ const Ice::Identity& id = info.proxy->ice_getIdentity();
+
+ Lock sync(*this);
+ assert(!getImpl(id));
+
+ AllocatableObjectEntryPtr entry = new AllocatableObjectEntry(*this, info, parent);
+ addImpl(id, entry);
+
+ map<string, TypeEntry>::iterator p = _types.find(entry->getType());
+ if(p == _types.end())
+ {
+ p = _types.insert(p, map<string, TypeEntry>::value_type(entry->getType(), TypeEntry()));
+ }
+ p->second.add(entry);
+
+ if(_traceLevels && _traceLevels->object > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->objectCat);
+ out << "added allocatable object `" << _communicator->identityToString(id) << "'";
+ }
+}
+
+AllocatableObjectEntryPtr
+AllocatableObjectCache::get(const Ice::Identity& id) const
+{
+ Lock sync(*this);
+ AllocatableObjectEntryPtr entry = getImpl(id);
+ if(!entry)
+ {
+ throw ObjectNotRegisteredException(id);
+ }
+ return entry;
+}
+
+AllocatableObjectEntryPtr
+AllocatableObjectCache::remove(const Ice::Identity& id)
+{
+ Lock sync(*this);
+ AllocatableObjectEntryPtr entry = removeImpl(id);
+ assert(entry);
+
+ map<string, TypeEntry>::iterator p = _types.find(entry->getType());
+ assert(p != _types.end());
+ if(p->second.remove(entry))
+ {
+ _types.erase(p);
+ }
+
+ if(_traceLevels && _traceLevels->object > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->objectCat);
+ out << "removed allocatable object `" << _communicator->identityToString(id) << "'";
+ }
+
+ return entry;
+}
+
+void
+AllocatableObjectCache::allocateByType(const string& type, const ObjectAllocationRequestPtr& request)
+{
+ Lock sync(*this);
+ map<string, TypeEntry>::iterator p = _types.find(type);
+ if(p == _types.end())
+ {
+ throw AllocationException("no allocatable objects with type `" + type + "' registered");
+ }
+
+ vector<AllocatableObjectEntryPtr> objects = p->second.getObjects();
+ random_shuffle(objects.begin(), objects.end(), _rand); // TODO: OPTIMIZE
+ try
+ {
+ for(vector<AllocatableObjectEntryPtr>::const_iterator q = objects.begin(); q != objects.end(); ++q)
+ {
+ if((*q)->tryAllocate(request))
+ {
+ return;
+ }
+ }
+ }
+ catch(const SessionDestroyedException&)
+ {
+ return;
+ }
+
+ p->second.addAllocationRequest(request);
+}
+
+bool
+AllocatableObjectCache::canTryAllocate(const AllocatableObjectEntryPtr& entry)
+{
+ //
+ // Notify the type entry that an object was released.
+ //
+ Lock sync(*this);
+ map<string, TypeEntry>::iterator p = _types.find(entry->getType());
+ if(p == _types.end())
+ {
+ return false;
+ }
+ return p->second.canTryAllocate(entry, true);
+}
+
+AllocatableObjectEntry::AllocatableObjectEntry(AllocatableObjectCache& cache,
+ const ObjectInfo& info,
+ const AllocatablePtr& parent) :
+ Allocatable(true, parent),
+ _cache(cache),
+ _info(info),
+ _destroyed(false)
+{
+}
+
+Ice::ObjectPrx
+AllocatableObjectEntry::getProxy() const
+{
+ return _info.proxy;
+}
+
+string
+AllocatableObjectEntry::getType() const
+{
+ return _info.type;
+}
+
+bool
+AllocatableObjectEntry::canRemove()
+{
+ return true;
+}
+
+void
+AllocatableObjectEntry::allocated(const SessionIPtr& session)
+{
+ //
+ // Add the object allocation to the session. The object will be
+ // released once the session is destroyed.
+ //
+ session->addAllocation(this);
+
+ TraceLevelsPtr traceLevels = _cache.getTraceLevels();
+ if(traceLevels && traceLevels->object > 1)
+ {
+ Ice::Trace out(traceLevels->logger, traceLevels->objectCat);
+ out << "object `" << _info.proxy << "' allocated by `" << session->getId() << "' (" << _count << ")";
+ }
+
+ Glacier2::SessionControlPrx ctl = session->getSessionControl();
+ if(ctl)
+ {
+ try
+ {
+ Ice::IdentitySeq seq(1);
+ seq.push_back(_info.proxy->ice_getIdentity());
+ ctl->identities()->add(seq);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ }
+}
+
+void
+AllocatableObjectEntry::released(const SessionIPtr& session)
+{
+ //
+ // Remove the object allocation from the session.
+ //
+ session->removeAllocation(this);
+
+ Glacier2::SessionControlPrx ctl = session->getSessionControl();
+ if(ctl)
+ {
+ try
+ {
+ Ice::IdentitySeq seq(1);
+ seq.push_back(_info.proxy->ice_getIdentity());
+ ctl->identities()->remove(seq);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ }
+
+ TraceLevelsPtr traceLevels = _cache.getTraceLevels();
+ if(traceLevels && traceLevels->object > 1)
+ {
+ Ice::Trace out(traceLevels->logger, traceLevels->objectCat);
+ out << "object `" << _info.proxy << "' released by `" << session->getId() << "' (" << _count << ")";
+ }
+}
+
+void
+AllocatableObjectEntry::destroy()
+{
+ SessionIPtr session;
+ {
+ Lock sync(*this);
+ _destroyed = true;
+ session = _session;
+ }
+ release(session);
+}
+
+void
+AllocatableObjectEntry::checkAllocatable()
+{
+ if(_destroyed)
+ {
+ throw ObjectNotRegisteredException(_info.proxy->ice_getIdentity());
+ }
+
+ Allocatable::checkAllocatable();
+}
+
+bool
+AllocatableObjectEntry::canTryAllocate()
+{
+ return _cache.canTryAllocate(this);
+}
+
diff --git a/cpp/src/IceGrid/AllocatableObjectCache.h b/cpp/src/IceGrid/AllocatableObjectCache.h
new file mode 100644
index 00000000000..3c906fc77c7
--- /dev/null
+++ b/cpp/src/IceGrid/AllocatableObjectCache.h
@@ -0,0 +1,121 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_GRID_ALLOCATABLEOBJECTCACHE_H
+#define ICE_GRID_ALLOCATABLEOBJECTCACHE_H
+
+#include <IceUtil/Mutex.h>
+#include <Ice/CommunicatorF.h>
+#include <IceGrid/Cache.h>
+#include <IceGrid/Admin.h>
+#include <IceGrid/Allocatable.h>
+
+namespace IceGrid
+{
+
+class AllocatableObjectCache;
+
+class AllocatableObjectEntry : public Allocatable
+{
+public:
+
+ AllocatableObjectEntry(AllocatableObjectCache&, const ObjectInfo&, const AllocatablePtr&);
+ Ice::ObjectPrx getProxy() const;
+ std::string getType() const;
+
+ bool canRemove();
+
+ virtual void allocated(const SessionIPtr&);
+ virtual void released(const SessionIPtr&);
+ virtual bool canTryAllocate();
+
+ void destroy();
+ virtual void checkAllocatable();
+
+private:
+
+ AllocatableObjectCache& _cache;
+ const ObjectInfo _info;
+ bool _destroyed;
+};
+typedef IceUtil::Handle<AllocatableObjectEntry> AllocatableObjectEntryPtr;
+
+class ObjectAllocationRequest : public AllocationRequest
+{
+public:
+
+ ObjectAllocationRequest(const SessionIPtr& session) : AllocationRequest(session) { }
+
+ virtual void response(const Ice::ObjectPrx&) = 0;
+ virtual void exception(const AllocationException&) = 0;
+
+private:
+
+ virtual bool allocated(const AllocatablePtr& allocatable, const SessionIPtr& session)
+ {
+ response(AllocatableObjectEntryPtr::dynamicCast(allocatable)->getProxy());
+ return true;
+ }
+
+ virtual void canceled(const AllocationException& ex)
+ {
+ exception(ex);
+ }
+};
+typedef IceUtil::Handle<ObjectAllocationRequest> ObjectAllocationRequestPtr;
+
+class AdapterCache;
+
+class AllocatableObjectCache : public Cache<Ice::Identity, AllocatableObjectEntry>
+{
+public:
+
+ AllocatableObjectCache(const Ice::CommunicatorPtr&);
+
+ void add(const ObjectInfo&, const AllocatablePtr&);
+ AllocatableObjectEntryPtr get(const Ice::Identity&) const;
+ AllocatableObjectEntryPtr remove(const Ice::Identity&);
+
+ void allocateByType(const std::string&, const ObjectAllocationRequestPtr&);
+ bool canTryAllocate(const AllocatableObjectEntryPtr&);
+
+ const Ice::CommunicatorPtr& getCommunicator() const { return _communicator; }
+
+private:
+
+ class TypeEntry
+ {
+ public:
+
+ TypeEntry();
+
+ void add(const AllocatableObjectEntryPtr&);
+ bool remove(const AllocatableObjectEntryPtr&);
+
+ void addAllocationRequest(const ObjectAllocationRequestPtr&);
+ bool canTryAllocate(const AllocatableObjectEntryPtr&, bool);
+
+ const std::vector<AllocatableObjectEntryPtr>& getObjects() const { return _objects; }
+
+ private:
+
+ std::vector<AllocatableObjectEntryPtr> _objects;
+ std::list<ObjectAllocationRequestPtr> _requests;
+ };
+
+ const Ice::CommunicatorPtr _communicator;
+ std::map<std::string, TypeEntry> _types;
+ std::map<std::string, std::vector<Ice::Identity> > _allocatablesByType;
+
+ static std::pointer_to_unary_function<int, int> _rand;
+};
+
+};
+
+#endif
diff --git a/cpp/src/IceGrid/Database.cpp b/cpp/src/IceGrid/Database.cpp
index 4a2be700876..9b478a19b2e 100644
--- a/cpp/src/IceGrid/Database.cpp
+++ b/cpp/src/IceGrid/Database.cpp
@@ -120,8 +120,9 @@ Database::Database(const Ice::ObjectAdapterPtr& adapter,
_instanceName(instanceName),
_traceLevels(traceLevels),
_nodeCache(_communicator, nodeSessionTimeout),
- _objectCache(_communicator, _adapterCache),
- _serverCache(_communicator, _nodeCache, _adapterCache, _objectCache),
+ _objectCache(_communicator),
+ _allocatableObjectCache(_communicator),
+ _serverCache(_communicator, _nodeCache, _adapterCache, _objectCache, _allocatableObjectCache),
_connection(Freeze::createConnection(adapter->getCommunicator(), envName)),
_descriptors(_connection, _descriptorDbName),
_objects(_connection, _objectDbName),
@@ -150,6 +151,7 @@ Database::Database(const Ice::ObjectAdapterPtr& adapter,
_nodeCache.setTraceLevels(_traceLevels);
_adapterCache.setTraceLevels(_traceLevels);
_objectCache.setTraceLevels(_traceLevels);
+ _allocatableObjectCache.setTraceLevels(_traceLevels);
//
// Register a default servant to manage manually registered object adapters.
@@ -1019,19 +1021,19 @@ Database::updateObject(const Ice::ObjectPrx& proxy)
void
Database::allocateObject(const Ice::Identity& id, const ObjectAllocationRequestPtr& request)
{
- _objectCache.get(id)->allocate(request);
+ _allocatableObjectCache.get(id)->allocate(request);
}
void
Database::allocateObjectByType(const string& type, const ObjectAllocationRequestPtr& request)
{
- _objectCache.allocateByType(type, request);
+ _allocatableObjectCache.allocateByType(type, request);
}
void
Database::releaseObject(const Ice::Identity& id, const SessionIPtr& session)
{
- _objectCache.get(id)->release(session);
+ _allocatableObjectCache.get(id)->release(session);
}
Ice::ObjectPrx
@@ -1228,7 +1230,9 @@ Database::checkAdapterForAddition(const string& id)
void
Database::checkObjectForAddition(const Ice::Identity& objectId)
{
- if(_objectCache.has(objectId) || _objects.find(objectId) != _objects.end())
+ if(_objectCache.has(objectId)
+ || _allocatableObjectCache.has(objectId)
+ || _objects.find(objectId) != _objects.end())
{
DeploymentException ex;
ex.reason = "object `" + _communicator->identityToString(objectId) + "' is already registered";
@@ -1256,7 +1260,7 @@ Database::load(const ApplicationHelper& app, ServerEntrySeq& entries)
ObjectInfo info;
info.type = o->type;
info.proxy = _communicator->stringToProxy(_communicator->identityToString(o->id) + "@" + r->id);
- _objectCache.add(info, application, false, 0); // Not allocatable
+ _objectCache.add(info, application);
}
}
@@ -1394,7 +1398,7 @@ Database::reload(const ApplicationHelper& oldApp, const ApplicationHelper& newAp
ObjectInfo info;
info.type = o->type;
info.proxy = _communicator->stringToProxy(_communicator->identityToString(o->id) + "@" + r->id);
- _objectCache.add(info, application, false, 0); // Not allocatable
+ _objectCache.add(info, application);
}
}
diff --git a/cpp/src/IceGrid/Database.h b/cpp/src/IceGrid/Database.h
index e4d76add5a1..eac64784f6d 100644
--- a/cpp/src/IceGrid/Database.h
+++ b/cpp/src/IceGrid/Database.h
@@ -22,6 +22,7 @@
#include <IceGrid/ServerCache.h>
#include <IceGrid/NodeCache.h>
#include <IceGrid/ObjectCache.h>
+#include <IceGrid/AllocatableObjectCache.h>
#include <IceGrid/AdapterCache.h>
namespace IceGrid
@@ -138,6 +139,7 @@ private:
NodeCache _nodeCache;
AdapterCache _adapterCache;
ObjectCache _objectCache;
+ AllocatableObjectCache _allocatableObjectCache;
ServerCache _serverCache;
RegistryObserverPrx _registryObserver;
diff --git a/cpp/src/IceGrid/DescriptorBuilder.cpp b/cpp/src/IceGrid/DescriptorBuilder.cpp
index 8a8687f28a1..1a33cdd0c87 100644
--- a/cpp/src/IceGrid/DescriptorBuilder.cpp
+++ b/cpp/src/IceGrid/DescriptorBuilder.cpp
@@ -618,6 +618,15 @@ CommunicatorDescriptorBuilder::addObject(const XmlAttributesHelper& attrs)
}
void
+CommunicatorDescriptorBuilder::addAllocatable(const XmlAttributesHelper& attrs)
+{
+ ObjectDescriptor object;
+ object.type = attrs("type", "");
+ object.id = _communicator->stringToIdentity(attrs("identity"));
+ _descriptor->adapters.back().allocatables.push_back(object);
+}
+
+void
CommunicatorDescriptorBuilder::addDbEnv(const XmlAttributesHelper& attrs)
{
DbEnvDescriptor desc;
diff --git a/cpp/src/IceGrid/DescriptorBuilder.h b/cpp/src/IceGrid/DescriptorBuilder.h
index e34f6a79432..5e7267338f3 100644
--- a/cpp/src/IceGrid/DescriptorBuilder.h
+++ b/cpp/src/IceGrid/DescriptorBuilder.h
@@ -207,6 +207,7 @@ public:
virtual void addAdapter(const XmlAttributesHelper&);
virtual void setAdapterDescription(const std::string&);
virtual void addObject(const XmlAttributesHelper&);
+ virtual void addAllocatable(const XmlAttributesHelper&);
virtual void addDbEnv(const XmlAttributesHelper&);
virtual void addDbEnvProperty(const XmlAttributesHelper&);
virtual void setDbEnvDescription(const std::string&);
diff --git a/cpp/src/IceGrid/DescriptorHelper.cpp b/cpp/src/IceGrid/DescriptorHelper.cpp
index a91396db68b..73e8b5a0b1a 100644
--- a/cpp/src/IceGrid/DescriptorHelper.cpp
+++ b/cpp/src/IceGrid/DescriptorHelper.cpp
@@ -454,14 +454,14 @@ Resolver::operator()(const PropertySetDescriptorDict& propertySets) const
}
ObjectDescriptorSeq
-Resolver::operator()(const ObjectDescriptorSeq& objects) const
+Resolver::operator()(const ObjectDescriptorSeq& objects, const string& type) const
{
ObjectDescriptorSeq result;
for(ObjectDescriptorSeq::const_iterator q = objects.begin(); q != objects.end(); ++q)
{
ObjectDescriptor obj;
- obj.type = operator()(q->type, "object type");
- obj.id = operator()(q->id, "object identity");
+ obj.type = operator()(q->type, type + " object type");
+ obj.id = operator()(q->id, type + " object identity");
result.push_back(obj);
}
return result;
@@ -878,10 +878,18 @@ CommunicatorHelper::getIds(multiset<string>& adapterIds, multiset<Ice::Identity>
{
adapterIds.insert(p->id);
}
- for(ObjectDescriptorSeq::const_iterator q = p->objects.begin(); q != p->objects.end(); ++q)
+
+ set<Ice::Identity> ids;
+ ObjectDescriptorSeq::const_iterator q;
+ for(q = p->objects.begin(); q != p->objects.end(); ++q)
+ {
+ ids.insert(q->id);
+ }
+ for(q = p->allocatables.begin(); q != p->allocatables.end(); ++q)
{
- objectIds.insert(q->id);
+ ids.insert(q->id);
}
+ objectIds.insert(ids.begin(), ids.end());
}
}
@@ -904,7 +912,8 @@ CommunicatorHelper::instantiateImpl(const CommunicatorDescriptorPtr& instance, c
{
resolve.exception("unknown replica group `" + adapter.replicaGroupId + "'");
}
- adapter.objects = resolve(p->objects);
+ adapter.objects = resolve(p->objects, "well-known");
+ adapter.allocatables = resolve(p->allocatables, "allocatable");
instance->adapters.push_back(adapter);
//
@@ -1003,9 +1012,21 @@ CommunicatorHelper::printObjectAdapter(Output& out, const AdapterDescriptor& ada
}
out << nl << "register process = `" << (adapter.registerProcess ? "true" : "false") << "'";
out << nl << "wait for activation = `" << (adapter.waitForActivation ? "true" : "false") << "'";
- for(ObjectDescriptorSeq::const_iterator p = adapter.objects.begin(); p != adapter.objects.end(); ++p)
+ ObjectDescriptorSeq::const_iterator p;
+ for(p = adapter.objects.begin(); p != adapter.objects.end(); ++p)
+ {
+ out << nl << "well-known object";
+ if(!p->type.empty())
+ {
+ out << sb;
+ out << nl << "identity = `" << _communicator->identityToString(p->id) << "' ";
+ out << nl << "type = `" << p->type << "'";
+ out << eb;
+ }
+ }
+ for(p = adapter.allocatables.begin(); p != adapter.allocatables.end(); ++p)
{
- out << nl << "object";
+ out << nl << "allocatable";
if(!p->type.empty())
{
out << sb;
@@ -2230,7 +2251,7 @@ ApplicationHelper::ApplicationHelper(const Ice::CommunicatorPtr& communicator, c
ReplicaGroupDescriptor desc;
desc.id = r->id;
desc.description = resolve(r->description, "replica group description");
- desc.objects = resolve(r->objects);
+ desc.objects = resolve(r->objects, "well-known");
if(r->loadBalancing)
{
diff --git a/cpp/src/IceGrid/DescriptorHelper.h b/cpp/src/IceGrid/DescriptorHelper.h
index b68c996c4d9..13715163c72 100644
--- a/cpp/src/IceGrid/DescriptorHelper.h
+++ b/cpp/src/IceGrid/DescriptorHelper.h
@@ -31,7 +31,7 @@ public:
DistributionDescriptor operator()(const DistributionDescriptor&) const;
PropertyDescriptorSeq operator()(const PropertyDescriptorSeq&, const std::string& = std::string("property")) const;
PropertySetDescriptorDict operator()(const PropertySetDescriptorDict&) const;
- ObjectDescriptorSeq operator()(const ObjectDescriptorSeq&) const;
+ ObjectDescriptorSeq operator()(const ObjectDescriptorSeq&, const std::string&) const;
Ice::Identity operator()(const Ice::Identity&, const std::string&) const;
PropertySetDescriptor operator()(const PropertySetDescriptor&) const;
diff --git a/cpp/src/IceGrid/DescriptorParser.cpp b/cpp/src/IceGrid/DescriptorParser.cpp
index e192a1ce380..8e7768b23d7 100644
--- a/cpp/src/IceGrid/DescriptorParser.cpp
+++ b/cpp/src/IceGrid/DescriptorParser.cpp
@@ -72,6 +72,7 @@ private:
bool _isTopLevel;
bool _inAdapter;
+ bool _inReplicaGroup;
bool _inDbEnv;
bool _inDistrib;
};
@@ -85,6 +86,7 @@ DescriptorHandler::DescriptorHandler(const string& filename, const Ice::Communic
_currentCommunicator(0),
_isTopLevel(true),
_inAdapter(false),
+ _inReplicaGroup(false),
_inDbEnv(false)
{
}
@@ -296,11 +298,11 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
error("the <replica-group> element can only be a child of a <application> element");
}
_currentApplication->addReplicaGroup(attributes);
- _inAdapter = true;
+ _inReplicaGroup = true;
}
else if(name == "load-balancing")
{
- if(!_inAdapter || _currentServer.get())
+ if(!_inReplicaGroup)
{
error("the <load-balancing> element can only be a child of a <replica-group> element");
}
@@ -387,11 +389,11 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
}
else if(name == "object")
{
- if(!_inAdapter)
+ if(!_inAdapter && !_inReplicaGroup)
{
error("the <object> element can only be a child of an <adapter> or <replica-group> element");
}
- if(!_currentCommunicator)
+ if(_inReplicaGroup)
{
_currentApplication->addObject(attributes);
}
@@ -400,6 +402,14 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
_currentCommunicator->addObject(attributes);
}
}
+ else if(name == "allocatable")
+ {
+ if(!_inAdapter)
+ {
+ error("the <allocatable> element can only be a child of an <adapter>");
+ }
+ _currentCommunicator->addAllocatable(attributes);
+ }
else if(name == "distrib")
{
if(!_currentApplication.get() && (!_currentServer.get() || _currentServer.get() != _currentCommunicator))
@@ -590,14 +600,11 @@ DescriptorHandler::endElement(const string& name, int line, int column)
{
if(_inAdapter)
{
- if(_currentCommunicator)
- {
- _currentCommunicator->setAdapterDescription(elementValue());
- }
- else
- {
- _currentApplication->setReplicaGroupDescription(elementValue());
- }
+ _currentCommunicator->setAdapterDescription(elementValue());
+ }
+ else if(_inReplicaGroup)
+ {
+ _currentApplication->setReplicaGroupDescription(elementValue());
}
else if(_inDbEnv)
{
@@ -658,7 +665,7 @@ DescriptorHandler::endElement(const string& name, int line, int column)
}
else if(name == "replica-group")
{
- _inAdapter = false;
+ _inReplicaGroup = false;
}
else if(name == "dbenv")
{
diff --git a/cpp/src/IceGrid/Makefile b/cpp/src/IceGrid/Makefile
index 55e0babf1b1..ac1efca9084 100644
--- a/cpp/src/IceGrid/Makefile
+++ b/cpp/src/IceGrid/Makefile
@@ -61,6 +61,7 @@ REGISTRY_OBJS = RegistryI.o \
Allocatable.o \
AdapterCache.o \
ObjectCache.o \
+ AllocatableObjectCache.o \
ServerCache.o \
NodeCache.o \
LocatorI.o \
diff --git a/cpp/src/IceGrid/ObjectCache.cpp b/cpp/src/IceGrid/ObjectCache.cpp
index 29132c8c221..c2b58f08833 100644
--- a/cpp/src/IceGrid/ObjectCache.cpp
+++ b/cpp/src/IceGrid/ObjectCache.cpp
@@ -44,7 +44,7 @@ struct ObjectLoadCI : binary_function<pair<Ice::ObjectPrx, float>&, pair<Ice::Ob
};
-ObjectCache::TypeEntry::TypeEntry() : _allocatablesCount(0)
+ObjectCache::TypeEntry::TypeEntry()
{
}
@@ -55,12 +55,6 @@ ObjectCache::TypeEntry::add(const ObjectEntryPtr& obj)
// No mutex protection here, this is called with the cache locked.
//
_objects.insert(lower_bound(_objects.begin(), _objects.end(), obj, ObjectEntryCI()), obj);
- _allocatablesCount += obj->isAllocatable() ? 1 : 0;
-
- if(!_requests.empty())
- {
- canTryAllocate(obj, false);
- }
}
bool
@@ -69,93 +63,25 @@ ObjectCache::TypeEntry::remove(const ObjectEntryPtr& obj)
//
// No mutex protection here, this is called with the cache locked.
//
- _allocatablesCount -= obj->isAllocatable() ? 1 : 0;
vector<ObjectEntryPtr>::iterator q = lower_bound(_objects.begin(), _objects.end(), obj, ObjectEntryCI());
assert(q->get() == obj.get());
_objects.erase(q);
-
- if(!_requests.empty() && !_allocatablesCount)
- {
- for(list<ObjectAllocationRequestPtr>::const_iterator p = _requests.begin(); p != _requests.end(); ++p)
- {
- (*p)->cancel(AllocationException("no allocatable objects with type `" + obj->getType() + "' registered"));
- }
- }
return _objects.empty();
}
-void
-ObjectCache::TypeEntry::addAllocationRequest(const ObjectAllocationRequestPtr& request)
-{
- //
- // No mutex protection here, this is called with the cache locked.
- //
- assert(_allocatablesCount);
- if(request->pending())
- {
- _requests.push_back(request);
- }
-}
-
-bool
-ObjectCache::TypeEntry::canTryAllocate(const ObjectEntryPtr& entry, bool fromRelease)
-{
- //
- // No mutex protection here, this is called with the cache locked.
- //
- list<ObjectAllocationRequestPtr>::iterator p = _requests.begin();
- while(p != _requests.end())
- {
- AllocationRequestPtr request = *p;
- try
- {
- if(request->isCanceled()) // If the request has been canceled, we just remove it.
- {
- p = _requests.erase(p);
- }
- else if(entry->tryAllocate(request, fromRelease))
- {
- p = _requests.erase(p);
- return true; // The request successfully allocated the entry!
- }
- else if(entry->getSession()) // If entry is allocated, we're done
- {
- return false;
- }
- else
- {
- ++p;
- }
- }
- catch(const SessionDestroyedException&)
- {
- p = _requests.erase(p);
- }
- }
- return false;
-}
-
-bool
-ObjectCache::TypeEntry::hasAllocatables() const
-{
- return _allocatablesCount;
-}
-
-ObjectCache::ObjectCache(const Ice::CommunicatorPtr& communicator, AdapterCache& adapterCache) :
- _communicator(communicator),
- _adapterCache(adapterCache)
+ObjectCache::ObjectCache(const Ice::CommunicatorPtr& communicator) : _communicator(communicator)
{
}
void
-ObjectCache::add(const ObjectInfo& info, const string& application, bool allocatable, const AllocatablePtr& parent)
+ObjectCache::add(const ObjectInfo& info, const string& application)
{
const Ice::Identity& id = info.proxy->ice_getIdentity();
Lock sync(*this);
assert(!getImpl(id));
- ObjectEntryPtr entry = new ObjectEntry(*this, info, application, allocatable, parent);
+ ObjectEntryPtr entry = new ObjectEntry(*this, info, application);
addImpl(id, entry);
map<string, TypeEntry>::iterator p = _types.find(entry->getType());
@@ -207,51 +133,6 @@ ObjectCache::remove(const Ice::Identity& id)
return entry;
}
-void
-ObjectCache::allocateByType(const string& type, const ObjectAllocationRequestPtr& request)
-{
- Lock sync(*this);
- map<string, TypeEntry>::iterator p = _types.find(type);
- if(p == _types.end() || !p->second.hasAllocatables())
- {
- throw AllocationException("no allocatable objects with type `" + type + "' registered");
- }
-
- vector<ObjectEntryPtr> objects = p->second.getObjects();
- random_shuffle(objects.begin(), objects.end(), _rand); // TODO: OPTIMIZE
- try
- {
- for(vector<ObjectEntryPtr>::const_iterator q = objects.begin(); q != objects.end(); ++q)
- {
- if((*q)->tryAllocate(request))
- {
- return;
- }
- }
- }
- catch(const SessionDestroyedException&)
- {
- return;
- }
-
- p->second.addAllocationRequest(request);
-}
-
-bool
-ObjectCache::canTryAllocate(const ObjectEntryPtr& entry)
-{
- //
- // Notify the type entry that an object was released.
- //
- Lock sync(*this);
- map<string, TypeEntry>::iterator p = _types.find(entry->getType());
- if(p == _types.end())
- {
- return false;
- }
- return p->second.canTryAllocate(entry, true);
-}
-
Ice::ObjectProxySeq
ObjectCache::getObjectsByType(const string& type)
{
@@ -304,16 +185,10 @@ ObjectCache::getAllByType(const string& type)
return infos;
}
-ObjectEntry::ObjectEntry(ObjectCache& cache,
- const ObjectInfo& info,
- const string& application,
- bool allocatable,
- const AllocatablePtr& parent) :
- Allocatable(allocatable, parent),
+ObjectEntry::ObjectEntry(ObjectCache& cache, const ObjectInfo& info, const string& application) :
_cache(cache),
_info(info),
- _application(application),
- _destroyed(false)
+ _application(application)
{
}
@@ -347,97 +222,3 @@ ObjectEntry::canRemove()
return true;
}
-void
-ObjectEntry::allocated(const SessionIPtr& session)
-{
- //
- // Add the object allocation to the session. The object will be
- // released once the session is destroyed.
- //
- session->addAllocation(this);
-
- TraceLevelsPtr traceLevels = _cache.getTraceLevels();
- if(traceLevels && traceLevels->object > 1)
- {
- Ice::Trace out(traceLevels->logger, traceLevels->objectCat);
- const Ice::Identity id = _info.proxy->ice_getIdentity();
- out << "object `" << _cache.communicator()->identityToString(id) << "' allocated by `" << session->getId()
- << "' (" << _count << ")";
- }
-
- Glacier2::SessionControlPrx ctl = session->getSessionControl();
- if(ctl)
- {
- try
- {
- Ice::IdentitySeq seq(1);
- seq.push_back(_info.proxy->ice_getIdentity());
- ctl->identities()->add(seq);
- }
- catch(const Ice::ObjectNotExistException&)
- {
- }
- }
-}
-
-void
-ObjectEntry::released(const SessionIPtr& session)
-{
- //
- // Remove the object allocation from the session.
- //
- session->removeAllocation(this);
-
- Glacier2::SessionControlPrx ctl = session->getSessionControl();
- if(ctl)
- {
- try
- {
- Ice::IdentitySeq seq(1);
- seq.push_back(_info.proxy->ice_getIdentity());
- ctl->identities()->remove(seq);
- }
- catch(const Ice::ObjectNotExistException&)
- {
- }
- }
-
- TraceLevelsPtr traceLevels = _cache.getTraceLevels();
- if(traceLevels && traceLevels->object > 1)
- {
- Ice::Trace out(traceLevels->logger, traceLevels->objectCat);
- const Ice::Identity id = _info.proxy->ice_getIdentity();
- out << "object `" << _cache.communicator()->identityToString(id) << "' released by `" << session->getId()
- << "' (" << _count << ")";
- }
-}
-
-void
-ObjectEntry::destroy()
-{
- SessionIPtr session;
- {
- Lock sync(*this);
- _destroyed = true;
- session = _session;
- }
- release(session);
-}
-
-void
-ObjectEntry::checkAllocatable()
-{
- if(_destroyed)
- {
- throw ObjectNotRegisteredException(_info.proxy->ice_getIdentity());
- }
-
- Allocatable::checkAllocatable();
-}
-
-bool
-ObjectEntry::canTryAllocate()
-{
- return _cache.canTryAllocate(this);
-}
-
diff --git a/cpp/src/IceGrid/ObjectCache.h b/cpp/src/IceGrid/ObjectCache.h
index 079bfaf9465..fa2d9c92e93 100644
--- a/cpp/src/IceGrid/ObjectCache.h
+++ b/cpp/src/IceGrid/ObjectCache.h
@@ -11,26 +11,20 @@
#define ICE_GRID_OBJECTCACHE_H
#include <IceUtil/Mutex.h>
-#include <IceUtil/Shared.h>
#include <Ice/CommunicatorF.h>
#include <IceGrid/Cache.h>
#include <IceGrid/Internal.h>
-#include <IceGrid/Query.h>
-#include <IceGrid/Allocatable.h>
namespace IceGrid
{
class ObjectCache;
-class ServerEntry;
-typedef IceUtil::Handle<ServerEntry> ServerEntryPtr;
-
-class ObjectEntry : public Allocatable
+class ObjectEntry : public IceUtil::Shared
{
public:
- ObjectEntry(ObjectCache&, const ObjectInfo&, const std::string&, bool, const AllocatablePtr&);
+ ObjectEntry(ObjectCache&, const ObjectInfo&, const std::string&);
Ice::ObjectPrx getProxy() const;
std::string getType() const;
std::string getApplication() const;
@@ -38,66 +32,29 @@ public:
bool canRemove();
- virtual void allocated(const SessionIPtr&);
- virtual void released(const SessionIPtr&);
- virtual bool canTryAllocate();
-
- void destroy();
- virtual void checkAllocatable();
-
private:
ObjectCache& _cache;
const ObjectInfo _info;
const std::string _application;
- bool _destroyed;
};
typedef IceUtil::Handle<ObjectEntry> ObjectEntryPtr;
-class ObjectAllocationRequest : public AllocationRequest
-{
-public:
-
- ObjectAllocationRequest(const SessionIPtr& session) : AllocationRequest(session) { }
-
- virtual void response(const Ice::ObjectPrx&) = 0;
- virtual void exception(const AllocationException&) = 0;
-
-private:
-
- virtual bool allocated(const AllocatablePtr& allocatable, const SessionIPtr& session)
- {
- response(ObjectEntryPtr::dynamicCast(allocatable)->getObjectInfo().proxy);
- return true;
- }
-
- virtual void canceled(const AllocationException& ex)
- {
- exception(ex);
- }
-};
-typedef IceUtil::Handle<ObjectAllocationRequest> ObjectAllocationRequestPtr;
-
-class AdapterCache;
-
class ObjectCache : public Cache<Ice::Identity, ObjectEntry>
{
public:
- ObjectCache(const Ice::CommunicatorPtr&, AdapterCache&);
+ ObjectCache(const Ice::CommunicatorPtr&);
- void add(const ObjectInfo&, const std::string&, bool, const AllocatablePtr&);
+ void add(const ObjectInfo&, const std::string&);
ObjectEntryPtr get(const Ice::Identity&) const;
ObjectEntryPtr remove(const Ice::Identity&);
- void allocateByType(const std::string&, const ObjectAllocationRequestPtr&);
- bool canTryAllocate(const ObjectEntryPtr&);
-
Ice::ObjectProxySeq getObjectsByType(const std::string&);
ObjectInfoSeq getAll(const std::string&);
ObjectInfoSeq getAllByType(const std::string&);
- const Ice::CommunicatorPtr& communicator() const { return _communicator; }
+ const Ice::CommunicatorPtr& getCommunicator() const { return _communicator; }
private:
@@ -110,24 +67,15 @@ private:
void add(const ObjectEntryPtr&);
bool remove(const ObjectEntryPtr&);
- void addAllocationRequest(const ObjectAllocationRequestPtr&);
- bool canTryAllocate(const ObjectEntryPtr&, bool);
-
const std::vector<ObjectEntryPtr>& getObjects() const { return _objects; }
- bool hasAllocatables() const;
private:
std::vector<ObjectEntryPtr> _objects;
- std::list<ObjectAllocationRequestPtr> _requests;
- int _allocatablesCount;
};
- Ice::CommunicatorPtr _communicator;
- AdapterCache& _adapterCache;
-
+ const Ice::CommunicatorPtr _communicator;
std::map<std::string, TypeEntry> _types;
- std::map<std::string, std::vector<Ice::Identity> > _allocatablesByType;
static std::pointer_to_unary_function<int, int> _rand;
};
diff --git a/cpp/src/IceGrid/ServerCache.cpp b/cpp/src/IceGrid/ServerCache.cpp
index 00a9e21f072..03ec1fdc3d5 100644
--- a/cpp/src/IceGrid/ServerCache.cpp
+++ b/cpp/src/IceGrid/ServerCache.cpp
@@ -14,6 +14,7 @@
#include <IceGrid/NodeCache.h>
#include <IceGrid/AdapterCache.h>
#include <IceGrid/ObjectCache.h>
+#include <IceGrid/AllocatableObjectCache.h>
#include <IceGrid/SessionI.h>
#include <IceGrid/DescriptorHelper.h>
@@ -61,11 +62,13 @@ namespace IceGrid
ServerCache::ServerCache(const Ice::CommunicatorPtr& communicator,
NodeCache& nodeCache,
AdapterCache& adapterCache,
- ObjectCache& objectCache) :
+ ObjectCache& objectCache,
+ AllocatableObjectCache& allocatableObjectCache) :
_communicator(communicator),
_nodeCache(nodeCache),
_adapterCache(adapterCache),
- _objectCache(objectCache)
+ _objectCache(objectCache),
+ _allocatableObjectCache(allocatableObjectCache)
{
}
@@ -154,25 +157,24 @@ ServerCache::addCommunicator(const CommunicatorDescriptorPtr& comm, const Server
const string application = server->getApplication();
for(AdapterDescriptorSeq::const_iterator q = comm->adapters.begin() ; q != comm->adapters.end(); ++q)
{
- if(!q->id.empty())
+ assert(!q->id.empty());
+ _adapterCache.addServerAdapter(q->id, q->replicaGroupId, server);
+
+ ObjectDescriptorSeq::const_iterator r;
+ for(r = q->objects.begin(); r != q->objects.end(); ++r)
{
- _adapterCache.addServerAdapter(q->id, q->replicaGroupId, server);
+ ObjectInfo info;
+ info.type = r->type;
+ info.proxy = _communicator->stringToProxy(_communicator->identityToString(r->id) + "@" + q->id);
+ _objectCache.add(info, application);
}
- for(ObjectDescriptorSeq::const_iterator r = q->objects.begin(); r != q->objects.end(); ++r)
+ for(r = q->allocatables.begin(); r != q->allocatables.end(); ++r)
{
ObjectInfo info;
info.type = r->type;
- if(q->id.empty())
- {
- const string edpts = IceGrid::getProperty(comm->propertySet.properties, q->name + ".Endpoints");
- info.proxy = _communicator->stringToProxy(_communicator->identityToString(r->id) + ":" + edpts);
- }
- else
- {
- info.proxy = _communicator->stringToProxy(_communicator->identityToString(r->id) + "@" + q->id);
- }
- _objectCache.add(info, application, true, server);
+ info.proxy = _communicator->stringToProxy(_communicator->identityToString(r->id) + "@" + q->id);
+ _allocatableObjectCache.add(info, server);
}
}
}
@@ -182,14 +184,16 @@ ServerCache::removeCommunicator(const CommunicatorDescriptorPtr& comm, const Ser
{
for(AdapterDescriptorSeq::const_iterator q = comm->adapters.begin() ; q != comm->adapters.end(); ++q)
{
- for(ObjectDescriptorSeq::const_iterator r = q->objects.begin(); r != q->objects.end(); ++r)
+ ObjectDescriptorSeq::const_iterator r;
+ for(r = q->objects.begin(); r != q->objects.end(); ++r)
{
_objectCache.remove(r->id);
}
- if(!q->id.empty())
+ for(r = q->allocatables.begin(); r != q->allocatables.end(); ++r)
{
- _adapterCache.removeServerAdapter(q->id);
+ _allocatableObjectCache.remove(r->id);
}
+ _adapterCache.removeServerAdapter(q->id);
}
}
diff --git a/cpp/src/IceGrid/ServerCache.h b/cpp/src/IceGrid/ServerCache.h
index 47837584468..48a3515b084 100644
--- a/cpp/src/IceGrid/ServerCache.h
+++ b/cpp/src/IceGrid/ServerCache.h
@@ -14,15 +14,17 @@
#include <IceUtil/Shared.h>
#include <IceGrid/Descriptor.h>
#include <IceGrid/Internal.h>
+#include <IceGrid/Query.h>
#include <IceGrid/Allocatable.h>
#include <IceGrid/Cache.h>
-#include <IceGrid/AdapterCache.h>
namespace IceGrid
{
class ServerCache;
class ObjectCache;
+class AdapterCache;
+class AllocatableObjectCache;
class NodeCache;
class NodeEntry;
@@ -86,7 +88,7 @@ class ServerCache : public CacheByString<ServerEntry>
{
public:
- ServerCache(const Ice::CommunicatorPtr&, NodeCache&, AdapterCache&, ObjectCache&);
+ ServerCache(const Ice::CommunicatorPtr&, NodeCache&, AdapterCache&, ObjectCache&, AllocatableObjectCache&);
ServerEntryPtr add(const ServerInfo&);
ServerEntryPtr get(const std::string&) const;
@@ -110,6 +112,7 @@ private:
NodeCache& _nodeCache;
AdapterCache& _adapterCache;
ObjectCache& _objectCache;
+ AllocatableObjectCache& _allocatableObjectCache;
};
};
diff --git a/cpp/test/IceGrid/activation/application.xml b/cpp/test/IceGrid/activation/application.xml
index f827361cd8f..e5e79e19a07 100644
--- a/cpp/test/IceGrid/activation/application.xml
+++ b/cpp/test/IceGrid/activation/application.xml
@@ -11,6 +11,7 @@
activation="${activation}" activation-timeout="4" deactivation-timeout="3">
<adapter name="TestAdapter" endpoints="default" register-process="true">
<object identity="${server}" type="Test"/>
+ <allocatable identity="${server}" type="Test"/>
</adapter>
<property name="ActivationDelay" value="${activation-delay}"/>
<property name="DeactivationDelay" value="${deactivation-delay}"/>
diff --git a/cpp/test/IceGrid/allocation/AllTests.cpp b/cpp/test/IceGrid/allocation/AllTests.cpp
index b9331e9329d..6f2db328b9d 100644
--- a/cpp/test/IceGrid/allocation/AllTests.cpp
+++ b/cpp/test/IceGrid/allocation/AllTests.cpp
@@ -388,7 +388,12 @@ allTests(const Ice::CommunicatorPtr& communicator)
}
catch(const AllocationException&)
{
+ test(false);
}
+ catch(const ObjectNotRegisteredException&)
+ {
+ }
+
try
{
session2->allocateObjectById(communicator->stringToIdentity("nonallocatable"));
@@ -396,7 +401,12 @@ allTests(const Ice::CommunicatorPtr& communicator)
}
catch(const AllocationException&)
{
+ test(false);
}
+ catch(const ObjectNotRegisteredException&)
+ {
+ }
+
try
{
session1->releaseObject(communicator->stringToIdentity("nonallocatable"));
@@ -404,7 +414,12 @@ allTests(const Ice::CommunicatorPtr& communicator)
}
catch(const AllocationException&)
{
+ test(false);
}
+ catch(const ObjectNotRegisteredException&)
+ {
+ }
+
try
{
session2->releaseObject(communicator->stringToIdentity("nonallocatable"));
@@ -412,6 +427,10 @@ allTests(const Ice::CommunicatorPtr& communicator)
}
catch(const AllocationException&)
{
+ test(false);
+ }
+ catch(const ObjectNotRegisteredException&)
+ {
}
session1->allocateObjectById(allocatable);
diff --git a/cpp/test/IceGrid/allocation/application.xml b/cpp/test/IceGrid/allocation/application.xml
index 05ff652f748..a520ab4deb3 100644
--- a/cpp/test/IceGrid/allocation/application.xml
+++ b/cpp/test/IceGrid/allocation/application.xml
@@ -2,11 +2,6 @@
<application name="Test">
- <replica-group id="Test">
- <object identity="nonallocatable" type="::Test"/>
- <object identity="nonallocatable2" type="::NotAllocatable"/>
- </replica-group>
-
<server-template id="Glacier2">
<parameter name="id"/>
<parameter name="endpoints"/>
@@ -35,51 +30,55 @@
<server id="ObjectAllocation" exe="${test.dir}/server" activation="on-demand" pwd=".">
<adapter name="Server" endpoints="default">
- <object identity="allocatable" type="::Test"/>
- <object identity="allocatablebis" type="::TestBis"/>
+ <allocatable identity="allocatable" type="::Test"/>
+ <allocatable identity="allocatablebis" type="::TestBis"/>
+
+ <object identity="nonallocatable" type="::Test"/>
+ <object identity="nonallocatable2" type="::NotAllocatable"/>
</adapter>
</server>
<server id="ServerAllocation" exe="${test.dir}/server" activation="on-demand" pwd="." allocatable="true">
<adapter name="Server" endpoints="default" id="ServerAlloc">
- <object identity="allocatable3" type="::TestServer1"/>
- <object identity="allocatable4" type="::TestServer2"/>
+ <allocatable identity="allocatable3" type="::TestServer1"/>
+ <allocatable identity="allocatable4" type="::TestServer2"/>
+ <object identity="allocatable4"/>
- <object identity="allocatable31" type="::TestMultipleByServer"/>
- <object identity="allocatable41" type="::TestMultipleByServer"/>
+ <allocatable identity="allocatable31" type="::TestMultipleByServer"/>
+ <allocatable identity="allocatable41" type="::TestMultipleByServer"/>
</adapter>
</server>
<server id="ServerAllocation-1" exe="${test.dir}/server" activation="on-demand" pwd="." allocatable="true">
<adapter name="Server" endpoints="default">
- <object identity="allocatable5" type="::TestMultipleServer"/>
+ <allocatable identity="allocatable5" type="::TestMultipleServer"/>
</adapter>
</server>
<server id="ServerAllocation-2" exe="${test.dir}/server" activation="on-demand" pwd="." allocatable="true">
<adapter name="Server" endpoints="default">
- <object identity="allocatable6" type="::TestMultipleServer"/>
+ <allocatable identity="allocatable6" type="::TestMultipleServer"/>
</adapter>
</server>
<server id="ServerStress-1" exe="${test.dir}/server" activation="on-demand" pwd=".">
<adapter name="Server" endpoints="default">
- <object identity="stress-1" type="::StressTest"/>
- <object identity="stress-2" type="::StressTest"/>
+ <allocatable identity="stress-1" type="::StressTest"/>
+ <allocatable identity="stress-2" type="::StressTest"/>
</adapter>
</server>
<server id="ServerStress-2" exe="${test.dir}/server" activation="on-demand" pwd="." allocatable="true">
<adapter name="Server" endpoints="default">
- <object identity="stress-3" type="::StressTest"/>
- <object identity="stress-4" type="::StressTest"/>
+ <allocatable identity="stress-3" type="::StressTest"/>
+ <allocatable identity="stress-4" type="::StressTest"/>
</adapter>
</server>
<server id="ServerStress-3" exe="${test.dir}/server" activation="on-demand" pwd="." allocatable="true">
<adapter name="Server" endpoints="default">
- <object identity="stress-5" type="::StressTest"/>
- <object identity="stress-6" type="::StressTest"/>
+ <allocatable identity="stress-5" type="::StressTest"/>
+ <allocatable identity="stress-6" type="::StressTest"/>
</adapter>
</server>