Showing
2 changed files
with
30 additions
and
26 deletions
| 1 | package org.onlab.netty; | 1 | package org.onlab.netty; |
| 2 | 2 | ||
| 3 | import io.netty.buffer.ByteBuf; | 3 | import io.netty.buffer.ByteBuf; |
| 4 | +import io.netty.channel.ChannelHandler.Sharable; | ||
| 4 | import io.netty.channel.ChannelHandlerContext; | 5 | import io.netty.channel.ChannelHandlerContext; |
| 5 | import io.netty.handler.codec.MessageToByteEncoder; | 6 | import io.netty.handler.codec.MessageToByteEncoder; |
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| 8 | * Encode InternalMessage out into a byte buffer. | 9 | * Encode InternalMessage out into a byte buffer. |
| 9 | */ | 10 | */ |
| 11 | +@Sharable | ||
| 10 | public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { | 12 | public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { |
| 11 | 13 | ||
| 12 | // onosiscool in ascii | 14 | // onosiscool in ascii | ... | ... |
| ... | @@ -11,6 +11,7 @@ import io.netty.bootstrap.ServerBootstrap; | ... | @@ -11,6 +11,7 @@ import io.netty.bootstrap.ServerBootstrap; |
| 11 | import io.netty.buffer.PooledByteBufAllocator; | 11 | import io.netty.buffer.PooledByteBufAllocator; |
| 12 | import io.netty.channel.Channel; | 12 | import io.netty.channel.Channel; |
| 13 | import io.netty.channel.ChannelFuture; | 13 | import io.netty.channel.ChannelFuture; |
| 14 | +import io.netty.channel.ChannelHandler; | ||
| 14 | import io.netty.channel.ChannelHandlerContext; | 15 | import io.netty.channel.ChannelHandlerContext; |
| 15 | import io.netty.channel.ChannelInitializer; | 16 | import io.netty.channel.ChannelInitializer; |
| 16 | import io.netty.channel.ChannelOption; | 17 | import io.netty.channel.ChannelOption; |
| ... | @@ -37,14 +38,19 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -37,14 +38,19 @@ public class NettyMessagingService implements MessagingService { |
| 37 | 38 | ||
| 38 | private final Logger log = LoggerFactory.getLogger(getClass()); | 39 | private final Logger log = LoggerFactory.getLogger(getClass()); |
| 39 | 40 | ||
| 40 | - private GenericKeyedObjectPool<Endpoint, Channel> channels; | ||
| 41 | - | ||
| 42 | private final int port; | 41 | private final int port; |
| 42 | + private final Endpoint localEp; | ||
| 43 | private final EventLoopGroup bossGroup = new NioEventLoopGroup(); | 43 | private final EventLoopGroup bossGroup = new NioEventLoopGroup(); |
| 44 | private final EventLoopGroup workerGroup = new NioEventLoopGroup(); | 44 | private final EventLoopGroup workerGroup = new NioEventLoopGroup(); |
| 45 | private final ConcurrentMap<String, MessageHandler> handlers = new ConcurrentHashMap<>(); | 45 | private final ConcurrentMap<String, MessageHandler> handlers = new ConcurrentHashMap<>(); |
| 46 | - private Cache<Long, AsyncResponse<?>> responseFutures; | 46 | + private final Cache<Long, AsyncResponse<?>> responseFutures = CacheBuilder.newBuilder() |
| 47 | - private final Endpoint localEp; | 47 | + .maximumSize(100000) |
| 48 | + .weakValues() | ||
| 49 | + // TODO: Once the entry expires, notify blocking threads (if any). | ||
| 50 | + .expireAfterWrite(10, TimeUnit.MINUTES) | ||
| 51 | + .build(); | ||
| 52 | + private final GenericKeyedObjectPool<Endpoint, Channel> channels | ||
| 53 | + = new GenericKeyedObjectPool<Endpoint, Channel>(new OnosCommunicationChannelFactory()); | ||
| 48 | 54 | ||
| 49 | protected Serializer serializer; | 55 | protected Serializer serializer; |
| 50 | 56 | ||
| ... | @@ -65,15 +71,8 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -65,15 +71,8 @@ public class NettyMessagingService implements MessagingService { |
| 65 | } | 71 | } |
| 66 | 72 | ||
| 67 | public void activate() throws Exception { | 73 | public void activate() throws Exception { |
| 68 | - channels = new GenericKeyedObjectPool<Endpoint, Channel>(new OnosCommunicationChannelFactory()); | ||
| 69 | channels.setTestOnBorrow(true); | 74 | channels.setTestOnBorrow(true); |
| 70 | channels.setTestOnReturn(true); | 75 | channels.setTestOnReturn(true); |
| 71 | - responseFutures = CacheBuilder.newBuilder() | ||
| 72 | - .maximumSize(100000) | ||
| 73 | - .weakValues() | ||
| 74 | - // TODO: Once the entry expires, notify blocking threads (if any). | ||
| 75 | - .expireAfterWrite(10, TimeUnit.MINUTES) | ||
| 76 | - .build(); | ||
| 77 | startAcceptingConnections(); | 76 | startAcceptingConnections(); |
| 78 | } | 77 | } |
| 79 | 78 | ||
| ... | @@ -145,7 +144,8 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -145,7 +144,8 @@ public class NettyMessagingService implements MessagingService { |
| 145 | private void startAcceptingConnections() throws InterruptedException { | 144 | private void startAcceptingConnections() throws InterruptedException { |
| 146 | ServerBootstrap b = new ServerBootstrap(); | 145 | ServerBootstrap b = new ServerBootstrap(); |
| 147 | b.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024); | 146 | b.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024); |
| 148 | - b.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 32 * 1024); | 147 | + b.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 8 * 1024); |
| 148 | + // TODO: Need JVM options to configure PooledByteBufAllocator. | ||
| 149 | b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); | 149 | b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); |
| 150 | b.group(bossGroup, workerGroup) | 150 | b.group(bossGroup, workerGroup) |
| 151 | .channel(NioServerSocketChannel.class) | 151 | .channel(NioServerSocketChannel.class) |
| ... | @@ -172,19 +172,18 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -172,19 +172,18 @@ public class NettyMessagingService implements MessagingService { |
| 172 | 172 | ||
| 173 | @Override | 173 | @Override |
| 174 | public Channel makeObject(Endpoint ep) throws Exception { | 174 | public Channel makeObject(Endpoint ep) throws Exception { |
| 175 | - Bootstrap b = new Bootstrap(); | 175 | + Bootstrap bootstrap = new Bootstrap(); |
| 176 | - b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); | 176 | + bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); |
| 177 | - b.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024); | 177 | + bootstrap.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024); |
| 178 | - b.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 32 * 1024); | 178 | + bootstrap.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 8 * 1024); |
| 179 | - b.group(workerGroup); | 179 | + bootstrap.group(workerGroup); |
| 180 | // TODO: Make this faster: | 180 | // TODO: Make this faster: |
| 181 | // http://normanmaurer.me/presentations/2014-facebook-eng-netty/slides.html#37.0 | 181 | // http://normanmaurer.me/presentations/2014-facebook-eng-netty/slides.html#37.0 |
| 182 | - b.channel(NioSocketChannel.class); | 182 | + bootstrap.channel(NioSocketChannel.class); |
| 183 | - b.option(ChannelOption.SO_KEEPALIVE, true); | 183 | + bootstrap.option(ChannelOption.SO_KEEPALIVE, true); |
| 184 | - b.handler(new OnosCommunicationChannelInitializer()); | 184 | + bootstrap.handler(new OnosCommunicationChannelInitializer()); |
| 185 | - | ||
| 186 | // Start the client. | 185 | // Start the client. |
| 187 | - ChannelFuture f = b.connect(ep.host(), ep.port()).sync(); | 186 | + ChannelFuture f = bootstrap.connect(ep.host(), ep.port()).sync(); |
| 188 | return f.channel(); | 187 | return f.channel(); |
| 189 | } | 188 | } |
| 190 | 189 | ||
| ... | @@ -201,12 +200,15 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -201,12 +200,15 @@ public class NettyMessagingService implements MessagingService { |
| 201 | 200 | ||
| 202 | private class OnosCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> { | 201 | private class OnosCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> { |
| 203 | 202 | ||
| 203 | + private final ChannelHandler dispatcher = new InboundMessageDispatcher(); | ||
| 204 | + private final ChannelHandler encoder = new MessageEncoder(serializer); | ||
| 205 | + | ||
| 204 | @Override | 206 | @Override |
| 205 | protected void initChannel(SocketChannel channel) throws Exception { | 207 | protected void initChannel(SocketChannel channel) throws Exception { |
| 206 | channel.pipeline() | 208 | channel.pipeline() |
| 207 | - .addLast("encoder", new MessageEncoder(serializer)) | 209 | + .addLast("encoder", encoder) |
| 208 | .addLast("decoder", new MessageDecoder(NettyMessagingService.this, serializer)) | 210 | .addLast("decoder", new MessageDecoder(NettyMessagingService.this, serializer)) |
| 209 | - .addLast("handler", new InboundMessageDispatcher()); | 211 | + .addLast("handler", dispatcher); |
| 210 | } | 212 | } |
| 211 | } | 213 | } |
| 212 | 214 | ||
| ... | @@ -222,10 +224,11 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -222,10 +224,11 @@ public class NettyMessagingService implements MessagingService { |
| 222 | 224 | ||
| 223 | @Override | 225 | @Override |
| 224 | public void run() { | 226 | public void run() { |
| 225 | - channel.writeAndFlush(message); | 227 | + channel.writeAndFlush(message, channel.voidPromise()); |
| 226 | } | 228 | } |
| 227 | } | 229 | } |
| 228 | 230 | ||
| 231 | + @ChannelHandler.Sharable | ||
| 229 | private class InboundMessageDispatcher extends SimpleChannelInboundHandler<InternalMessage> { | 232 | private class InboundMessageDispatcher extends SimpleChannelInboundHandler<InternalMessage> { |
| 230 | 233 | ||
| 231 | @Override | 234 | @Override |
| ... | @@ -248,7 +251,6 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -248,7 +251,6 @@ public class NettyMessagingService implements MessagingService { |
| 248 | handler.handle(message); | 251 | handler.handle(message); |
| 249 | } | 252 | } |
| 250 | 253 | ||
| 251 | - | ||
| 252 | @Override | 254 | @Override |
| 253 | public void exceptionCaught(ChannelHandlerContext context, Throwable cause) { | 255 | public void exceptionCaught(ChannelHandlerContext context, Throwable cause) { |
| 254 | context.close(); | 256 | context.close(); | ... | ... |
-
Please register or login to post a comment