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

Reply via email to