HADOOP-6498. IPC client bug may cause rpc call hang. Contributed by Ruyue Ma and Hairong Kuang.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@903471 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Hairong Kuang 2010-01-26 22:55:17 +00:00
parent d6f4cf3dfe
commit 34d1b39c75
3 changed files with 44 additions and 4 deletions

View File

@ -1320,6 +1320,9 @@ Release 0.20.2 - Unreleased
HADOOP-6315. Avoid incorrect use of BuiltInflater/BuiltInDeflater in HADOOP-6315. Avoid incorrect use of BuiltInflater/BuiltInDeflater in
GzipCodec. (Aaron Kimball via cdouglas) 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 Release 0.20.1 - 2009-09-01
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -529,13 +529,14 @@ private void receiveResponse() {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug(getName() + " got value #" + id); LOG.debug(getName() + " got value #" + id);
Call call = calls.remove(id); Call call = calls.get(id);
int state = in.readInt(); // read call status int state = in.readInt(); // read call status
if (state == Status.SUCCESS.state) { if (state == Status.SUCCESS.state) {
Writable value = ReflectionUtils.newInstance(valueClass, conf); Writable value = ReflectionUtils.newInstance(valueClass, conf);
value.readFields(in); // read value value.readFields(in); // read value
call.setValue(value); call.setValue(value);
calls.remove(id);
} else if (state == Status.ERROR.state) { } else if (state == Status.ERROR.state) {
call.setException(new RemoteException(WritableUtils.readString(in), call.setException(new RemoteException(WritableUtils.readString(in),
WritableUtils.readString(in))); WritableUtils.readString(in)));

View File

@ -26,6 +26,7 @@
import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.net.NetUtils;
import java.util.Random; import java.util.Random;
import java.io.DataInput;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -88,7 +89,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); (LongWritable)client.call(param, server, null, null);
if (!param.equals(value)) { if (!param.equals(value)) {
LOG.fatal("Call failed!"); LOG.fatal("Call failed!");
failed = true; failed = true;
@ -121,7 +122,7 @@ public void run() {
Writable[] params = new Writable[addresses.length]; Writable[] params = new Writable[addresses.length];
for (int j = 0; j < addresses.length; j++) for (int j = 0; j < addresses.length; j++)
params[j] = new LongWritable(RANDOM.nextLong()); 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++) { for (int j = 0; j < addresses.length; j++) {
if (!params[j].equals(values[j])) { if (!params[j].equals(values[j])) {
LOG.fatal("Call failed!"); LOG.fatal("Call failed!");
@ -216,7 +217,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); address, null, null);
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();
@ -231,6 +232,41 @@ public void testStandAloneClient() throws Exception {
} }
} }
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 { public static void main(String[] args) throws Exception {