Author: hairong Date: Tue Jan 26 22:55:17 2010 New Revision: 903471 URL: http://svn.apache.org/viewvc?rev=903471&view=rev Log: HADOOP-6498. IPC client bug may cause rpc call hang. Contributed by Ruyue Ma and Hairong Kuang.
Modified: hadoop/common/trunk/CHANGES.txt hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java hadoop/common/trunk/src/test/core/org/apache/hadoop/ipc/TestIPC.java Modified: hadoop/common/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/hadoop/common/trunk/CHANGES.txt?rev=903471&r1=903470&r2=903471&view=diff ============================================================================== --- hadoop/common/trunk/CHANGES.txt (original) +++ hadoop/common/trunk/CHANGES.txt Tue Jan 26 22:55:17 2010 @@ -1320,6 +1320,9 @@ HADOOP-6315. Avoid incorrect use of BuiltInflater/BuiltInDeflater in GzipCodec. (Aaron Kimball via cdouglas) + HADOOP-6498. IPC client bug may cause rpc call hang. (Ruyue Ma and + hairong via hairong) + Release 0.20.1 - 2009-09-01 INCOMPATIBLE CHANGES Modified: hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java?rev=903471&r1=903470&r2=903471&view=diff ============================================================================== --- hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java (original) +++ hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java Tue Jan 26 22:55:17 2010 @@ -529,13 +529,14 @@ if (LOG.isDebugEnabled()) LOG.debug(getName() + " got value #" + id); - Call call = calls.remove(id); + Call call = calls.get(id); int state = in.readInt(); // read call status if (state == Status.SUCCESS.state) { Writable value = ReflectionUtils.newInstance(valueClass, conf); value.readFields(in); // read value call.setValue(value); + calls.remove(id); } else if (state == Status.ERROR.state) { call.setException(new RemoteException(WritableUtils.readString(in), WritableUtils.readString(in))); Modified: hadoop/common/trunk/src/test/core/org/apache/hadoop/ipc/TestIPC.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/test/core/org/apache/hadoop/ipc/TestIPC.java?rev=903471&r1=903470&r2=903471&view=diff ============================================================================== --- hadoop/common/trunk/src/test/core/org/apache/hadoop/ipc/TestIPC.java (original) +++ hadoop/common/trunk/src/test/core/org/apache/hadoop/ipc/TestIPC.java Tue Jan 26 22:55:17 2010 @@ -26,6 +26,7 @@ import org.apache.hadoop.net.NetUtils; import java.util.Random; +import java.io.DataInput; import java.io.IOException; import java.net.InetSocketAddress; @@ -88,7 +89,7 @@ try { LongWritable param = new LongWritable(RANDOM.nextLong()); LongWritable value = - (LongWritable)client.call(param, server); + (LongWritable)client.call(param, server, null, null); if (!param.equals(value)) { LOG.fatal("Call failed!"); failed = true; @@ -121,7 +122,7 @@ Writable[] params = new Writable[addresses.length]; for (int j = 0; j < addresses.length; j++) params[j] = new LongWritable(RANDOM.nextLong()); - Writable[] values = client.call(params, addresses); + Writable[] values = client.call(params, addresses, null, null); for (int j = 0; j < addresses.length; j++) { if (!params[j].equals(values[j])) { LOG.fatal("Call failed!"); @@ -216,7 +217,7 @@ InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10); try { client.call(new LongWritable(RANDOM.nextLong()), - address); + address, null, null); fail("Expected an exception to have been thrown"); } catch (IOException e) { String message = e.getMessage(); @@ -231,6 +232,41 @@ } } + private static class LongErrorWritable extends LongWritable { + private final static String ERR_MSG = + "Come across an exception while reading"; + + LongErrorWritable() {} + + LongErrorWritable(long longValue) { + super(longValue); + } + + public void readFields(DataInput in) throws IOException { + super.readFields(in); + throw new IOException(ERR_MSG); + } + } + public void testErrorClient() throws Exception { + // start server + Server server = new TestServer(1, false); + InetSocketAddress addr = NetUtils.getConnectAddress(server); + server.start(); + + // start client + Client client = new Client(LongErrorWritable.class, conf); + try { + client.call(new LongErrorWritable(RANDOM.nextLong()), + addr, null, null); + fail("Expected an exception to have been thrown"); + } catch (IOException e) { + // check error + Throwable cause = e.getCause(); + assertTrue(cause instanceof IOException); + assertEquals(LongErrorWritable.ERR_MSG, cause.getMessage()); + } + } + public static void main(String[] args) throws Exception {