34
34
import io .seata .config .Configuration ;
35
35
import io .seata .config .ConfigurationFactory ;
36
36
import io .seata .discovery .registry .RegistryService ;
37
+ import java .util .Objects ;
37
38
import org .slf4j .Logger ;
38
39
import org .slf4j .LoggerFactory ;
39
40
@@ -85,7 +86,7 @@ public class EtcdRegistryServiceImpl implements RegistryService<Watch.Listener>
85
86
private final static long LIFE_KEEP_CRITICAL = 6 ;
86
87
private static volatile EtcdRegistryServiceImpl instance ;
87
88
private static volatile Client client ;
88
- private ConcurrentMap <String , List <InetSocketAddress >> clusterAddressMap ;
89
+ private ConcurrentMap <String , Pair < Long /*revision*/ , List <InetSocketAddress > >> clusterAddressMap ;
89
90
private ConcurrentMap <String , Set <Watch .Listener >> listenerMap ;
90
91
private ConcurrentMap <String , EtcdWatcher > watcherMap ;
91
92
private static long leaseId = 0 ;
@@ -158,7 +159,7 @@ private void doUnregister(InetSocketAddress address) throws Exception {
158
159
public void subscribe (String cluster , Watch .Listener listener ) throws Exception {
159
160
listenerMap .putIfAbsent (cluster , new HashSet <>());
160
161
listenerMap .get (cluster ).add (listener );
161
- EtcdWatcher watcher = watcherMap .computeIfAbsent (cluster , w -> new EtcdWatcher (listener ));
162
+ EtcdWatcher watcher = watcherMap .computeIfAbsent (cluster , w -> new EtcdWatcher (cluster , listener ));
162
163
executorService .submit (watcher );
163
164
}
164
165
@@ -212,7 +213,7 @@ public void onCompleted() {
212
213
});
213
214
214
215
}
215
- return clusterAddressMap .get (cluster );
216
+ return clusterAddressMap .get (cluster ). getValue () ;
216
217
}
217
218
218
219
@ Override
@@ -244,7 +245,7 @@ private void refreshCluster(String cluster) throws Exception {
244
245
String [] instanceInfo = keyValue .getValue ().toString (UTF_8 ).split (":" );
245
246
return new InetSocketAddress (instanceInfo [0 ], Integer .parseInt (instanceInfo [1 ]));
246
247
}).collect (Collectors .toList ());
247
- clusterAddressMap .put (cluster , instanceList );
248
+ clusterAddressMap .put (cluster , new Pair <>( getResponse . getHeader (). getRevision (), instanceList ) );
248
249
}
249
250
250
251
/**
@@ -390,16 +391,23 @@ public Boolean call() {
390
391
private class EtcdWatcher implements Runnable {
391
392
private final Watch .Listener listener ;
392
393
private Watch .Watcher watcher ;
394
+ private String cluster ;
393
395
394
- public EtcdWatcher (Watch .Listener listener ) {
396
+ public EtcdWatcher (String cluster , Watch .Listener listener ) {
397
+ this .cluster = cluster ;
395
398
this .listener = listener ;
396
399
}
397
400
398
401
@ Override
399
402
public void run () {
400
403
Watch watchClient = getClient ().getWatchClient ();
401
- WatchOption watchOption = WatchOption .newBuilder ().withPrefix (buildRegistryKeyPrefix ()).build ();
402
- this .watcher = watchClient .watch (buildRegistryKeyPrefix (), watchOption , this .listener );
404
+ WatchOption .Builder watchOptionBuilder = WatchOption .newBuilder ().withPrefix (buildRegistryKeyPrefix ());
405
+ Pair <Long /*revision*/ , List <InetSocketAddress >> addressPair = clusterAddressMap .get (cluster );
406
+ if (Objects .nonNull (addressPair )) {
407
+ // Maybe addressPair isn't newest now, but it's ok
408
+ watchOptionBuilder .withRevision (addressPair .getKey ());
409
+ }
410
+ this .watcher = watchClient .watch (buildRegistryKeyPrefix (), watchOptionBuilder .build (), this .listener );
403
411
}
404
412
405
413
/**
@@ -409,4 +417,39 @@ public void stop() {
409
417
this .watcher .close ();
410
418
}
411
419
}
420
+
421
+ private static class Pair <K ,V > {
422
+
423
+ /**
424
+ * Key of this <code>Pair</code>.
425
+ */
426
+ private K key ;
427
+
428
+ /**
429
+ * Value of this this <code>Pair</code>.
430
+ */
431
+ private V value ;
432
+
433
+ /**
434
+ * Creates a new pair
435
+ * @param key The key for this pair
436
+ * @param value The value to use for this pair
437
+ */
438
+ public Pair (K key , V value ) {
439
+ this .key = key ;
440
+ this .value = value ;
441
+ }
442
+
443
+ /**
444
+ * Gets the key for this pair.
445
+ * @return key for this pair
446
+ */
447
+ public K getKey () { return key ; }
448
+
449
+ /**
450
+ * Gets the value for this pair.
451
+ * @return value for this pair
452
+ */
453
+ public V getValue () { return value ; }
454
+ }
412
455
}
0 commit comments