Search in sources :

Example 1 with WatchedEvent

use of org.apache.zookeeper.WatchedEvent in project hbase by apache.

the class HBaseTestingUtility method expireSession.

/**
   * Expire a ZooKeeper session as recommended in ZooKeeper documentation
   * http://hbase.apache.org/book.html#trouble.zookeeper
   * There are issues when doing this:
   * [1] http://www.mail-archive.com/dev@zookeeper.apache.org/msg01942.html
   * [2] https://issues.apache.org/jira/browse/ZOOKEEPER-1105
   *
   * @param nodeZK - the ZK watcher to expire
   * @param checkStatus - true to check if we can create an HTable with the
   *                    current configuration.
   */
public void expireSession(ZooKeeperWatcher nodeZK, boolean checkStatus) throws Exception {
    Configuration c = new Configuration(this.conf);
    String quorumServers = ZKConfig.getZKQuorumServersString(c);
    ZooKeeper zk = nodeZK.getRecoverableZooKeeper().getZooKeeper();
    byte[] password = zk.getSessionPasswd();
    long sessionID = zk.getSessionId();
    // Expiry seems to be asynchronous (see comment from P. Hunt in [1]),
    //  so we create a first watcher to be sure that the
    //  event was sent. We expect that if our watcher receives the event
    //  other watchers on the same machine will get is as well.
    // When we ask to close the connection, ZK does not close it before
    //  we receive all the events, so don't have to capture the event, just
    //  closing the connection should be enough.
    ZooKeeper monitor = new ZooKeeper(quorumServers, 1000, new org.apache.zookeeper.Watcher() {

        @Override
        public void process(WatchedEvent watchedEvent) {
            LOG.info("Monitor ZKW received event=" + watchedEvent);
        }
    }, sessionID, password);
    // Making it expire
    ZooKeeper newZK = new ZooKeeper(quorumServers, 1000, EmptyWatcher.instance, sessionID, password);
    //ensure that we have connection to the server before closing down, otherwise
    //the close session event will be eaten out before we start CONNECTING state
    long start = System.currentTimeMillis();
    while (newZK.getState() != States.CONNECTED && System.currentTimeMillis() - start < 1000) {
        Thread.sleep(1);
    }
    newZK.close();
    LOG.info("ZK Closed Session 0x" + Long.toHexString(sessionID));
    // Now closing & waiting to be sure that the clients get it.
    monitor.close();
    if (checkStatus) {
        getConnection().getTable(TableName.META_TABLE_NAME).close();
    }
}
Also used : WatchedEvent(org.apache.zookeeper.WatchedEvent) ZooKeeper(org.apache.zookeeper.ZooKeeper) Configuration(org.apache.hadoop.conf.Configuration)

Example 2 with WatchedEvent

use of org.apache.zookeeper.WatchedEvent in project weave by continuuity.

the class KillZKSession method kill.

/**
   * Kills a Zookeeper client to simulate failure scenarious during testing.
   * Callee will provide the amount of time to wait before it's considered failure
   * to kill a client.
   *
   * @param client that needs to be killed.
   * @param connectionString of Quorum
   * @param maxMs time in millisecond specifying the max time to kill a client.
   * @throws IOException When there is IO error
   * @throws InterruptedException When call has been interrupted.
   */
public static void kill(ZooKeeper client, String connectionString, int maxMs) throws IOException, InterruptedException {
    final CountDownLatch latch = new CountDownLatch(1);
    ZooKeeper zk = new ZooKeeper(connectionString, maxMs, new Watcher() {

        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == Event.KeeperState.SyncConnected) {
                latch.countDown();
            }
        }
    }, client.getSessionId(), client.getSessionPasswd());
    try {
        Preconditions.checkState(latch.await(maxMs, TimeUnit.MILLISECONDS), "Fail to kill ZK connection.");
    } finally {
        zk.close();
    }
}
Also used : WatchedEvent(org.apache.zookeeper.WatchedEvent) ZooKeeper(org.apache.zookeeper.ZooKeeper) Watcher(org.apache.zookeeper.Watcher) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 3 with WatchedEvent

use of org.apache.zookeeper.WatchedEvent in project weave by continuuity.

the class ZKClientTest method testExpireRewatch.

