Пример #1
0
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
}
Пример #2
0
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);
    }
}
Пример #3
0
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);
        }
    }
}
Пример #4
0
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;
}
Пример #5
0
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;
}