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

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


The following commit(s) were added to refs/heads/3.2 by this push:
     new 1dd248affa Service offline speedup (#12869)
1dd248affa is described below

commit 1dd248affa1c38a10c8fa920a50e8c6d740fab63
Author: Albumen Kevin <[email protected]>
AuthorDate: Wed Aug 9 17:11:16 2023 +0800

    Service offline speedup (#12869)
    
    * Service offline speedup
    
    * Service offline speedup
---
 .../apache/dubbo/qos/command/impl/BaseOffline.java | 35 ++++++++++++++++------
 .../dubbo/qos/command/impl/GracefulShutdown.java   |  2 +-
 .../registry/integration/RegistryProtocol.java     | 19 +++++++++---
 3 files changed, 42 insertions(+), 14 deletions(-)

diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java
 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java
index 1832d0b55d..1eda8f6a76 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.qos.command.impl;
 
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
 import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.qos.api.BaseCommand;
 import org.apache.dubbo.qos.api.CommandContext;
@@ -29,14 +30,20 @@ import org.apache.dubbo.rpc.model.ProviderModel;
 import org.apache.dubbo.rpc.model.ServiceMetadata;
 
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
 
 public class BaseOffline implements BaseCommand {
     private static final Logger logger = 
LoggerFactory.getLogger(BaseOffline.class);
     public FrameworkServiceRepository serviceRepository;
+    private ExecutorService executorService;
 
     public BaseOffline(FrameworkModel frameworkModel) {
         this.serviceRepository = frameworkModel.getServiceRepository();
+        this.executorService = 
frameworkModel.getBeanFactory().getBean(FrameworkExecutorRepository.class).getSharedExecutor();
     }
 
     @Override
@@ -63,18 +70,28 @@ public class BaseOffline implements BaseCommand {
     public boolean offline(String servicePattern) {
         boolean hasService = false;
 
-        Collection<ProviderModel> providerModelList = 
serviceRepository.allProviderModels();
-        for (ProviderModel providerModel : providerModelList) {
-            ServiceMetadata metadata = providerModel.getServiceMetadata();
-            if (metadata.getServiceKey().matches(servicePattern) || 
metadata.getDisplayServiceKey().matches(servicePattern)) {
-                hasService = true;
-                List<ProviderModel.RegisterStatedURL> statedUrls = 
providerModel.getStatedUrl();
-                for (ProviderModel.RegisterStatedURL statedURL : statedUrls) {
-                    if (statedURL.isRegistered()) {
-                        doUnexport(statedURL);
+        try {
+            List<CompletableFuture<Void>> futures = new LinkedList<>();
+            Collection<ProviderModel> providerModelList = 
serviceRepository.allProviderModels();
+            for (ProviderModel providerModel : providerModelList) {
+                ServiceMetadata metadata = providerModel.getServiceMetadata();
+                if (metadata.getServiceKey().matches(servicePattern) || 
metadata.getDisplayServiceKey().matches(servicePattern)) {
+                    hasService = true;
+                    List<ProviderModel.RegisterStatedURL> statedUrls = 
providerModel.getStatedUrl();
+                    for (ProviderModel.RegisterStatedURL statedURL : 
statedUrls) {
+                        if (statedURL.isRegistered()) {
+                            futures.add(CompletableFuture.runAsync(() -> {
+                                doUnexport(statedURL);
+                            }, executorService));
+                        }
                     }
                 }
             }
+            for (CompletableFuture<Void> future : futures) {
+                future.get();
+            }
+        } catch (ExecutionException | InterruptedException e) {
+            throw new RuntimeException(e);
         }
 
         return hasService;
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GracefulShutdown.java
 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GracefulShutdown.java
index c4fa69557d..f21e6473f8 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GracefulShutdown.java
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GracefulShutdown.java
@@ -37,11 +37,11 @@ public class GracefulShutdown implements BaseCommand {
 
     @Override
     public String execute(CommandContext commandContext, String[] args) {
-        offline.execute(commandContext, new String[0]);
         for (org.apache.dubbo.rpc.GracefulShutdown gracefulShutdown :
             
org.apache.dubbo.rpc.GracefulShutdown.getGracefulShutdowns(frameworkModel)) {
             gracefulShutdown.readonly();
         }
+        offline.execute(commandContext, new String[0]);
         return "OK";
     }
 }
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
index 9db1323951..f56ab73802 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
@@ -1016,11 +1016,22 @@ public class RegistryProtocol implements Protocol, 
ScopeModelAware {
         public synchronized void unregister() {
             if (registered.compareAndSet(true, false)) {
                 Registry registry = 
RegistryProtocol.this.getRegistry(getRegistryUrl(originInvoker));
-                try {
-                    registry.unregister(registerUrl);
-                } catch (Throwable t) {
-                    logger.warn(INTERNAL_ERROR, "unknown error in registry 
module", "", t.getMessage(), t);
+
+                ProviderModel providerModel = 
frameworkModel.getServiceRepository()
+                    .lookupExportedService(getRegisterUrl().getServiceKey());
+
+                List<ProviderModel.RegisterStatedURL> statedUrls = 
providerModel.getStatedUrl();
+                if (statedUrls.stream()
+                    .filter(u -> u.getRegistryUrl().equals(getRegisterUrl())
+                        && 
u.getProviderUrl().getProtocol().equals(getRegisterUrl().getProtocol()))
+                    .anyMatch(ProviderModel.RegisterStatedURL::isRegistered)) {
+                    try {
+                        registry.unregister(registerUrl);
+                    } catch (Throwable t) {
+                        logger.warn(INTERNAL_ERROR, "unknown error in registry 
module", "", t.getMessage(), t);
+                    }
                 }
+
                 try {
                     if (subscribeUrl != null) {
                         Map<URL, Set<NotifyListener>> overrideListeners = 
getProviderConfigurationListener(subscribeUrl).getOverrideListeners();

Reply via email to