HADOOP-6889. Make RPC to have an option to timeout. Contributed by Hairong Kuang.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@982681 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Hairong Kuang 2010-08-05 16:39:10 +00:00
parent c47d34a866
commit 714e5f7165
7 changed files with 148 additions and 52 deletions

View File

@ -33,6 +33,8 @@ Trunk (unreleased changes)
HADOOP-6892. Common component of HDFS-1150 (Verify datanodes' identities HADOOP-6892. Common component of HDFS-1150 (Verify datanodes' identities
to clients in secure clusters) (jghoman) to clients in secure clusters) (jghoman)
HADOOP-6889. Make RPC to have an option to timeout. (hairong)
IMPROVEMENTS IMPROVEMENTS
HADOOP-6644. util.Shell getGROUPS_FOR_USER_COMMAND method name HADOOP-6644. util.Shell getGROUPS_FOR_USER_COMMAND method name
@ -105,6 +107,7 @@ Trunk (unreleased changes)
periodically. (Owen O'Malley and ddas via ddas) periodically. (Owen O'Malley and ddas via ddas)
HADOOP-6890. Improve listFiles API introduced by HADOOP-6870. (hairong) HADOOP-6890. Improve listFiles API introduced by HADOOP-6870. (hairong)
OPTIMIZATIONS OPTIMIZATIONS
BUG FIXES BUG FIXES

View File