@Test
public void testExpireRewatch() throws InterruptedException, IOException, ExecutionException {
    InMemoryZKServer zkServer = InMemoryZKServer.builder().setTickTime(1000).build();
    zkServer.startAndWait();
    try {
        final CountDownLatch expireReconnectLatch = new CountDownLatch(1);
        final AtomicBoolean expired = new AtomicBoolean(false);
        final ZKClientService client = ZKClientServices.delegate(ZKClients.reWatchOnExpire(ZKClientService.Builder.of(zkServer.getConnectionStr()).setSessionTimeout(2000).setConnectionWatcher(new Watcher() {

            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    expired.set(true);
                } else if (event.getState() == Event.KeeperState.SyncConnected && expired.compareAndSet(true, true)) {
                    expireReconnectLatch.countDown();
                }
            }
        }).build()));
        client.startAndWait();
        try {
            final BlockingQueue<Watcher.Event.EventType> events = new LinkedBlockingQueue<Watcher.Event.EventType>();
            client.exists("/expireRewatch", new Watcher() {

                @Override
                public void process(WatchedEvent event) {
                    client.exists("/expireRewatch", this);
                    events.add(event.getType());
                }
            });
            client.create("/expireRewatch", null, CreateMode.PERSISTENT);
            Assert.assertEquals(Watcher.Event.EventType.NodeCreated, events.poll(2, TimeUnit.SECONDS));
            KillZKSession.kill(client.getZooKeeperSupplier().get(), zkServer.getConnectionStr(), 1000);
            Assert.assertTrue(expireReconnectLatch.await(5, TimeUnit.SECONDS));
            client.delete("/expireRewatch");
            Assert.assertEquals(Watcher.Event.EventType.NodeDeleted, events.poll(4, TimeUnit.SECONDS));
        } finally {
            client.stopAndWait();
        }
    } finally {
        zkServer.stopAndWait();
    }
}
Also used : WatchedEvent(org.apache.zookeeper.WatchedEvent) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Watcher(org.apache.zookeeper.Watcher) WatchedEvent(org.apache.zookeeper.WatchedEvent) CountDownLatch(java.util.concurrent.CountDownLatch) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) InMemoryZKServer(com.continuuity.weave.internal.zookeeper.InMemoryZKServer) Test(org.junit.Test)

Example 4 with WatchedEvent

use of org.apache.zookeeper.WatchedEvent in project hadoop by apache.

the class TestActiveStandbyElector method testSuccessiveStandbyCalls.

/**
   * verify becomeStandby is not called if already in standby
   */
@Test
public void testSuccessiveStandbyCalls() {
    elector.joinElection(data);
    // make the object go into the monitoring standby state
    elector.processResult(Code.NODEEXISTS.intValue(), ZK_LOCK_NAME, mockZK, ZK_LOCK_NAME);
    Mockito.verify(mockApp, Mockito.times(1)).becomeStandby();
    verifyExistCall(1);
    Assert.assertTrue(elector.isMonitorLockNodePending());
    Stat stat = new Stat();
    stat.setEphemeralOwner(0L);
    Mockito.when(mockZK.getSessionId()).thenReturn(1L);
    elector.processResult(Code.OK.intValue(), ZK_LOCK_NAME, mockZK, stat);
    Assert.assertFalse(elector.isMonitorLockNodePending());
    WatchedEvent mockEvent = Mockito.mock(WatchedEvent.class);
    Mockito.when(mockEvent.getPath()).thenReturn(ZK_LOCK_NAME);
    // notify node deletion
    // monitoring should be setup again after event is received
    Mockito.when(mockEvent.getType()).thenReturn(Event.EventType.NodeDeleted);
    elector.processWatchEvent(mockZK, mockEvent);
    // is standby. no need to notify anything now
    Mockito.verify(mockApp, Mockito.times(0)).enterNeutralMode();
    // another joinElection called.
    Mockito.verify(mockZK, Mockito.times(2)).create(ZK_LOCK_NAME, data, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, elector, mockZK);
    // lost election
    elector.processResult(Code.NODEEXISTS.intValue(), ZK_LOCK_NAME, mockZK, ZK_LOCK_NAME);
    // still standby. so no need to notify again
    Mockito.verify(mockApp, Mockito.times(1)).becomeStandby();
    // monitor is set again
    verifyExistCall(2);
}
Also used : WatchedEvent(org.apache.zookeeper.WatchedEvent) Stat(org.apache.zookeeper.data.Stat) Test(org.junit.Test)

Example 5 with WatchedEvent

use of org.apache.zookeeper.WatchedEvent in project druid by druid-io.

the class LoadQueuePeon method processSegmentChangeRequest.

