This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 00c2e56093 fix(bootstrap): own and dispose the gateway's custom Netty
event loops (#7715) (#7726)
00c2e56093 is described below
commit 00c2e5609374a02835a127661f776ae3e6ff0b3f
Author: konlue <[email protected]>
AuthorDate: Mon Oct 19 09:33:59 2026 +0800
fix(bootstrap): own and dispose the gateway's custom Netty event loops
(#7715) (#7726)
---
.../netty/ShenyuNettyWebServerConfiguration.java | 30 +++++++++++++++++++---
.../ShenyuNettyWebServerConfigurationTest.java | 18 +++++++++++++
2 files changed, 44 insertions(+), 4 deletions(-)
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfiguration.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfiguration.java
index f8063b4a98..5345ec4357 100644
---
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfiguration.java
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfiguration.java
@@ -75,22 +75,37 @@ public class ShenyuNettyWebServerConfiguration {
return new ShenyuSniAsyncMapping();
}
+ /**
+ * Event loop resources owned by the application context, released when it
closes.
+ *
+ * @param properties the properties
+ * @return the loop resources
+ */
+ @Bean(destroyMethod = "dispose")
+ @ConditionalOnProperty(value =
"shenyu.netty.http.web-server-factory-enabled", havingValue = "true",
matchIfMissing = true)
+ public LoopResources shenyuServerLoopResources(final
ObjectProvider<NettyHttpProperties> properties) {
+ NettyHttpProperties nettyHttpProperties =
Optional.ofNullable(properties.getIfAvailable()).orElse(new
NettyHttpProperties());
+ return LoopResources.create("shenyu-netty",
nettyHttpProperties.getSelectCount(), nettyHttpProperties.getWorkerCount(),
true);
+ }
+
/**
* Netty reactive web server factory.
*
* @param properties the properties
* @param shenyuSniAsyncMappingProvider shenyuSniAsyncMapping
* @param tcpSslContextSpecs default tcpSslContextSpecs
+ * @param loopResources the event loop resources
* @return the netty reactive web server factory
*/
@Bean
@ConditionalOnProperty(value =
"shenyu.netty.http.web-server-factory-enabled", havingValue = "true",
matchIfMissing = true)
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory(final
ObjectProvider<NettyHttpProperties> properties,
final
ObjectProvider<ShenyuSniAsyncMapping> shenyuSniAsyncMappingProvider,
- final
ObjectProvider<TcpSslContextSpec> tcpSslContextSpecs) {
+ final
ObjectProvider<TcpSslContextSpec> tcpSslContextSpecs,
+ final
LoopResources loopResources) {
NettyReactiveWebServerFactory webServerFactory = new
NettyReactiveWebServerFactory();
NettyHttpProperties nettyHttpProperties =
Optional.ofNullable(properties.getIfAvailable()).orElse(new
NettyHttpProperties());
- webServerFactory.addServerCustomizers(new
EventLoopNettyCustomizer(nettyHttpProperties, httpServer -> {
+ webServerFactory.addServerCustomizers(new
EventLoopNettyCustomizer(nettyHttpProperties, loopResources, httpServer -> {
HttpServer server = httpServer;
// Configure sni certificates
NettyHttpProperties.SniProperties sniProperties =
nettyHttpProperties.getSni();
@@ -139,22 +154,29 @@ public class ShenyuNettyWebServerConfiguration {
private final NettyHttpProperties nettyHttpProperties;
+ private final LoopResources loopResources;
+
private final Function<HttpServer, HttpServer> sniProcessor;
/**
* Instantiates a new Event loop netty customizer.
*
* @param nettyHttpProperties the netty tcp config
+ * @param loopResources the event loop resources
+ * @param sniProcessor the sni processor
*/
- EventLoopNettyCustomizer(final NettyHttpProperties
nettyHttpProperties, final Function<HttpServer, HttpServer> sniProcessor) {
+ EventLoopNettyCustomizer(final NettyHttpProperties nettyHttpProperties,
+ final LoopResources loopResources,
+ final Function<HttpServer, HttpServer>
sniProcessor) {
this.nettyHttpProperties = nettyHttpProperties;
+ this.loopResources = loopResources;
this.sniProcessor = sniProcessor;
}
@Override
public HttpServer apply(final HttpServer httpServer) {
return sniProcessor.apply(httpServer)
- .runOn(LoopResources.create("shenyu-netty",
nettyHttpProperties.getSelectCount(), nettyHttpProperties.getWorkerCount(),
true))
+ .runOn(loopResources)
.accessLog(nettyHttpProperties.getAccessLog())
// configure http request decoder
.httpRequestDecoder(spec -> {
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/test/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfigurationTest.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/test/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfigurationTest.java
index dffde11104..c1307a0b12 100644
---
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/test/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfigurationTest.java
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/test/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfigurationTest.java
@@ -24,6 +24,9 @@ import
org.springframework.boot.autoconfigure.AutoConfigurations;
import
org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
+import reactor.netty.resources.LoopResources;
+
+import java.util.concurrent.atomic.AtomicReference;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@@ -117,6 +120,21 @@ public class ShenyuNettyWebServerConfigurationTest {
});
}
+ @Test
+ public void testEventLoopResourcesDisposedWithContext() {
+ final AtomicReference<LoopResources> loopResourcesRef = new
AtomicReference<>();
+ applicationContextRunner
+ .withPropertyValues(
+ "shenyu.netty.http.web-server-factory-enabled=true"
+ )
+ .run(context -> {
+ LoopResources loopResources =
context.getBean("shenyuServerLoopResources", LoopResources.class);
+ assertThat(loopResources.isDisposed(), is(false));
+ loopResourcesRef.set(loopResources);
+ });
+ assertThat(loopResourcesRef.get().isDisposed(), is(true));
+ }
+
@Test
public void testHttpDecoderDefaultProperties() {
applicationContextRunner