Search in sources :

Example 1 with PersistentLease

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();
    }
}
Also used : LeaseClient(com.ibm.etcd.client.lease.LeaseClient) PersistentLease(com.ibm.etcd.client.lease.PersistentLease) LeaseState(com.ibm.etcd.client.lease.PersistentLease.LeaseState) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Test(org.junit.Test)

Example 2 with PersistentLease

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;
                }
            }
        }
    }
}
Also used : KeyValue(com.ibm.etcd.api.KeyValue) ByteString(com.google.protobuf.ByteString) EtcdClient(com.ibm.etcd.client.EtcdClient) KvClient(com.ibm.etcd.client.kv.KvClient) PersistentLease(com.ibm.etcd.client.lease.PersistentLease) Event(com.ibm.etcd.api.Event) WatchIterator(com.ibm.etcd.client.kv.KvClient.WatchIterator) Test(org.junit.Test)

Aggregations

PersistentLease (com.ibm.etcd.client.lease.PersistentLease)2 Test (org.junit.Test)2 ByteString (com.google.protobuf.ByteString)1 Event (com.ibm.etcd.api.Event)1 KeyValue (com.ibm.etcd.api.KeyValue)1 EtcdClient (com.ibm.etcd.client.EtcdClient)1 KvClient (com.ibm.etcd.client.kv.KvClient)1 WatchIterator (com.ibm.etcd.client.kv.KvClient.WatchIterator)1 LeaseClient (com.ibm.etcd.client.lease.LeaseClient)1 LeaseState (com.ibm.etcd.client.lease.PersistentLease.LeaseState)1 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)1