LocatorPrxPtr ICE_OBJECT_PRX::ice_getLocator() const { LocatorInfoPtr ri = _reference->getLocatorInfo(); #ifdef ICE_CPP11_MAPPING return ri ? ri->getLocator() : nullptr; #else return ri ? ri->getLocator() : LocatorPrxPtr(); #endif }
void IceInternal::LocatorInfo::RequestCallback::response(const LocatorInfoPtr& locatorInfo, const Ice::ObjectPrx& proxy) { vector<EndpointIPtr> endpoints; if(proxy) { ReferencePtr r = proxy->__reference(); if(_ref->isWellKnown() && !isSupported(_ref->getEncoding(), r->getEncoding())) { // // If a well-known proxy and the returned proxy encoding // isn't supported, we're done: there's no compatible // endpoint we can use. // } else 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); } } }
bool Ice::ObjectAdapterI::isLocal(const ObjectPrx& proxy) const { ReferencePtr ref = proxy->__reference(); vector<EndpointIPtr>::const_iterator p; vector<EndpointIPtr> endpoints; IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(ref); if(ir) { if(!ir->getAdapterId().empty()) { // // Proxy is local if the reference adapter id matches this // adapter id or replica group id. // return ir->getAdapterId() == _id || ir->getAdapterId() == _replicaGroupId; } // // Get Locator endpoint information for indirect references. // LocatorInfoPtr info = ir->getLocatorInfo(); if(info) { bool isCached; try { endpoints = info->getEndpoints(ir, ir->getLocatorCacheTimeout(), isCached); } catch(const Ice::LocalException&) { return false; } } else { return false; } } else { endpoints = ref->getEndpoints(); } IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); checkForDeactivation(); // // Proxies which have at least one endpoint in common with the // endpoints used by this object adapter's incoming connection // factories are considered local. // for(p = endpoints.begin(); p != endpoints.end(); ++p) { vector<IncomingConnectionFactoryPtr>::const_iterator q; for(q = _incomingConnectionFactories.begin(); q != _incomingConnectionFactories.end(); ++q) { if((*q)->equivalent(*p)) { return true; } } } // // Proxies which have at least one endpoint in common with the // router's server proxy endpoints (if any), are also considered // local. // if(_routerInfo && _routerInfo->getRouter() == proxy->ice_getRouter()) { for(p = endpoints.begin(); p != endpoints.end(); ++p) { if(binary_search(_routerEndpoints.begin(), _routerEndpoints.end(), *p)) // _routerEndpoints is sorted. { return true; } } } return false; }
int IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, const ReferencePtr& ref, bool sleep, int& cnt) const { TraceLevelsPtr traceLevels = _instance->traceLevels(); LoggerPtr logger = _instance->initializationData().logger; // // We don't retry batch requests because the exception might have caused // the all the requests batched with the connection to be aborted and we // want the application to be notified. // if(ref->getMode() == Reference::ModeBatchOneway || ref->getMode() == Reference::ModeBatchDatagram) { ex.ice_throw(); } const ObjectNotExistException* one = dynamic_cast<const ObjectNotExistException*>(&ex); if(one) { if(ref->getRouterInfo() && one->operation == "ice_add_proxy") { // // If we have a router, an ObjectNotExistException with an // operation name "ice_add_proxy" indicates to the client // that the router isn't aware of the proxy (for example, // because it was evicted by the router). In this case, we // must *always* retry, so that the missing proxy is added // to the router. // ref->getRouterInfo()->clearCache(ref); if(traceLevels->retry >= 1) { Trace out(logger, traceLevels->retryCat); out << "retrying operation call to add proxy to router\n" << ex; } return 0; // We must always retry, so we don't look at the retry count. } else if(ref->isIndirect()) { // // We retry ObjectNotExistException if the reference is // indirect. // if(ref->isWellKnown()) { LocatorInfoPtr li = ref->getLocatorInfo(); if(li) { li->clearCache(ref); } } } else { // // For all other cases, we don't retry // ObjectNotExistException. // ex.ice_throw(); } } else if(dynamic_cast<const RequestFailedException*>(&ex)) { // // We don't retry other *NotExistException, which are all // derived from RequestFailedException. // ex.ice_throw(); } // // There is no point in retrying an operation that resulted in a // MarshalException. This must have been raised locally (because // if it happened in a server it would result in an // UnknownLocalException instead), which means there was a problem // in this process that will not change if we try again. // // The most likely cause for a MarshalException is exceeding the // maximum message size, which is represented by the subclass // MemoryLimitException. For example, a client can attempt to send // a message that exceeds the maximum memory size, or accumulate // enough batch requests without flushing that the maximum size is // reached. // // This latter case is especially problematic, because if we were // to retry a batch request after a MarshalException, we would in // fact silently discard the accumulated requests and allow new // batch requests to accumulate. If the subsequent batched // requests do not exceed the maximum message size, it appears to // the client that all of the batched requests were accepted, when // in reality only the last few are actually sent. // if(dynamic_cast<const MarshalException*>(&ex)) { ex.ice_throw(); } ++cnt; assert(cnt > 0); int interval = -1; if(cnt == static_cast<int>(_retryIntervals.size() + 1) && dynamic_cast<const CloseConnectionException*>(&ex)) { // // A close connection exception is always retried at least once, even if the retry // limit is reached. // interval = 0; } else if(cnt > static_cast<int>(_retryIntervals.size())) { if(traceLevels->retry >= 1) { Trace out(logger, traceLevels->retryCat); out << "cannot retry operation call because retry limit has been exceeded\n" << ex; } ex.ice_throw(); } else { interval = _retryIntervals[cnt - 1]; } if(traceLevels->retry >= 1) { Trace out(logger, traceLevels->retryCat); out << "retrying operation call"; if(interval > 0) { out << " in " << interval << "ms"; } out << " because of exception\n" << ex; } if(sleep && interval > 0) { // // Sleep before retrying. // IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(interval)); } return interval; }