From 66ab357d913fcc6730f93ea92e75b8ec90096c0f Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Wed, 5 Feb 2025 21:01:49 +0800 Subject: [PATCH] added epoll native transport for server --- .../net/woggioni/gbcs/api/Configuration.java | 7 ++++-- gbcs-cli/build.gradle | 12 +++++++++ gbcs-server/src/main/java/module-info.java | 1 + .../gbcs/server/GradleBuildCacheServer.kt | 25 ++++++++++++++++--- .../gbcs/server/configuration/Parser.kt | 8 +++++- .../gbcs/server/configuration/Serializer.kt | 4 +++ .../net/woggioni/gbcs/server/schema/gbcs.xsd | 5 ++++ .../test/AbstractBasicAuthServerTest.kt | 1 + .../gbcs/server/test/AbstractTlsServerTest.kt | 3 ++- .../gbcs/server/test/NoAuthServerTest.kt | 4 ++- .../gbcs/server/test/valid/gbcs-default.xml | 1 + 11 files changed, 62 insertions(+), 9 deletions(-) diff --git a/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java b/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java index b09522a..11d7b2e 100644 --- a/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java +++ b/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java @@ -27,6 +27,7 @@ public class Configuration { Cache cache; Authentication authentication; Tls tls; + boolean useNativeTransport; @Value public static class EventExecutor { @@ -151,7 +152,8 @@ public class Configuration { Map groups, Cache cache, Authentication authentication, - Tls tls + Tls tls, + boolean useNativeTransport ) { return new Configuration( host, @@ -164,7 +166,8 @@ public class Configuration { groups, cache, authentication, - tls + tls, + useNativeTransport ); } } \ No newline at end of file diff --git a/gbcs-cli/build.gradle b/gbcs-cli/build.gradle index 6c8f61f..d31aae9 100644 --- a/gbcs-cli/build.gradle +++ b/gbcs-cli/build.gradle @@ -32,6 +32,13 @@ configurations { canBeResolved = true visible = true } + + nativeLibraries { + transitive = false + canBeConsumed = false + canBeResolved = true + visible = false + } } envelopeJar { @@ -53,6 +60,8 @@ dependencies { // runtimeOnly catalog.slf4j.jdk14 runtimeOnly catalog.logback.classic // runtimeOnly catalog.slf4j.simple + + nativeLibraries group: 'io.netty', name: 'netty-transport-native-epoll', version: catalog.versions.netty.get(), classifier: 'linux-x86_64' } Provider envelopeJarTaskProvider = tasks.named('envelopeJar', EnvelopeJarTask.class) { @@ -67,6 +76,9 @@ Provider envelopeJarTaskProvider = tasks.named('envelopeJar', E // systemProperties['org.slf4j.simpleLogger.log.com.google.code.yanf4j'] = 'warn' // systemProperties['org.slf4j.simpleLogger.log.net.rubyeye.xmemcached'] = 'warn' // systemProperties['org.slf4j.simpleLogger.dateTimeFormat'] = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ' + from { + configurations.nativeLibraries.collect { it.isDirectory() ? it : zipTree(it) } + } } tasks.named(NativeImagePlugin.CONFIGURE_NATIVE_IMAGE_TASK_NAME, NativeImageConfigurationTask) { diff --git a/gbcs-server/src/main/java/module-info.java b/gbcs-server/src/main/java/module-info.java index 4e00a8c..3f0e0ab 100644 --- a/gbcs-server/src/main/java/module-info.java +++ b/gbcs-server/src/main/java/module-info.java @@ -18,6 +18,7 @@ module net.woggioni.gbcs.server { requires net.woggioni.jwo; requires net.woggioni.gbcs.common; requires net.woggioni.gbcs.api; + requires io.netty.transport.classes.epoll; exports net.woggioni.gbcs.server; diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt index 516f2aa..fdaa3f6 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt @@ -10,6 +10,9 @@ import io.netty.channel.ChannelInboundHandlerAdapter import io.netty.channel.ChannelInitializer import io.netty.channel.ChannelOption import io.netty.channel.ChannelPromise +import io.netty.channel.MultithreadEventLoopGroup +import io.netty.channel.epoll.EpollEventLoopGroup +import io.netty.channel.epoll.EpollServerSocketChannel import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioServerSocketChannel import io.netty.handler.codec.compression.CompressionOptions @@ -49,6 +52,7 @@ import net.woggioni.gbcs.server.exception.ExceptionHandler import net.woggioni.gbcs.server.handler.ServerHandler import net.woggioni.gbcs.server.throttling.ThrottlingHandler import net.woggioni.jwo.JWO +import net.woggioni.jwo.OS import net.woggioni.jwo.Tuple2 import java.io.OutputStream import java.net.InetSocketAddress @@ -399,10 +403,23 @@ class GradleBuildCacheServer(private val cfg: Configuration) { } fun run(): ServerHandle { - // Create the multithreaded event loops for the server - val bossGroup = NioEventLoopGroup(1) - val serverSocketChannel = NioServerSocketChannel::class.java - val workerGroup = NioEventLoopGroup(0) + val bossGroup : MultithreadEventLoopGroup + val workerGroup : MultithreadEventLoopGroup + val serverSocketChannel : Class<*> + if(cfg.isUseNativeTransport) { + if(OS.isLinux) { + bossGroup = EpollEventLoopGroup(1) + serverSocketChannel = EpollServerSocketChannel::class.java + workerGroup = EpollEventLoopGroup(0) + } else { + throw java.lang.IllegalArgumentException("Native transport is not supported on ${OS.current.name}") + } + } else { + bossGroup = NioEventLoopGroup(1) + serverSocketChannel = NioServerSocketChannel::class.java + workerGroup = NioEventLoopGroup(0) + } + val eventExecutorGroup = run { val threadFactory = if (cfg.eventExecutor.isUseVirtualThreads) { Thread.ofVirtual().factory() diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt index 251d16d..8abd6f6 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt @@ -44,6 +44,7 @@ object Parser { val serverPath = root.renderAttribute("path") var incomingConnectionsBacklogSize = 1024 var authentication: Authentication? = null + var useNativeTransport = false for (child in root.asIterable()) { val tagName = child.localName when (tagName) { @@ -136,7 +137,7 @@ object Parser { } "event-executor" -> { - val useVirtualThread = root.renderAttribute("use-virtual-threads") + val useVirtualThread = child.renderAttribute("use-virtual-threads") ?.let(String::toBoolean) ?: true eventExecutor = Configuration.EventExecutor(useVirtualThread) } @@ -180,6 +181,10 @@ object Parser { } tls = Tls(keyStore, trustStore) } + "transport" -> { + useNativeTransport = child.renderAttribute("use-native-transport") + ?.let(String::toBoolean) ?: false + } } } return Configuration.of( @@ -194,6 +199,7 @@ object Parser { cache!!, authentication, tls, + useNativeTransport ) } diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt index f481da5..1f77b1c 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt @@ -44,8 +44,12 @@ object Serializer { attr("max-request-size", connection.maxRequestSize.toString()) } } + node("transport") { + attr("use-native-transport", conf.isUseNativeTransport.toString()) + } node("event-executor") { attr("use-virtual-threads", conf.eventExecutor.isUseVirtualThreads.toString()) + attr("use-virtual-threads", conf.eventExecutor.isUseVirtualThreads.toString()) } val cache = conf.cache val serializer : CacheProvider = diff --git a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd index a436257..a7c5550 100644 --- a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd +++ b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd @@ -9,6 +9,7 @@ + @@ -42,6 +43,10 @@ + + + + diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt index fbd260f..d6167e7 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt @@ -55,6 +55,7 @@ abstract class AbstractBasicAuthServerTest : AbstractServerTest() { ), Configuration.BasicAuthentication(), null, + false, ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt index 7ff0e9e..ea5c1d3 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt @@ -171,7 +171,8 @@ abstract class AbstractTlsServerTest : AbstractServerTest() { Configuration.Tls( Configuration.KeyStore(this.serverKeyStoreFile, null, SERVER_CERTIFICATE_ENTRY, PASSWORD), Configuration.TrustStore(this.trustStoreFile, null, false, false), - ) + ), + false ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt index d436808..0ddfe3c 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt @@ -51,10 +51,12 @@ class NoAuthServerTest : AbstractServerTest() { maxAge = Duration.ofSeconds(3600 * 24), compressionEnabled = true, digestAlgorithm = "MD5", - compressionLevel = Deflater.DEFAULT_COMPRESSION + compressionLevel = Deflater.DEFAULT_COMPRESSION, + maxSize = 0x1000000 ), null, null, + false, ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-default.xml b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-default.xml index b302012..8f00594 100644 --- a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-default.xml +++ b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-default.xml @@ -10,6 +10,7 @@ write-idle-timeout="PT11M" idle-timeout="PT30M" max-request-size="101325"/> +