added epoll native transport for server
This commit is contained in:
@@ -27,6 +27,7 @@ public class Configuration {
|
|||||||
Cache cache;
|
Cache cache;
|
||||||
Authentication authentication;
|
Authentication authentication;
|
||||||
Tls tls;
|
Tls tls;
|
||||||
|
boolean useNativeTransport;
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
public static class EventExecutor {
|
public static class EventExecutor {
|
||||||
@@ -151,7 +152,8 @@ public class Configuration {
|
|||||||
Map<String, Group> groups,
|
Map<String, Group> groups,
|
||||||
Cache cache,
|
Cache cache,
|
||||||
Authentication authentication,
|
Authentication authentication,
|
||||||
Tls tls
|
Tls tls,
|
||||||
|
boolean useNativeTransport
|
||||||
) {
|
) {
|
||||||
return new Configuration(
|
return new Configuration(
|
||||||
host,
|
host,
|
||||||
@@ -164,7 +166,8 @@ public class Configuration {
|
|||||||
groups,
|
groups,
|
||||||
cache,
|
cache,
|
||||||
authentication,
|
authentication,
|
||||||
tls
|
tls,
|
||||||
|
useNativeTransport
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -32,6 +32,13 @@ configurations {
|
|||||||
canBeResolved = true
|
canBeResolved = true
|
||||||
visible = true
|
visible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nativeLibraries {
|
||||||
|
transitive = false
|
||||||
|
canBeConsumed = false
|
||||||
|
canBeResolved = true
|
||||||
|
visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
envelopeJar {
|
envelopeJar {
|
||||||
@@ -53,6 +60,8 @@ dependencies {
|
|||||||
// runtimeOnly catalog.slf4j.jdk14
|
// runtimeOnly catalog.slf4j.jdk14
|
||||||
runtimeOnly catalog.logback.classic
|
runtimeOnly catalog.logback.classic
|
||||||
// runtimeOnly catalog.slf4j.simple
|
// runtimeOnly catalog.slf4j.simple
|
||||||
|
|
||||||
|
nativeLibraries group: 'io.netty', name: 'netty-transport-native-epoll', version: catalog.versions.netty.get(), classifier: 'linux-x86_64'
|
||||||
}
|
}
|
||||||
|
|
||||||
Provider<EnvelopeJarTask> envelopeJarTaskProvider = tasks.named('envelopeJar', EnvelopeJarTask.class) {
|
Provider<EnvelopeJarTask> envelopeJarTaskProvider = tasks.named('envelopeJar', EnvelopeJarTask.class) {
|
||||||
@@ -67,6 +76,9 @@ Provider<EnvelopeJarTask> envelopeJarTaskProvider = tasks.named('envelopeJar', E
|
|||||||
// systemProperties['org.slf4j.simpleLogger.log.com.google.code.yanf4j'] = 'warn'
|
// systemProperties['org.slf4j.simpleLogger.log.com.google.code.yanf4j'] = 'warn'
|
||||||
// systemProperties['org.slf4j.simpleLogger.log.net.rubyeye.xmemcached'] = 'warn'
|
// systemProperties['org.slf4j.simpleLogger.log.net.rubyeye.xmemcached'] = 'warn'
|
||||||
// systemProperties['org.slf4j.simpleLogger.dateTimeFormat'] = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ'
|
// 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) {
|
tasks.named(NativeImagePlugin.CONFIGURE_NATIVE_IMAGE_TASK_NAME, NativeImageConfigurationTask) {
|
||||||
|
@@ -18,6 +18,7 @@ module net.woggioni.gbcs.server {
|
|||||||
requires net.woggioni.jwo;
|
requires net.woggioni.jwo;
|
||||||
requires net.woggioni.gbcs.common;
|
requires net.woggioni.gbcs.common;
|
||||||
requires net.woggioni.gbcs.api;
|
requires net.woggioni.gbcs.api;
|
||||||
|
requires io.netty.transport.classes.epoll;
|
||||||
|
|
||||||
exports net.woggioni.gbcs.server;
|
exports net.woggioni.gbcs.server;
|
||||||
|
|
||||||
|
@@ -10,6 +10,9 @@ import io.netty.channel.ChannelInboundHandlerAdapter
|
|||||||
import io.netty.channel.ChannelInitializer
|
import io.netty.channel.ChannelInitializer
|
||||||
import io.netty.channel.ChannelOption
|
import io.netty.channel.ChannelOption
|
||||||
import io.netty.channel.ChannelPromise
|
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.nio.NioEventLoopGroup
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel
|
import io.netty.channel.socket.nio.NioServerSocketChannel
|
||||||
import io.netty.handler.codec.compression.CompressionOptions
|
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.handler.ServerHandler
|
||||||
import net.woggioni.gbcs.server.throttling.ThrottlingHandler
|
import net.woggioni.gbcs.server.throttling.ThrottlingHandler
|
||||||
import net.woggioni.jwo.JWO
|
import net.woggioni.jwo.JWO
|
||||||
|
import net.woggioni.jwo.OS
|
||||||
import net.woggioni.jwo.Tuple2
|
import net.woggioni.jwo.Tuple2
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.net.InetSocketAddress
|
import java.net.InetSocketAddress
|
||||||
@@ -399,10 +403,23 @@ class GradleBuildCacheServer(private val cfg: Configuration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun run(): ServerHandle {
|
fun run(): ServerHandle {
|
||||||
// Create the multithreaded event loops for the server
|
val bossGroup : MultithreadEventLoopGroup
|
||||||
val bossGroup = NioEventLoopGroup(1)
|
val workerGroup : MultithreadEventLoopGroup
|
||||||
val serverSocketChannel = NioServerSocketChannel::class.java
|
val serverSocketChannel : Class<*>
|
||||||
val workerGroup = NioEventLoopGroup(0)
|
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 eventExecutorGroup = run {
|
||||||
val threadFactory = if (cfg.eventExecutor.isUseVirtualThreads) {
|
val threadFactory = if (cfg.eventExecutor.isUseVirtualThreads) {
|
||||||
Thread.ofVirtual().factory()
|
Thread.ofVirtual().factory()
|
||||||
|
@@ -44,6 +44,7 @@ object Parser {
|
|||||||
val serverPath = root.renderAttribute("path")
|
val serverPath = root.renderAttribute("path")
|
||||||
var incomingConnectionsBacklogSize = 1024
|
var incomingConnectionsBacklogSize = 1024
|
||||||
var authentication: Authentication? = null
|
var authentication: Authentication? = null
|
||||||
|
var useNativeTransport = false
|
||||||
for (child in root.asIterable()) {
|
for (child in root.asIterable()) {
|
||||||
val tagName = child.localName
|
val tagName = child.localName
|
||||||
when (tagName) {
|
when (tagName) {
|
||||||
@@ -136,7 +137,7 @@ object Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
"event-executor" -> {
|
"event-executor" -> {
|
||||||
val useVirtualThread = root.renderAttribute("use-virtual-threads")
|
val useVirtualThread = child.renderAttribute("use-virtual-threads")
|
||||||
?.let(String::toBoolean) ?: true
|
?.let(String::toBoolean) ?: true
|
||||||
eventExecutor = Configuration.EventExecutor(useVirtualThread)
|
eventExecutor = Configuration.EventExecutor(useVirtualThread)
|
||||||
}
|
}
|
||||||
@@ -180,6 +181,10 @@ object Parser {
|
|||||||
}
|
}
|
||||||
tls = Tls(keyStore, trustStore)
|
tls = Tls(keyStore, trustStore)
|
||||||
}
|
}
|
||||||
|
"transport" -> {
|
||||||
|
useNativeTransport = child.renderAttribute("use-native-transport")
|
||||||
|
?.let(String::toBoolean) ?: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Configuration.of(
|
return Configuration.of(
|
||||||
@@ -194,6 +199,7 @@ object Parser {
|
|||||||
cache!!,
|
cache!!,
|
||||||
authentication,
|
authentication,
|
||||||
tls,
|
tls,
|
||||||
|
useNativeTransport
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,8 +44,12 @@ object Serializer {
|
|||||||
attr("max-request-size", connection.maxRequestSize.toString())
|
attr("max-request-size", connection.maxRequestSize.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
node("transport") {
|
||||||
|
attr("use-native-transport", conf.isUseNativeTransport.toString())
|
||||||
|
}
|
||||||
node("event-executor") {
|
node("event-executor") {
|
||||||
attr("use-virtual-threads", conf.eventExecutor.isUseVirtualThreads.toString())
|
attr("use-virtual-threads", conf.eventExecutor.isUseVirtualThreads.toString())
|
||||||
|
attr("use-virtual-threads", conf.eventExecutor.isUseVirtualThreads.toString())
|
||||||
}
|
}
|
||||||
val cache = conf.cache
|
val cache = conf.cache
|
||||||
val serializer : CacheProvider<Configuration.Cache> =
|
val serializer : CacheProvider<Configuration.Cache> =
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
<xs:sequence minOccurs="0">
|
<xs:sequence minOccurs="0">
|
||||||
<xs:element name="bind" type="gbcs:bindType" maxOccurs="1"/>
|
<xs:element name="bind" type="gbcs:bindType" maxOccurs="1"/>
|
||||||
<xs:element name="connection" type="gbcs:connectionType" minOccurs="0" maxOccurs="1"/>
|
<xs:element name="connection" type="gbcs:connectionType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="transport" type="gbcs:transportType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="event-executor" type="gbcs:eventExecutorType" minOccurs="0" maxOccurs="1"/>
|
<xs:element name="event-executor" type="gbcs:eventExecutorType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="cache" type="gbcs:cacheType" maxOccurs="1"/>
|
<xs:element name="cache" type="gbcs:cacheType" maxOccurs="1"/>
|
||||||
<xs:element name="authorization" type="gbcs:authorizationType" minOccurs="0">
|
<xs:element name="authorization" type="gbcs:authorizationType" minOccurs="0">
|
||||||
@@ -42,6 +43,10 @@
|
|||||||
<xs:attribute name="max-request-size" type="xs:unsignedInt" use="optional" default="67108864"/>
|
<xs:attribute name="max-request-size" type="xs:unsignedInt" use="optional" default="67108864"/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="transportType">
|
||||||
|
<xs:attribute name="use-native-transport" type="xs:boolean" use="optional" default="false"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
<xs:complexType name="eventExecutorType">
|
<xs:complexType name="eventExecutorType">
|
||||||
<xs:attribute name="use-virtual-threads" type="xs:boolean" use="optional" default="true"/>
|
<xs:attribute name="use-virtual-threads" type="xs:boolean" use="optional" default="true"/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
@@ -55,6 +55,7 @@ abstract class AbstractBasicAuthServerTest : AbstractServerTest() {
|
|||||||
),
|
),
|
||||||
Configuration.BasicAuthentication(),
|
Configuration.BasicAuthentication(),
|
||||||
null,
|
null,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
Xml.write(Serializer.serialize(cfg), System.out)
|
Xml.write(Serializer.serialize(cfg), System.out)
|
||||||
}
|
}
|
||||||
|
@@ -171,7 +171,8 @@ abstract class AbstractTlsServerTest : AbstractServerTest() {
|
|||||||
Configuration.Tls(
|
Configuration.Tls(
|
||||||
Configuration.KeyStore(this.serverKeyStoreFile, null, SERVER_CERTIFICATE_ENTRY, PASSWORD),
|
Configuration.KeyStore(this.serverKeyStoreFile, null, SERVER_CERTIFICATE_ENTRY, PASSWORD),
|
||||||
Configuration.TrustStore(this.trustStoreFile, null, false, false),
|
Configuration.TrustStore(this.trustStoreFile, null, false, false),
|
||||||
)
|
),
|
||||||
|
false
|
||||||
)
|
)
|
||||||
Xml.write(Serializer.serialize(cfg), System.out)
|
Xml.write(Serializer.serialize(cfg), System.out)
|
||||||
}
|
}
|
||||||
|
@@ -51,10 +51,12 @@ class NoAuthServerTest : AbstractServerTest() {
|
|||||||
maxAge = Duration.ofSeconds(3600 * 24),
|
maxAge = Duration.ofSeconds(3600 * 24),
|
||||||
compressionEnabled = true,
|
compressionEnabled = true,
|
||||||
digestAlgorithm = "MD5",
|
digestAlgorithm = "MD5",
|
||||||
compressionLevel = Deflater.DEFAULT_COMPRESSION
|
compressionLevel = Deflater.DEFAULT_COMPRESSION,
|
||||||
|
maxSize = 0x1000000
|
||||||
),
|
),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
Xml.write(Serializer.serialize(cfg), System.out)
|
Xml.write(Serializer.serialize(cfg), System.out)
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
write-idle-timeout="PT11M"
|
write-idle-timeout="PT11M"
|
||||||
idle-timeout="PT30M"
|
idle-timeout="PT30M"
|
||||||
max-request-size="101325"/>
|
max-request-size="101325"/>
|
||||||
|
<transport use-native-transport="true"/>
|
||||||
<event-executor use-virtual-threads="false"/>
|
<event-executor use-virtual-threads="false"/>
|
||||||
<cache xs:type="gbcs:fileSystemCacheType" path="/tmp/gbcs" max-age="P7D"/>
|
<cache xs:type="gbcs:fileSystemCacheType" path="/tmp/gbcs" max-age="P7D"/>
|
||||||
<authentication>
|
<authentication>
|
||||||
|
Reference in New Issue
Block a user