@ -98,11 +98,13 @@ private static class ClientTransceiver extends Transceiver {
public ClientTransceiver(InetSocketAddress addr, public ClientTransceiver(InetSocketAddress addr,
UserGroupInformation ticket, UserGroupInformation ticket,
Configuration conf, SocketFactory factory) Configuration conf, SocketFactory factory,
int rpcTimeout)
throws IOException { throws IOException {
this.tunnel = this.tunnel =
(TunnelProtocol)ENGINE.getProxy(TunnelProtocol.class, VERSION, (TunnelProtocol)ENGINE.getProxy(TunnelProtocol.class, VERSION,
addr, ticket, conf, factory); addr, ticket, conf, factory,
rpcTimeout);
this.remote = addr; this.remote = addr;
} }
@ -128,14 +130,15 @@ public void close() throws IOException {
/** Construct a client-side proxy object that implements the named protocol, /** Construct a client-side proxy object that implements the named protocol,
* talking to a server at the named address. */ * talking to a server at the named address. */
public Object getProxy(Class protocol, long clientVersion, public Object getProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, UserGroupInformation ticket, InetSocketAddress addr, UserGroupInformation ticket,
Configuration conf, SocketFactory factory) Configuration conf, SocketFactory factory,
int rpcTimeout)
throws IOException { throws IOException {
return Proxy.newProxyInstance return Proxy.newProxyInstance
(protocol.getClassLoader(), (protocol.getClassLoader(),
new Class[] { protocol }, new Class[] { protocol },
new Invoker(protocol, addr, ticket, conf, factory)); new Invoker(protocol, addr, ticket, conf, factory, rpcTimeout));
} }
/** Stop this proxy. */ /** Stop this proxy. */
@ -152,8 +155,9 @@ private static class Invoker implements InvocationHandler, Closeable {
private final ReflectRequestor requestor; private final ReflectRequestor requestor;
public Invoker(Class<?> protocol, InetSocketAddress addr, public Invoker(Class<?> protocol, InetSocketAddress addr,
UserGroupInformation ticket, Configuration conf, UserGroupInformation ticket, Configuration conf,
SocketFactory factory) throws IOException { SocketFactory factory,
this.tx = new ClientTransceiver(addr, ticket, conf, factory); int rpcTimeout) throws IOException {
this.tx = new ClientTransceiver(addr, ticket, conf, factory, rpcTimeout);
this.requestor = new ReflectRequestor(protocol, tx); this.requestor = new ReflectRequestor(protocol, tx);
} }
@Override public Object invoke(Object proxy, Method method, Object[] args) @Override public Object invoke(Object proxy, Method method, Object[] args)
@ -169,7 +173,7 @@ public void close() throws IOException {
private static class TunnelResponder extends ReflectResponder private static class TunnelResponder extends ReflectResponder
implements TunnelProtocol { implements TunnelProtocol {
public TunnelResponder(Class iface, Object impl) { public TunnelResponder(Class<?> iface, Object impl) {
super(iface, impl); super(iface, impl);
} }
@ -192,7 +196,7 @@ public Object[] call(Method method, Object[][] params,
/** Construct a server for a protocol implementation instance listening on a /** Construct a server for a protocol implementation instance listening on a
* port and address. */ * port and address. */
public RPC.Server getServer(Class iface, Object impl, String bindAddress, public RPC.Server getServer(Class<?> iface, Object impl, String bindAddress,
int port, int numHandlers, boolean verbose, int port, int numHandlers, boolean verbose,
Configuration conf, Configuration conf,
SecretManager<? extends TokenIdentifier> secretManager SecretManager<? extends TokenIdentifier> secretManager

View File

@ -219,6 +219,7 @@ private class Connection extends Thread {
private Socket socket = null; // connected socket private Socket socket = null; // connected socket
private DataInputStream in; private DataInputStream in;
private DataOutputStream out; private DataOutputStream out;
private int rpcTimeout;
// currently active calls // currently active calls
private Hashtable<Integer, Call> calls = new Hashtable<Integer, Call>(); private Hashtable<Integer, Call> calls = new Hashtable<Integer, Call>();
@ -233,7 +234,7 @@ public Connection(ConnectionId remoteId) throws IOException {
throw new UnknownHostException("unknown host: " + throw new UnknownHostException("unknown host: " +
remoteId.getAddress().getHostName()); remoteId.getAddress().getHostName());
} }
this.rpcTimeout = remoteId.getRpcTimeout();
UserGroupInformation ticket = remoteId.getTicket(); UserGroupInformation ticket = remoteId.getTicket();
Class<?> protocol = remoteId.getProtocol(); Class<?> protocol = remoteId.getProtocol();
this.useSasl = UserGroupInformation.isSecurityEnabled(); this.useSasl = UserGroupInformation.isSecurityEnabled();
@ -321,11 +322,13 @@ protected PingInputStream(InputStream in) {
} }
/* Process timeout exception /* Process timeout exception
* if the connection is not going to be closed, send a ping. * if the connection is not going to be closed or
* is not configured to have a RPC timeout, send a ping.
* (if rpcTimeout is not set to be 0, then RPC should timeout.
* otherwise, throw the timeout exception. * otherwise, throw the timeout exception.
*/ */
private void handleTimeout(SocketTimeoutException e) throws IOException { private void handleTimeout(SocketTimeoutException e) throws IOException {
if (shouldCloseConnection.get() || !running.get()) { if (shouldCloseConnection.get() || !running.get() || rpcTimeout > 0) {
throw e; throw e;
} else { } else {
sendPing(); sendPing();
@ -405,6 +408,9 @@ private synchronized void setupConnection() throws IOException {
this.socket.setTcpNoDelay(tcpNoDelay); this.socket.setTcpNoDelay(tcpNoDelay);
// connection time out is 20s // connection time out is 20s
NetUtils.connect(this.socket, remoteId.getAddress(), 20000); NetUtils.connect(this.socket, remoteId.getAddress(), 20000);
if (rpcTimeout > 0) {
pingInterval = rpcTimeout; // rpcTimeout overwrites pingInterval
}
this.socket.setSoTimeout(pingInterval); this.socket.setSoTimeout(pingInterval);
return; return;
} catch (SocketTimeoutException toe) { } catch (SocketTimeoutException toe) {
@ -952,7 +958,7 @@ public Writable call(Writable param, InetSocketAddress address)
public Writable call(Writable param, InetSocketAddress addr, public Writable call(Writable param, InetSocketAddress addr,
UserGroupInformation ticket) UserGroupInformation ticket)
throws InterruptedException, IOException { throws InterruptedException, IOException {
return call(param, addr, null, ticket); return call(param, addr, null, ticket, 0);
} }
/** Make a call, passing <code>param</code>, to the IPC server running at /** Make a call, passing <code>param</code>, to the IPC server running at
@ -961,10 +967,12 @@ public Writable call(Writable param, InetSocketAddress addr,
* Throws exceptions if there are network problems or if the remote code * Throws exceptions if there are network problems or if the remote code
* threw an exception. */ * threw an exception. */
public Writable call(Writable param, InetSocketAddress addr, public Writable call(Writable param, InetSocketAddress addr,
Class<?> protocol, UserGroupInformation ticket) Class<?> protocol, UserGroupInformation ticket,
int rpcTimeout)
throws InterruptedException, IOException { throws InterruptedException, IOException {
Call call = new Call(param); Call call = new Call(param);
Connection connection = getConnection(addr, protocol, ticket, call); Connection connection = getConnection(
addr, protocol, ticket, rpcTimeout, call);
connection.sendParam(call); // send the parameter connection.sendParam(call); // send the parameter
boolean interrupted = false; boolean interrupted = false;
synchronized (call) { synchronized (call) {
@ -1054,7 +1062,7 @@ public Writable[] call(Writable[] params, InetSocketAddress[] addresses,
ParallelCall call = new ParallelCall(params[i], results, i); ParallelCall call = new ParallelCall(params[i], results, i);
try { try {
Connection connection = Connection connection =
getConnection(addresses[i], protocol, ticket, call); getConnection(addresses[i], protocol, ticket, 0, call);
connection.sendParam(call); // send each parameter connection.sendParam(call); // send each parameter
} catch (IOException e) { } catch (IOException e) {
// log errors // log errors
@ -1078,6 +1086,7 @@ public Writable[] call(Writable[] params, InetSocketAddress[] addresses,
private Connection getConnection(InetSocketAddress addr, private Connection getConnection(InetSocketAddress addr,
Class<?> protocol, Class<?> protocol,
UserGroupInformation ticket, UserGroupInformation ticket,
int rpcTimeout,
Call call) Call call)
throws IOException, InterruptedException { throws IOException, InterruptedException {
if (!running.get()) { if (!running.get()) {
@ -1089,7 +1098,8 @@ private Connection getConnection(InetSocketAddress addr,
* connectionsId object and with set() method. We need to manage the * connectionsId object and with set() method. We need to manage the
* refs for keys in HashMap properly. For now its ok. * refs for keys in HashMap properly. For now its ok.
*/ */
ConnectionId remoteId = new ConnectionId(addr, protocol, ticket); ConnectionId remoteId = new ConnectionId(
addr, protocol, ticket, rpcTimeout);
do { do {
synchronized (connections) { synchronized (connections) {
connection = connections.get(remoteId); connection = connections.get(remoteId);
@ -1117,12 +1127,14 @@ private static class ConnectionId {
UserGroupInformation ticket; UserGroupInformation ticket;
Class<?> protocol; Class<?> protocol;
private static final int PRIME = 16777619; private static final int PRIME = 16777619;
private int rpcTimeout;
ConnectionId(InetSocketAddress address, Class<?> protocol, ConnectionId(InetSocketAddress address, Class<?> protocol,
UserGroupInformation ticket) { UserGroupInformation ticket, int rpcTimeout) {
this.protocol = protocol; this.protocol = protocol;
this.address = address; this.address = address;
this.ticket = ticket; this.ticket = ticket;
this.rpcTimeout = rpcTimeout;
} }
InetSocketAddress getAddress() { InetSocketAddress getAddress() {
@ -1137,6 +1149,9 @@ UserGroupInformation getTicket() {
return ticket; return ticket;
} }
private int getRpcTimeout() {
return rpcTimeout;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
@ -1144,15 +1159,19 @@ public boolean equals(Object obj) {
ConnectionId id = (ConnectionId) obj; ConnectionId id = (ConnectionId) obj;
return address.equals(id.address) && protocol == id.protocol && return address.equals(id.address) && protocol == id.protocol &&
((ticket != null && ticket.equals(id.ticket)) || ((ticket != null && ticket.equals(id.ticket)) ||
(ticket == id.ticket)); (ticket == id.ticket)) && rpcTimeout == id.rpcTimeout;
} }
return false; return false;
} }
@Override @Override // simply use the default Object#hashcode() ?
public int hashCode() { public int hashCode() {
return (address.hashCode() + PRIME * System.identityHashCode(protocol)) ^ return (address.hashCode() + PRIME * (
(ticket == null ? 0 : ticket.hashCode()); PRIME * (
PRIME * System.identityHashCode(protocol) ^
System.identityHashCode(ticket)
) ^ System.identityHashCode(rpcTimeout)
));
} }
} }
} }

View File

@ -156,7 +156,7 @@ public long getServerVersion() {
} }
public static Object waitForProxy( public static Object waitForProxy(
Class protocol, Class<?> protocol,
long clientVersion, long clientVersion,
InetSocketAddress addr, InetSocketAddress addr,
Configuration conf Configuration conf
@ -170,18 +170,37 @@ public static Object waitForProxy(
* @param clientVersion client version * @param clientVersion client version
* @param addr remote address * @param addr remote address
* @param conf configuration to use * @param conf configuration to use
* @param connTimeout time in milliseconds before giving up
* @return the proxy
* @throws IOException if the far end through a RemoteException
*/
public static Object waitForProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, Configuration conf,
long connTimeout) throws IOException {
return waitForProxy(protocol, clientVersion, addr, conf, 0, connTimeout);
}
/**
* Get a proxy connection to a remote server
* @param protocol protocol class
* @param clientVersion client version
* @param addr remote address
* @param conf configuration to use
* @param rpcTimeout timeout for each RPC
* @param timeout time in milliseconds before giving up * @param timeout time in milliseconds before giving up
* @return the proxy * @return the proxy
* @throws IOException if the far end through a RemoteException * @throws IOException if the far end through a RemoteException
*/ */
public static Object waitForProxy(Class protocol, long clientVersion, public static Object waitForProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, Configuration conf, InetSocketAddress addr, Configuration conf,
int rpcTimeout,
long timeout) throws IOException { long timeout) throws IOException {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
IOException ioe; IOException ioe;
while (true) { while (true) {
try { try {
return getProxy(protocol, clientVersion, addr, conf); return getProxy(protocol, clientVersion, addr,
UserGroupInformation.getCurrentUser(), conf, NetUtils
.getDefaultSocketFactory(conf), rpcTimeout);
} catch(ConnectException se) { // namenode has not been started } catch(ConnectException se) { // namenode has not been started
LOG.info("Server at " + addr + " not available yet, Zzzzz..."); LOG.info("Server at " + addr + " not available yet, Zzzzz...");
ioe = se; ioe = se;
@ -208,7 +227,7 @@ public static Object waitForProxy(Class protocol, long clientVersion,
/** Construct a client-side proxy object that implements the named protocol, /** Construct a client-side proxy object that implements the named protocol,
* talking to a server at the named address. */ * talking to a server at the named address. */
public static Object getProxy(Class protocol, long clientVersion, public static Object getProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, Configuration conf, InetSocketAddress addr, Configuration conf,
SocketFactory factory) throws IOException { SocketFactory factory) throws IOException {
UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
@ -217,16 +236,39 @@ public static Object getProxy(Class protocol, long clientVersion,
/** Construct a client-side proxy object that implements the named protocol, /** Construct a client-side proxy object that implements the named protocol,
* talking to a server at the named address. */ * talking to a server at the named address. */
public static Object getProxy(Class protocol, long clientVersion, public static Object getProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, InetSocketAddress addr,
UserGroupInformation ticket, UserGroupInformation ticket,
Configuration conf, Configuration conf,
SocketFactory factory) throws IOException { SocketFactory factory) throws IOException {
return getProxy(protocol, clientVersion, addr, ticket, conf, factory, 0);
}
/**
* Construct a client-side proxy that implements the named protocol,
* talking to a server at the named address.
*
* @param protocol protocol
* @param clientVersion client's version
* @param addr server address
* @param ticket security ticket
* @param conf configuration
* @param factory socket factory
* @param rpcTimeout max time for each rpc; 0 means no timeout
* @return the proxy
* @throws IOException if any error occurs
*/
public static Object getProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr,
UserGroupInformation ticket,
Configuration conf,
SocketFactory factory,
int rpcTimeout) throws IOException {
if (UserGroupInformation.isSecurityEnabled()) { if (UserGroupInformation.isSecurityEnabled()) {
SaslRpcServer.init(conf); SaslRpcServer.init(conf);
} }
return getProtocolEngine(protocol,conf) return getProtocolEngine(protocol,conf).getProxy(protocol,
.getProxy(protocol, clientVersion, addr, ticket, conf, factory); clientVersion, addr, ticket, conf, factory, rpcTimeout);
} }
/** /**
@ -239,7 +281,7 @@ public static Object getProxy(Class protocol, long clientVersion,
* @return a proxy instance * @return a proxy instance
* @throws IOException * @throws IOException
*/ */
public static Object getProxy(Class protocol, long clientVersion, public static Object getProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, Configuration conf) InetSocketAddress addr, Configuration conf)
throws IOException { throws IOException {

View File

@ -32,10 +32,10 @@
interface RpcEngine { interface RpcEngine {
/** Construct a client-side proxy object. */ /** Construct a client-side proxy object. */
Object getProxy(Class protocol, Object getProxy(Class<?> protocol,
long clientVersion, InetSocketAddress addr, long clientVersion, InetSocketAddress addr,
UserGroupInformation ticket, Configuration conf, UserGroupInformation ticket, Configuration conf,
SocketFactory factory) throws IOException; SocketFactory factory, int rpcTimeout) throws IOException;
/** Stop this proxy. */ /** Stop this proxy. */
void stopProxy(Object proxy); void stopProxy(Object proxy);
@ -46,7 +46,7 @@ Object[] call(Method method, Object[][] params, InetSocketAddress[] addrs,
throws IOException, InterruptedException; throws IOException, InterruptedException;
/** Construct a server for a protocol implementation instance. */ /** Construct a server for a protocol implementation instance. */
RPC.Server getServer(Class protocol, Object instance, String bindAddress, RPC.Server getServer(Class<?> protocol, Object instance, String bindAddress,
int port, int numHandlers, boolean verbose, int port, int numHandlers, boolean verbose,
Configuration conf, Configuration conf,
SecretManager<? extends TokenIdentifier> secretManager SecretManager<? extends TokenIdentifier> secretManager

View File

@ -48,7 +48,7 @@ class WritableRpcEngine implements RpcEngine {
/** A method invocation, including the method name and its parameters.*/ /** A method invocation, including the method name and its parameters.*/
private static class Invocation implements Writable, Configurable { private static class Invocation implements Writable, Configurable {
private String methodName; private String methodName;
private Class[] parameterClasses; private Class<?>[] parameterClasses;
private Object[] parameters; private Object[] parameters;
private Configuration conf; private Configuration conf;
@ -64,7 +64,7 @@ public Invocation(Method method, Object[] parameters) {
public String getMethodName() { return methodName; } public String getMethodName() { return methodName; }
/** The parameter classes. */ /** The parameter classes. */
public Class[] getParameterClasses() { return parameterClasses; } public Class<?>[] getParameterClasses() { return parameterClasses; }
/** The parameter instances. */ /** The parameter instances. */
public Object[] getParameters() { return parameters; } public Object[] getParameters() { return parameters; }
@ -172,18 +172,21 @@ private void stopClient(Client client) {
private static ClientCache CLIENTS=new ClientCache(); private static ClientCache CLIENTS=new ClientCache();
private static class Invoker implements InvocationHandler { private static class Invoker implements InvocationHandler {
private Class protocol; private Class<?> protocol;
private InetSocketAddress address; private InetSocketAddress address;
private UserGroupInformation ticket; private UserGroupInformation ticket;
private int rpcTimeout;
private Client client; private Client client;
private boolean isClosed = false; private boolean isClosed = false;
public Invoker(Class protocol, public Invoker(Class<?> protocol,
InetSocketAddress address, UserGroupInformation ticket, InetSocketAddress address, UserGroupInformation ticket,
Configuration conf, SocketFactory factory) { Configuration conf, SocketFactory factory,
int rpcTimeout) {
this.protocol = protocol; this.protocol = protocol;
this.address = address; this.address = address;
this.ticket = ticket; this.ticket = ticket;
this.rpcTimeout = rpcTimeout;
this.client = CLIENTS.getClient(conf, factory); this.client = CLIENTS.getClient(conf, factory);
} }
@ -197,7 +200,7 @@ public Object invoke(Object proxy, Method method, Object[] args)
ObjectWritable value = (ObjectWritable) ObjectWritable value = (ObjectWritable)
client.call(new Invocation(method, args), address, client.call(new Invocation(method, args), address,
protocol, ticket); protocol, ticket, rpcTimeout);
if (logDebug) { if (logDebug) {
long callTime = System.currentTimeMillis() - startTime; long callTime = System.currentTimeMillis() - startTime;
LOG.debug("Call: " + method.getName() + " " + callTime); LOG.debug("Call: " + method.getName() + " " + callTime);
@ -216,14 +219,15 @@ synchronized private void close() {
/** Construct a client-side proxy object that implements the named protocol, /** Construct a client-side proxy object that implements the named protocol,
* talking to a server at the named address. */ * talking to a server at the named address. */
public Object getProxy(Class protocol, long clientVersion, public Object getProxy(Class<?> protocol, long clientVersion,
InetSocketAddress addr, UserGroupInformation ticket, InetSocketAddress addr, UserGroupInformation ticket,
Configuration conf, SocketFactory factory) Configuration conf, SocketFactory factory,
int rpcTimeout)
throws IOException { throws IOException {
Object proxy = Proxy.newProxyInstance Object proxy = Proxy.newProxyInstance
(protocol.getClassLoader(), new Class[] { protocol }, (protocol.getClassLoader(), new Class[] { protocol },
new Invoker(protocol, addr, ticket, conf, factory)); new Invoker(protocol, addr, ticket, conf, factory, rpcTimeout));
if (proxy instanceof VersionedProtocol) { if (proxy instanceof VersionedProtocol) {
long serverVersion = ((VersionedProtocol)proxy) long serverVersion = ((VersionedProtocol)proxy)
.getProtocolVersion(protocol.getName(), clientVersion); .getProtocolVersion(protocol.getName(), clientVersion);
@ -276,7 +280,7 @@ public Object[] call(Method method, Object[][] params,
/** Construct a server for a protocol implementation instance listening on a /** Construct a server for a protocol implementation instance listening on a
* port and address. */ * port and address. */
public Server getServer(Class protocol, public Server getServer(Class<?> protocol,
Object instance, String bindAddress, int port, Object instance, String bindAddress, int port,
int numHandlers, boolean verbose, Configuration conf, int numHandlers, boolean verbose, Configuration conf,
SecretManager<? extends TokenIdentifier> secretManager) SecretManager<? extends TokenIdentifier> secretManager)

View File

@ -29,6 +29,7 @@
import java.io.DataInput; import java.io.DataInput;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -43,6 +44,7 @@ public class TestIPC extends TestCase {
final private static Configuration conf = new Configuration(); final private static Configuration conf = new Configuration();
final static private int PING_INTERVAL = 1000; final static private int PING_INTERVAL = 1000;
final static private int MIN_SLEEP_TIME = 1000;
static { static {
Client.setPingInterval(conf, PING_INTERVAL); Client.setPingInterval(conf, PING_INTERVAL);
@ -66,8 +68,9 @@ public TestServer(int handlerCount, boolean sleep)
public Writable call(Class<?> protocol, Writable param, long receiveTime) public Writable call(Class<?> protocol, Writable param, long receiveTime)
throws IOException { throws IOException {
if (sleep) { if (sleep) {
// sleep a bit
try { try {
Thread.sleep(RANDOM.nextInt(2*PING_INTERVAL)); // sleep a bit Thread.sleep(RANDOM.nextInt(PING_INTERVAL) + MIN_SLEEP_TIME);
} catch (InterruptedException e) {} } catch (InterruptedException e) {}
} }
return param; // echo param as result return param; // echo param as result
@ -91,7 +94,7 @@ public void run() {
try { try {
LongWritable param = new LongWritable(RANDOM.nextLong()); LongWritable param = new LongWritable(RANDOM.nextLong());
LongWritable value = LongWritable value =
(LongWritable)client.call(param, server, null, null); (LongWritable)client.call(param, server, null, null, 0);
if (!param.equals(value)) { if (!param.equals(value)) {
LOG.fatal("Call failed!"); LOG.fatal("Call failed!");
failed = true; failed = true;
@ -142,6 +145,7 @@ public void run() {
public void testSerial() throws Exception { public void testSerial() throws Exception {
testSerial(3, false, 2, 5, 100); testSerial(3, false, 2, 5, 100);
testSerial(3, true, 2, 5, 10);
} }
public void testSerial(int handlerCount, boolean handlerSleep, public void testSerial(int handlerCount, boolean handlerSleep,
@ -219,7 +223,7 @@ public void testStandAloneClient() throws Exception {
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10); InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10);
try { try {
client.call(new LongWritable(RANDOM.nextLong()), client.call(new LongWritable(RANDOM.nextLong()),
address, null, null); address, null, null, 0);
fail("Expected an exception to have been thrown"); fail("Expected an exception to have been thrown");
} catch (IOException e) { } catch (IOException e) {
String message = e.getMessage(); String message = e.getMessage();
@ -276,7 +280,7 @@ public void testErrorClient() throws Exception {
Client client = new Client(LongErrorWritable.class, conf); Client client = new Client(LongErrorWritable.class, conf);
try { try {
client.call(new LongErrorWritable(RANDOM.nextLong()), client.call(new LongErrorWritable(RANDOM.nextLong()),
addr, null, null); addr, null, null, 0);
fail("Expected an exception to have been thrown"); fail("Expected an exception to have been thrown");
} catch (IOException e) { } catch (IOException e) {
// check error // check error
@ -296,7 +300,7 @@ public void testRuntimeExceptionWritable() throws Exception {
Client client = new Client(LongRTEWritable.class, conf); Client client = new Client(LongRTEWritable.class, conf);
try { try {
client.call(new LongRTEWritable(RANDOM.nextLong()), client.call(new LongRTEWritable(RANDOM.nextLong()),
addr, null, null); addr, null, null, 0);
fail("Expected an exception to have been thrown"); fail("Expected an exception to have been thrown");
} catch (IOException e) { } catch (IOException e) {
// check error // check error
@ -322,13 +326,33 @@ public void testSocketFactoryException() throws Exception {
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10); InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10);
try { try {
client.call(new LongWritable(RANDOM.nextLong()), client.call(new LongWritable(RANDOM.nextLong()),
address, null, null); address, null, null, 0);
fail("Expected an exception to have been thrown"); fail("Expected an exception to have been thrown");
} catch (IOException e) { } catch (IOException e) {
assertTrue(e.getMessage().contains("Injected fault")); assertTrue(e.getMessage().contains("Injected fault"));
} }
} }
public void testIpcTimeout() throws Exception {
// start server
Server server = new TestServer(1, true);
InetSocketAddress addr = NetUtils.getConnectAddress(server);
server.start();
// start client
Client client = new Client(LongWritable.class, conf);
// set timeout to be less than MIN_SLEEP_TIME
try {
client.call(new LongWritable(RANDOM.nextLong()),
addr, null, null, MIN_SLEEP_TIME/2);
fail("Expected an exception to have been thrown");
} catch (SocketTimeoutException e) {
LOG.info("Get a SocketTimeoutException ", e);
}
// set timeout to be bigger than 3*ping interval
client.call(new LongWritable(RANDOM.nextLong()),
addr, null, null, 3*PING_INTERVAL+MIN_SLEEP_TIME);
}
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {