HADOOP-9786. RetryInvocationHandler#isRpcInvocation should support ProtocolTranslator. Contributed by Suresh Srinivas and Jing Zhao.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1508304 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3ca892dc0a
commit
f451228250
@ -500,6 +500,9 @@ Release 2.1.0-beta - 2013-07-02
|
||||
|
||||
HADOOP-9770. Make RetryCache#state non volatile. (suresh)
|
||||
|
||||
HADOOP-9786. RetryInvocationHandler#isRpcInvocation should support
|
||||
ProtocolTranslator. (suresh and jing9)
|
||||
|
||||
OPTIMIZATIONS
|
||||
|
||||
HADOOP-9150. Avoid unnecessary DNS resolution attempts for logical URIs
|
||||
|
@ -30,12 +30,13 @@
|
||||
import org.apache.hadoop.io.retry.RetryPolicy.RetryAction;
|
||||
import org.apache.hadoop.ipc.Client;
|
||||
import org.apache.hadoop.ipc.Client.ConnectionId;
|
||||
import org.apache.hadoop.ipc.ProtocolTranslator;
|
||||
import org.apache.hadoop.ipc.RPC;
|
||||
import org.apache.hadoop.ipc.RpcConstants;
|
||||
import org.apache.hadoop.ipc.RpcInvocationHandler;
|
||||
import org.apache.hadoop.util.ThreadUtil;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
class RetryInvocationHandler implements RpcInvocationHandler {
|
||||
public static final Log LOG = LogFactory.getLog(RetryInvocationHandler.class);
|
||||
@ -75,7 +76,7 @@ public Object invoke(Object proxy, Method method, Object[] args)
|
||||
|
||||
// The number of times this method invocation has been failed over.
|
||||
int invocationFailoverCount = 0;
|
||||
final boolean isRpc = isRpcInvocation();
|
||||
final boolean isRpc = isRpcInvocation(currentProxy);
|
||||
final int callId = isRpc? Client.nextCallId(): RpcConstants.INVALID_CALL_ID;
|
||||
int retries = 0;
|
||||
while (true) {
|
||||
@ -178,11 +179,15 @@ private Object invokeMethod(Method method, Object[] args) throws Throwable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRpcInvocation() {
|
||||
if (!Proxy.isProxyClass(currentProxy.getClass())) {
|
||||
@VisibleForTesting
|
||||
static boolean isRpcInvocation(Object proxy) {
|
||||
if (proxy instanceof ProtocolTranslator) {
|
||||
proxy = ((ProtocolTranslator) proxy).getUnderlyingProxyObject();
|
||||
}
|
||||
if (!Proxy.isProxyClass(proxy.getClass())) {
|
||||
return false;
|
||||
}
|
||||
final InvocationHandler ih = Proxy.getInvocationHandler(currentProxy);
|
||||
final InvocationHandler ih = Proxy.getInvocationHandler(proxy);
|
||||
return ih instanceof RpcInvocationHandler;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
import org.apache.hadoop.io.retry.UnreliableInterface.FatalException;
|
||||
import org.apache.hadoop.io.retry.UnreliableInterface.UnreliableException;
|
||||
import org.apache.hadoop.ipc.ProtocolTranslator;
|
||||
import org.apache.hadoop.ipc.RemoteException;
|
||||
|
||||
public class TestRetryProxy extends TestCase {
|
||||
@ -58,6 +59,38 @@ public void testTryOnceThenFail() throws UnreliableException {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for {@link RetryInvocationHandler#isRpcInvocation(Object)}
|
||||
*/
|
||||
public void testRpcInvocation() throws Exception {
|
||||
// For a proxy method should return true
|
||||
final UnreliableInterface unreliable = (UnreliableInterface)
|
||||
RetryProxy.create(UnreliableInterface.class, unreliableImpl, RETRY_FOREVER);
|
||||
assertTrue(RetryInvocationHandler.isRpcInvocation(unreliable));
|
||||
|
||||
// Embed the proxy in ProtocolTranslator
|
||||
ProtocolTranslator xlator = new ProtocolTranslator() {
|
||||
int count = 0;
|
||||
@Override
|
||||
public Object getUnderlyingProxyObject() {
|
||||
count++;
|
||||
return unreliable;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + count;
|
||||
}
|
||||
};
|
||||
|
||||
// For a proxy wrapped in ProtocolTranslator method should return true
|
||||
assertTrue(RetryInvocationHandler.isRpcInvocation(xlator));
|
||||
// Ensure underlying proxy was looked at
|
||||
assertEquals(xlator.toString(), "1");
|
||||
|
||||
// For non-proxy the method must return false
|
||||
assertFalse(RetryInvocationHandler.isRpcInvocation(new Object()));
|
||||
}
|
||||
|
||||
public void testRetryForever() throws UnreliableException {
|
||||
UnreliableInterface unreliable = (UnreliableInterface)
|
||||
RetryProxy.create(UnreliableInterface.class, unreliableImpl, RETRY_FOREVER);
|
||||
@ -138,7 +171,7 @@ public void testRetryByException() throws UnreliableException {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRetryByRemoteException() throws UnreliableException {
|
||||
public void testRetryByRemoteException() {
|
||||
Map<Class<? extends Exception>, RetryPolicy> exceptionToPolicyMap =
|
||||
Collections.<Class<? extends Exception>, RetryPolicy>singletonMap(FatalException.class, TRY_ONCE_THEN_FAIL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user