Skip to content
This repository was archived by the owner on Jul 27, 2023. It is now read-only.

Race condition when adding listener to ServiceHealthCache #269

Merged
merged 10 commits into from
Nov 12, 2017
Next Next commit
Fixes #207 - notify listeners even if key doesn't exists in consul
maqdev committed Apr 27, 2017
commit d7f3d28d9b4bd2f586c3b54b14bed18ad41673e5
2 changes: 1 addition & 1 deletion src/main/java/com/orbitz/consul/cache/ConsulCache.java
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ enum State {latent, starting, started, stopped }
private static final long BACKOFF_DELAY_QTY_IN_MS = getBackOffDelayInMs(System.getProperties());

private final AtomicReference<BigInteger> latestIndex = new AtomicReference<BigInteger>(null);
private final AtomicReference<ImmutableMap<K, V>> lastResponse = new AtomicReference<ImmutableMap<K, V>>(ImmutableMap.<K, V>of());
private final AtomicReference<ImmutableMap<K, V>> lastResponse = new AtomicReference<ImmutableMap<K, V>>(null);
private final AtomicReference<State> state = new AtomicReference<State>(State.latent);
private final CountDownLatch initLatch = new CountDownLatch(1);
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(
37 changes: 34 additions & 3 deletions src/test/java/com/orbitz/consul/cache/ConsulCacheTest.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

public class ConsulCacheTest extends BaseIntegrationTest {
@@ -188,11 +189,11 @@ public void notify(Map<String, Value> newValues) {
Thread.sleep(100);
}

assertEquals(5, events.size());
assertEquals(6, events.size());

for (int i = 0; i < 5; i++) {
for (int i = -1; i < 5; i++) {

Map<String, Value> map = events.get(i);
Map<String, Value> map = events.get(i+1);
assertEquals(i + 1, map.size());
for (int j = 0; j < i; j++) {
String keyStr = "" + j;
@@ -244,6 +245,36 @@ public void notify(Map<String, Value> newValues) {
kvClient.deleteKeys(root);
}

@Test
public void testListenersNonExistingKeys() throws Exception {
KeyValueClient kvClient = client.keyValueClient();
String root = UUID.randomUUID().toString();

KVCache nc = KVCache.newCache(
kvClient, root, 10
);

final List<Map<String, Value>> events = new ArrayList<Map<String, Value>>();
nc.addListener(new ConsulCache.Listener<String, Value>() {
@Override
public void notify(Map<String, Value> newValues) {
events.add(newValues);
}
});

nc.start();

if (!nc.awaitInitialized(1, TimeUnit.SECONDS)) {
fail("cache initialization failed");
}

Thread.sleep(100);

assertEquals(1, events.size());
Map<String, Value> map = events.get(0);
assertEquals(0, map.size());
}

@Test(expected = IllegalStateException.class)
public void testLifeCycleDoubleStart() throws Exception {
KeyValueClient kvClient = client.keyValueClient();