You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/08/05 11:04:30 UTC

[dubbo] branch 3.0 updated: [3.0] dubbo bootstrap start re-entry, export/refer new services (#8409)

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

albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 1832ff5  [3.0] dubbo bootstrap start re-entry, export/refer new services (#8409)
1832ff5 is described below

commit 1832ff597758bcbb80de024ddde589fd36ec5865
Author: Gong Dewei <ky...@qq.com>
AuthorDate: Thu Aug 5 19:03:44 2021 +0800

    [3.0] dubbo bootstrap start re-entry, export/refer new services (#8409)
    
    * dubbo bootstrap start re-entry, export/refer new services
    
    * avoid re-entry start method multiple times in same thread
---
 .../dubbo/config/bootstrap/DubboBootstrap.java     | 133 ++++++++++++---------
 1 file changed, 77 insertions(+), 56 deletions(-)

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 a70eab3..9d4c4d1 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
@@ -178,6 +178,8 @@ public class DubboBootstrap {
 
     private AtomicBoolean shutdown = new AtomicBoolean(false);
 
+    private volatile boolean isCurrentlyInStart = false;
+
     private volatile ServiceInstance serviceInstance;
 
     private volatile MetadataService metadataService;
@@ -1086,61 +1088,78 @@ public class DubboBootstrap {
     /**
      * Start the bootstrap
      */
-    public DubboBootstrap start() {
-        if (started.compareAndSet(false, true)) {
-            startup.set(false);
-            shutdown.set(false);
-            awaited.set(false);
+    public synchronized DubboBootstrap start() {
+        // avoid re-entry start method multiple times in same thread
+        if (isCurrentlyInStart){
+            return this;
+        }
 
-            initialize();
-            if (logger.isInfoEnabled()) {
-                logger.info(NAME + " is starting...");
-            }
-            // 1. export Dubbo Services
-            exportServices();
-
-            // If register consumer instance or has exported services
-            if (isRegisterConsumerInstance() || hasExportedServices()) {
-                // 2. export MetadataService
-                exportMetadataService();
-                // 3. Register the local ServiceInstance if required
-                registerServiceInstance();
-            }
+        isCurrentlyInStart = true;
+        try {
+            if (started.compareAndSet(false, true)) {
+                startup.set(false);
+                shutdown.set(false);
+                awaited.set(false);
 
-            referServices();
+                initialize();
 
-            // wait async export / refer finish if needed
-            awaitFinish();
+                if (logger.isInfoEnabled()) {
+                    logger.info(NAME + " is starting...");
+                }
 
-            if (isExportBackground() || isReferBackground()) {
-                new Thread(() -> {
-                    while (!asyncExportFinish || !asyncReferFinish) {
-                        try {
-                            Thread.sleep(1000);
-                        } catch (InterruptedException e) {
-                            logger.error(NAME + " waiting async export / refer occurred and error.", e);
-                        }
-                    }
+                doStart();
 
-                    startup.set(true);
-                    if (logger.isInfoEnabled()) {
-                        logger.info(NAME + " is ready.");
-                    }
-                    onStart();
-                }).start();
+                if (logger.isInfoEnabled()) {
+                    logger.info(NAME + " has started.");
+                }
             } else {
-                startup.set(true);
                 if (logger.isInfoEnabled()) {
-                    logger.info(NAME + " is ready.");
+                    logger.info(NAME + " is started, export/refer new services.");
                 }
-                onStart();
-            }
 
-            if (logger.isInfoEnabled()) {
-                logger.info(NAME + " has started.");
+                doStart();
+
+                if (logger.isInfoEnabled()) {
+                    logger.info(NAME + " finish export/refer new services.");
+                }
             }
+            return this;
+        } finally {
+            isCurrentlyInStart = false;
+        }
+    }
+
+    private void doStart() {
+        // 1. export Dubbo Services
+        exportServices();
+
+        // If register consumer instance or has exported services
+        if (isRegisterConsumerInstance() || hasExportedServices()) {
+            // 2. export MetadataService
+            exportMetadataService();
+            // 3. Register the local ServiceInstance if required
+            registerServiceInstance();
+        }
+
+        referServices();
+
+        // wait async export / refer finish if needed
+        awaitFinish();
+
+        if (isExportBackground() || isReferBackground()) {
+            new Thread(() -> {
+                while (!asyncExportFinish || !asyncReferFinish) {
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        logger.error(NAME + " waiting async export / refer occurred and error.", e);
+                    }
+                }
+                onStarted();
+            }).start();
+        } else {
+            onStarted();
         }
-        return this;
     }
 
     private boolean hasExportedServices() {
@@ -1243,10 +1262,9 @@ public class DubboBootstrap {
         }
     }
 
-    public DubboBootstrap awaitFinish() {
+    private void awaitFinish() {
         waitAsyncExportIfNeeded();
         waitAsyncReferIfNeeded();
-        return this;
     }
 
     public boolean isInitialized() {
@@ -1362,7 +1380,9 @@ public class DubboBootstrap {
             if (!serviceConfig.isRefreshed()) {
                 serviceConfig.refresh();
             }
-
+            if (sc.isExported()) {
+                continue;
+            }
             if (sc.shouldExportAsync()) {
                 ExecutorService executor = executorRepository.getServiceExportExecutor();
                 CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
@@ -1448,10 +1468,12 @@ public class DubboBootstrap {
     }
 
     private void registerServiceInstance() {
-        ApplicationConfig application = getApplication();
+        if (this.serviceInstance != null) {
+            return;
+        }
 
+        ApplicationConfig application = getApplication();
         String serviceName = application.getName();
-
         ServiceInstance serviceInstance = createServiceInstance(serviceName);
 
         try {
@@ -1555,7 +1577,11 @@ public class DubboBootstrap {
         }
     }
 
-    private void onStart() {
+    private void onStarted() {
+        startup.set(true);
+        if (logger.isInfoEnabled()) {
+            logger.info(NAME + " is ready.");
+        }
         ExtensionLoader<DubboBootstrapStartStopListener> exts = getExtensionLoader(DubboBootstrapStartStopListener.class);
         exts.getSupportedExtensionInstances().forEach(ext -> ext.onStart(this));
     }
@@ -1637,16 +1663,11 @@ public class DubboBootstrap {
 
     private void release() {
         executeMutually(() -> {
-            while (awaited.compareAndSet(false, true)) {
+            if (awaited.compareAndSet(false, true)) {
                 if (logger.isInfoEnabled()) {
                     logger.info(NAME + " is about to shutdown...");
                 }
                 condition.signalAll();
-                // sleep
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                }
             }
         });
     }