private void processSegmentChangeRequest() {
    if (currentlyProcessing == null) {
        if (!segmentsToDrop.isEmpty()) {
            currentlyProcessing = segmentsToDrop.firstEntry().getValue();
            log.info("Server[%s] dropping [%s]", basePath, currentlyProcessing.getSegmentIdentifier());
        } else if (!segmentsToLoad.isEmpty()) {
            currentlyProcessing = segmentsToLoad.firstEntry().getValue();
            log.info("Server[%s] loading [%s]", basePath, currentlyProcessing.getSegmentIdentifier());
        } else {
            return;
        }
        try {
            if (currentlyProcessing == null) {
                if (!stopped) {
                    log.makeAlert("Crazy race condition! server[%s]", basePath).emit();
                }
                actionCompleted();
                return;
            }
            log.info("Server[%s] processing segment[%s]", basePath, currentlyProcessing.getSegmentIdentifier());
            final String path = ZKPaths.makePath(basePath, currentlyProcessing.getSegmentIdentifier());
            final byte[] payload = jsonMapper.writeValueAsBytes(currentlyProcessing.getChangeRequest());
            curator.create().withMode(CreateMode.EPHEMERAL).forPath(path, payload);
            processingExecutor.schedule(new Runnable() {

                @Override
                public void run() {
                    try {
                        if (curator.checkExists().forPath(path) != null) {
                            failAssign(new ISE("%s was never removed! Failing this operation!", path));
                        }
                    } catch (Exception e) {
                        failAssign(e);
                    }
                }
            }, config.getLoadTimeoutDelay().getMillis(), TimeUnit.MILLISECONDS);
            final Stat stat = curator.checkExists().usingWatcher(new CuratorWatcher() {

                @Override
                public void process(WatchedEvent watchedEvent) throws Exception {
                    switch(watchedEvent.getType()) {
                        case NodeDeleted:
                            entryRemoved(watchedEvent.getPath());
                    }
                }
            }).forPath(path);
            if (stat == null) {
                final byte[] noopPayload = jsonMapper.writeValueAsBytes(new SegmentChangeRequestNoop());
                // Create a node and then delete it to remove the registered watcher.  This is a work-around for
                // a zookeeper race condition.  Specifically, when you set a watcher, it fires on the next event
                // that happens for that node.  If no events happen, the watcher stays registered foreverz.
                // Couple that with the fact that you cannot set a watcher when you create a node, but what we
                // want is to create a node and then watch for it to get deleted.  The solution is that you *can*
                // set a watcher when you check to see if it exists so, we first create the node and then set a
                // watcher on its existence.  However, if already does not exist by the time the existence check
                // returns, then the watcher that was set will never fire (nobody will ever create the node
                // again) and thus lead to a slow, but real, memory leak.  So, we create another node to cause
                // that watcher to fire and delete it right away.
                //
                // We do not create the existence watcher first, because then it will fire when we create the
                // node and we'll have the same race when trying to refresh that watcher.
                curator.create().withMode(CreateMode.EPHEMERAL).forPath(path, noopPayload);
                entryRemoved(path);
            }
        } catch (Exception e) {
            failAssign(e);
        }
    } else {
        log.info("Server[%s] skipping doNext() because something is currently loading[%s].", basePath, currentlyProcessing.getSegmentIdentifier());
    }
}
Also used : WatchedEvent(org.apache.zookeeper.WatchedEvent) Stat(org.apache.zookeeper.data.Stat) CuratorWatcher(org.apache.curator.framework.api.CuratorWatcher) ISE(io.druid.java.util.common.ISE) SegmentChangeRequestNoop(io.druid.server.coordination.SegmentChangeRequestNoop)

Aggregations

WatchedEvent (org.apache.zookeeper.WatchedEvent)192 Watcher (org.apache.zookeeper.Watcher)121 ZooKeeper (org.apache.zookeeper.ZooKeeper)65 CountDownLatch (java.util.concurrent.CountDownLatch)64 KeeperException (org.apache.zookeeper.KeeperException)55 Test (org.junit.Test)38 Stat (org.apache.zookeeper.data.Stat)35 IOException (java.io.IOException)30 Test (org.testng.annotations.Test)27 Test (org.junit.jupiter.api.Test)18 CuratorFramework (org.apache.curator.framework.CuratorFramework)14 AsyncCallback (org.apache.zookeeper.AsyncCallback)14 List (java.util.List)10 KeeperState (org.apache.zookeeper.Watcher.Event.KeeperState)10 Set (java.util.Set)7 TimeoutException (java.util.concurrent.TimeoutException)7 HashSet (java.util.HashSet)6 CompletableFuture (java.util.concurrent.CompletableFuture)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 RetryOneTime (org.apache.curator.retry.RetryOneTime)6