ReferencePtr IceInternal::ReferenceFactory::create(const Identity& ident, const string& facet, const ReferencePtr& tmpl, const string& adapterId) { if(ident.name.empty() && ident.category.empty()) { return 0; } return create(ident, facet, tmpl->getMode(), tmpl->getSecure(), vector<EndpointIPtr>(), adapterId, ""); }
ReferencePtr IceInternal::ReferenceFactory::create(const Identity& ident, const string& facet, const ReferencePtr& tmpl, const vector<EndpointIPtr>& endpoints) { if(ident.name.empty() && ident.category.empty()) { return 0; } return create(ident, facet, tmpl->getMode(), tmpl->getSecure(), tmpl->getProtocol(), tmpl->getEncoding(), endpoints, "", ""); }
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; }
RequestHandler::RequestHandler(const ReferencePtr& reference) : _reference(reference), _response(reference->getMode() == Reference::ModeTwoway) { }