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 54b65bdef refactor(extension): use registry for shutdown callbacks 
(#3388)
54b65bdef is described below

commit 54b65bdef41abad81eef5ef4de768b5ac5c86dba
Author: 吴杨帆 <[email protected]>
AuthorDate: Sun Jun 14 15:40:42 2026 +0800

    refactor(extension): use registry for shutdown callbacks (#3388)
    
    * refactor(extension): use registry for shutdown callbacks
    
    * refactor(extension): simplify shutdown callback registration
---
 common/extension/graceful_shutdown.go      | 30 +++++-------------------------
 common/extension/graceful_shutdown_test.go | 21 +++++++++++++++++++++
 common/extension/registry_type.go          | 10 ++++++++++
 common/extension/registry_type_test.go     | 15 ++++++++++++---
 4 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/common/extension/graceful_shutdown.go 
b/common/extension/graceful_shutdown.go
index 5468ed5de..147c30139 100644
--- a/common/extension/graceful_shutdown.go
+++ b/common/extension/graceful_shutdown.go
@@ -36,8 +36,7 @@ var (
        customShutdownCallbacks     = list.New()
        customShutdownCallbacksLock sync.RWMutex
        customShutdownCallbacksMu   = &customShutdownCallbacksLock
-       gracefulShutdownCallbacksMu sync.RWMutex
-       gracefulShutdownCallbacks   = make(map[string]GracefulShutdownCallback)
+       gracefulShutdownCallbacks   = 
NewRegistry[GracefulShutdownCallback]("graceful shutdown callback")
 )
 
 /**
@@ -81,41 +80,22 @@ func GetAllCustomShutdownCallbacks() *list.List {
 
 // RegisterGracefulShutdownCallback registers a protocol-level graceful 
shutdown callback.
 func RegisterGracefulShutdownCallback(name string, f GracefulShutdownCallback) 
{
-       gracefulShutdownCallbacksMu.Lock()
-       defer gracefulShutdownCallbacksMu.Unlock()
-
-       if _, exists := gracefulShutdownCallbacks[name]; exists {
+       if !gracefulShutdownCallbacks.RegisterIfAbsent(name, f) {
                logger.Warnf("[GracefulShutdown] graceful shutdown callback %q 
already registered, duplicate registration ignored", name)
-               return
        }
-
-       gracefulShutdownCallbacks[name] = f
 }
 
 // LookupGracefulShutdownCallback returns a protocol graceful shutdown 
callback by name.
 func LookupGracefulShutdownCallback(name string) (GracefulShutdownCallback, 
bool) {
-       gracefulShutdownCallbacksMu.RLock()
-       defer gracefulShutdownCallbacksMu.RUnlock()
-       f, ok := gracefulShutdownCallbacks[name]
-       return f, ok
+       return gracefulShutdownCallbacks.Get(name)
 }
 
 // UnregisterGracefulShutdownCallback removes a protocol graceful shutdown 
callback by name.
 func UnregisterGracefulShutdownCallback(name string) {
-       gracefulShutdownCallbacksMu.Lock()
-       defer gracefulShutdownCallbacksMu.Unlock()
-       delete(gracefulShutdownCallbacks, name)
+       gracefulShutdownCallbacks.Unregister(name)
 }
 
 // GracefulShutdownCallbacks returns a snapshot of all protocol graceful 
shutdown callbacks.
 func GracefulShutdownCallbacks() map[string]GracefulShutdownCallback {
-       gracefulShutdownCallbacksMu.RLock()
-       defer gracefulShutdownCallbacksMu.RUnlock()
-
-       callbacks := make(map[string]GracefulShutdownCallback, 
len(gracefulShutdownCallbacks))
-       for name, callback := range gracefulShutdownCallbacks {
-               callbacks[name] = callback
-       }
-
-       return callbacks
+       return gracefulShutdownCallbacks.Snapshot()
 }
diff --git a/common/extension/graceful_shutdown_test.go 
b/common/extension/graceful_shutdown_test.go
index 311530936..0fca07c11 100644
--- a/common/extension/graceful_shutdown_test.go
+++ b/common/extension/graceful_shutdown_test.go
@@ -40,6 +40,27 @@ func TestGracefulShutdownCallbacksReturnsSnapshot(t 
*testing.T) {
        }
 }
 
+func TestRegisterGracefulShutdownCallbackIgnoresDuplicate(t *testing.T) {
+       t.Cleanup(func() {
+               UnregisterGracefulShutdownCallback("duplicate-test")
+       })
+
+       RegisterGracefulShutdownCallback("duplicate-test", 
func(context.Context) error {
+               return context.Canceled
+       })
+       RegisterGracefulShutdownCallback("duplicate-test", 
func(context.Context) error {
+               return context.DeadlineExceeded
+       })
+
+       callback, ok := LookupGracefulShutdownCallback("duplicate-test")
+       if !ok {
+               t.Fatal("expected registered callback")
+       }
+       if err := callback(context.Background()); err != context.Canceled {
+               t.Fatalf("expected first callback to remain registered, got 
%v", err)
+       }
+}
+
 func TestGetAllCustomShutdownCallbacksReturnsSnapshot(t *testing.T) {
        customShutdownCallbacksMu.Lock()
        original := customShutdownCallbacks
diff --git a/common/extension/registry_type.go 
b/common/extension/registry_type.go
index 9e601998d..c4f7f7a15 100644
--- a/common/extension/registry_type.go
+++ b/common/extension/registry_type.go
@@ -41,6 +41,16 @@ func (r *Registry[T]) Register(name string, v T) {
        r.items[name] = v
 }
 
+func (r *Registry[T]) RegisterIfAbsent(name string, v T) bool {
+       r.mu.Lock()
+       defer r.mu.Unlock()
+       if _, ok := r.items[name]; ok {
+               return false
+       }
+       r.items[name] = v
+       return true
+}
+
 func (r *Registry[T]) Get(name string) (T, bool) {
        r.mu.RLock()
        defer r.mu.RUnlock()
diff --git a/common/extension/registry_type_test.go 
b/common/extension/registry_type_test.go
index 0a7aedadc..e3ca761f2 100644
--- a/common/extension/registry_type_test.go
+++ b/common/extension/registry_type_test.go
@@ -38,11 +38,21 @@ func TestRegistryBasicOps(t *testing.T) {
        assert.True(t, ok)
        assert.Equal(t, 1, v)
 
+       assert.False(t, r.RegisterIfAbsent("a", 2))
+       v, ok = r.Get("a")
+       assert.True(t, ok)
+       assert.Equal(t, 1, v)
+
+       assert.True(t, r.RegisterIfAbsent("b", 2))
+       v, ok = r.Get("b")
+       assert.True(t, ok)
+       assert.Equal(t, 2, v)
+
        must := r.MustGet("a")
        assert.Equal(t, 1, must)
 
        snapshot := r.Snapshot()
-       assert.Equal(t, map[string]int{"a": 1}, snapshot)
+       assert.Equal(t, map[string]int{"a": 1, "b": 2}, snapshot)
        snapshot["a"] = 99
 
        v, ok = r.Get("a")
@@ -50,8 +60,7 @@ func TestRegistryBasicOps(t *testing.T) {
        assert.Equal(t, 1, v)
 
        names := r.Names()
-       assert.Len(t, names, 1)
-       assert.Equal(t, "a", names[0])
+       assert.ElementsMatch(t, []string{"a", "b"}, names)
 
        r.Unregister("a")
        _, ok = r.Get("a")

Reply via email to