From 13b1c6189577dd240cd8f02d128525c471a4da23 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Sun, 3 Nov 2024 23:16:34 +0800 Subject: [PATCH] Update initial mapping apps of service discovery MappingListener --- .../client/ServiceDiscoveryRegistry.java | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java index b2ded478955..f84255abeb7 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java @@ -211,8 +211,12 @@ public void doSubscribe(URL url, NotifyListener listener) { mappingLock.lock(); mappingByUrl = serviceNameMapping.getMapping(url); try { - MappingListener mappingListener = new DefaultMappingListener(url, mappingByUrl, listener); + DefaultMappingListener mappingListener = new DefaultMappingListener(url, mappingByUrl, listener); mappingByUrl = serviceNameMapping.getAndListen(this.getUrl(), url, mappingListener); + // update the initial mapping apps we started to listen, to make sure it reflects the real value + // used do subscription before any event. + // it's protected by the mapping lock, so it won't override the event value. + mappingListener.updateInitialApps(mappingByUrl); synchronized (mappingListeners) { mappingListeners .computeIfAbsent(url.getProtocolServiceKey(), (k) -> new ConcurrentHashSet<>()) @@ -399,8 +403,8 @@ public Map getServiceListeners() { private class DefaultMappingListener implements MappingListener { private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DefaultMappingListener.class); private final URL url; - private Set oldApps; - private NotifyListener listener; + private final NotifyListener listener; + private volatile Set oldApps; private volatile boolean stopped; public DefaultMappingListener(URL subscribedURL, Set serviceNames, NotifyListener listener) { @@ -424,16 +428,15 @@ public synchronized void onEvent(MappingChangedEvent event) { Set newApps = event.getApps(); Set tempOldApps = oldApps; - if (CollectionUtils.isEmpty(newApps) || CollectionUtils.equals(newApps, tempOldApps)) { - return; - } - - logger.info( - "Mapping of service " + event.getServiceKey() + "changed from " + tempOldApps + " to " + newApps); - Lock mappingLock = serviceNameMapping.getMappingLock(event.getServiceKey()); try { mappingLock.lock(); + if (CollectionUtils.isEmpty(newApps) || CollectionUtils.equals(newApps, tempOldApps)) { + return; + } + logger.info("Mapping of service " + event.getServiceKey() + "changed from " + tempOldApps + " to " + + newApps); + if (CollectionUtils.isEmpty(tempOldApps) && !newApps.isEmpty()) { serviceNameMapping.putCachedMapping(ServiceNameMapping.buildMappingKey(url), newApps); subscribeURLs(url, listener, newApps); @@ -478,6 +481,14 @@ protected NotifyListener getListener() { return listener; } + // writing of oldApps is protected by mapping lock to guarantee sequence consistency. + public void updateInitialApps(Set oldApps) { + if (oldApps != null && !CollectionUtils.equals(oldApps, this.oldApps)) { + this.oldApps = oldApps; + logger.info("Update initial mapping apps from " + this.oldApps + " to " + oldApps); + } + } + @Override public void stop() { stopped = true;