You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2020/03/13 06:17:45 UTC

[dubbo] branch 2.7.6-release updated: avoid potential shutdown race condition. (#5856)

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

liujun pushed a commit to branch 2.7.6-release
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/2.7.6-release by this push:
     new 1b937ac  avoid potential shutdown race condition. (#5856)
1b937ac is described below

commit 1b937ac1e46d45a6110bc22fd59ba29007a73bea
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri Mar 13 14:17:32 2020 +0800

    avoid potential shutdown race condition. (#5856)
---
 .../apache/dubbo/config/context/ConfigManager.java |  1 -
 .../org/apache/dubbo/config/DubboShutdownHook.java | 14 +++---
 .../dubbo/config/bootstrap/DubboBootstrap.java     | 52 ++++++++--------------
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
index 9c9e185..81e4bc9 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
@@ -365,7 +365,6 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
         }
     }
 
-    // For test purpose
     public void clear() {
         write(() -> {
             this.configsCache.clear();
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java
index 56dab50..df2a295 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java
@@ -115,6 +115,14 @@ public class DubboShutdownHook extends Thread {
         dispatch(new DubboServiceDestroyedEvent(this));
     }
 
+    private void dispatch(Event event) {
+        eventDispatcher.dispatch(event);
+    }
+
+    public boolean getRegistered() {
+        return registered.get();
+    }
+
     public static void destroyAll() {
         if (destroyed.compareAndSet(false, true)) {
             AbstractRegistryFactory.destroyAll();
@@ -122,14 +130,10 @@ public class DubboShutdownHook extends Thread {
         }
     }
 
-    private void dispatch(Event event) {
-        eventDispatcher.dispatch(event);
-    }
-
     /**
      * Destroy all the protocols.
      */
-    private static void destroyProtocols() {
+    public static void destroyProtocols() {
         ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
         for (String protocolName : loader.getLoadedExtensions()) {
             try {
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
index ccdaa98..8780d9d 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
@@ -67,7 +67,6 @@ import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-import org.apache.dubbo.rpc.Protocol;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.io.IOException;
@@ -135,6 +134,8 @@ public class DubboBootstrap extends GenericEventListener {
 
     private final Condition condition = lock.newCondition();
 
+    private final Lock destroyLock = new ReentrantLock();
+
     private final ExecutorService executorService = newSingleThreadExecutor();
 
     private final EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
@@ -1033,45 +1034,30 @@ public class DubboBootstrap extends GenericEventListener {
     }
 
     public void destroy() {
-        // for compatibility purpose
-        DubboShutdownHook.destroyAll();
-
-        if (started.compareAndSet(true, false)
-                && destroyed.compareAndSet(false, true)) {
+        if (destroyLock.tryLock()) {
+            try {
+                DubboShutdownHook.destroyAll();
 
-            unregisterServiceInstance();
-            unexportMetadataService();
-            unexportServices();
-            unreferServices();
+                if (started.compareAndSet(true, false)
+                        && destroyed.compareAndSet(false, true)) {
 
-            destroyRegistries();
-            destroyProtocols();
-            destroyServiceDiscoveries();
+                    unregisterServiceInstance();
+                    unexportMetadataService();
+                    unexportServices();
+                    unreferServices();
 
-            clear();
-            shutdown();
-            release();
-        }
-    }
+                    destroyRegistries();
+                    DubboShutdownHook.destroyProtocols();
+                    destroyServiceDiscoveries();
 
-    /**
-     * Destroy all the protocols.
-     */
-    private void destroyProtocols() {
-        ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
-        for (String protocolName : loader.getLoadedExtensions()) {
-            try {
-                Protocol protocol = loader.getLoadedExtension(protocolName);
-                if (protocol != null) {
-                    protocol.destroy();
+                    clear();
+                    shutdown();
+                    release();
                 }
-            } catch (Throwable t) {
-                logger.warn(t.getMessage(), t);
+            } finally {
+                destroyLock.unlock();
             }
         }
-        if (logger.isDebugEnabled()) {
-            logger.debug(NAME + "'s all ProtocolConfigs have been destroyed.");
-        }
     }
 
     private void destroyRegistries() {