Example usage for org.apache.zookeeper Watcher Watcher

List of usage examples for org.apache.zookeeper Watcher Watcher

Introduction

In this page you can find the example usage for org.apache.zookeeper Watcher Watcher.

Prototype

Watcher

Source Link

Usage

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;
}