List of usage examples for org.apache.zookeeper Watcher Watcher
Watcher
From source file:org.apache.twill.internal.kafka.client.ZKBrokerService.java
License:Apache License
/** * Checks exists of a given ZK path and execute the action when it exists. */// www . j a v a2s .co m private void actOnExists(final String path, final Runnable action, final SettableFuture<?> readyFuture, final long retryTime, final TimeUnit retryUnit) { Futures.addCallback(zkClient.exists(path, new Watcher() { @Override public void process(WatchedEvent event) { if (!isRunning()) { return; } if (event.getType() == Event.EventType.NodeCreated) { action.run(); } } }), new FutureCallback<Stat>() { @Override public void onSuccess(Stat result) { if (result != null) { action.run(); } else { // If the node doesn't exists, treat it as ready. When the node becomes available later, data will be // fetched by the watcher. readyFuture.set(null); } } @Override public void onFailure(Throwable t) { // Retry the operation based on the retry time. Thread retryThread = new Thread("zk-broker-service-retry") { @Override public void run() { try { retryUnit.sleep(retryTime); actOnExists(path, action, readyFuture, retryTime, retryUnit); } catch (InterruptedException e) { LOG.warn("ZK retry thread interrupted. Action not retried."); } } }; retryThread.setDaemon(true); retryThread.start(); } }, executorService); }
From source file:org.apache.twill.internal.state.ZKServiceDecoratorTest.java
License:Apache License
private void watchDataChange(final ZKClientService zkClient, final String path, final Semaphore semaphore, final AtomicReference<String> stateMatch) { Futures.addCallback(zkClient.getData(path, new Watcher() { @Override/*w w w .ja v a 2s .co m*/ public void process(WatchedEvent event) { if (event.getType() == Event.EventType.NodeDataChanged) { watchDataChange(zkClient, path, semaphore, stateMatch); } } }), new FutureCallback<NodeData>() { @Override public void onSuccess(NodeData result) { String content = new String(result.getData(), Charsets.UTF_8); JsonObject json = new Gson().fromJson(content, JsonElement.class).getAsJsonObject(); if (stateMatch.get().equals(json.get("state").getAsString())) { semaphore.release(); } } @Override public void onFailure(Throwable t) { exists(); } private void exists() { Futures.addCallback(zkClient.exists(path, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getType() == Event.EventType.NodeCreated) { watchDataChange(zkClient, path, semaphore, stateMatch); } } }), new FutureCallback<Stat>() { @Override public void onSuccess(Stat result) { if (result != null) { watchDataChange(zkClient, path, semaphore, stateMatch); } } @Override public void onFailure(Throwable t) { LOG.error(t.getMessage(), t); } }); } }); }
From source file:org.apache.twill.internal.ZKServiceDecorator.java
License:Apache License
@Override protected void doStart() { callbackExecutor = Executors.newSingleThreadExecutor(Threads.createDaemonThreadFactory("message-callback")); // Create the live node, if succeeded, start the decorated service, otherwise fail out. Futures.addCallback(createLiveNode(), new FutureCallback<String>() { @Override/* ww w. j av a2 s.c om*/ public void onSuccess(String result) { // Create nodes for states and messaging StateNode stateNode = new StateNode(ServiceController.State.STARTING); final ListenableFuture<List<String>> createFuture = Futures.allAsList( ZKOperations.ignoreError( zkClient.create(getZKPath("messages"), null, CreateMode.PERSISTENT), KeeperException.NodeExistsException.class, null), zkClient.create(getZKPath("state"), encodeStateNode(stateNode), CreateMode.PERSISTENT)); createFuture.addListener(new Runnable() { @Override public void run() { try { createFuture.get(); // Starts the decorated service decoratedService.addListener(createListener(), Threads.SAME_THREAD_EXECUTOR); decoratedService.start(); } catch (Exception e) { notifyFailed(e); } } }, Threads.SAME_THREAD_EXECUTOR); } @Override public void onFailure(Throwable t) { notifyFailed(t); } }); // Watch for session expiration, recreate the live node if reconnected after expiration. zkClient.addConnectionWatcher(new Watcher() { private boolean expired = false; @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.Expired) { LOG.warn("ZK Session expired for service {} with runId {}.", decoratedService, id.getId()); expired = true; } else if (event.getState() == Event.KeeperState.SyncConnected && expired) { LOG.info("Reconnected after expiration for service {} with runId {}", decoratedService, id.getId()); expired = false; Futures.addCallback(createLiveNode(), new FutureCallback<String>() { @Override public void onSuccess(String result) { // All good, no-op } @Override public void onFailure(Throwable t) { notifyFailed(t); } }, Threads.SAME_THREAD_EXECUTOR); } } }); }
From source file:org.apache.twill.internal.zookeeper.ReentrantDistributedLock.java
License:Apache License
/** * Acquires a distributed lock through ZooKeeper. * * @param interruptible true if acquisition of lock can be interrupted * @param waitForLock true if wants to wait for the lock when not able to acquire it * @param timeout time to wait for the lock before giving up * @param unit unit for the timeout/*w ww . j a va 2 s .c o m*/ * @throws InterruptedException if {@code interruptible} is set to {@code true} and the current thread is interrupted * while acquiring the lock * @throws ExecutionException if there is failure while trying to acquire the lock */ private boolean acquire(boolean interruptible, final boolean waitForLock, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { Preconditions.checkState(lock.isHeldByCurrentThread(), "Not owner of local lock."); if (lock.getHoldCount() > 1) { // Already owner of the lock, simply return. return true; } // Use a Future to help deal with different variants of locking // (lock, lockInterruptibly, tryLock, tryLock with timeout) // When the completion future is completed successfully, it means the lock is acquired and the future contains // the ZK node path to the ephemeral node that is representing this lock. // If it is failed, it means there is exception while trying to acquire the lock // If it is cancelled, it means to abort the acquisition logic (due to timeout / interrupt). final SettableFuture<String> completion = SettableFuture.create(); // If the connection expired, fail the locking process if it is still in progress final Cancellable watcherCancellable = zkClient.addConnectionWatcher(new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.Expired) { completion.setException(new IllegalStateException("ZK session expired")); } } }); // Always remove the watcher on completion completion.addListener(new Runnable() { @Override public void run() { watcherCancellable.cancel(); } }, Threads.SAME_THREAD_EXECUTOR); // Step 1. Create a ephemeral sequential node final String guid = UUID.randomUUID().toString(); final String lockPath = String.format("%s/%s-", path, guid); OperationFuture<String> future = zkClient.create(lockPath, null, CreateMode.EPHEMERAL_SEQUENTIAL, true); Futures.addCallback(future, new FutureCallback<String>() { @Override public void onSuccess(final String lockNode) { // If lock failed due to whatever reason, delete the lock node. deleteNodeOnFailure(completion, lockNode); // If the lock is completed (mainly due to cancellation), simply abort the lock acquisition logic. if (completion.isDone()) { return; } // Step 2-5. Try to determine who is the lock owner and watch for ZK node changes if itself is not the owner. doAcquire(completion, waitForLock, guid, lockNode); } @Override public void onFailure(Throwable t) { if (t instanceof KeeperException.ConnectionLossException) { // Ignore connection exception in create. Going to handle it in next step. // See the ZK receipt for details about the possible failure situation that can cause this. doAcquire(completion, waitForLock, guid, null); } else { LOG.error("Exception raised when creating lock node at {}", lockPath, t); completion.setException(t); } } }); // Gets the result from the completion try { if (interruptible) { localLockNode.set(completion.get(timeout, unit)); } else { localLockNode.set(Uninterruptibles.getUninterruptibly(completion, timeout, unit)); } return true; } catch (InterruptedException e) { completion.cancel(true); throw e; } catch (TimeoutException e) { completion.cancel(true); throw e; } catch (CancellationException e) { // If the completion get cancelled, meaning the lock acquisition is aborted. return false; } }
From source file:org.apache.twill.internal.zookeeper.ReentrantDistributedLock.java
License:Apache License
/** * Executes the lock acquisition process. This corresponds to step 2-5 of the distributed lock receipt. *///from w w w .j av a 2 s . c o m private void doAcquire(final SettableFuture<String> completion, final boolean waitForLock, final String guid, @Nullable final String lockPath) { // Step 2. Get all children under the lock parent. Futures.addCallback(zkClient.getChildren(path), new FutureCallback<NodeChildren>() { @Override public void onSuccess(NodeChildren children) { // Find the lock node in case the creation step failed by matching the guid // See "Recoverable Errors and the GUID" in the ZooKeeper guide final String lockNode = lockPath == null ? findLockNode(children.getChildren(), guid) : lockPath; if (lockNode == null) { // If not able to find the lock node, fail the locking procedure. completion.setException(new IllegalStateException("Failed to acquire lock").fillInStackTrace()); return; } if (lockPath == null) { // If lock node was not determined in step 1 due to connection loss exception, need to add the // node deletion handler in here after the actual lockNode is determined. deleteNodeOnFailure(completion, lockNode); } // Find the node to watch, which is the one with the largest id that is smaller than currentId // If the current id is the smallest one, nodeToWatch will be null final String nodeToWatch = findNodeToWatch(children, lockNode, guid); // Step 3a. lockNode is the lowest, hence this become lock owner. if (nodeToWatch == null) { // Acquired lock completion.set(lockNode); } else if (!waitForLock) { // This is for the case of tryLock() without timeout. completion.cancel(true); } // If the lock acquisition is completed, due to whatever reason, we don't need to watch for any other nodes if (completion.isDone()) { return; } // Step 3b and 4. See if the the next lowest sequence ID exists. If it does, leave a watch // Use getData() instead of exists() to avoid leaking Watcher resources (if the node is gone, there will // be a watch left on the ZK server if exists() is used). OperationFuture<NodeData> getDataFuture = zkClient.getData(nodeToWatch, new Watcher() { @Override public void process(WatchedEvent event) { if (!completion.isDone()) { // If the watching node changed, go to step 2. doAcquire(completion, waitForLock, guid, lockNode); } } }); // Step 5. Depends on the exists call result, either go to step 2 if the nodeToWatch is gone or just // let the watcher to trigger step 2 when there is change to the nodeToWatch. Futures.addCallback(getDataFuture, new FutureCallback<NodeData>() { @Override public void onSuccess(NodeData nodeData) { // No-op } @Override public void onFailure(Throwable t) { // See if the failure is due to node not exists. If that's the case, go to step 2. if (t instanceof KeeperException.NoNodeException && !completion.isDone()) { doAcquire(completion, waitForLock, guid, lockNode); } else { // If failed due to something else, fail the lock acquisition. completion.setException(t); } } }); } @Override public void onFailure(Throwable t) { if (lockPath != null) { completion.setException(t); } else { doAcquire(completion, waitForLock, guid, null); } } }); }
From source file:org.apache.twill.zookeeper.ZKClientTest.java
License:Apache License
@Test public void testExpireRewatch() throws InterruptedException, IOException, ExecutionException { InMemoryZKServer zkServer = InMemoryZKServer.builder().setTickTime(1000).build(); zkServer.startAndWait();//from www . jav a 2 s .com 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<>(); client.exists("/expireRewatch", new Watcher() { @Override public void process(final WatchedEvent event) { Futures.addCallback(client.exists("/expireRewatch", this), new FutureCallback<Stat>() { @Override public void onSuccess(Stat result) { events.add(event.getType()); } @Override public void onFailure(Throwable t) { LOG.error("Failed to call exists on /expireRewatch", t); } }); } }); client.create("/expireRewatch", null, CreateMode.PERSISTENT); Assert.assertEquals(Watcher.Event.EventType.NodeCreated, events.poll(60, TimeUnit.SECONDS)); KillZKSession.kill(client.getZooKeeperSupplier().get(), zkServer.getConnectionStr(), 10000); Assert.assertTrue(expireReconnectLatch.await(60, TimeUnit.SECONDS)); // Keep trying to delete the node until it succeed while (ZKOperations.ignoreError(client.delete("/expireRewatch"), KeeperException.class, null) .get() == null) { LOG.info("Delete failed. Retrying to delete /expireRewatch"); TimeUnit.MILLISECONDS.sleep(10); } Assert.assertEquals(Watcher.Event.EventType.NodeDeleted, events.poll(60, TimeUnit.SECONDS)); } finally { client.stopAndWait(); } } finally { zkServer.stopAndWait(); } }
From source file:org.apache.twill.zookeeper.ZKClientTest.java
License:Apache License
@Test public void testRetry() throws ExecutionException, InterruptedException, TimeoutException, IOException { File dataDir = tmpFolder.newFolder(); InMemoryZKServer zkServer = InMemoryZKServer.builder().setDataDir(dataDir).setTickTime(1000).build(); zkServer.startAndWait();/*from www . jav a 2s .c om*/ int port = zkServer.getLocalAddress().getPort(); final CountDownLatch disconnectLatch = new CountDownLatch(1); ZKClientService client = ZKClientServices.delegate(ZKClients.retryOnFailure( ZKClientService.Builder.of(zkServer.getConnectionStr()).setConnectionWatcher(new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.Disconnected) { disconnectLatch.countDown(); } } }).build(), RetryStrategies.fixDelay(0, TimeUnit.SECONDS))); final CountDownLatch createLatch = new CountDownLatch(1); client.startAndWait(); try { zkServer.stopAndWait(); Assert.assertTrue(disconnectLatch.await(1, TimeUnit.SECONDS)); Futures.addCallback(client.create("/testretry/test", null, CreateMode.PERSISTENT), new FutureCallback<String>() { @Override public void onSuccess(String result) { createLatch.countDown(); } @Override public void onFailure(Throwable t) { t.printStackTrace(System.out); } }); TimeUnit.SECONDS.sleep(2); zkServer = InMemoryZKServer.builder().setDataDir(dataDir).setAutoCleanDataDir(true).setPort(port) .setTickTime(1000).build(); zkServer.startAndWait(); try { Assert.assertTrue(createLatch.await(10, TimeUnit.SECONDS)); } finally { zkServer.stopAndWait(); } } finally { client.stopAndWait(); } }
From source file:org.apache.twill.zookeeper.ZKClientTest.java
License:Apache License
@Test(timeout = 120000L) public void testDeadlock() throws IOException, InterruptedException { // This is to test deadlock bug as described in (TWILL-110) // This test has very high chance to get deadlock before the bug fix, hence failed with timeout. InMemoryZKServer zkServer = InMemoryZKServer.builder().setDataDir(tmpFolder.newFolder()).build(); zkServer.startAndWait();/*from w w w .ja va2s. c o m*/ try { for (int i = 0; i < 5000; i++) { final ZKClientService zkClient = ZKClientService.Builder.of(zkServer.getConnectionStr()).build(); zkClient.addConnectionWatcher(new Watcher() { @Override public void process(WatchedEvent event) { LOG.debug("Connection event: {}", event); } }); zkClient.startAndWait(); zkClient.stopAndWait(); } } finally { zkServer.stopAndWait(); } }
From source file:org.bboxdb.distribution.zookeeper.ZookeeperClient.java
License:Apache License
/** * Connect to zookeeper// w w w. j a v a 2s . c om */ @Override public void init() { if (zookeeperHosts == null || zookeeperHosts.isEmpty()) { logger.warn("No Zookeeper hosts are defined, not connecting to zookeeper"); return; } try { shutdownPending = false; final CountDownLatch connectLatch = new CountDownLatch(1); zookeeper = new ZooKeeper(generateConnectString(), ZOOKEEPER_SESSION_TIMEOUT, new Watcher() { @Override public void process(final WatchedEvent event) { if (event.getState() == Watcher.Event.KeeperState.SyncConnected) { connectLatch.countDown(); } } }); boolean waitResult = connectLatch.await(ZOOKEEPER_CONNCT_TIMEOUT, TimeUnit.SECONDS); if (waitResult == false) { logger.warn("Unable to connect in " + ZOOKEEPER_CONNCT_TIMEOUT + " seconds"); closeZookeeperConnectionNE(); return; } createDirectoryStructureIfNeeded(); registerInstanceIfNameWasSet(); } catch (Exception e) { logger.warn("Got exception while connecting to zookeeper", e); } }
From source file:org.cane.rpc.servicectrl.ServiceRegistry.java
License:Open Source License
/** * create connection to zookeeper server * @return/*from w ww. j a va 2 s .c o m*/ */ private ZooKeeper connectZookeeperServer() { ZooKeeper zk = null; try { zk = new ZooKeeper(zookeeperAddress, ServiceConstant.SESSION_TIMEOUT, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { latch.countDown(); } } }); latch.await(); } catch (Exception e) { LOG.error("Can not connect given zookeeper server!", e); } return zk; }