use of com.ibm.etcd.client.lease.PersistentLease in project etcd-java by IBM.
the class LeaseTest method testPersistentLease.
@Test
public void testPersistentLease() throws Exception {
proxy.start();
try (KvStoreClient directClient = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build();
KvStoreClient client = EtcdClient.forEndpoint("localhost", 2393).withPlainText().build()) {
LeaseClient lc = client.getLeaseClient();
long start = System.currentTimeMillis();
final BlockingQueue<Object> observerEvents = new LinkedBlockingQueue<>();
final Object COMPLETED = new Object();
int minTtl = 5, kaFreq = 4;
PersistentLease pl = lc.maintain().minTtl(minTtl).keepAliveFreq(kaFreq).start(new StreamObserver<LeaseState>() {
@Override
public void onNext(LeaseState value) {
System.out.println(t(start) + "PL state change: " + value);
observerEvents.add(value);
}
@Override
public void onError(Throwable t) {
System.out.println(t(start) + "PL error: " + t);
observerEvents.add(t);
}
@Override
public void onCompleted() {
System.out.println(t(start) + "PL completed");
observerEvents.add(COMPLETED);
}
});
long newId = pl.get(3L, TimeUnit.SECONDS);
assertEquals(LeaseState.ACTIVE, pl.getState());
System.out.println(t(start) + "new lease id: " + newId);
assertEquals(minTtl + kaFreq, pl.getPreferredTtlSecs());
assertTrue(newId > 0L);
assertEquals(newId, pl.getLeaseId());
assertEquals(LeaseState.ACTIVE, observerEvents.poll(200, TimeUnit.MILLISECONDS));
assertNull(observerEvents.poll());
Thread.sleep(2000L);
assertTrue(Math.abs(lc.ttl(newId).get().getTTL() - pl.getCurrentTtlSecs()) <= 1);
Thread.sleep(4000L);
assertNull(observerEvents.poll());
assertTrue(Math.abs(lc.ttl(newId).get().getTTL() - pl.getCurrentTtlSecs()) <= 1);
assertEquals(LeaseState.ACTIVE, pl.getState());
// cut the cord
proxy.kill();
// state should reflect disconnection
assertEquals(LeaseState.ACTIVE_NO_CONN, observerEvents.poll(2, TimeUnit.SECONDS));
proxy.start();
// should go back to active
assertEquals(LeaseState.ACTIVE, observerEvents.poll(4, TimeUnit.SECONDS));
Thread.sleep(500L);
System.out.println("ttl now " + pl.getCurrentTtlSecs() + "s");
assertTrue(pl.getCurrentTtlSecs() > minTtl);
proxy.kill();
long afterKill = System.nanoTime();
assertEquals(LeaseState.ACTIVE_NO_CONN, observerEvents.poll(2, TimeUnit.SECONDS));
// test creating 2nd lease while disconnected
PersistentLease pl2 = lc.maintain().minTtl(minTtl).keepAliveFreq(kaFreq).start();
// should stay in pending state
assertEquals(LeaseState.PENDING, pl2.getState());
Thread.sleep(500L);
assertEquals(LeaseState.PENDING, pl2.getState());
assertEquals(0L, pl2.getLeaseId());
// wait for expiry
assertEquals(LeaseState.EXPIRED, observerEvents.poll(minTtl + kaFreq, TimeUnit.SECONDS));
long expiredMs = (System.nanoTime() - afterKill) / 1000_000L;
System.out.println("expired after " + expiredMs + "ms");
// make sure it lasted at least minTtl
assertTrue("expired too quickly", expiredMs >= minTtl * 1000L);
// second lease still waiting
assertFalse(pl2.isDone());
proxy.start();
long before = System.currentTimeMillis();
// second lease should now become active
long newLeaseId = pl2.get(20, TimeUnit.SECONDS);
assertTrue(newLeaseId > 0L);
assertNotEquals(pl.getLeaseId(), newLeaseId);
assertEquals(LeaseState.ACTIVE, pl2.getState());
// should go back to active after expired
assertEquals(LeaseState.ACTIVE, observerEvents.poll(10, TimeUnit.SECONDS));
System.out.println("took " + (System.nanoTime() - before) / 1000_000L + "ms to become active again");
pl.close();
pl2.close();
assertEquals(LeaseState.CLOSED, observerEvents.poll(1, TimeUnit.SECONDS));
assertEquals(COMPLETED, observerEvents.poll(1, TimeUnit.SECONDS));
assertNull(observerEvents.poll(500, TimeUnit.MILLISECONDS));
assertEquals(LeaseState.CLOSED, pl.getState());
assertEquals(0, pl.getCurrentTtlSecs());
assertEquals(-1L, lc.ttl(newId).get().getTTL());
} finally {
proxy.kill();
}
}
use of com.ibm.etcd.client.lease.PersistentLease in project etcd-java by IBM.
the class PersistentLeaseKeyTest method testLeaseKey.
@Test
public void testLeaseKey() throws Exception {
try (EtcdClient client = EtcdClient.forEndpoint("localhost", 2392).withPlainText().build();
EtcdClient directClient = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build()) {
KvClient directKvClient = directClient.getKvClient();
ByteString mykey = bs("mykeyy");
PersistentLeaseKey plk = new PersistentLeaseKey(client, mykey, bs("defaultdata"), null);
ListenableFuture<ByteString> startFuture = plk.startWithFuture();
Thread.sleep(300L);
// network conn to server not established yet
assertFalse(startFuture.isDone());
// key won't exist yet
assertEquals(0, directKvClient.get(mykey).countOnly().sync().getCount());
// reestablish network
proxy.start();
assertEquals(mykey, startFuture.get(3000, MILLISECONDS));
// check key is present via other client
assertEquals(bs("defaultdata"), directKvClient.get(mykey).sync().getKvs(0).getValue());
plk.closeWithFuture().get(500, MILLISECONDS);
// key should now be gone
assertEquals(0, directKvClient.get(bs("mykeyy")).countOnly().sync().getCount());
// -----------------
PersistentLease pl = client.getLeaseClient().maintain().minTtl(2).start();
System.out.println("PL state: " + pl.getState());
plk = new PersistentLeaseKey(client, pl, mykey, bs("somedata"), null);
plk.start();
assertFalse(pl.isDone());
Long leaseId = pl.get(1, TimeUnit.SECONDS);
assertNotNull(leaseId);
System.out.println("PL state: " + pl.getState());
// will take a small amount of time after lease is created for PLK to be
// created
assertFalse(plk.isDone());
plk.get(1, TimeUnit.SECONDS);
KeyValue kv = directKvClient.get(mykey).sync().getKvs(0);
assertEquals(bs("somedata"), kv.getValue());
assertEquals((long) leaseId, kv.getLease());
plk.setDefaultValue(bs("updateddata"));
Thread.sleep(200L);
// data doesn't change until key has to be recreated
assertEquals(bs("somedata"), directKvClient.get(mykey).sync().getKvs(0).getValue());
proxy.kill();
long ttl = pl.getCurrentTtlSecs();
System.out.println("TTL after kill is " + ttl);
Thread.sleep(1000L);
// key should still be there (lease not yet expired)
kv = directKvClient.get(mykey).sync().getKvs(0);
assertEquals(bs("somedata"), kv.getValue());
assertEquals((long) leaseId, kv.getLease());
Thread.sleep((pl.getCurrentTtlSecs() + 2) * 1000L);
// lease should have now expired and key should be gone
assertEquals(0, directKvClient.get(bs("mykeyy")).sync().getCount());
proxy.start();
long before = System.nanoTime();
try (WatchIterator it = directKvClient.watch(bs("mykeyy")).start()) {
for (int i = 0; i < 5; i++) {
List<Event> events = it.next().getEvents();
if (!events.isEmpty()) {
// key should be updated with new value once
// connection is reestablished
assertEquals(bs("updateddata"), events.get(0).getKv().getValue());
System.out.println("took " + (System.nanoTime() - before) / 1000_000L + "ms for key to re-appear");
break;
}
}
}
}
}
Aggregations