package com.sissi.server.netty.impl;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sissi.commons.Trace;
import com.sissi.pipeline.Transfer;
import com.sissi.pipeline.TransferBuffer;
/**
* @author kim 2013年12月1日
*/
public class NetworkTransfer implements Transfer {
private final GenericFutureListener<Future<Void>> futureListener;
private ChannelHandlerContext context;
public NetworkTransfer(ChannelHandlerContext context) {
this(FailLogedGenericFutureListener.FUTURE, context);
}
public NetworkTransfer(GenericFutureListener<Future<Void>> futureListener, ChannelHandlerContext context) {
super();
this.futureListener = futureListener;
this.context = context;
}
@Override
public NetworkTransfer transfer(TransferBuffer buffer) {
this.context.writeAndFlush(ByteBuf.class.cast(buffer.getBuffer())).addListener(new ReleaseGenericFutureListener(buffer)).addListener(this.futureListener);
return this;
}
@Override
public void close() {
this.context.close().addListener(FailLogedGenericFutureListener.FUTURE);
}
private class ReleaseGenericFutureListener implements GenericFutureListener<Future<Void>> {
private final TransferBuffer transferBuffer;
public ReleaseGenericFutureListener(TransferBuffer transferBuffer) {
super();
this.transferBuffer = transferBuffer;
}
public void operationComplete(Future<Void> future) throws Exception {
this.transferBuffer.release();
}
}
private static class FailLogedGenericFutureListener implements GenericFutureListener<Future<Void>> {
private final static GenericFutureListener<Future<Void>> FUTURE = new FailLogedGenericFutureListener();
private final Log log = LogFactory.getLog(this.getClass());
private FailLogedGenericFutureListener() {
super();
}
public void operationComplete(Future<Void> future) throws Exception {
if (!future.isSuccess()) {
this.log.warn(future.cause().toString());
Trace.trace(this.log, future.cause());
}
}
}
}