com.tencent.angel.ipc.NettyTransportCodec Maven / Gradle / Ivy
The newest version!
/*
* Tencent is pleased to support the open source community by making Angel available.
*
* Copyright (C) 2017-2018 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/Apache-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*
*/
package com.tencent.angel.ipc;
import com.google.common.base.Objects;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.MessageToMessageEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* Data structure, encoder and decoder classes for the Netty transport.
*/
public class NettyTransportCodec {
private static final Logger LOG = LoggerFactory.getLogger(NettyTransportCodec.class.getName());
/**
* Transport protocol data structure when using Netty.
*/
public static class NettyDataPack {
private int serial; // to track each call in client side
private List datas;
public NettyDataPack() {
}
public NettyDataPack(int serial, List datas) {
this.serial = serial;
this.datas = datas;
}
public void setSerial(int serial) {
this.serial = serial;
}
public int getSerial() {
return serial;
}
public void setDatas(List datas) {
this.datas = datas;
}
public List getDatas() {
return datas;
}
@Override public String toString() {
// return Objects.toStringHelper(this).add("serial", serial).add("listSize", datas.size())
// .toString();
return "";
}
/**
* Writes a NettyDataPack, reconnecting to the remote peer if necessary.
* NOTE: The stateLock read lock *must* be acquired before calling this method.
*
* @param dataPack the data pack to write.
* @throws java.io.IOException if an error occurs connecting to the remote peer.
*/
public static void writeDataPack(Channel channel, NettyDataPack dataPack) throws IOException {
channel.writeAndFlush(dataPack).addListener(future -> {
if (future.isSuccess()) {
LOG.trace("Sent result {} to client {}", dataPack, NettyUtils.getRemoteAddress(channel));
} else {
String msg = String.format("Error sending result %s to %s; closing connection", dataPack,
NettyUtils.getRemoteAddress(channel));
LOG.error(msg, future.cause());
throw new IOException(msg, future.cause());
}
});
}
}
/**
* Protocol encoder which converts NettyDataPack which contains the Responder's output
* List<ByteBuffer> to ChannelBuffer needed by Netty.
*/
@ChannelHandler.Sharable public static class NettyFrameEncoder
extends MessageToMessageEncoder {
public static final NettyFrameEncoder INSTANCE = new NettyFrameEncoder();
/**
* encode msg to ChannelBuffer
*
* @param dataPack NettyDataPack from NettyServerAvroHandler/NettyClientAvroHandler in the pipeline
* @return encoded ChannelBuffer
*/
@Override public void encode(ChannelHandlerContext ctx, NettyDataPack dataPack,
List