summaryrefslogtreecommitdiff
path: root/cpp/src/IcePack/LocatorI.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2005-01-24 17:24:04 +0000
committerBenoit Foucher <benoit@zeroc.com>2005-01-24 17:24:04 +0000
commit8a2308eeffc62f65ed69abe5a1afce324b2d3417 (patch)
treed84b471868f461c956a97c8fd84b497b16fcf2ff /cpp/src/IcePack/LocatorI.cpp
parentadding stringification (diff)
downloadice-8a2308eeffc62f65ed69abe5a1afce324b2d3417.tar.bz2
ice-8a2308eeffc62f65ed69abe5a1afce324b2d3417.tar.xz
ice-8a2308eeffc62f65ed69abe5a1afce324b2d3417.zip
Better support for slow server activation and IcePack registry timeout.
Diffstat (limited to 'cpp/src/IcePack/LocatorI.cpp')
-rw-r--r--cpp/src/IcePack/LocatorI.cpp221
1 files changed, 158 insertions, 63 deletions
diff --git a/cpp/src/IcePack/LocatorI.cpp b/cpp/src/IcePack/LocatorI.cpp
index 882c9c2c27c..4a245b79d28 100644
--- a/cpp/src/IcePack/LocatorI.cpp
+++ b/cpp/src/IcePack/LocatorI.cpp
@@ -23,70 +23,51 @@ class AMI_Adapter_getDirectProxyI : public AMI_Adapter_getDirectProxy
{
public:
- AMI_Adapter_getDirectProxyI(const Ice::AMD_Locator_findAdapterByIdPtr& cb,
- const AdapterRegistryPtr& registry,
- const string& id,
- const AdapterPrx& adapter) :
- _cb(cb), _adapterRegistry(registry), _id(id), _adapter(adapter)
+ AMI_Adapter_getDirectProxyI(const LocatorIPtr& locator, const string& id, const AdapterPrx& adapter) :
+ _locator(locator), _id(id), _adapter(adapter)
{
}
virtual void ice_response(const ::Ice::ObjectPrx& obj)
{
- //
- // Return the adapter dummy direct proxy.
- //
- _cb->ice_response(obj);
+ assert(obj);
+ _locator->getDirectProxyCallback(_adapter->ice_getIdentity(), obj);
}
virtual void ice_exception(const ::Ice::Exception& ex)
{
- try
- {
- ex.ice_throw();
- }
- catch(const Ice::ObjectNotExistException&)
- {
- //
- // Expected if the adapter is destroyed, if that's the case, we remove it from the adapter
- // registry.
- //
- try
- {
- _adapterRegistry->remove(_id, _adapter);
- }
- catch(const AdapterNotExistException&)
- {
- }
- _cb->ice_exception(Ice::AdapterNotFoundException());
- return;
- }
- catch(const Ice::LocalException&)
- {
- //
- // Expected if we couldn't contact the adapter object (possibly because the IcePack node is
- // down). Return a null proxy in this case (the client will get empty endpoints and throw a
- // NoEndpointException).
- //
- _cb->ice_response(0);
- return;
- }
- catch(const Ice::Exception& ex)
- {
- //
- // Rethrow unexpected exception.
- //
- _cb->ice_exception(ex);
- return;
- }
+ _locator->getDirectProxyException(_adapter, _id, ex);
+ }
- assert(false);
+private:
+
+ const LocatorIPtr _locator;
+ const string _id;
+ const AdapterPrx _adapter;
+};
+
+class AMI_Adapter_activateI : public AMI_Adapter_activate
+{
+public:
+
+ AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id, const AdapterPrx& adapter) :
+ _locator(locator), _id(id), _adapter(adapter)
+ {
+ }
+
+ virtual void ice_response(const ::Ice::ObjectPrx& obj)
+ {
+ _locator->getDirectProxyCallback(_adapter->ice_getIdentity(), obj);
+ }
+
+ virtual void ice_exception(const ::Ice::Exception& ex)
+ {
+ _locator->getDirectProxyException(_adapter, _id, ex);
}
private:
- const Ice::AMD_Locator_findAdapterByIdPtr _cb;
- const AdapterRegistryPtr& _adapterRegistry;
+ const LocatorIPtr _locator;
const string _id;
const AdapterPrx _adapter;
};
@@ -169,9 +150,9 @@ private:
}
-IcePack::LocatorI::LocatorI(const AdapterRegistryPtr& adapterRegistry,
- const ObjectRegistryPtr& objectRegistry,
- const Ice::LocatorRegistryPrx& locatorRegistry) :
+LocatorI::LocatorI(const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LocatorRegistryPrx& locatorRegistry) :
_adapterRegistry(adapterRegistry),
_objectRegistry(objectRegistry),
_locatorRegistry(locatorRegistry)
@@ -183,9 +164,9 @@ IcePack::LocatorI::LocatorI(const AdapterRegistryPtr& adapterRegistry,
// registry.
//
void
-IcePack::LocatorI::findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr& cb,
- const Ice::Identity& id,
- const Ice::Current& current) const
+LocatorI::findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr& cb,
+ const Ice::Identity& id,
+ const Ice::Current& current) const
{
ObjectDescriptor obj;
try
@@ -218,24 +199,138 @@ IcePack::LocatorI::findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr
// registry. If found, we try to get its direct proxy.
//
void
-IcePack::LocatorI::findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& cb,
- const string& id,
- const Ice::Current&) const
+LocatorI::findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& cb,
+ const string& id,
+ const Ice::Current&) const
{
+ AdapterPrx adapter;
try
{
- AdapterPrx adapter = AdapterPrx::uncheckedCast(_adapterRegistry->findById(id));
- AMI_Adapter_getDirectProxyPtr amiCB = new AMI_Adapter_getDirectProxyI(cb, _adapterRegistry, id, adapter);
- adapter->getDirectProxy_async(amiCB, true);
+ adapter = AdapterPrx::uncheckedCast(_adapterRegistry->findById(id));
}
catch(const AdapterNotExistException&)
{
throw Ice::AdapterNotFoundException();
}
+
+ LocatorIPtr self = const_cast<LocatorI*>(this);
+ if(self->getDirectProxyRequest(cb, adapter))
+ {
+ try
+ {
+ AMI_Adapter_getDirectProxyPtr amiCB = new AMI_Adapter_getDirectProxyI(self, id, adapter);
+ adapter->getDirectProxy_async(amiCB);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ self->getDirectProxyException(adapter, id, ex);
+ }
+ }
}
Ice::LocatorRegistryPrx
-IcePack::LocatorI::getRegistry(const Ice::Current&) const
+LocatorI::getRegistry(const Ice::Current&) const
{
return _locatorRegistry;
}
+
+bool
+LocatorI::getDirectProxyRequest(const Ice::AMD_Locator_findAdapterByIdPtr& cb, const AdapterPrx& adapter)
+{
+ Lock sync(*this);
+
+ //
+ // Check if there's already pending requests for this adapter. If that's the case,
+ // we just add this one to the queue. If not, we add it to the queue and initiate
+ // a call on the adapter to get its direct proxy.
+ //
+ PendingRequestsMap::iterator p;
+ p = _pendingRequests.insert(make_pair(adapter->ice_getIdentity(), PendingRequests())).first;
+ p->second.push_back(cb);
+ return p->second.size() == 1;
+}
+
+void
+LocatorI::getDirectProxyException(const AdapterPrx& adapter, const string& id, const Ice::Exception& ex)
+{
+ Lock sync(*this);
+
+ PendingRequestsMap::iterator p = _pendingRequests.find(adapter->ice_getIdentity());
+ assert(p != _pendingRequests.end());
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const AdapterNotActiveException& ex)
+ {
+ if(ex.activatable)
+ {
+ //
+ // Activate the adapter if it can be activated on demand. NOTE: we use the timeout
+ // provided in the exception to activate the adapter. The timeout correspond to the
+ // wait time configured for the server.
+ //
+ try
+ {
+ AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, id, adapter);
+ AdapterPrx::uncheckedCast(adapter->ice_timeout(ex.timeout))->activate_async(amiCB);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ getDirectProxyException(adapter, id, ex);
+ }
+ return;
+ }
+ else
+ {
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_response(0);
+ }
+ }
+ }
+ catch(const Ice::ObjectNotExistException& ex)
+ {
+ //
+ // Expected if the adapter is destroyed, if that's the case, we remove it from the adapter registry.
+ //
+ try
+ {
+ _adapterRegistry->remove(id, adapter);
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_exception(Ice::AdapterNotFoundException());
+ }
+ }
+ catch(const Ice::LocalException&)
+ {
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_response(0);
+ }
+ }
+ catch(const Ice::Exception&)
+ {
+ assert(false);
+ }
+ _pendingRequests.erase(p);
+}
+
+void
+LocatorI::getDirectProxyCallback(const Ice::Identity& adapterId, const Ice::ObjectPrx& proxy)
+{
+ Lock sync(*this);
+
+ PendingRequestsMap::iterator p = _pendingRequests.find(adapterId);
+ assert(p != _pendingRequests.end());
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_response(proxy);
+ }
+ _pendingRequests.erase(p);
+}