diff options
Diffstat (limited to 'cpp/src/IcePack/LocatorI.cpp')
-rw-r--r-- | cpp/src/IcePack/LocatorI.cpp | 221 |
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); +} |