|
@@ -17,13 +17,65 @@
|
|
|
*/
|
|
|
package org.apache.hadoop.oncrpc;
|
|
|
|
|
|
-/**
|
|
|
- * The XID in RPC call. It is used for starting with new seed after each reboot.
|
|
|
- */
|
|
|
+import org.apache.commons.logging.Log;
|
|
|
+import org.apache.commons.logging.LogFactory;
|
|
|
+import org.jboss.netty.buffer.ChannelBuffer;
|
|
|
+import org.jboss.netty.buffer.ChannelBuffers;
|
|
|
+import org.jboss.netty.channel.Channel;
|
|
|
+import org.jboss.netty.channel.ChannelHandlerContext;
|
|
|
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
|
|
|
+
|
|
|
public class RpcUtil {
|
|
|
+ /**
|
|
|
+ * The XID in RPC call. It is used for starting with new seed after each reboot.
|
|
|
+ */
|
|
|
private static int xid = (int) (System.currentTimeMillis() / 1000) << 12;
|
|
|
|
|
|
public static int getNewXid(String caller) {
|
|
|
return xid = ++xid + caller.hashCode();
|
|
|
}
|
|
|
+
|
|
|
+ public static FrameDecoder constructRpcFrameDecoder() {
|
|
|
+ return new RpcFrameDecoder();
|
|
|
+ }
|
|
|
+
|
|
|
+ static class RpcFrameDecoder extends FrameDecoder {
|
|
|
+ public static final Log LOG = LogFactory.getLog(RpcFrameDecoder.class);
|
|
|
+ private ChannelBuffer currentFrame;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected Object decode(ChannelHandlerContext ctx, Channel channel,
|
|
|
+ ChannelBuffer buf) {
|
|
|
+
|
|
|
+ if (buf.readableBytes() < 4)
|
|
|
+ return null;
|
|
|
+
|
|
|
+ buf.markReaderIndex();
|
|
|
+
|
|
|
+ byte[] fragmentHeader = new byte[4];
|
|
|
+ buf.readBytes(fragmentHeader);
|
|
|
+ int length = XDR.fragmentSize(fragmentHeader);
|
|
|
+ boolean isLast = XDR.isLastFragment(fragmentHeader);
|
|
|
+
|
|
|
+ if (buf.readableBytes() < length) {
|
|
|
+ buf.resetReaderIndex();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ ChannelBuffer newFragment = buf.readSlice(length);
|
|
|
+ if (currentFrame == null) {
|
|
|
+ currentFrame = newFragment;
|
|
|
+ } else {
|
|
|
+ currentFrame = ChannelBuffers.wrappedBuffer(currentFrame, newFragment);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isLast) {
|
|
|
+ ChannelBuffer completeFrame = currentFrame;
|
|
|
+ currentFrame = null;
|
|
|
+ return completeFrame;
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|