|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object com.healthmarketscience.rmiio.RemoteRetry
public abstract class RemoteRetry
Utility class for automatically retrying remote method calls (which might fail for spurious reasons). Pretty much any remote method call should deal with RemoteExceptions because many transient failures (such as temporary network connection failures) can cause these exceptions, and the call may succeed when reattempted.
The major caveat for this class is the remote method call must be idempotent. This means, in essence, that repeated calls with the same arguments should generate the exact same results. An example of a non-idempotent call would be "remove $10 from my bank account". If this call were sent twice (because the first attempt seemed to fail), you could end up with $20 removed from your bank account. In order to solve this, you could add a unique sequence id to the call, "remove $10 from my bank account, seqId(5)", and the server could ignore the second call (assuming it was keeping track of the sequence ids that it had processed thus far). In other words, remote method calls are a lot harder to make than local method calls and much care should be taken when dealing with remote APIs.
Although RemoteRetry is an abstract class, there are a variety of simple implementations, as well as static instances of these implementations. See the implementations for more details.
Example usage:
// use simple retry mechanism RemoteRetry retry = RemoteRetry.SIMPLE; // since we are using anonymous inner classes, these must be final final MyRemoteObject myRemoteObject; final int myArgument; // make a call with a return value Result res = retry.call(new RemoteRetry.Caller<Result>() { public Result call() throws RemoteException, MyException { return myRemoteObject.getResult(myArgument); } }, LOG, MyException.class, RemoteException.class); // make a call with no return value (use VoidCaller) retry.call(new RemoteRetry.VoidCaller() { public void call() throws RemoteException, MyException { return myRemoteObject.setValue(myArgument); } }, LOG, MyException.class, RemoteException.class);
Note that the various call() methods use generics to create methods with custom Exception signatures in addition to the custom return types.
Nested Class Summary | |
---|---|
static class |
RemoteRetry.Always
Simple implementation of RemoteRetry which always retries RemoteExceptions thrown from the remote method call. |
static class |
RemoteRetry.Caller<RetType>
Utility type implemented by those atttempting to make remote method calls using this retry mechanism. |
static class |
RemoteRetry.Never
Simple implementation of RemoteRetry which never retries. |
static class |
RemoteRetry.Simple
Simple implementation of RemoteRetry which retries RemoteExceptions some number of times and uses the backoff strategy from simpleBackOff(int, org.apache.commons.logging.Log) . |
static class |
RemoteRetry.SimpleAlways
Simple implementation of Always retry strategy which uses the backoff strategy from simpleBackOff(int, org.apache.commons.logging.Log) . |
static class |
RemoteRetry.VoidCaller
Simple subclass of Caller for use by remote method calls which do not need to return values. |
Field Summary | |
---|---|
protected static org.apache.commons.logging.Log |
LOG
|
static RemoteRetry |
NEVER
instance of the RemoteRetry.Never retry strategy for general use. |
protected static Class<RuntimeException> |
RUNTIME_CLASS
RuntimeException class for overloading of exception types |
static RemoteRetry |
SIMPLE
instance of the RemoteRetry.Simple retry strategy for general use. |
static RemoteRetry.Always |
SIMPLE_ALWAYS
instance of the RemoteRetry.SimpleAlways retry strategy for general use. |
Constructor Summary | |
---|---|
protected |
RemoteRetry()
|
Method Summary | ||
---|---|---|
abstract void |
backOff(int numRetries,
org.apache.commons.logging.Log log)
Should delay for some implementation defined amount of time (to give the callee, network, etc. |
|
|
call(RemoteRetry.Caller<RetType> caller)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which only throws RuntimeException. |
|
|
call(RemoteRetry.Caller<RetType> caller,
Class<ExType1> throwType1)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which throws RuntimeException and one user
defined Exception. |
|
|
call(RemoteRetry.Caller<RetType> caller,
Class<ExType1> throwType1,
Class<ExType2> throwType2)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which throws RuntimeException and two user
defined Exceptions. |
|
|
call(RemoteRetry.Caller<RetType> caller,
Class<ExType1> throwType1,
Class<ExType2> throwType2,
Class<ExType3> throwType3)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which throws RuntimeException and three
user defined Exceptions. |
|
|
call(RemoteRetry.Caller<RetType> caller,
org.apache.commons.logging.Log log)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which only throws RuntimeException. |
|
|
call(RemoteRetry.Caller<RetType> caller,
org.apache.commons.logging.Log log,
Class<ExType1> throwType1)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which throws RuntimeException and one user
defined Exception. |
|
|
call(RemoteRetry.Caller<RetType> caller,
org.apache.commons.logging.Log log,
Class<ExType1> throwType1,
Class<ExType2> throwType2)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which throws RuntimeException and two user
defined Exceptions. |
|
|
call(RemoteRetry.Caller<RetType> caller,
org.apache.commons.logging.Log log,
Class<ExType1> throwType1,
Class<ExType2> throwType2,
Class<ExType3> throwType3)
Wrapper for callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller which throws RuntimeException and three
user defined Exceptions. |
|
protected
|
callImpl(RemoteRetry.Caller<RetType> caller,
org.apache.commons.logging.Log log)
Implementation of the actual retry logic. |
|
abstract boolean |
shouldRetry(Throwable t,
int numRetries)
Returns true if the caller should attempt to repeat the
current remote method call given the number of previous reattempts. |
|
protected static void |
simpleBackOff(int numRetries,
org.apache.commons.logging.Log log)
Implementation of a simple backoff strategy: First retry returns immediately Retries 1 - 30 wait that many seconds each time before returning (after 1st retry wait 1 second, after 2nd retry wait 2 seconds...) Retries > 30 wait 30 seconds each time before returning |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
protected static final org.apache.commons.logging.Log LOG
protected static final Class<RuntimeException> RUNTIME_CLASS
public static final RemoteRetry NEVER
RemoteRetry.Never
retry strategy for general use.
public static final RemoteRetry SIMPLE
RemoteRetry.Simple
retry strategy for general use.
public static final RemoteRetry.Always SIMPLE_ALWAYS
RemoteRetry.SimpleAlways
retry strategy for general use.
Constructor Detail |
---|
protected RemoteRetry()
Method Detail |
---|
protected static void simpleBackOff(int numRetries, org.apache.commons.logging.Log log)
numRetries
- number of retries which have happended thus farlog
- debug logprotected final <RetType> RetType callImpl(RemoteRetry.Caller<RetType> caller, org.apache.commons.logging.Log log) throws Throwable
true
, backoff() is called in order
to allow the other end of the connection to have a breather and then the
call() is reattempted (and the cycle repeats). Otherwise, the original
Throwable is thrown to the caller.
caller
- implementation of the actual remote method call
Throwable
public <RetType> RetType call(RemoteRetry.Caller<RetType> caller)
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which only throws RuntimeException.
public <RetType> RetType call(RemoteRetry.Caller<RetType> caller, org.apache.commons.logging.Log log)
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which only throws RuntimeException.
public <RetType,ExType1 extends Throwable> RetType call(RemoteRetry.Caller<RetType> caller, Class<ExType1> throwType1) throws ExType1 extends Throwable
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which throws RuntimeException and one user
defined Exception.
ExType1 extends Throwable
public <RetType,ExType1 extends Throwable> RetType call(RemoteRetry.Caller<RetType> caller, org.apache.commons.logging.Log log, Class<ExType1> throwType1) throws ExType1 extends Throwable
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which throws RuntimeException and one user
defined Exception.
ExType1 extends Throwable
public <RetType,ExType1 extends Throwable,ExType2 extends Throwable> RetType call(RemoteRetry.Caller<RetType> caller, Class<ExType1> throwType1, Class<ExType2> throwType2) throws ExType1 extends Throwable, ExType2 extends Throwable
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which throws RuntimeException and two user
defined Exceptions.
ExType1 extends Throwable
public <RetType,ExType1 extends Throwable,ExType2 extends Throwable> RetType call(RemoteRetry.Caller<RetType> caller, org.apache.commons.logging.Log log, Class<ExType1> throwType1, Class<ExType2> throwType2) throws ExType1 extends Throwable, ExType2 extends Throwable
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which throws RuntimeException and two user
defined Exceptions.
ExType1 extends Throwable
public <RetType,ExType1 extends Throwable,ExType2 extends Throwable,ExType3 extends Throwable> RetType call(RemoteRetry.Caller<RetType> caller, Class<ExType1> throwType1, Class<ExType2> throwType2, Class<ExType3> throwType3) throws ExType1 extends Throwable, ExType2 extends Throwable, ExType3 extends Throwable
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which throws RuntimeException and three
user defined Exceptions.
ExType1 extends Throwable
public <RetType,ExType1 extends Throwable,ExType2 extends Throwable,ExType3 extends Throwable> RetType call(RemoteRetry.Caller<RetType> caller, org.apache.commons.logging.Log log, Class<ExType1> throwType1, Class<ExType2> throwType2, Class<ExType3> throwType3) throws ExType1 extends Throwable, ExType2 extends Throwable, ExType3 extends Throwable
callImpl(com.healthmarketscience.rmiio.RemoteRetry.Caller, org.apache.commons.logging.Log)
which throws RuntimeException and three
user defined Exceptions.
ExType1 extends Throwable
public abstract boolean shouldRetry(Throwable t, int numRetries)
true
if the caller should attempt to repeat the
current remote method call given the number of previous reattempts.
t
- throwable thrownnumRetries
- number of previous reattempts
true
iff call should be repeated, true
otherwisepublic abstract void backOff(int numRetries, org.apache.commons.logging.Log log)
true
.
Good implementations should implement some sort of increased delay
based on the number of reattempts.
numRetries
- number of previous reattemptslog
- debug log
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |