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); }
public int checkRetryAfterException(Ice.LocalException ex, Reference @ref, ref int cnt) { TraceLevels traceLevels = _instance.traceLevels(); Ice.Logger logger = _instance.initializationData().logger; if (@ref.getMode() == Reference.Mode.ModeBatchOneway || @ref.getMode() == Reference.Mode.ModeBatchDatagram) { Debug.Assert(false); // batch no longer implemented anyway 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. // if (ex is Ice.MarshalException) { throw ex; } // // Don't retry if the communicator is destroyed, object adapter is deactivated, // or connection is manually closed. // if (ex is Ice.CommunicatorDestroyedException || ex is Ice.ObjectAdapterDeactivatedException || ex is Ice.ConnectionManuallyClosedException) { throw ex; } // // Don't retry invocation timeouts. // if (ex is Ice.InvocationTimeoutException || ex is Ice.InvocationCanceledException) { 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); } return(interval); }