2020import org .apache .dubbo .common .URL ;
2121import org .apache .dubbo .common .logger .Logger ;
2222import org .apache .dubbo .common .logger .LoggerFactory ;
23+ import org .apache .dubbo .common .utils .CollectionUtils ;
2324import org .apache .dubbo .common .utils .ConcurrentHashSet ;
2425import org .apache .dubbo .common .utils .ConfigUtils ;
2526import org .apache .dubbo .common .utils .NamedThreadFactory ;
5253
5354/**
5455 * AbstractRegistry. (SPI, Prototype, ThreadSafe)
55- *
5656 */
5757public abstract class AbstractRegistry implements Registry {
5858
@@ -62,16 +62,16 @@ public abstract class AbstractRegistry implements Registry {
6262 private static final String URL_SPLIT = "\\ s+" ;
6363 // Log output
6464 protected final Logger logger = LoggerFactory .getLogger (getClass ());
65- // Local disk cache, where the special key value.registies records the list of registry centers, and the others are the list of notified service providers
65+ // Local disk cache, where the special key value.registries records the list of registry centers, and the others are the list of notified service providers
6666 private final Properties properties = new Properties ();
6767 // File cache timing writing
6868 private final ExecutorService registryCacheExecutor = Executors .newFixedThreadPool (1 , new NamedThreadFactory ("DubboSaveRegistryCache" , true ));
6969 // Is it synchronized to save the file
7070 private final boolean syncSaveFile ;
7171 private final AtomicLong lastCacheChanged = new AtomicLong ();
72- private final Set <URL > registered = new ConcurrentHashSet <URL >();
73- private final ConcurrentMap <URL , Set <NotifyListener >> subscribed = new ConcurrentHashMap <URL , Set < NotifyListener > >();
74- private final ConcurrentMap <URL , Map <String , List <URL >>> notified = new ConcurrentHashMap <URL , Map < String , List < URL >> >();
72+ private final Set <URL > registered = new ConcurrentHashSet <>();
73+ private final ConcurrentMap <URL , Set <NotifyListener >> subscribed = new ConcurrentHashMap <>();
74+ private final ConcurrentMap <URL , Map <String , List <URL >>> notified = new ConcurrentHashMap <>();
7575 private URL registryUrl ;
7676 // Local disk cache file
7777 private File file ;
@@ -91,13 +91,15 @@ public AbstractRegistry(URL url) {
9191 }
9292 }
9393 this .file = file ;
94+ // When starting the subscription center,
95+ // we need to read the local cache file for future Registry fault tolerance processing.
9496 loadProperties ();
9597 notify (url .getBackupUrls ());
9698 }
9799
98100 protected static List <URL > filterEmpty (URL url , List <URL > urls ) {
99- if (urls == null || urls .isEmpty ()) {
100- List <URL > result = new ArrayList <URL >(1 );
101+ if (CollectionUtils .isEmpty (urls )) {
102+ List <URL > result = new ArrayList <>(1 );
101103 result .add (url .setProtocol (Constants .EMPTY_PROTOCOL ));
102104 return result ;
103105 }
@@ -222,7 +224,7 @@ public List<URL> getCacheUrls(URL url) {
222224 && (Character .isLetter (key .charAt (0 )) || key .charAt (0 ) == '_' )
223225 && value != null && value .length () > 0 ) {
224226 String [] arr = value .trim ().split (URL_SPLIT );
225- List <URL > urls = new ArrayList <URL >();
227+ List <URL > urls = new ArrayList <>();
226228 for (String u : arr ) {
227229 urls .add (URL .valueOf (u ));
228230 }
@@ -234,7 +236,7 @@ public List<URL> getCacheUrls(URL url) {
234236
235237 @ Override
236238 public List <URL > lookup (URL url ) {
237- List <URL > result = new ArrayList <URL >();
239+ List <URL > result = new ArrayList <>();
238240 Map <String , List <URL >> notifiedUrls = getNotified ().get (url );
239241 if (notifiedUrls != null && notifiedUrls .size () > 0 ) {
240242 for (List <URL > urls : notifiedUrls .values ()) {
@@ -245,7 +247,7 @@ public List<URL> lookup(URL url) {
245247 }
246248 }
247249 } else {
248- final AtomicReference <List <URL >> reference = new AtomicReference <List < URL > >();
250+ final AtomicReference <List <URL >> reference = new AtomicReference <>();
249251 NotifyListener listener = reference ::set ;
250252 subscribe (url , listener ); // Subscribe logic guarantees the first notify to return
251253 List <URL > urls = reference .get ();
@@ -293,10 +295,7 @@ public void subscribe(URL url, NotifyListener listener) {
293295 if (logger .isInfoEnabled ()) {
294296 logger .info ("Subscribe: " + url );
295297 }
296-
297- Set <NotifyListener > listeners = subscribed .computeIfAbsent (url , k -> {
298- return new ConcurrentHashSet <>();
299- });
298+ Set <NotifyListener > listeners = subscribed .computeIfAbsent (url , n -> new ConcurrentHashSet <>());
300299 listeners .add (listener );
301300 }
302301
@@ -319,7 +318,7 @@ public void unsubscribe(URL url, NotifyListener listener) {
319318
320319 protected void recover () throws Exception {
321320 // register
322- Set <URL > recoverRegistered = new HashSet <URL >(getRegistered ());
321+ Set <URL > recoverRegistered = new HashSet <>(getRegistered ());
323322 if (!recoverRegistered .isEmpty ()) {
324323 if (logger .isInfoEnabled ()) {
325324 logger .info ("Recover register url " + recoverRegistered );
@@ -329,7 +328,7 @@ protected void recover() throws Exception {
329328 }
330329 }
331330 // subscribe
332- Map <URL , Set <NotifyListener >> recoverSubscribed = new HashMap <URL , Set < NotifyListener > >(getSubscribed ());
331+ Map <URL , Set <NotifyListener >> recoverSubscribed = new HashMap <>(getSubscribed ());
333332 if (!recoverSubscribed .isEmpty ()) {
334333 if (logger .isInfoEnabled ()) {
335334 logger .info ("Recover subscribe url " + recoverSubscribed .keySet ());
@@ -344,7 +343,7 @@ protected void recover() throws Exception {
344343 }
345344
346345 protected void notify (List <URL > urls ) {
347- if (urls == null || urls .isEmpty ()) {
346+ if (CollectionUtils .isEmpty (urls )) {
348347 return ;
349348 }
350349
@@ -368,43 +367,49 @@ protected void notify(List<URL> urls) {
368367 }
369368 }
370369
370+ /**
371+ * Notify changes from the Provider side.
372+ *
373+ * @param url consumer side url
374+ * @param listener listener
375+ * @param urls provider latest urls
376+ */
371377 protected void notify (URL url , NotifyListener listener , List <URL > urls ) {
372378 if (url == null ) {
373379 throw new IllegalArgumentException ("notify url == null" );
374380 }
375381 if (listener == null ) {
376382 throw new IllegalArgumentException ("notify listener == null" );
377383 }
378- if ((urls == null || urls .isEmpty ())
384+ if ((CollectionUtils .isEmpty (urls ))
379385 && !Constants .ANY_VALUE .equals (url .getServiceInterface ())) {
380386 logger .warn ("Ignore empty notify urls for subscribe url " + url );
381387 return ;
382388 }
383389 if (logger .isInfoEnabled ()) {
384390 logger .info ("Notify urls for subscribe url " + url + ", urls: " + urls );
385391 }
386- Map <String , List <URL >> result = new HashMap <String , List <URL >>();
392+ // keep every provider's category.
393+ Map <String , List <URL >> result = new HashMap <>();
387394 for (URL u : urls ) {
388395 if (UrlUtils .isMatch (url , u )) {
389396 String category = u .getParameter (Constants .CATEGORY_KEY , Constants .DEFAULT_CATEGORY );
390- List <URL > categoryList = result .computeIfAbsent (category , k -> {
391- return new ArrayList <>();
392- });
397+ List <URL > categoryList = result .computeIfAbsent (category , k -> new ArrayList <>());
393398 categoryList .add (u );
394399 }
395400 }
396401 if (result .size () == 0 ) {
397402 return ;
398403 }
399- Map <String , List <URL >> categoryNotified = notified .computeIfAbsent (url , k -> {
400- return new ConcurrentHashMap <>();
401- });
404+ Map <String , List <URL >> categoryNotified = notified .computeIfAbsent (url , u -> new ConcurrentHashMap <>());
402405 for (Map .Entry <String , List <URL >> entry : result .entrySet ()) {
403406 String category = entry .getKey ();
404407 List <URL > categoryList = entry .getValue ();
405408 categoryNotified .put (category , categoryList );
406- saveProperties (url );
407409 listener .notify (categoryList );
410+ // We will update our cache file after each notification.
411+ // When our Registry has a subscribe failure due to network jitter, we can return at least the existing cache URL.
412+ saveProperties (url );
408413 }
409414 }
410415
@@ -443,9 +448,9 @@ public void destroy() {
443448 if (logger .isInfoEnabled ()) {
444449 logger .info ("Destroy registry:" + getUrl ());
445450 }
446- Set <URL > destroyRegistered = new HashSet <URL >(getRegistered ());
451+ Set <URL > destroyRegistered = new HashSet <>(getRegistered ());
447452 if (!destroyRegistered .isEmpty ()) {
448- for (URL url : new HashSet <URL >(getRegistered ())) {
453+ for (URL url : new HashSet <>(getRegistered ())) {
449454 if (url .getParameter (Constants .DYNAMIC_KEY , true )) {
450455 try {
451456 unregister (url );
@@ -458,7 +463,7 @@ public void destroy() {
458463 }
459464 }
460465 }
461- Map <URL , Set <NotifyListener >> destroySubscribed = new HashMap <URL , Set < NotifyListener > >(getSubscribed ());
466+ Map <URL , Set <NotifyListener >> destroySubscribed = new HashMap <>(getSubscribed ());
462467 if (!destroySubscribed .isEmpty ()) {
463468 for (Map .Entry <URL , Set <NotifyListener >> entry : destroySubscribed .entrySet ()) {
464469 URL url = entry .getKey ();
0 commit comments