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

zihaoxiang pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 94e39c65fb [Fix-16811] [JdbcRegistry] Clear the jdbc EPHEMERAL data 
and lock which client is not exist (#16837)
94e39c65fb is described below

commit 94e39c65fb4ac3fa9c8dc18e5b5a8168b04fb1b9
Author: Wenjun Ruan <[email protected]>
AuthorDate: Tue Nov 26 21:23:06 2024 +0800

    [Fix-16811] [JdbcRegistry] Clear the jdbc EPHEMERAL data and lock which 
client is not exist (#16837)
---
 .../plugin/registry/jdbc/JdbcRegistry.java         |  1 +
 .../jdbc/client/JdbcRegistryClientIdentify.java    |  6 +-
 .../model/DTO/JdbcRegistryClientHeartbeatDTO.java  |  4 +-
 .../repository/JdbcRegistryLockRepository.java     |  8 +++
 .../jdbc/server/IJdbcRegistryDataManager.java      |  5 ++
 .../jdbc/server/JdbcRegistryDataManager.java       |  7 +-
 .../registry/jdbc/server/JdbcRegistryServer.java   | 81 ++++++++++++----------
 7 files changed, 70 insertions(+), 42 deletions(-)

diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistry.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistry.java
index cc646e12e5..11e3f62172 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistry.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistry.java
@@ -262,6 +262,7 @@ public final class JdbcRegistry implements Registry {
         log.info("Closing Jdbc Registry...");
         // remove the current Ephemeral node, if can connect to jdbc
         try (JdbcRegistryClient closed1 = jdbcRegistryClient) {
+            
JdbcRegistryThreadFactory.getDefaultSchedulerThreadExecutor().shutdownNow();
         } catch (Exception e) {
             log.error("Close Jdbc Registry error", e);
         }
diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/client/JdbcRegistryClientIdentify.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/client/JdbcRegistryClientIdentify.java
index b6c8e0986e..008b9a3a9d 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/client/JdbcRegistryClientIdentify.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/client/JdbcRegistryClientIdentify.java
@@ -18,11 +18,9 @@
 package org.apache.dolphinscheduler.plugin.registry.jdbc.client;
 
 import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.ToString;
+import lombok.Data;
 
-@ToString
-@Getter
+@Data
 @AllArgsConstructor
 public class JdbcRegistryClientIdentify {
 
diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/model/DTO/JdbcRegistryClientHeartbeatDTO.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/model/DTO/JdbcRegistryClientHeartbeatDTO.java
index 1f006291f5..5caa00eeab 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/model/DTO/JdbcRegistryClientHeartbeatDTO.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/model/DTO/JdbcRegistryClientHeartbeatDTO.java
@@ -21,6 +21,7 @@ import org.apache.dolphinscheduler.common.utils.JSONUtils;
 import 
org.apache.dolphinscheduler.plugin.registry.jdbc.model.DO.JdbcRegistryClientHeartbeat;
 
 import java.util.Date;
+import java.util.concurrent.TimeUnit;
 
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -36,7 +37,6 @@ public class JdbcRegistryClientHeartbeatDTO {
 
     private Long id;
 
-    // clientName
     private String clientName;
 
     private Long lastHeartbeatTime;
@@ -90,7 +90,7 @@ public class JdbcRegistryClientHeartbeatDTO {
     public static class ClientConfig {
 
         @Builder.Default
-        private long sessionTimeout = 60 * 1000L;
+        private long sessionTimeout = TimeUnit.SECONDS.toMillis(60);
 
     }
 
diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/repository/JdbcRegistryLockRepository.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/repository/JdbcRegistryLockRepository.java
index ef7e23fbbf..7133b3e534 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/repository/JdbcRegistryLockRepository.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/repository/JdbcRegistryLockRepository.java
@@ -26,6 +26,7 @@ import 
org.apache.dolphinscheduler.plugin.registry.jdbc.model.DTO.JdbcRegistryLo
 import org.apache.commons.collections4.CollectionUtils;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -36,6 +37,13 @@ public class JdbcRegistryLockRepository {
     @Autowired
     private JdbcRegistryLockMapper jdbcRegistryLockMapper;
 
+    public List<JdbcRegistryLockDTO> queryAll() {
+        return jdbcRegistryLockMapper.selectList(null)
+                .stream()
+                .map(JdbcRegistryLockDTO::fromJdbcRegistryLock)
+                .collect(Collectors.toList());
+    }
+
     public void deleteByClientIds(List<Long> clientIds) {
         if (CollectionUtils.isEmpty(clientIds)) {
             return;
diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/IJdbcRegistryDataManager.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/IJdbcRegistryDataManager.java
index 1c12f8cd8e..86db4de6ab 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/IJdbcRegistryDataManager.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/IJdbcRegistryDataManager.java
@@ -27,6 +27,11 @@ public interface IJdbcRegistryDataManager {
 
     boolean existKey(String key);
 
+    /**
+     * Get all the {@link JdbcRegistryDataDTO}.
+     */
+    List<JdbcRegistryDataDTO> getAllJdbcRegistryData();
+
     /**
      * Get the {@link JdbcRegistryDataDTO} by key.
      */
diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataManager.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataManager.java
index 5d44949b3f..e0f091bde7 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataManager.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataManager.java
@@ -135,6 +135,11 @@ public class JdbcRegistryDataManager
         return jdbcRegistryDataRepository.selectByKey(key).isPresent();
     }
 
+    @Override
+    public List<JdbcRegistryDataDTO> getAllJdbcRegistryData() {
+        return jdbcRegistryDataRepository.selectAll();
+    }
+
     @Override
     public Optional<JdbcRegistryDataDTO> getRegistryDataByKey(String key) {
         checkNotNull(key);
@@ -212,7 +217,7 @@ public class JdbcRegistryDataManager
             return;
         }
         jdbcRegistryDataRepository.deleteByKey(key);
-        JdbcRegistryDataChanceEventDTO registryDataChanceEvent = 
JdbcRegistryDataChanceEventDTO.builder()
+        final JdbcRegistryDataChanceEventDTO registryDataChanceEvent = 
JdbcRegistryDataChanceEventDTO.builder()
                 .jdbcRegistryData(jdbcRegistryDataOptional.get())
                 .eventType(JdbcRegistryDataChanceEventDTO.EventType.DELETE)
                 .createTime(new Date())
diff --git 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
index 0ac985dae3..e04360bc6f 100644
--- 
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
+++ 
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
@@ -33,11 +33,13 @@ import 
org.apache.dolphinscheduler.plugin.registry.jdbc.repository.JdbcRegistryL
 import org.apache.dolphinscheduler.registry.api.RegistryException;
 
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.time.StopWatch;
 
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
@@ -100,25 +102,22 @@ public class JdbcRegistryServer implements 
IJdbcRegistryServer {
             // The server is already started or stopped, will not start again.
             return;
         }
-        // Purge the previous client to avoid the client is still in the 
registry.
-        purgePreviousJdbcRegistryClient();
         // Start the Purge thread
-        // The Purge thread will remove the client from the registry, and 
remove it's related data and lock.
-        // Connect to the database, load the data and lock.
-        purgeDeadJdbcRegistryClient();
-        JdbcRegistryThreadFactory.getDefaultSchedulerThreadExecutor()
-                .scheduleWithFixedDelay(this::purgeDeadJdbcRegistryClient,
-                        
jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis(),
-                        
jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis(),
-                        TimeUnit.MILLISECONDS);
+        // The Purge thread will clear the invalidated data
+        purgeInvalidJdbcRegistryMetadata();
+        
JdbcRegistryThreadFactory.getDefaultSchedulerThreadExecutor().scheduleWithFixedDelay(
+                this::purgeInvalidJdbcRegistryMetadata,
+                
jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis(),
+                
jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis(),
+                TimeUnit.MILLISECONDS);
         jdbcRegistryDataManager.start();
         jdbcRegistryServerState = JdbcRegistryServerState.STARTED;
         doTriggerOnConnectedListener();
-        JdbcRegistryThreadFactory.getDefaultSchedulerThreadExecutor()
-                .scheduleWithFixedDelay(this::refreshClientsHeartbeat,
-                        0,
-                        
jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis(),
-                        TimeUnit.MILLISECONDS);
+        
JdbcRegistryThreadFactory.getDefaultSchedulerThreadExecutor().scheduleWithFixedDelay(
+                this::refreshClientsHeartbeat,
+                0,
+                
jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis(),
+                TimeUnit.MILLISECONDS);
     }
 
     @SneakyThrows
@@ -139,9 +138,8 @@ public class JdbcRegistryServer implements 
IJdbcRegistryServer {
                 .lastHeartbeatTime(System.currentTimeMillis())
                 .build();
 
-        while 
(jdbcRegistryClientDTOMap.containsKey(jdbcRegistryClientIdentify)) {
-            log.warn("The client {} is already exist the registry.", 
jdbcRegistryClientIdentify.getClientId());
-            
Thread.sleep(jdbcRegistryProperties.getHeartbeatRefreshInterval().toMillis());
+        if (jdbcRegistryClientDTOMap.containsKey(jdbcRegistryClientIdentify)) {
+            throw new IllegalArgumentException("The client is already 
registered: " + jdbcRegistryClientIdentify);
         }
         jdbcRegistryClientRepository.insert(registryClientDTO);
         jdbcRegistryClients.add(jdbcRegistryClient);
@@ -260,34 +258,47 @@ public class JdbcRegistryServer implements 
IJdbcRegistryServer {
         jdbcRegistryClientDTOMap.clear();
     }
 
-    private void purgePreviousJdbcRegistryClient() {
+    private void purgeInvalidJdbcRegistryMetadata() {
+        final StopWatch stopWatch = StopWatch.createStarted();
         if (jdbcRegistryServerState == JdbcRegistryServerState.STOPPED) {
             return;
         }
-        List<Long> previousJdbcRegistryClientIds = 
jdbcRegistryClientRepository.queryAll()
-                .stream()
-                .filter(jdbcRegistryClientHeartbeat -> 
jdbcRegistryClientHeartbeat.getClientName()
-                        
.equals(jdbcRegistryProperties.getJdbcRegistryClientName()))
-                .map(JdbcRegistryClientHeartbeatDTO::getId)
-                .collect(Collectors.toList());
-        doPurgeJdbcRegistryClientInDB(previousJdbcRegistryClientIds);
-
-    }
-
-    private void purgeDeadJdbcRegistryClient() {
-        if (jdbcRegistryServerState == JdbcRegistryServerState.STOPPED) {
-            return;
-        }
-        List<Long> deadJdbcRegistryClientIds = 
jdbcRegistryClientRepository.queryAll()
+        // remove the client which is already dead from the registry, and 
remove it's related data and lock.
+        final List<JdbcRegistryClientHeartbeatDTO> jdbcRegistryClients = 
jdbcRegistryClientRepository.queryAll();
+        final List<Long> deadJdbcRegistryClientIds = jdbcRegistryClients
                 .stream()
                 .filter(JdbcRegistryClientHeartbeatDTO::isDead)
                 .map(JdbcRegistryClientHeartbeatDTO::getId)
                 .collect(Collectors.toList());
         doPurgeJdbcRegistryClientInDB(deadJdbcRegistryClientIds);
 
+        // remove the data and lock which client is not exist.
+        final Set<Long> existJdbcRegistryClientIds = jdbcRegistryClients
+                .stream()
+                .map(JdbcRegistryClientHeartbeatDTO::getId)
+                .collect(Collectors.toSet());
+        jdbcRegistryDataManager.getAllJdbcRegistryData()
+                .stream()
+                .filter(jdbcRegistryDataDTO -> 
!existJdbcRegistryClientIds.contains(jdbcRegistryDataDTO.getClientId()))
+                .filter(jdbcRegistryDataDTO -> 
DataType.EPHEMERAL.name().equals(jdbcRegistryDataDTO.getDataType()))
+                .forEach(jdbcRegistryData -> {
+                    log.info("Remove the JdbcRegistryData: {} which client is 
not exist in the registry",
+                            jdbcRegistryData);
+                    
jdbcRegistryDataManager.deleteJdbcRegistryDataByKey(jdbcRegistryData.getDataKey());
+                });
+        jdbcRegistryLockRepository.queryAll()
+                .stream()
+                .filter(jdbcRegistryLockDTO -> 
!existJdbcRegistryClientIds.contains(jdbcRegistryLockDTO.getClientId()))
+                .forEach(jdbcRegistryLockDTO -> {
+                    log.info("Remove the JdbcRegistryLock: {} which client is 
not exist in the registry",
+                            jdbcRegistryLockDTO);
+                    
jdbcRegistryLockRepository.deleteById(jdbcRegistryLockDTO.getId());
+                });
+        stopWatch.stop();
+        log.debug("Success purge invalid jdbcRegistryMetadata, cost: {} ms", 
stopWatch.getTime());
     }
 
-    private void doPurgeJdbcRegistryClientInDB(List<Long> 
jdbcRegistryClientIds) {
+    private void doPurgeJdbcRegistryClientInDB(final List<Long> 
jdbcRegistryClientIds) {
         if (CollectionUtils.isEmpty(jdbcRegistryClientIds)) {
             return;
         }

Reply via email to