public ConnectionRequestHandler(Reference @ref, Ice.ObjectPrx proxy) { _reference = @ref; _response = _reference.getMode() == Reference.Mode.ModeTwoway; _connection = _reference.getConnection(out _compress); // // If this proxy is for a non-local object, and we are using a router, then // add this proxy to the router info object. // IceInternal.RouterInfo ri = _reference.getRouterInfo(); if(ri != null) { ri.addProxy(proxy); } }
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; }