public void clearCache(Reference rf) { Debug.Assert(rf.isIndirect()); if(!rf.isWellKnown()) { EndpointI[] endpoints = _table.removeAdapterEndpoints(rf.getAdapterId()); if(endpoints != null && rf.getInstance().traceLevels().location >= 2) { trace("removed endpoints from locator table\n", rf, endpoints); } } else { Reference r = _table.removeObjectReference(rf.getIdentity()); if(r != null) { if(!r.isIndirect()) { if(rf.getInstance().traceLevels().location >= 2) { trace("removed endpoints from locator table", rf, r.getEndpoints()); } } else if(!r.isWellKnown()) { clearCache(r); } } } }
public int checkRetryAfterException(Ice.LocalException ex, Reference @ref, bool sleep, ref int cnt) { TraceLevels traceLevels = instance_.traceLevels(); Ice.Logger 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.Mode.ModeBatchOneway || @ref.getMode() == Reference.Mode.ModeBatchDatagram) { throw ex; } Ice.ObjectNotExistException one = ex as Ice.ObjectNotExistException; if(one != null) { if(@ref.getRouterInfo() != null && one.operation.Equals("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) { string s = "retrying operation call to add proxy to router\n" + ex; logger.trace(traceLevels.retryCat, s); } 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()) { LocatorInfo li = @ref.getLocatorInfo(); if(li != null) { li.clearCache(@ref); } } } else { // // For all other cases, we don't retry ObjectNotExistException. // throw ex; } } else if(ex is Ice.RequestFailedException) { throw ex; } // // 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(ex is Ice.MarshalException) { throw ex; } ++cnt; Debug.Assert(cnt > 0); int interval; if(cnt == (_retryIntervals.Length + 1) && ex is Ice.CloseConnectionException) { // // A close connection exception is always retried at least once, even if the retry // limit is reached. // interval = 0; } else if(cnt > _retryIntervals.Length) { if(traceLevels.retry >= 1) { string s = "cannot retry operation call because retry limit has been exceeded\n" + ex; logger.trace(traceLevels.retryCat, s); } throw ex; } else { interval = _retryIntervals[cnt - 1]; } if(traceLevels.retry >= 1) { string s = "retrying operation call"; if(interval > 0) { s += " in " + interval + "ms"; } s += " because of exception\n" + ex; logger.trace(traceLevels.retryCat, s); } if(sleep && interval > 0) { // // Sleep before retrying. // System.Threading.Thread.Sleep(interval); } return interval; }
finishRequest(Reference @ref, List<Reference> wellKnownRefs, Ice.ObjectPrx proxy, bool notRegistered) { Ice.ObjectPrxHelperBase @base = proxy as Ice.ObjectPrxHelperBase; if(proxy == null || @base.reference__().isIndirect()) { // // Remove the cached references of well-known objects for which we tried // to resolved the endpoints if these endpoints are empty. // foreach(Reference r in wellKnownRefs) { _table.removeObjectReference(r.getIdentity()); } } if([email protected]()) { if(proxy != null && [email protected]__().isIndirect()) { // Cache the adapter endpoints. _table.addAdapterEndpoints(@ref.getAdapterId(), @base.reference__().getEndpoints()); } else if(notRegistered) // If the adapter isn't registered anymore, remove it from the cache. { _table.removeAdapterEndpoints(@ref.getAdapterId()); } lock(this) { Debug.Assert(_adapterRequests.ContainsKey(@ref.getAdapterId())); _adapterRequests.Remove(@ref.getAdapterId()); } } else { if(proxy != null && [email protected]__().isWellKnown()) { // Cache the well-known object reference. _table.addObjectReference(@ref.getIdentity(), @base.reference__()); } else if(notRegistered) // If the well-known object isn't registered anymore, remove it from the cache. { _table.removeObjectReference(@ref.getIdentity()); } lock(this) { Debug.Assert(_objectRequests.ContainsKey(@ref.getIdentity())); _objectRequests.Remove(@ref.getIdentity()); } } }
getEndpoints(Reference @ref, Reference wellKnownRef, int ttl, GetEndpointsCallback callback) { Debug.Assert(@ref.isIndirect()); EndpointI[] endpoints = null; bool cached = false; if([email protected]()) { endpoints = _table.getAdapterEndpoints(@ref.getAdapterId(), ttl, out cached); if(!cached) { if(_background && endpoints != null) { getAdapterRequest(@ref).addCallback(@ref, wellKnownRef, ttl, null); } else { getAdapterRequest(@ref).addCallback(@ref, wellKnownRef, ttl, callback); return; } } } else { Reference r = _table.getObjectReference(@ref.getIdentity(), ttl, out cached); if(!cached) { if(_background && r != null) { getObjectRequest(@ref).addCallback(@ref, null, ttl, null); } else { getObjectRequest(@ref).addCallback(@ref, null, ttl, callback); return; } } if(!r.isIndirect()) { endpoints = r.getEndpoints(); } else if(!r.isWellKnown()) { getEndpoints(r, @ref, ttl, callback); return; } } Debug.Assert(endpoints != null); if(@ref.getInstance().traceLevels().location >= 1) { getEndpointsTrace(@ref, endpoints, true); } if(callback != null) { callback.setEndpoints(endpoints, true); } }
getEndpoints(Reference @ref, Reference wellKnownRef, int ttl, out bool cached) { _m.Lock(); try { if(!_response || _exception == null) { if(wellKnownRef != null) { // This request is to resolve the endpoints of a cached well-known object ref _wellKnownRefs.Add(wellKnownRef); } if(!_sent) { _sent = true; send(true); } while(!_response && _exception == null) { _m.Wait(); } } if(_exception != null) { _locatorInfo.getEndpointsException(@ref, _exception); // This throws. } Debug.Assert(_response); EndpointI[] endpoints = null; if(_proxy != null) { Reference r = ((Ice.ObjectPrxHelperBase)_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, out cached); } } cached = false; if(_ref.getInstance().traceLevels().location >= 1) { _locatorInfo.getEndpointsTrace(@ref, endpoints, false); } return endpoints == null ? new EndpointI[0] : endpoints; } finally { _m.Unlock(); } }