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