diff options
Diffstat (limited to 'cpp/src/Ice/LocatorInfo.cpp')
-rw-r--r-- | cpp/src/Ice/LocatorInfo.cpp | 824 |
1 files changed, 464 insertions, 360 deletions
diff --git a/cpp/src/Ice/LocatorInfo.cpp b/cpp/src/Ice/LocatorInfo.cpp index 027261900aa..a2cc09ff1af 100644 --- a/cpp/src/Ice/LocatorInfo.cpp +++ b/cpp/src/Ice/LocatorInfo.cpp @@ -1,6 +1,6 @@ // ********************************************************************** // -// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// Copyright (c) 2003-2009 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. @@ -16,6 +16,7 @@ #include <Ice/EndpointI.h> #include <Ice/Reference.h> #include <Ice/Functional.h> +#include <Ice/Properties.h> #include <iterator> using namespace std; @@ -26,7 +27,91 @@ IceUtil::Shared* IceInternal::upCast(LocatorManager* p) { return p; } IceUtil::Shared* IceInternal::upCast(LocatorInfo* p) { return p; } IceUtil::Shared* IceInternal::upCast(LocatorTable* p) { return p; } -IceInternal::LocatorManager::LocatorManager() : +namespace +{ + +class ObjectRequest : public LocatorInfo::Request, public Ice::AMI_Locator_findObjectById +{ +public: + + ObjectRequest(const LocatorInfoPtr& locatorInfo, const ReferencePtr& ref) : Request(locatorInfo, ref) + { + assert(ref->isWellKnown()); + } + + virtual void ice_response(const Ice::ObjectPrx& proxy) + { + response(proxy); + } + + virtual void ice_exception(const Ice::Exception& ex) + { + exception(ex); + } + + virtual void send(bool async) + { + try + { + if(async) + { + _locatorInfo->getLocator()->findObjectById_async(this, _ref->getIdentity()); + } + else + { + ice_response(_locatorInfo->getLocator()->findObjectById(_ref->getIdentity())); + } + } + catch(const Ice::Exception& ex) + { + ice_exception(ex); + } + } +}; + +class AdapterRequest : public LocatorInfo::Request, public Ice::AMI_Locator_findAdapterById +{ +public: + + AdapterRequest(const LocatorInfoPtr& locatorInfo, const ReferencePtr& ref) : Request(locatorInfo, ref) + { + assert(ref->isIndirect() && !ref->isWellKnown()); + } + + virtual void ice_response(const Ice::ObjectPrx& proxy) + { + response(proxy); + } + + virtual void ice_exception(const Ice::Exception& ex) + { + exception(ex); + } + + virtual void send(bool async) + { + try + { + if(async) + { + _locatorInfo->getLocator()->findAdapterById_async(this, _ref->getAdapterId()); + } + else + { + ice_response(_locatorInfo->getLocator()->findAdapterById(_ref->getAdapterId())); + } + } + catch(const Ice::Exception& ex) + { + ice_exception(ex); + } + } +}; + +} + +IceInternal::LocatorManager::LocatorManager(const Ice::PropertiesPtr& properties) : + _background(properties->getPropertyAsInt("Ice.BackgroundLocatorCacheUpdates") > 0), _tableHint(_table.end()) { } @@ -92,7 +177,8 @@ IceInternal::LocatorManager::get(const LocatorPrx& loc) _tableHint = _table.insert(_tableHint, pair<const LocatorPrx, LocatorInfoPtr>(locator, - new LocatorInfo(locator, t->second))); + new LocatorInfo(locator, t->second, + _background))); } else { @@ -127,10 +213,10 @@ IceInternal::LocatorTable::getAdapterEndpoints(const string& adapter, int ttl, v map<string, pair<IceUtil::Time, vector<EndpointIPtr> > >::iterator p = _adapterEndpointsMap.find(adapter); - if(p != _adapterEndpointsMap.end() && checkTTL(p->second.first, ttl)) + if(p != _adapterEndpointsMap.end()) { endpoints = p->second.second; - return true; + return checkTTL(p->second.first, ttl); } return false; } @@ -172,7 +258,7 @@ IceInternal::LocatorTable::removeAdapterEndpoints(const string& adapter) } bool -IceInternal::LocatorTable::getProxy(const Identity& id, int ttl, ObjectPrx& proxy) +IceInternal::LocatorTable::getObjectReference(const Identity& id, int ttl, ReferencePtr& ref) { if(ttl == 0) // No locator cache { @@ -181,47 +267,47 @@ IceInternal::LocatorTable::getProxy(const Identity& id, int ttl, ObjectPrx& prox IceUtil::Mutex::Lock sync(*this); - map<Identity, pair<IceUtil::Time, ObjectPrx> >::iterator p = _objectMap.find(id); + map<Identity, pair<IceUtil::Time, ReferencePtr> >::iterator p = _objectMap.find(id); - if(p != _objectMap.end() && checkTTL(p->second.first, ttl)) + if(p != _objectMap.end()) { - proxy = p->second.second; - return true; + ref = p->second.second; + return checkTTL(p->second.first, ttl); } return false; } void -IceInternal::LocatorTable::addProxy(const Identity& id, const ObjectPrx& proxy) +IceInternal::LocatorTable::addObjectReference(const Identity& id, const ReferencePtr& ref) { IceUtil::Mutex::Lock sync(*this); - map<Identity, pair<IceUtil::Time, ObjectPrx> >::iterator p = _objectMap.find(id); + map<Identity, pair<IceUtil::Time, ReferencePtr> >::iterator p = _objectMap.find(id); if(p != _objectMap.end()) { - p->second = make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), proxy); + p->second = make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), ref); } else { - _objectMap.insert(make_pair(id, make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), proxy))); + _objectMap.insert(make_pair(id, make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), ref))); } } -ObjectPrx -IceInternal::LocatorTable::removeProxy(const Identity& id) +ReferencePtr +IceInternal::LocatorTable::removeObjectReference(const Identity& id) { IceUtil::Mutex::Lock sync(*this); - map<Identity, pair<IceUtil::Time, ObjectPrx> >::iterator p = _objectMap.find(id); + map<Identity, pair<IceUtil::Time, ReferencePtr> >::iterator p = _objectMap.find(id); if(p == _objectMap.end()) { return 0; } - ObjectPrx proxy = p->second.second; + ReferencePtr ref = p->second.second; _objectMap.erase(p); - return proxy; + return ref; } bool @@ -238,9 +324,197 @@ IceInternal::LocatorTable::checkTTL(const IceUtil::Time& time, int ttl) const } } -IceInternal::LocatorInfo::LocatorInfo(const LocatorPrx& locator, const LocatorTablePtr& table) : +void +IceInternal::LocatorInfo::RequestCallback::response(const LocatorInfoPtr& locatorInfo, const Ice::ObjectPrx& proxy) +{ + vector<EndpointIPtr> endpoints; + if(proxy) + { + ReferencePtr r = proxy->__reference(); + if(!r->isIndirect()) + { + endpoints = r->getEndpoints(); + } + else if(_ref->isWellKnown() && !r->isWellKnown()) + { + // + // We're resolving the endpoints of a well-known object and the proxy returned + // by the locator is an indirect proxy. We now need to resolve the endpoints + // of this indirect proxy. + // + locatorInfo->getEndpoints(r, _ref, _ttl, _callback); + return; + } + } + + if(_ref->getInstance()->traceLevels()->location >= 1) + { + locatorInfo->getEndpointsTrace(_ref, endpoints, false); + } + if(_callback) + { + _callback->setEndpoints(endpoints, false); + } +} + +void +IceInternal::LocatorInfo::RequestCallback::exception(const LocatorInfoPtr& locatorInfo, const Ice::Exception& exc) +{ + try + { + locatorInfo->getEndpointsException(_ref, exc); // This throws. + } + catch(const Ice::LocalException& ex) + { + if(_callback) + { + _callback->setException(ex); + } + } +} + +IceInternal::LocatorInfo::RequestCallback::RequestCallback(const ReferencePtr& ref, + int ttl, + const GetEndpointsCallbackPtr& cb) : + _ref(ref), _ttl(ttl), _callback(cb) +{ +} + +void +IceInternal::LocatorInfo::Request::addCallback(const ReferencePtr& ref, + const ReferencePtr& wellKnownRef, + int ttl, + const GetEndpointsCallbackPtr& cb) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + + RequestCallbackPtr callback = new RequestCallback(ref, ttl, cb); + if(_response) + { + callback->response(_locatorInfo, _proxy); + } + else if(_exception.get()) + { + callback->exception(_locatorInfo, *_exception.get()); + } + else + { + _callbacks.push_back(callback); + if(wellKnownRef) // This request is to resolve the endpoints of a cached well-known object reference + { + _wellKnownRefs.push_back(wellKnownRef); + } + if(!_sent) + { + _sent = true; + sync.release(); + send(true); // send() might call exception() from this thread so we need to release the mutex. + } + } +} + +vector<EndpointIPtr> +IceInternal::LocatorInfo::Request::getEndpoints(const ReferencePtr& ref, + const ReferencePtr& wellKnownRef, + int ttl, + bool& cached) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + if(!_response || _exception.get()) + { + if(wellKnownRef) // This request is to resolve the endpoints of a cached well-known object reference + { + _wellKnownRefs.push_back(wellKnownRef); + } + if(!_sent) + { + _sent = true; + sync.release(); + send(true); // send() might call exception() from this thread so we need to release the mutex. + sync.acquire(); + } + + while(!_response && !_exception.get()) + { + _monitor.wait(); + } + } + + if(_exception.get()) + { + _locatorInfo->getEndpointsException(ref, *_exception.get()); // This throws. + } + + assert(_response); + vector<EndpointIPtr> endpoints; + if(_proxy) + { + ReferencePtr r = _proxy->__reference(); + if(!r->isIndirect()) + { + endpoints = r->getEndpoints(); + } + else if(ref->isWellKnown() && !r->isWellKnown()) + { + // + // We're resolving the endpoints of a well-known object and the proxy returned + // by the locator is an indirect proxy. We now need to resolve the endpoints + // of this indirect proxy. + // + return _locatorInfo->getEndpoints(r, ref, ttl, cached); + } + } + + cached = false; + if(_ref->getInstance()->traceLevels()->location >= 1) + { + _locatorInfo->getEndpointsTrace(ref, endpoints, false); + } + return endpoints; +} + +IceInternal::LocatorInfo::Request::Request(const LocatorInfoPtr& locatorInfo, const ReferencePtr& ref) : + _locatorInfo(locatorInfo), _ref(ref), _sent(false), _response(false) +{ +} + +void +IceInternal::LocatorInfo::Request::response(const Ice::ObjectPrx& proxy) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + _locatorInfo->finishRequest(_ref, _wellKnownRefs, proxy, false); + _response = true; + _proxy = proxy; + for(vector<RequestCallbackPtr>::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p) + { + (*p)->response(_locatorInfo, proxy); + } + _monitor.notifyAll(); +} + +void +IceInternal::LocatorInfo::Request::exception(const Ice::Exception& ex) +{ + if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex)) + { + send(false); // Use synchronous collocation optimized locator request instead. + return; + } + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + _locatorInfo->finishRequest(_ref, _wellKnownRefs, 0, dynamic_cast<const Ice::UserException*>(&ex)); + _exception.reset(ex.ice_clone()); + for(vector<RequestCallbackPtr>::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p) + { + (*p)->exception(_locatorInfo, ex); + } + _monitor.notifyAll(); +} + +IceInternal::LocatorInfo::LocatorInfo(const LocatorPrx& locator, const LocatorTablePtr& table, bool background) : _locator(locator), - _table(table) + _table(table), + _background(background) { assert(_locator); assert(_table); @@ -301,284 +575,116 @@ IceInternal::LocatorInfo::getLocatorRegistry() } vector<EndpointIPtr> -IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, bool& cached) +IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, const ReferencePtr& wellKnownRef, int ttl, bool& cached) { assert(ref->isIndirect()); vector<EndpointIPtr> endpoints; - ObjectPrx object; - cached = true; - try + if(!ref->isWellKnown()) { - if(!ref->isWellKnown()) - { - if(!_table->getAdapterEndpoints(ref->getAdapterId(), ttl, endpoints)) - { - cached = false; - - if(ref->getInstance()->traceLevels()->location >= 1) - { - Trace out(ref->getInstance()->initializationData().logger, - ref->getInstance()->traceLevels()->locationCat); - out << "searching for adapter by id" << "\n"; - out << "adapter = " << ref->getAdapterId(); - } - - object = _locator->findAdapterById(ref->getAdapterId()); - if(object) - { - endpoints = object->__reference()->getEndpoints(); - _table->addAdapterEndpoints(ref->getAdapterId(), endpoints); - } - } - } - else + if(!_table->getAdapterEndpoints(ref->getAdapterId(), ttl, endpoints)) { - bool objectCached = true; - if(!_table->getProxy(ref->getIdentity(), ttl, object)) + if(_background && !endpoints.empty()) { - if(ref->getInstance()->traceLevels()->location >= 1) - { - Trace out(ref->getInstance()->initializationData().logger, - ref->getInstance()->traceLevels()->locationCat); - out << "searching for object by id" << "\n"; - out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); - } - - objectCached = false; - object = _locator->findObjectById(ref->getIdentity()); + getAdapterRequest(ref)->addCallback(ref, wellKnownRef, ttl, 0); } - - bool endpointsCached = true; - if(object) - { - ReferencePtr r = object->__reference(); - if(!r->isIndirect()) - { - endpointsCached = false; - endpoints = r->getEndpoints(); - } - else if(!r->isWellKnown()) - { - endpoints = getEndpoints(r, ttl, endpointsCached); - } - } - - if(!objectCached && !endpoints.empty()) + else { - _table->addProxy(ref->getIdentity(), object); + return getAdapterRequest(ref)->getEndpoints(ref, wellKnownRef, ttl, cached); } - - cached = objectCached || endpointsCached; } } - catch(const Ice::Exception& ex) - { - getEndpointsException(ref, ex); - } - - if(ref->getInstance()->traceLevels()->location >= 1) - { - getEndpointsTrace(ref, endpoints, cached); - } - - return endpoints; -} - -namespace IceInternal -{ - -class findAdapterByIdCallback : public AMI_Locator_findAdapterById -{ -public: - - virtual void - ice_response(const Ice::ObjectPrx& object) + else { - vector<EndpointIPtr> endpoints; - if(object) + ReferencePtr r; + if(!_table->getObjectReference(ref->getIdentity(), ttl, r)) { - endpoints = object->__reference()->getEndpoints(); - if(!endpoints.empty()) + if(_background && r) { - _table->addAdapterEndpoints(_reference->getAdapterId(), endpoints); + getObjectRequest(ref)->addCallback(ref, 0, ttl, 0); + } + else + { + return getObjectRequest(ref)->getEndpoints(ref, 0, ttl, cached); } } - if(_reference->getInstance()->traceLevels()->location >= 1) - { - _locatorInfo->getEndpointsTrace(_reference, endpoints, false); - } - - _callback->setEndpoints(endpoints, false); - } - - virtual void - ice_exception(const Ice::Exception& ex) - { - if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex)) + if(!r->isIndirect()) { - try - { - bool cached; - vector<EndpointIPtr> endpoints = _locatorInfo->getEndpoints(_reference, _ttl, cached); - _callback->setEndpoints(endpoints, cached); - } - catch(const Ice::LocalException& e) - { - _callback->setException(e); - } + endpoints = r->getEndpoints(); } - else + else if(!r->isWellKnown()) { - _locatorInfo->getEndpointsException(_reference, ex, _callback); + return getEndpoints(r, ref, ttl, cached); } } - findAdapterByIdCallback(const LocatorInfoPtr& locatorInfo, const LocatorTablePtr& table, - const ReferencePtr& reference, int ttl, const LocatorInfo::GetEndpointsCallbackPtr& callback) : - _locatorInfo(locatorInfo), _table(table), _reference(reference), _ttl(ttl), _callback(callback) + assert(!endpoints.empty()); + cached = true; + if(ref->getInstance()->traceLevels()->location >= 1) { + getEndpointsTrace(ref, endpoints, true); } - -private: - - const LocatorInfoPtr _locatorInfo; - const LocatorTablePtr _table; - const ReferencePtr _reference; - const int _ttl; - const LocatorInfo::GetEndpointsCallbackPtr _callback; -}; - -}; + return endpoints; +} void -IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, const GetEndpointsCallbackPtr& callback) +IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, + const ReferencePtr& wellKnownRef, + int ttl, + const GetEndpointsCallbackPtr& callback) { assert(ref->isIndirect()); - - string adapterId = ref->getAdapterId(); - Ice::Identity identity = ref->getIdentity(); - InstancePtr instance = ref->getInstance(); - if(!adapterId.empty()) + vector<EndpointIPtr> endpoints; + if(!ref->isWellKnown()) { - vector<EndpointIPtr> endpoints; - if(!_table->getAdapterEndpoints(adapterId, ttl, endpoints)) + if(!_table->getAdapterEndpoints(ref->getAdapterId(), ttl, endpoints)) { - if(instance->traceLevels()->location >= 1) + if(_background && !endpoints.empty()) { - Trace out(instance->initializationData().logger, instance->traceLevels()->locationCat); - out << "searching for adapter by id" << "\nadapter = " << adapterId; + getAdapterRequest(ref)->addCallback(ref, wellKnownRef, ttl, 0); } - - // - // Search the adapter in the location service if we didn't - // find it in the cache. - // - _locator->findAdapterById_async( - new IceInternal::findAdapterByIdCallback(this, _table, ref, ttl, callback), adapterId); - return; - } - else - { - if(instance->traceLevels()->location >= 1) + else { - getEndpointsTrace(ref, endpoints, true); + getAdapterRequest(ref)->addCallback(ref, wellKnownRef, ttl, callback); + return; } - callback->setEndpoints(endpoints, true); - return; } } else { - Ice::ObjectPrx object; - if(!_table->getProxy(identity, ttl, object)) + ReferencePtr r; + if(!_table->getObjectReference(ref->getIdentity(), ttl, r)) { - if(instance->traceLevels()->location >= 1) + if(_background && r) { - Trace out(instance->initializationData().logger, instance->traceLevels()->locationCat); - out << "searching for object by id" << "\nobject = " << instance->identityToString(ref->getIdentity()); + getObjectRequest(ref)->addCallback(ref, 0, ttl, 0); } - - class Callback : public Ice::AMI_Locator_findObjectById + else { - public: - - virtual void - ice_response(const Ice::ObjectPrx& object) - { - _locatorInfo->getWellKnownObjectEndpoints(_reference, object, _ttl, false, _callback); - } - - virtual void - ice_exception(const Ice::Exception& ex) - { - if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex)) - { - try - { - bool cached; - vector<EndpointIPtr> endpoints = _locatorInfo->getEndpoints(_reference, _ttl, cached); - _callback->setEndpoints(endpoints, cached); - } - catch(const Ice::LocalException& e) - { - _callback->setException(e); - } - } - else - { - _locatorInfo->getEndpointsException(_reference, ex, _callback); - } - } - - Callback(const LocatorInfoPtr& locatorInfo, const ReferencePtr& reference, int ttl, - const GetEndpointsCallbackPtr& callback) : - _locatorInfo(locatorInfo), _reference(reference), _ttl(ttl), _callback(callback) - { - } - - private: - - const LocatorInfoPtr _locatorInfo; - const ReferencePtr _reference; - int _ttl; - const GetEndpointsCallbackPtr _callback; - }; + getObjectRequest(ref)->addCallback(ref, 0, ttl, callback); + return; + } + } - _locator->findObjectById_async(new Callback(this, ref, ttl, callback), identity); - return; + if(!r->isIndirect()) + { + endpoints = r->getEndpoints(); } - else + else if(!r->isWellKnown()) { - getWellKnownObjectEndpoints(ref, object, ttl, true, callback); + getEndpoints(r, ref, ttl, callback); return; } } -} -void -IceInternal::LocatorInfo::clearObjectCache(const ReferencePtr& ref) -{ - assert(ref->isIndirect()); - - if(ref->isWellKnown()) + assert(!endpoints.empty()); + if(ref->getInstance()->traceLevels()->location >= 1) { - ObjectPrx object = _table->removeProxy(ref->getIdentity()); - if(object) - { - ReferencePtr r = object->__reference(); - if(!r->isIndirect()) - { - if(ref->getInstance()->traceLevels()->location >= 2) - { - trace("removed endpoints from locator table", ref, r->getEndpoints()); - } - } - else if(!r->isWellKnown()) - { - clearCache(r); - } - } + getEndpointsTrace(ref, endpoints, true); + } + if(callback) + { + callback->setEndpoints(endpoints, true); } } @@ -598,10 +704,9 @@ IceInternal::LocatorInfo::clearCache(const ReferencePtr& ref) } else { - ObjectPrx object = _table->removeProxy(ref->getIdentity()); - if(object) + ReferencePtr r = _table->removeObjectReference(ref->getIdentity()); + if(r) { - ReferencePtr r = object->__reference(); if(!r->isIndirect()) { if(ref->getInstance()->traceLevels()->location >= 2) @@ -617,29 +722,6 @@ IceInternal::LocatorInfo::clearCache(const ReferencePtr& ref) } } -void -IceInternal::LocatorInfo::trace(const string& msg, const ReferencePtr& ref, const vector<EndpointIPtr>& endpoints) -{ - assert(ref->isIndirect()); - - Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); - out << msg << '\n'; - if(!ref->isWellKnown()) - { - out << "adapter = " << ref->getAdapterId() << '\n'; - } - else - { - out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()) << '\n'; - } - - const char* sep = endpoints.size() > 1 ? ":" : ""; - ostringstream o; - transform(endpoints.begin(), endpoints.end(), ostream_iterator<string>(o, sep), - Ice::constMemFun(&Endpoint::toString)); - out << "endpoints = " << o.str(); -} - void IceInternal::LocatorInfo::getEndpointsException(const ReferencePtr& ref, const Ice::Exception& exc) { @@ -704,127 +786,149 @@ IceInternal::LocatorInfo::getEndpointsException(const ReferencePtr& ref, const I } } -void -IceInternal::LocatorInfo::getEndpointsException(const ReferencePtr& ref, const Ice::Exception& exc, - const GetEndpointsCallbackPtr& callback) +void +IceInternal::LocatorInfo::getEndpointsTrace(const ReferencePtr& ref, + const vector<EndpointIPtr>& endpoints, + bool cached) { - try + if(!endpoints.empty()) { - getEndpointsException(ref, exc); + if(cached) + { + trace("found endpoints in locator table", ref, endpoints); + } + else + { + trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + } } - catch(const Ice::LocalException& ex) + else { - callback->setException(ex); + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "no endpoints configured for "; + if(ref->getAdapterId().empty()) + { + out << "object\n"; + out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); + } + else + { + out << "adapter\n"; + out << "adapter = " << ref->getAdapterId(); + } } } void -IceInternal::LocatorInfo::getWellKnownObjectEndpoints(const ReferencePtr& ref, - const Ice::ObjectPrx& object, - int ttl, - bool objectCached, - const GetEndpointsCallbackPtr& callback) +IceInternal::LocatorInfo::trace(const string& msg, const ReferencePtr& ref, const vector<EndpointIPtr>& endpoints) { - class Callback : public GetEndpointsCallback - { - public: + assert(ref->isIndirect()); - virtual void - setEndpoints(const vector<EndpointIPtr>& endpoints, bool endpointsCached) - { - if(!_objectCached && !endpoints.empty()) - { - _table->addProxy(_reference->getIdentity(), _object); - } - - if(_reference->getInstance()->traceLevels()->location >= 1) - { - _locatorInfo->getEndpointsTrace(_reference, endpoints, _objectCached || endpointsCached); - } - - _callback->setEndpoints(endpoints, _objectCached || endpointsCached); - } - - virtual void - setException(const Ice::LocalException& ex) - { - _callback->setException(ex); - } - - Callback(const LocatorInfoPtr& locatorInfo, const LocatorTablePtr& table, - const ReferencePtr& reference, const Ice::ObjectPrx& object, - bool objectCached, const GetEndpointsCallbackPtr& callback) : - _locatorInfo(locatorInfo), _table(table), _reference(reference), _object(object), - _objectCached(objectCached), _callback(callback) - { - } + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << msg << '\n'; + if(!ref->isWellKnown()) + { + out << "adapter = " << ref->getAdapterId() << '\n'; + } + else + { + out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()) << '\n'; + } - private: - - const LocatorInfoPtr _locatorInfo; - const LocatorTablePtr _table; - const ReferencePtr _reference; - const Ice::ObjectPrx _object; - const bool _objectCached; - const GetEndpointsCallbackPtr _callback; - }; + const char* sep = endpoints.size() > 1 ? ":" : ""; + ostringstream o; + transform(endpoints.begin(), endpoints.end(), ostream_iterator<string>(o, sep), + Ice::constMemFun(&Endpoint::toString)); + out << "endpoints = " << o.str(); +} - vector<EndpointIPtr> endpoints; - if(object) +IceInternal::LocatorInfo::RequestPtr +IceInternal::LocatorInfo::getAdapterRequest(const ReferencePtr& ref) +{ + IceUtil::Mutex::Lock sync(*this); + if(ref->getInstance()->traceLevels()->location >= 1) { - ReferencePtr r = object->__reference(); - if(!r->isIndirect()) - { - endpoints = r->getEndpoints(); - } - else if(!r->isWellKnown()) - { - getEndpoints(r, ttl, new Callback(this, _table, ref, object, objectCached, callback)); - return; - } + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "searching for adapter by id\nadapter = " << ref->getAdapterId(); } - if(!objectCached && !endpoints.empty()) + map<string, RequestPtr>::const_iterator p = _adapterRequests.find(ref->getAdapterId()); + if(p != _adapterRequests.end()) { - _table->addProxy(ref->getIdentity(), object); + return p->second; } - + + RequestPtr request = new AdapterRequest(this, ref); + _adapterRequests.insert(make_pair(ref->getAdapterId(), request)); + return request; +} + +IceInternal::LocatorInfo::RequestPtr +IceInternal::LocatorInfo::getObjectRequest(const ReferencePtr& ref) +{ + IceUtil::Mutex::Lock sync(*this); if(ref->getInstance()->traceLevels()->location >= 1) { - getEndpointsTrace(ref, endpoints, objectCached); + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "searching for object by id\nobject = " << ref->getInstance()->identityToString(ref->getIdentity()); } - - callback->setEndpoints(endpoints, objectCached); + + map<Ice::Identity, RequestPtr>::const_iterator p = _objectRequests.find(ref->getIdentity()); + if(p != _objectRequests.end()) + { + return p->second; + } + RequestPtr request = new ObjectRequest(this, ref); + _objectRequests.insert(make_pair(ref->getIdentity(), request)); + return request; } void -IceInternal::LocatorInfo::getEndpointsTrace(const ReferencePtr& ref, const vector<EndpointIPtr>& endpoints, - bool cached) +IceInternal::LocatorInfo::finishRequest(const ReferencePtr& ref, + const vector<ReferencePtr>& wellKnownRefs, + const Ice::ObjectPrx& proxy, + bool notRegistered) { - if(!endpoints.empty()) + if(!proxy || proxy->__reference()->isIndirect()) { - if(cached) + // + // Remove the cached references of well-known objects for which we tried + // to resolved the endpoints if these endpoints are empty. + // + for(vector<ReferencePtr>::const_iterator q = wellKnownRefs.begin(); q != wellKnownRefs.end(); ++q) { - trace("found endpoints in locator table", ref, endpoints); + _table->removeObjectReference((*q)->getIdentity()); } - else + } + + if(!ref->isWellKnown()) + { + if(proxy && !proxy->__reference()->isIndirect()) // Cache the adapter endpoints. { - trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + _table->addAdapterEndpoints(ref->getAdapterId(), proxy->__reference()->getEndpoints()); } + else if(notRegistered) // If the adapter isn't registered anymore, remove it from the cache. + { + _table->removeAdapterEndpoints(ref->getAdapterId()); + } + + IceUtil::Mutex::Lock sync(*this); + assert(_adapterRequests.find(ref->getAdapterId()) != _adapterRequests.end()); + _adapterRequests.erase(ref->getAdapterId()); } else { - Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); - out << "no endpoints configured for "; - if(ref->getAdapterId().empty()) + if(proxy && !proxy->__reference()->isWellKnown()) // Cache the well-known object reference. { - out << "object\n"; - out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); + _table->addObjectReference(ref->getIdentity(), proxy->__reference()); } - else + else if(notRegistered) // If the well-known object isn't registered anymore, remove it from the cache. { - out << "adapter\n"; - out << "adapter = " << ref->getAdapterId(); + _table->removeObjectReference(ref->getIdentity()); } + + IceUtil::Mutex::Lock sync(*this); + assert(_objectRequests.find(ref->getIdentity()) != _objectRequests.end()); + _objectRequests.erase(ref->getIdentity()); } } |