From 13a7d507466f466865f26eb791ddd1543a3bb5eb Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 3 Dec 2019 16:54:47 +0100 Subject: [PATCH] Add support for using epoll Netty transport Since we have GlobalNettyContext, we can easily provide the necessary glue to select either epoll(7) or java.nio backend based on availability. JIRA: OVSDB-331 Change-Id: Id79e13e21dd5bc2358b7a9567bd145a4ca166a39 Signed-off-by: Robert Varga --- library/impl/pom.xml | 6 ++ .../ovsdb/lib/impl/NettyBootstrapFactory.java | 87 +++++++++++++++++-- 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/library/impl/pom.xml b/library/impl/pom.xml index 970f9196c..0a7f3d2b5 100644 --- a/library/impl/pom.xml +++ b/library/impl/pom.xml @@ -67,6 +67,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html io.netty netty-transport + + io.netty + netty-transport-native-epoll + linux-x86_64 + + org.slf4j slf4j-api diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/NettyBootstrapFactory.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/NettyBootstrapFactory.java index 0449cf095..1d2195787 100644 --- a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/NettyBootstrapFactory.java +++ b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/NettyBootstrapFactory.java @@ -13,9 +13,14 @@ import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.AdaptiveRecvByteBufAllocator; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; +import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollEventLoopGroup; +import io.netty.channel.epoll.EpollServerSocketChannel; +import io.netty.channel.epoll.EpollSocketChannel; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; +import java.util.concurrent.ThreadFactory; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Singleton; @@ -27,30 +32,94 @@ import org.slf4j.LoggerFactory; */ @Singleton public class NettyBootstrapFactory implements AutoCloseable { + private abstract static class Provider { + /** + * Return user friendly name, suitable for system operators. + * + * @return An admin-friendly name. + */ + abstract String name(); + + abstract EventLoopGroup createGroup(ThreadFactory threadFactory); + + abstract Bootstrap createBootstrap(); + + abstract ServerBootstrap createServerBootstrap(); + } + + private static final class EpollProvider extends Provider { + @Override + String name() { + return "epoll(7)"; + } + + @Override + EventLoopGroup createGroup(final ThreadFactory threadFactory) { + return new EpollEventLoopGroup(0, threadFactory); + } + + @Override + Bootstrap createBootstrap() { + return new Bootstrap() + .channel(EpollSocketChannel.class); + } + + @Override + ServerBootstrap createServerBootstrap() { + return new ServerBootstrap() + .channel(EpollServerSocketChannel.class); + } + } + + private static final class NioProvider extends Provider { + @Override + String name() { + return "java.nio"; + } + + @Override + EventLoopGroup createGroup(final ThreadFactory threadFactory) { + return new NioEventLoopGroup(0, threadFactory); + } + + @Override + Bootstrap createBootstrap() { + return new Bootstrap() + .channel(NioSocketChannel.class); + } + + @Override + ServerBootstrap createServerBootstrap() { + return new ServerBootstrap() + .channel(NioServerSocketChannel.class); + } + } + private static final Logger LOG = LoggerFactory.getLogger(NettyBootstrapFactory.class); - private final EventLoopGroup bossGroup = new NioEventLoopGroup(0, - new ThreadFactoryBuilder().setNameFormat("OVSDB listener-%d").build()); - private final EventLoopGroup workerGroup = new NioEventLoopGroup(0, - new ThreadFactoryBuilder().setNameFormat("OVSDB connection-%d").build()); + // Minimum footprint runtime-constant + private static final Provider PROVIDER = Epoll.isAvailable() ? new EpollProvider() : new NioProvider(); + + private final EventLoopGroup bossGroup; + private final EventLoopGroup workerGroup; @Inject public NettyBootstrapFactory() { - LOG.info("OVSDB global Netty context instantiated"); + bossGroup = PROVIDER.createGroup(new ThreadFactoryBuilder().setNameFormat("OVSDB listener-%d").build()); + workerGroup = PROVIDER.createGroup(new ThreadFactoryBuilder().setNameFormat("OVSDB connection-%d").build()); + LOG.info("OVSDB global Netty context started with {}", PROVIDER.name()); } Bootstrap newClient() { - return new Bootstrap() + return PROVIDER.createBootstrap() .group(workerGroup) - .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(65535, 65535, 65535)); } ServerBootstrap newServer() { - return new ServerBootstrap() + return PROVIDER.createServerBootstrap() .group(bossGroup, workerGroup) - .channel(NioServerSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(65535, 65535, 65535)) .option(ChannelOption.SO_BACKLOG, 100); -- 2.36.6