This is an automated email from the ASF dual-hosted git repository.

Alanxtl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git


The following commit(s) were added to refs/heads/develop by this push:
     new ccb2f6609 refactor: migrate graceful shutdown config to global (#3386)
ccb2f6609 is described below

commit ccb2f6609ac48c67659a1b48115118f85ab2bf75
Author: Oxidaner <[email protected]>
AuthorDate: Fri Jun 19 22:42:42 2026 +0800

    refactor: migrate graceful shutdown config to global (#3386)
    
    * refactor: migrate graceful shutdown config to global
    
    * refactor: remove config dependency from graceful shutdown
    
    * refactor: centralize shutdown config defaults
    
    * fix: align graceful shutdown config logging
    
    * fix: protocol/triple/triple_protocol/triple_ext_test.go gRPC streaming 
does not support HTTP/1
---
 .../compat.go => common/constant/shutdown.go       |  32 ++---
 compat.go                                          |  18 +--
 config/graceful_shutdown.go                        |   2 +-
 config/graceful_shutdown_config.go                 | 133 +--------------------
 config/graceful_shutdown_config_test.go            |   6 +-
 config/graceful_shutdown_test.go                   |  91 ++++++++++++++
 filter/graceful_shutdown/consumer_filter.go        |   4 -
 filter/graceful_shutdown/provider_filter.go        |   4 -
 global/shutdown_config.go                          |  76 ++++++++++++
 graceful_shutdown/shutdown.go                      |  32 +++--
 graceful_shutdown/shutdown_test.go                 |   8 +-
 protocol/triple/triple_protocol/triple_ext_test.go |   5 +
 12 files changed, 208 insertions(+), 203 deletions(-)

diff --git a/filter/graceful_shutdown/compat.go b/common/constant/shutdown.go
similarity index 52%
rename from filter/graceful_shutdown/compat.go
rename to common/constant/shutdown.go
index 0bdffbbe2..20e535642 100644
--- a/filter/graceful_shutdown/compat.go
+++ b/common/constant/shutdown.go
@@ -15,32 +15,16 @@
  * limitations under the License.
  */
 
-package graceful_shutdown
+package constant
 
 import (
-       "go.uber.org/atomic"
+       "time"
 )
 
-import (
-       "dubbo.apache.org/dubbo-go/v3/config"
-       "dubbo.apache.org/dubbo-go/v3/global"
+const (
+       DefaultShutdownConfigTimeout                     = 60 * time.Second
+       DefaultShutdownConfigStepTimeout                 = 3 * time.Second
+       DefaultShutdownConfigNotifyTimeout               = 5 * time.Second
+       DefaultShutdownConfigConsumerUpdateWaitTime      = 3 * time.Second
+       DefaultShutdownConfigOfflineRequestWindowTimeout = 3 * time.Second
 )
-
-func compatGlobalShutdownConfig(c *config.ShutdownConfig) 
*global.ShutdownConfig {
-       if c == nil {
-               return nil
-       }
-       cfg := &global.ShutdownConfig{
-               Timeout:                     c.Timeout,
-               StepTimeout:                 c.StepTimeout,
-               NotifyTimeout:               c.NotifyTimeout,
-               ConsumerUpdateWaitTime:      c.ConsumerUpdateWaitTime,
-               RejectRequestHandler:        c.RejectRequestHandler,
-               InternalSignal:              c.InternalSignal,
-               OfflineRequestWindowTimeout: c.OfflineRequestWindowTimeout,
-               RejectRequest:               atomic.Bool{},
-       }
-       cfg.RejectRequest.Store(c.RejectRequest.Load())
-
-       return cfg
-}
diff --git a/compat.go b/compat.go
index a7e500072..f786bd543 100644
--- a/compat.go
+++ b/compat.go
@@ -17,10 +17,6 @@
 
 package dubbo
 
-import (
-       "go.uber.org/atomic"
-)
-
 import (
        "dubbo.apache.org/dubbo-go/v3/common"
        "dubbo.apache.org/dubbo-go/v3/config"
@@ -471,19 +467,7 @@ func compatShutdownConfig(c *global.ShutdownConfig) 
*config.ShutdownConfig {
        if c == nil {
                return nil
        }
-       cfg := &config.ShutdownConfig{
-               Timeout:                     c.Timeout,
-               StepTimeout:                 c.StepTimeout,
-               NotifyTimeout:               c.NotifyTimeout,
-               ConsumerUpdateWaitTime:      c.ConsumerUpdateWaitTime,
-               RejectRequestHandler:        c.RejectRequestHandler,
-               InternalSignal:              c.InternalSignal,
-               OfflineRequestWindowTimeout: c.OfflineRequestWindowTimeout,
-               RejectRequest:               atomic.Bool{},
-       }
-       cfg.RejectRequest.Store(c.RejectRequest.Load())
-
-       return cfg
+       return c.Clone()
 }
 
 func compatRouterConfig(c *global.RouterConfig) *config.RouterConfig {
diff --git a/config/graceful_shutdown.go b/config/graceful_shutdown.go
index c41508df7..8080f994b 100644
--- a/config/graceful_shutdown.go
+++ b/config/graceful_shutdown.go
@@ -51,7 +51,7 @@ import (
  * The signals are different on different platforms.
  * We define them by using 'package build' feature 
https://golang.org/pkg/go/build/
  */
-const defaultShutDownTime = time.Second * 60
+const defaultShutDownTime = constant.DefaultShutdownConfigTimeout
 
 func gracefulShutdownInit() {
        // retrieve ShutdownConfig for gracefulShutdownFilter
diff --git a/config/graceful_shutdown_config.go 
b/config/graceful_shutdown_config.go
index a905ab6a9..eb288312a 100644
--- a/config/graceful_shutdown_config.go
+++ b/config/graceful_shutdown_config.go
@@ -17,141 +17,18 @@
 
 package config
 
-import (
-       "time"
-)
-
 import (
        "github.com/creasty/defaults"
-
-       "github.com/dubbogo/gost/log/logger"
-
-       "go.uber.org/atomic"
 )
 
 import (
-       "dubbo.apache.org/dubbo-go/v3/common/constant"
-)
-
-const (
-       defaultTimeout                     = 60 * time.Second
-       defaultStepTimeout                 = 3 * time.Second
-       defaultNotifyTimeout               = 5 * time.Second
-       defaultConsumerUpdateWaitTime      = 3 * time.Second
-       defaultOfflineRequestWindowTimeout = 3 * time.Second
+       "dubbo.apache.org/dubbo-go/v3/global"
 )
 
-// ShutdownConfig is used as configuration for graceful shutdown
-type ShutdownConfig struct {
-       /*
-        * Total timeout. Even though we don't release all resources,
-        * the applicationConfig will shutdown if the costing time is over this 
configuration. The unit is ms.
-        * default value is 60 * 1000 ms = 1 minutes
-        * In general, it should be bigger than 3 * StepTimeout.
-        */
-       Timeout string `default:"60s" yaml:"timeout" json:"timeout,omitempty" 
property:"timeout"`
-       /*
-        * the timeout on each step. You should evaluate the response time of 
request
-        * and the time that client noticed that server shutdown.
-        * For example, if your client will received the notification within 
10s when you start to close server,
-        * and the 99.9% requests will return response in 2s, so the 
StepTimeout will be bigger than(10+2) * 1000ms,
-        * maybe (10 + 2*3) * 1000ms is a good choice.
-        */
-       StepTimeout string `default:"3s" yaml:"step-timeout" 
json:"step.timeout,omitempty" property:"step.timeout"`
-
-       /*
-        * NotifyTimeout means the timeout budget for actively notifying 
long-connection consumers
-        * during graceful shutdown. It only controls the notify step and 
should not be coupled to
-        * request draining timeouts.
-        */
-       NotifyTimeout string `default:"5s" yaml:"notify-timeout" 
json:"notify.timeout,omitempty" property:"notify.timeout"`
-
-       /*
-        * ConsumerUpdateWaitTime means when provider is shutting down, after 
the unregister, time to wait for client to
-        * update invokers. During this time, incoming invocation can be 
treated normally.
-        */
-       ConsumerUpdateWaitTime string `default:"3s" 
yaml:"consumer-update-wait-time" json:"consumerUpdate.waitTIme,omitempty" 
property:"consumerUpdate.waitTIme"`
-       // when we try to shutdown the applicationConfig, we will reject the 
new requests. In most cases, you don't need to configure this.
-       RejectRequestHandler string `yaml:"reject-handler" 
json:"reject-handler,omitempty" property:"reject_handler"`
-       // internal listen kill signal,the default is true.
-       InternalSignal *bool `default:"true" yaml:"internal-signal" 
json:"internal.signal,omitempty" property:"internal.signal"`
-       // offline request window length
-       OfflineRequestWindowTimeout string `default:"3s" 
yaml:"offline-request-window-timeout" 
json:"offlineRequestWindowTimeout,omitempty" 
property:"offlineRequestWindowTimeout"`
-       // true -> new request will be rejected.
-       RejectRequest atomic.Bool
-       // active invocation
-       ConsumerActiveCount atomic.Int32
-       ProviderActiveCount atomic.Int32
-
-       // provider last received request timestamp
-       ProviderLastReceivedRequestTime atomic.Time
-}
-
-// Prefix dubbo.shutdown
-func (config *ShutdownConfig) Prefix() string {
-       return constant.ShutdownConfigPrefix
-}
-
-func (config *ShutdownConfig) GetTimeout() time.Duration {
-       result, err := time.ParseDuration(config.Timeout)
-       if err != nil {
-               logger.Errorf("The Timeout configuration is invalid: %s, and we 
will use the default value: %s, err: %v",
-                       config.Timeout, defaultTimeout.String(), err)
-               return defaultTimeout
-       }
-       return result
-}
-
-func (config *ShutdownConfig) GetStepTimeout() time.Duration {
-       result, err := time.ParseDuration(config.StepTimeout)
-       if err != nil {
-               logger.Errorf("The StepTimeout configuration is invalid: %s, 
and we will use the default value: %s, err: %v",
-                       config.StepTimeout, defaultStepTimeout.String(), err)
-               return defaultStepTimeout
-       }
-       return result
-}
-
-func (config *ShutdownConfig) GetNotifyTimeout() time.Duration {
-       result, err := time.ParseDuration(config.NotifyTimeout)
-       if err != nil {
-               logger.Errorf("The NotifyTimeout configuration is invalid: %s, 
and we will use the default value: %s, err: %v",
-                       config.NotifyTimeout, defaultNotifyTimeout.String(), 
err)
-               return defaultNotifyTimeout
-       }
-       return result
-}
-
-func (config *ShutdownConfig) GetOfflineRequestWindowTimeout() time.Duration {
-       result, err := time.ParseDuration(config.OfflineRequestWindowTimeout)
-       if err != nil {
-               logger.Errorf("The OfflineRequestWindowTimeout configuration is 
invalid: %s, and we will use the default value: %s, err: %v",
-                       config.OfflineRequestWindowTimeout, 
defaultOfflineRequestWindowTimeout.String(), err)
-               return defaultOfflineRequestWindowTimeout
-       }
-       return result
-}
-
-func (config *ShutdownConfig) GetConsumerUpdateWaitTime() time.Duration {
-       result, err := time.ParseDuration(config.ConsumerUpdateWaitTime)
-       if err != nil {
-               logger.Errorf("The ConsumerUpdateTimeout configuration is 
invalid: %s, and we will use the default value: %s, err: %v",
-                       config.ConsumerActiveCount.Load(), 
defaultConsumerUpdateWaitTime.String(), err)
-               return defaultConsumerUpdateWaitTime
-       }
-       return result
-}
-
-func (config *ShutdownConfig) GetInternalSignal() bool {
-       if config.InternalSignal == nil {
-               return false
-       }
-       return *config.InternalSignal
-}
-
-func (config *ShutdownConfig) Init() error {
-       return defaults.Set(config)
-}
+// ShutdownConfig is kept as a compatibility alias for global.ShutdownConfig.
+// Use global.ShutdownConfig directly in new code. Field documentation lives on
+// global.ShutdownConfig because it owns the graceful shutdown configuration.
+type ShutdownConfig = global.ShutdownConfig
 
 type ShutdownConfigBuilder struct {
        shutdownConfig *ShutdownConfig
diff --git a/config/graceful_shutdown_config_test.go 
b/config/graceful_shutdown_config_test.go
index 30fa36eea..73aba2da8 100644
--- a/config/graceful_shutdown_config_test.go
+++ b/config/graceful_shutdown_config_test.go
@@ -57,9 +57,9 @@ func TestShutdownConfigGetTimeout(t *testing.T) {
        // test default
        config = ShutdownConfig{}
 
-       assert.Equal(t, defaultTimeout, config.GetTimeout())
-       assert.Equal(t, defaultStepTimeout, config.GetStepTimeout())
-       assert.Equal(t, defaultOfflineRequestWindowTimeout, 
config.GetOfflineRequestWindowTimeout())
+       assert.Equal(t, 60*time.Second, config.GetTimeout())
+       assert.Equal(t, 3*time.Second, config.GetStepTimeout())
+       assert.Equal(t, 3*time.Second, config.GetOfflineRequestWindowTimeout())
 }
 
 func TestNewShutDownConfigBuilder(t *testing.T) {
diff --git a/config/graceful_shutdown_test.go b/config/graceful_shutdown_test.go
index 5be5d8223..9b9245b51 100644
--- a/config/graceful_shutdown_test.go
+++ b/config/graceful_shutdown_test.go
@@ -17,6 +17,97 @@
 
 package config
 
+import (
+       "context"
+       "testing"
+)
+
+import (
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/common/extension"
+       "dubbo.apache.org/dubbo-go/v3/filter"
+       "dubbo.apache.org/dubbo-go/v3/global"
+       "dubbo.apache.org/dubbo-go/v3/protocol/base"
+       "dubbo.apache.org/dubbo-go/v3/protocol/result"
+)
+
+type captureShutdownConfigFilter struct {
+       captured any
+}
+
+func (f *captureShutdownConfigFilter) Invoke(context.Context, base.Invoker, 
base.Invocation) result.Result {
+       return &result.RPCResult{}
+}
+
+func (f *captureShutdownConfigFilter) OnResponse(context.Context, 
result.Result, base.Invoker, base.Invocation) result.Result {
+       return &result.RPCResult{}
+}
+
+func (f *captureShutdownConfigFilter) Set(_ string, config any) {
+       f.captured = config
+}
+
+func TestGracefulShutdownInitPassesGlobalShutdownConfigToFilters(t *testing.T) 
{
+       oldRoot := GetRootConfig()
+       oldConsumerFilter, hadConsumerFilter := 
extension.GetFilter(constant.GracefulShutdownConsumerFilterKey)
+       oldProviderFilter, hadProviderFilter := 
extension.GetFilter(constant.GracefulShutdownProviderFilterKey)
+       t.Cleanup(func() {
+               setRootConfigInternal(oldRoot)
+               if hadConsumerFilter {
+                       
extension.SetFilter(constant.GracefulShutdownConsumerFilterKey, func() 
filter.Filter {
+                               return oldConsumerFilter
+                       })
+               } else {
+                       
extension.UnregisterFilter(constant.GracefulShutdownConsumerFilterKey)
+               }
+               if hadProviderFilter {
+                       
extension.SetFilter(constant.GracefulShutdownProviderFilterKey, func() 
filter.Filter {
+                               return oldProviderFilter
+                       })
+               } else {
+                       
extension.UnregisterFilter(constant.GracefulShutdownProviderFilterKey)
+               }
+       })
+
+       internalSignal := false
+       SetRootConfig(RootConfig{
+               Shutdown: &ShutdownConfig{
+                       Timeout:        "11s",
+                       StepTimeout:    "2s",
+                       NotifyTimeout:  "4s",
+                       InternalSignal: &internalSignal,
+               },
+       })
+
+       consumerFilter := &captureShutdownConfigFilter{}
+       providerFilter := &captureShutdownConfigFilter{}
+       extension.SetFilter(constant.GracefulShutdownConsumerFilterKey, func() 
filter.Filter {
+               return consumerFilter
+       })
+       extension.SetFilter(constant.GracefulShutdownProviderFilterKey, func() 
filter.Filter {
+               return providerFilter
+       })
+
+       gracefulShutdownInit()
+
+       consumerShutdown, ok := consumerFilter.captured.(*global.ShutdownConfig)
+       require.True(t, ok)
+       assert.Equal(t, "11s", consumerShutdown.Timeout)
+       assert.Equal(t, "2s", consumerShutdown.StepTimeout)
+       assert.Equal(t, "4s", consumerShutdown.NotifyTimeout)
+
+       providerShutdown, ok := providerFilter.captured.(*global.ShutdownConfig)
+       require.True(t, ok)
+       assert.Equal(t, "11s", providerShutdown.Timeout)
+       assert.Equal(t, "2s", providerShutdown.StepTimeout)
+       assert.Equal(t, "4s", providerShutdown.NotifyTimeout)
+}
+
 //
 //import (
 //     "dubbo.apache.org/dubbo-go/v3/config"
diff --git a/filter/graceful_shutdown/consumer_filter.go 
b/filter/graceful_shutdown/consumer_filter.go
index 0f6f5783d..f9c8c6db1 100644
--- a/filter/graceful_shutdown/consumer_filter.go
+++ b/filter/graceful_shutdown/consumer_filter.go
@@ -36,7 +36,6 @@ import (
 import (
        "dubbo.apache.org/dubbo-go/v3/common/constant"
        "dubbo.apache.org/dubbo-go/v3/common/extension"
-       "dubbo.apache.org/dubbo-go/v3/config"
        "dubbo.apache.org/dubbo-go/v3/filter"
        "dubbo.apache.org/dubbo-go/v3/global"
        gracefulshutdown "dubbo.apache.org/dubbo-go/v3/graceful_shutdown"
@@ -122,9 +121,6 @@ func (f *consumerGracefulShutdownFilter) Set(name string, 
conf any) {
                switch ct := conf.(type) {
                case *global.ShutdownConfig:
                        f.shutdownConfig = ct
-               // only for compatibility with old config, able to directly 
remove after config is deleted
-               case *config.ShutdownConfig:
-                       f.shutdownConfig = compatGlobalShutdownConfig(ct)
                default:
                        logger.Warnf("[Filter][GracefulShutdown] the type of 
config for %s should be *global.ShutdownConfig", 
constant.GracefulShutdownFilterShutdownConfig)
                }
diff --git a/filter/graceful_shutdown/provider_filter.go 
b/filter/graceful_shutdown/provider_filter.go
index 3747dce21..5f8c4e289 100644
--- a/filter/graceful_shutdown/provider_filter.go
+++ b/filter/graceful_shutdown/provider_filter.go
@@ -30,7 +30,6 @@ import (
 import (
        "dubbo.apache.org/dubbo-go/v3/common/constant"
        "dubbo.apache.org/dubbo-go/v3/common/extension"
-       "dubbo.apache.org/dubbo-go/v3/config"
        "dubbo.apache.org/dubbo-go/v3/filter"
        "dubbo.apache.org/dubbo-go/v3/global"
        "dubbo.apache.org/dubbo-go/v3/protocol/base"
@@ -114,9 +113,6 @@ func (f *providerGracefulShutdownFilter) Set(name string, 
conf any) {
                switch ct := conf.(type) {
                case *global.ShutdownConfig:
                        f.shutdownConfig = ct
-               // only for compatibility with old config, able to directly 
remove after config is deleted
-               case *config.ShutdownConfig:
-                       f.shutdownConfig = compatGlobalShutdownConfig(ct)
                default:
                        logger.Warnf("[Filter][GracefulShutdown] the type of 
config for %s should be *global.ShutdownConfig", 
constant.GracefulShutdownFilterShutdownConfig)
                }
diff --git a/global/shutdown_config.go b/global/shutdown_config.go
index 8374e2578..52c4d6eb1 100644
--- a/global/shutdown_config.go
+++ b/global/shutdown_config.go
@@ -17,12 +17,22 @@
 
 package global
 
+import (
+       "time"
+)
+
 import (
        "github.com/creasty/defaults"
 
+       "github.com/dubbogo/gost/log/logger"
+
        "go.uber.org/atomic"
 )
 
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+)
+
 // ShutdownConfig is used as configuration for graceful shutdown
 type ShutdownConfig struct {
        /*
@@ -82,6 +92,72 @@ func DefaultShutdownConfig() *ShutdownConfig {
        return cfg
 }
 
+// Prefix dubbo.shutdown
+func (c *ShutdownConfig) Prefix() string {
+       return constant.ShutdownConfigPrefix
+}
+
+func (c *ShutdownConfig) GetTimeout() time.Duration {
+       result, err := time.ParseDuration(c.Timeout)
+       if err != nil {
+               logger.Errorf("[GracefulShutdown] the Timeout configuration is 
invalid: %s, and we will use the default value: %s, err=%v",
+                       c.Timeout, 
constant.DefaultShutdownConfigTimeout.String(), err)
+               return constant.DefaultShutdownConfigTimeout
+       }
+       return result
+}
+
+func (c *ShutdownConfig) GetStepTimeout() time.Duration {
+       result, err := time.ParseDuration(c.StepTimeout)
+       if err != nil {
+               logger.Errorf("[GracefulShutdown] the StepTimeout configuration 
is invalid: %s, and we will use the default value: %s, err=%v",
+                       c.StepTimeout, 
constant.DefaultShutdownConfigStepTimeout.String(), err)
+               return constant.DefaultShutdownConfigStepTimeout
+       }
+       return result
+}
+
+func (c *ShutdownConfig) GetNotifyTimeout() time.Duration {
+       result, err := time.ParseDuration(c.NotifyTimeout)
+       if err != nil {
+               logger.Errorf("[GracefulShutdown] the NotifyTimeout 
configuration is invalid: %s, and we will use the default value: %s, err=%v",
+                       c.NotifyTimeout, 
constant.DefaultShutdownConfigNotifyTimeout.String(), err)
+               return constant.DefaultShutdownConfigNotifyTimeout
+       }
+       return result
+}
+
+func (c *ShutdownConfig) GetOfflineRequestWindowTimeout() time.Duration {
+       result, err := time.ParseDuration(c.OfflineRequestWindowTimeout)
+       if err != nil {
+               logger.Errorf("[GracefulShutdown] the 
OfflineRequestWindowTimeout configuration is invalid: %s, and we will use the 
default value: %s, err=%v",
+                       c.OfflineRequestWindowTimeout, 
constant.DefaultShutdownConfigOfflineRequestWindowTimeout.String(), err)
+               return constant.DefaultShutdownConfigOfflineRequestWindowTimeout
+       }
+       return result
+}
+
+func (c *ShutdownConfig) GetConsumerUpdateWaitTime() time.Duration {
+       result, err := time.ParseDuration(c.ConsumerUpdateWaitTime)
+       if err != nil {
+               logger.Errorf("[GracefulShutdown] the ConsumerUpdateWaitTime 
configuration is invalid: %s, and we will use the default value: %s, err=%v",
+                       c.ConsumerUpdateWaitTime, 
constant.DefaultShutdownConfigConsumerUpdateWaitTime.String(), err)
+               return constant.DefaultShutdownConfigConsumerUpdateWaitTime
+       }
+       return result
+}
+
+func (c *ShutdownConfig) GetInternalSignal() bool {
+       if c.InternalSignal == nil {
+               return false
+       }
+       return *c.InternalSignal
+}
+
+func (c *ShutdownConfig) Init() error {
+       return defaults.Set(c)
+}
+
 // Clone a new ShutdownConfig
 func (c *ShutdownConfig) Clone() *ShutdownConfig {
        if c == nil {
diff --git a/graceful_shutdown/shutdown.go b/graceful_shutdown/shutdown.go
index e9942da34..7b07ed369 100644
--- a/graceful_shutdown/shutdown.go
+++ b/graceful_shutdown/shutdown.go
@@ -37,20 +37,12 @@ import (
 import (
        "dubbo.apache.org/dubbo-go/v3/common/constant"
        "dubbo.apache.org/dubbo-go/v3/common/extension"
-       "dubbo.apache.org/dubbo-go/v3/config"
        "dubbo.apache.org/dubbo-go/v3/global"
        "dubbo.apache.org/dubbo-go/v3/metrics/probe"
        protocolbase "dubbo.apache.org/dubbo-go/v3/protocol/base"
 )
 
 const (
-       // todo(DMwangnima): these descriptions and defaults could be wrapped 
by functions of Options
-       defaultTimeout                     = 60 * time.Second
-       defaultStepTimeout                 = 3 * time.Second
-       defaultNotifyTimeout               = 5 * time.Second
-       defaultConsumerUpdateWaitTime      = 3 * time.Second
-       defaultOfflineRequestWindowTimeout = 3 * time.Second
-
        // retry config
        defaultMaxRetries     = 3
        defaultRetryBaseDelay = 500 * time.Millisecond
@@ -80,6 +72,10 @@ var (
        signalNotify = signal.Notify
 )
 
+type shutdownConfigSetter interface {
+       Set(name string, config any)
+}
+
 func Init(opts ...Option) {
        initOnce.Do(func() {
                protocols = make(map[string]struct{})
@@ -100,10 +96,10 @@ func Init(opts ...Option) {
 
                storeShutdownConfig(newOpts.Shutdown)
 
-               if filter, ok := 
gracefulShutdownConsumerFilter.(config.Setter); ok {
+               if filter, ok := 
gracefulShutdownConsumerFilter.(shutdownConfigSetter); ok {
                        
filter.Set(constant.GracefulShutdownFilterShutdownConfig, newOpts.Shutdown)
                }
-               if filter, ok := 
gracefulShutdownProviderFilter.(config.Setter); ok {
+               if filter, ok := 
gracefulShutdownProviderFilter.(shutdownConfigSetter); ok {
                        
filter.Set(constant.GracefulShutdownFilterShutdownConfig, newOpts.Shutdown)
                }
 
@@ -175,9 +171,9 @@ func RegisterProtocol(name string) {
 }
 
 func totalTimeout(shutdown *global.ShutdownConfig) time.Duration {
-       timeout := parseDuration(shutdown.Timeout, timeoutDesc, defaultTimeout)
-       if timeout < defaultTimeout {
-               timeout = defaultTimeout
+       timeout := parseDuration(shutdown.Timeout, timeoutDesc, 
constant.DefaultShutdownConfigTimeout)
+       if timeout < constant.DefaultShutdownConfigTimeout {
+               timeout = constant.DefaultShutdownConfigTimeout
        }
 
        return timeout
@@ -253,7 +249,7 @@ func unregisterRegistries() {
 func notifyLongConnectionConsumers(shutdown *global.ShutdownConfig) {
        logger.Info("[GracefulShutdown] notify long connection consumers.")
 
-       notifyTimeout := parseDuration(shutdown.NotifyTimeout, 
notifyTimeoutDesc, defaultNotifyTimeout)
+       notifyTimeout := parseDuration(shutdown.NotifyTimeout, 
notifyTimeoutDesc, constant.DefaultShutdownConfigNotifyTimeout)
        callbacks := extension.GracefulShutdownCallbacks()
        var wg sync.WaitGroup
        for name, callback := range callbacks {
@@ -326,10 +322,10 @@ func invokeGracefulShutdownCallback(ctx context.Context, 
name string, callback e
 func waitAndAcceptNewRequests(shutdown *global.ShutdownConfig) {
        logger.Info("[GracefulShutdown] keep waiting and accept new requests 
for a short time. ")
 
-       updateWaitTime := parseDuration(shutdown.ConsumerUpdateWaitTime, 
consumerUpdateWaitTimeDesc, defaultConsumerUpdateWaitTime)
+       updateWaitTime := parseDuration(shutdown.ConsumerUpdateWaitTime, 
consumerUpdateWaitTimeDesc, 
constant.DefaultShutdownConfigConsumerUpdateWaitTime)
        time.Sleep(updateWaitTime)
 
-       stepTimeout := parseDuration(shutdown.StepTimeout, stepTimeoutDesc, 
defaultStepTimeout)
+       stepTimeout := parseDuration(shutdown.StepTimeout, stepTimeoutDesc, 
constant.DefaultShutdownConfigStepTimeout)
 
        // ignore this step
        if stepTimeout < 0 {
@@ -341,7 +337,7 @@ func waitAndAcceptNewRequests(shutdown 
*global.ShutdownConfig) {
 func waitingProviderProcessedTimeout(shutdown *global.ShutdownConfig, timeout 
time.Duration) {
        deadline := time.Now().Add(timeout)
 
-       offlineRequestWindowTimeout := 
parseDuration(shutdown.OfflineRequestWindowTimeout, 
offlineRequestWindowTimeoutDesc, defaultOfflineRequestWindowTimeout)
+       offlineRequestWindowTimeout := 
parseDuration(shutdown.OfflineRequestWindowTimeout, 
offlineRequestWindowTimeoutDesc, 
constant.DefaultShutdownConfigOfflineRequestWindowTimeout)
 
        for time.Now().Before(deadline) &&
                (shutdown.ProviderActiveCount.Load() > 0 || 
time.Now().Before(shutdown.ProviderLastReceivedRequestTime.Load().Add(offlineRequestWindowTimeout)))
 {
@@ -360,7 +356,7 @@ func waitForSendingAndReceivingRequests(shutdown 
*global.ShutdownConfig) {
 }
 
 func waitingConsumerProcessedTimeout(shutdown *global.ShutdownConfig) {
-       stepTimeout := parseDuration(shutdown.StepTimeout, stepTimeoutDesc, 
defaultStepTimeout)
+       stepTimeout := parseDuration(shutdown.StepTimeout, stepTimeoutDesc, 
constant.DefaultShutdownConfigStepTimeout)
 
        if stepTimeout <= 0 {
                return
diff --git a/graceful_shutdown/shutdown_test.go 
b/graceful_shutdown/shutdown_test.go
index 1e7a6ab25..e69280f48 100644
--- a/graceful_shutdown/shutdown_test.go
+++ b/graceful_shutdown/shutdown_test.go
@@ -45,7 +45,7 @@ import (
        "dubbo.apache.org/dubbo-go/v3/protocol/result"
 )
 
-// MockFilter implements filter.Filter and config.Setter for testing
+// MockFilter implements filter.Filter and shutdownConfigSetter for testing.
 type MockFilter struct {
        mock.Mock
 }
@@ -281,7 +281,7 @@ func TestTotalTimeout(t *testing.T) {
        // Test with default timeout
        config := global.DefaultShutdownConfig()
        timeout := totalTimeout(config)
-       assert.Equal(t, defaultTimeout, timeout)
+       assert.Equal(t, constant.DefaultShutdownConfigTimeout, timeout)
 
        // Test with custom timeout
        config.Timeout = "120s"
@@ -291,12 +291,12 @@ func TestTotalTimeout(t *testing.T) {
        // Test with invalid timeout
        config.Timeout = "invalid"
        timeout = totalTimeout(config)
-       assert.Equal(t, defaultTimeout, timeout)
+       assert.Equal(t, constant.DefaultShutdownConfigTimeout, timeout)
 
        // Test with timeout less than default
        config.Timeout = "30s"
        timeout = totalTimeout(config)
-       assert.Equal(t, defaultTimeout, timeout) // Should use default if less 
than default
+       assert.Equal(t, constant.DefaultShutdownConfigTimeout, timeout) // 
Should use default if less than default
 }
 
 func TestParseDuration(t *testing.T) {
diff --git a/protocol/triple/triple_protocol/triple_ext_test.go 
b/protocol/triple/triple_protocol/triple_ext_test.go
index 639db4edb..353b58f48 100644
--- a/protocol/triple/triple_protocol/triple_ext_test.go
+++ b/protocol/triple/triple_protocol/triple_ext_test.go
@@ -378,6 +378,11 @@ func TestServer(t *testing.T) {
                        stream, err := client.CumSum(ctx)
                        assert.Nil(t, err)
                        stream.RequestHeader().Set(clientHeader, headerValue)
+                       if !expectSuccess { // server doesn't support HTTP/2
+                               failNoHTTP2(t, stream)
+                               cancel()
+                               return
+                       }
                        assert.Nil(t, stream.Send(&pingv1.CumSumRequest{Number: 
8}))
                        cancel()
                        // On a subsequent send, ensure that we are still 
catching context

Reply via email to