From c6e3cc7864011180eeeab9ce8cfeae354c53e55b Mon Sep 17 00:00:00 2001 From: Christopher Wirt Date: Thu, 8 May 2025 11:40:07 +0100 Subject: [PATCH 1/2] Add support for io_uring with Netty 4.2.1.Final Netty has finally added io_uring support as part of the 4.2 release. In this update, they've changed the EventLoop class hierarchy, deprecating Epoll/KQueue/Nio EventLoopGroup and replacing it with Multi/SingleThreadIoEventLoopGroup composed of IoHandlerFactory, which defines the event framework. No IOURingEventLoopGroup was ever added. NettyEventLoops needs to adopt a new approach to deciding which EventLoopType we are using. Using isIoType(Handler) seems like a reasonable way to do this. I've also removed usages of the deprecated EventLoopGroup classes and replaced them with the new way of doing things. --- benchmarks/pom.xml | 4 +- .../src/com/aerospike/benchmarks/Main.java | 17 +++--- client/pom.xml | 4 +- .../aerospike/client/async/NettyCommand.java | 4 +- .../client/async/NettyEventLoops.java | 60 +++++++------------ examples/pom.xml | 4 +- .../com/aerospike/examples/AsyncExample.java | 17 +++--- pom.xml | 8 +-- test/pom.xml | 4 +- test/src/com/aerospike/test/SuiteAsync.java | 17 +++--- 10 files changed, 62 insertions(+), 77 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index b9bf042e7..c33d3b215 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -36,8 +36,8 @@ - io.netty.incubator - netty-incubator-transport-native-io_uring + io.netty + netty-transport-native-io_uring linux-x86_64 diff --git a/benchmarks/src/com/aerospike/benchmarks/Main.java b/benchmarks/src/com/aerospike/benchmarks/Main.java index 75f538478..9c18c6fbe 100644 --- a/benchmarks/src/com/aerospike/benchmarks/Main.java +++ b/benchmarks/src/com/aerospike/benchmarks/Main.java @@ -66,10 +66,11 @@ import com.aerospike.client.util.Util; import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.incubator.channel.uring.IOUringEventLoopGroup; +import io.netty.channel.MultiThreadIoEventLoopGroup; +import io.netty.channel.epoll.EpollIoHandler; +import io.netty.channel.kqueue.KQueueIoHandler; +import io.netty.channel.nio.NioIoHandler; +import io.netty.channel.uring.IoUringIoHandler; public class Main implements Log.Callback { @@ -1176,25 +1177,25 @@ public void runBenchmarks() throws Exception { } case NETTY_NIO: { - EventLoopGroup group = new NioEventLoopGroup(this.eventLoopSize); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(this.eventLoopSize, NioIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, this.eventLoopType); break; } case NETTY_EPOLL: { - EventLoopGroup group = new EpollEventLoopGroup(this.eventLoopSize); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(this.eventLoopSize, EpollIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, this.eventLoopType); break; } case NETTY_KQUEUE: { - EventLoopGroup group = new KQueueEventLoopGroup(this.eventLoopSize); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(this.eventLoopSize, KQueueIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, this.eventLoopType); break; } case NETTY_IOURING: { - EventLoopGroup group = new IOUringEventLoopGroup(this.eventLoopSize); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(this.eventLoopSize, IoUringIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, this.eventLoopType); break; } diff --git a/client/pom.xml b/client/pom.xml index 361d6f59c..96ca615b4 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -38,8 +38,8 @@ - io.netty.incubator - netty-incubator-transport-native-io_uring + io.netty + netty-transport-native-io_uring linux-x86_64 provided true diff --git a/client/src/com/aerospike/client/async/NettyCommand.java b/client/src/com/aerospike/client/async/NettyCommand.java index 00d06bb9a..f447ac626 100644 --- a/client/src/com/aerospike/client/async/NettyCommand.java +++ b/client/src/com/aerospike/client/async/NettyCommand.java @@ -55,7 +55,7 @@ import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandshakeCompletionEvent; -import io.netty.incubator.channel.uring.IOUringSocketChannel; +import io.netty.channel.uring.IoUringSocketChannel; /** * Asynchronous command handler using netty. @@ -379,7 +379,7 @@ static final void initBootstrap(Bootstrap b, Cluster cluster, NettyEventLoop eve break; case NETTY_IOURING: - b.channel(IOUringSocketChannel.class); + b.channel(IoUringSocketChannel.class); break; } diff --git a/client/src/com/aerospike/client/async/NettyEventLoops.java b/client/src/com/aerospike/client/async/NettyEventLoops.java index 8cfc996a6..86908b5f0 100644 --- a/client/src/com/aerospike/client/async/NettyEventLoops.java +++ b/client/src/com/aerospike/client/async/NettyEventLoops.java @@ -24,15 +24,17 @@ import com.aerospike.client.AerospikeException; import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.EpollEventLoopGroup; +import io.netty.channel.IoEventLoopGroup; +import io.netty.channel.epoll.EpollIoHandler; import io.netty.channel.epoll.EpollSocketChannel; -import io.netty.channel.kqueue.KQueueEventLoopGroup; +import io.netty.channel.kqueue.KQueueIoHandler; import io.netty.channel.kqueue.KQueueSocketChannel; -import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.local.LocalIoHandler; +import io.netty.channel.nio.NioIoHandler; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.incubator.channel.uring.IOUringEventLoopGroup; -import io.netty.incubator.channel.uring.IOUringSocketChannel; +import io.netty.channel.uring.IoUringIoHandler; +import io.netty.channel.uring.IoUringSocketChannel; import io.netty.util.concurrent.EventExecutor; /** @@ -99,41 +101,21 @@ public void run() { } private static EventLoopType getEventLoopType(EventLoopGroup group) { - // Wrap each instanceof comparison in a try/catch block because these classes reference - // libraries that are optional and might not be specified in the build file (pom.xml). - // This is preferable to using a "getClass().getSimpleName()" switch statement because - // that requires exact classname equality and does not handle custom classes that might - // inherit from these classes. try { - if (group instanceof NioEventLoopGroup) { - return EventLoopType.NETTY_NIO; - } - } - catch (NoClassDefFoundError e) { - } - - try { - if (group instanceof EpollEventLoopGroup) { - return EventLoopType.NETTY_EPOLL; - } - } - catch (NoClassDefFoundError e) { - } - - try { - if (group instanceof KQueueEventLoopGroup) { - return EventLoopType.NETTY_KQUEUE; - } - } - catch (NoClassDefFoundError e) { - } - - try { - if (group instanceof IOUringEventLoopGroup) { - return EventLoopType.NETTY_IOURING; + if (group instanceof IoEventLoopGroup g) { + if (g.isIoType(EpollIoHandler.class)) { + return EventLoopType.NETTY_EPOLL; + } else if (g.isIoType(KQueueIoHandler.class)) { + return EventLoopType.NETTY_KQUEUE; + } else if (g.isIoType(IoUringIoHandler.class)) { + return EventLoopType.NETTY_IOURING; + } else if (g.isIoType(NioIoHandler.class)) { + return EventLoopType.NETTY_NIO; + } else if (g.isIoType(LocalIoHandler.class)) { + return EventLoopType.DIRECT_NIO; + } } - } - catch (NoClassDefFoundError e) { + }catch (NoClassDefFoundError e) { } throw new AerospikeException("Unexpected EventLoopGroup"); @@ -155,7 +137,7 @@ public Class getSocketChannelClass() { return KQueueSocketChannel.class; case NETTY_IOURING: - return IOUringSocketChannel.class; + return IoUringSocketChannel.class; } } diff --git a/examples/pom.xml b/examples/pom.xml index f3cbdfcef..cd2768306 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -37,8 +37,8 @@ - io.netty.incubator - netty-incubator-transport-native-io_uring + io.netty + netty-transport-native-io_uring linux-x86_64 diff --git a/examples/src/com/aerospike/examples/AsyncExample.java b/examples/src/com/aerospike/examples/AsyncExample.java index 0fc0e3e57..24a513f4d 100644 --- a/examples/src/com/aerospike/examples/AsyncExample.java +++ b/examples/src/com/aerospike/examples/AsyncExample.java @@ -33,10 +33,11 @@ import com.aerospike.client.util.Util; import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.incubator.channel.uring.IOUringEventLoopGroup; +import io.netty.channel.MultiThreadIoEventLoopGroup; +import io.netty.channel.epoll.EpollIoHandler; +import io.netty.channel.kqueue.KQueueIoHandler; +import io.netty.channel.nio.NioIoHandler; +import io.netty.channel.uring.IoUringIoHandler; public abstract class AsyncExample { /** @@ -57,25 +58,25 @@ public static void runExamples(Console console, Parameters params, List } case NETTY_NIO: { - EventLoopGroup group = new NioEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, params.eventLoopType); break; } case NETTY_EPOLL: { - EventLoopGroup group = new EpollEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, EpollIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, params.eventLoopType); break; } case NETTY_KQUEUE: { - EventLoopGroup group = new KQueueEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, KQueueIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, params.eventLoopType); break; } case NETTY_IOURING: { - EventLoopGroup group = new IOUringEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, IoUringIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, params.eventLoopType); break; } diff --git a/pom.xml b/pom.xml index 0dd8d624d..8779ffea5 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 2.18.1 3.2.0 - 4.1.119.Final + 4.2.1.Final 3.0.1 0.4 1.9.0 @@ -77,10 +77,10 @@ - io.netty.incubator - netty-incubator-transport-native-io_uring + io.netty + netty-transport-native-io_uring linux-x86_64 - 0.0.26.Final + ${netty.version} diff --git a/test/pom.xml b/test/pom.xml index 43b6bcb17..4d3ba9ad6 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -42,8 +42,8 @@ - io.netty.incubator - netty-incubator-transport-native-io_uring + io.netty + netty-transport-native-io_uring linux-x86_64 diff --git a/test/src/com/aerospike/test/SuiteAsync.java b/test/src/com/aerospike/test/SuiteAsync.java index a8ccdf373..34b90c426 100644 --- a/test/src/com/aerospike/test/SuiteAsync.java +++ b/test/src/com/aerospike/test/SuiteAsync.java @@ -40,11 +40,12 @@ import com.aerospike.test.async.TestAsyncUDF; import com.aerospike.test.util.Args; +import io.netty.channel.MultiThreadIoEventLoopGroup; +import io.netty.channel.epoll.EpollIoHandler; +import io.netty.channel.kqueue.KQueueIoHandler; +import io.netty.channel.nio.NioIoHandler; +import io.netty.channel.uring.IoUringIoHandler; import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.incubator.channel.uring.IOUringEventLoopGroup; @RunWith(Suite.class) @Suite.SuiteClasses({ @@ -78,25 +79,25 @@ public static void init() { } case NETTY_NIO: { - EventLoopGroup group = new NioEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, args.eventLoopType); break; } case NETTY_EPOLL: { - EventLoopGroup group = new EpollEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, EpollIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, args.eventLoopType); break; } case NETTY_KQUEUE: { - EventLoopGroup group = new KQueueEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, KQueueIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, args.eventLoopType); break; } case NETTY_IOURING: { - EventLoopGroup group = new IOUringEventLoopGroup(1); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, IoUringIoHandler.newFactory()); eventLoops = new NettyEventLoops(eventPolicy, group, args.eventLoopType); break; } From 92c175621130b8f2a9904ed7216b0fc26dd0071d Mon Sep 17 00:00:00 2001 From: Christopher Wirt Date: Mon, 9 Jun 2025 16:37:55 +0100 Subject: [PATCH 2/2] Netty 4.2.2 released --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8779ffea5..dc42d60fd 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 2.18.1 3.2.0 - 4.2.1.Final + 4.2.2.Final 3.0.1 0.4 1.9.0