From 0ed1d61e7620392c909cff011b00624ec50be809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E4=B8=9C=E5=8D=8E?= <591327356@qq.com> Date: Fri, 2 Jun 2023 12:04:20 +0800 Subject: [PATCH] Fixed the reloadRules method that caused ruleMetaData.getRules() to be null briefly --- .../database/ShardingSphereDatabase.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java index 0cd0869d263b7..5428a9ebebbf7 100644 --- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java +++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java @@ -43,6 +43,8 @@ import java.util.LinkedList; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; /** * ShardingSphere database. @@ -189,13 +191,24 @@ public boolean containsDataSource() { */ public synchronized void reloadRules(final Class ruleClass) { Collection toBeReloadedRules = ruleMetaData.findRules(ruleClass); - RuleConfiguration ruleConfig = toBeReloadedRules.stream().map(ShardingSphereRule::getConfiguration).findFirst().orElse(null); - Collection databaseRules = new LinkedList<>(ruleMetaData.getRules()); - toBeReloadedRules.stream().findFirst().ifPresent(optional -> { + if (toBeReloadedRules != null && toBeReloadedRules.size() != 0) { + RuleConfiguration ruleConfig = toBeReloadedRules.stream().map(ShardingSphereRule::getConfiguration).findFirst().orElse(null); + CopyOnWriteArrayList databaseRules = new CopyOnWriteArrayList<>(ruleMetaData.getRules()); databaseRules.removeAll(toBeReloadedRules); - databaseRules.add(((MutableDataNodeRule) optional).reloadRule(ruleConfig, name, resourceMetaData.getDataSources(), databaseRules)); - }); - ruleMetaData.getRules().clear(); - ruleMetaData.getRules().addAll(databaseRules); + ShardingSphereRule newShardingSphereRule = ((MutableDataNodeRule) toBeReloadedRules.stream().findFirst().get()) + .reloadRule(ruleConfig, name, resourceMetaData.getDataSources(), databaseRules); + // Only replace one, and the rest will be cleared later (normal logic will only have one, in order to be consistent with the previous logic) + // replaceAll atomic operation, do logical assembly in advance, and finally directly replace the underlying array through setArray + AtomicBoolean replaced = new AtomicBoolean(false); + ((CopyOnWriteArrayList) ruleMetaData.getRules()).replaceAll(shardingSphereRule -> { + if (!replaced.get() && toBeReloadedRules.contains(shardingSphereRule)) { + replaced.set(true); + return newShardingSphereRule; + } + return shardingSphereRule; + }); + // Clearing toBeReloaded Rules is the case for more than one + ruleMetaData.getRules().removeAll(toBeReloadedRules); + } } }