Index: hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestDelayedRpc.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestDelayedRpc.java (revision 1379689) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestDelayedRpc.java (working copy) @@ -326,6 +326,56 @@ } } + /** + * If {@link Delayable#endDelay()} is called before the function called by the + * RPC handler returns, do not send a response right away. + */ + @Test + public void testEndDelayBeforeReturn() throws Exception { + Configuration conf = HBaseConfiguration.create(); + InetSocketAddress isa = new InetSocketAddress("localhost", 0); + + rpcServer = HBaseRPC.getServer(new EndDelayBeforeReturnRpc(), + new Class[]{ TestRpc.class }, + isa.getHostName(), isa.getPort(), 1, 0, true, conf, 0); + rpcServer.start(); + + TestRpc client = (TestRpc) HBaseRPC.getProxy(TestRpc.class, 0, + rpcServer.getListenerAddress(), conf, 1000); + + int result = client.test(true); + assertTrue(result == DELAYED); + } + + /** + * This handler ends the delay before the actual + */ + private static class EndDelayBeforeReturnRpc implements TestRpc { + @Override + public int test(boolean delay) { + if (!delay) + return UNDELAYED; + Delayable call = rpcServer.getCurrentCall(); + call.startDelay(false); + try { + call.endDelay(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return DELAYED; + } + + @Override + public long getProtocolVersion(String arg0, long arg1) throws IOException { + return 0; + } + } + @org.junit.Rule public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); Index: hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseServer.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseServer.java (revision 1379689) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/HBaseServer.java (working copy) @@ -422,6 +422,10 @@ assert this.delayReturnValue || result == null; this.delayResponse = false; delayedCalls.decrementAndGet(); + // If delay is ended before the original call completed, we have no + // response. So do nothing. + if (!this.delayReturnValue && this.response == null) + return; if (this.delayReturnValue) this.setResponse(result, Status.SUCCESS, null, null); this.responder.doRespond(this);