public PathChildrenCache make(CuratorFramework curator, String path) { return new PathChildrenCache( curator, path, cacheData, compressed, new CloseableExecutorService(exec, shutdownExecutorOnClose) ); }
/** * Attempt leadership. This attempt is done in the background - i.e. this method returns * immediately.<br><br> * <b>IMPORTANT: </b> previous versions allowed this method to be called multiple times. This * is no longer supported. Use {@link #requeue()} for this purpose. */ public void start() { Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once"); Preconditions.checkState(!executorService.isShutdown(), "Already started"); Preconditions.checkState(!hasLeadership, "Already has leadership"); client.getConnectionStateListenable().addListener(listener); requeue(); }
/** * Shutdown this selector and remove yourself from the leadership group */ public synchronized void close() { Preconditions.checkState(state.compareAndSet(State.STARTED, State.CLOSED), "Already closed or has not been started"); client.getConnectionStateListenable().removeListener(listener); executorService.close(); ourTask.set(null); }
/** * Submits a runnable to the executor. * <p> * This method is synchronized because it has to check state about whether this instance is still open. Without this check * there is a race condition with the dataWatchers that get set. Even after this object is closed() it can still be * called by those watchers, because the close() method cannot actually disable the watcher. * <p> * The synchronization overhead should be minimal if non-existant as this is generally only called from the * ZK client thread and will only contend if close() is called in parallel with an update, and that's the exact state * we want to protect from. * * @param command The runnable to run */ private synchronized void submitToExecutor(final Runnable command) { if ( state.get() == State.STARTED ) { executorService.submit(command); } } }
/** * NOTE: this is a BLOCKING method. Rebuild the internal cache for the given node by querying * for all needed data WITHOUT generating any events to send to listeners. * * @param fullPath full path of the node to rebuild * @throws Exception errors */ public void rebuildNode(String fullPath) throws Exception { Preconditions.checkArgument(ZKPaths.getPathAndNode(fullPath).getPath().equals(path), "Node is not part of this cache: " + fullPath); Preconditions.checkState(!executorService.isShutdown(), "cache has been closed"); ensurePath(); internalRebuildNode(fullPath); // this is necessary so that any updates that occurred while rebuilding are taken // have to rebuild entire tree in case this node got deleted in the interim offerOperation(new RefreshOperation(this, RefreshMode.FORCE_GET_DATA_AND_STAT)); }
/** * Close/end the cache * * @throws IOException errors */ @Override public void close() throws IOException { if ( state.compareAndSet(State.STARTED, State.CLOSED) ) { client.getConnectionStateListenable().removeListener(connectionStateListener); listeners.clear(); executorService.close(); client.clearWatcherReferences(childrenWatcher); client.clearWatcherReferences(dataWatcher); // TODO // This seems to enable even more GC - I'm not sure why yet - it // has something to do with Guava's cache and circular references connectionStateListener = null; childrenWatcher = null; dataWatcher = null; } }
private synchronized boolean internalRequeue() { if ( !isQueued && (state.get() == State.STARTED) ) { isQueued = true; Future<Void> task = executorService.submit(new Callable<Void>() { @Override public Void call() throws Exception { try { doWorkLoop(); } finally { clearIsQueued(); if ( autoRequeue.get() ) { internalRequeue(); } } return null; } }); ourTask.set(task); return true; } return false; }
/** * Optional executor getGroup to use for the cache's background thread * * @param executorService executor getGroup * @return this */ @Override public ServiceCacheBuilder<T> executorService(ExecutorService executorService) { this.executorService = new CloseableExecutorService(executorService); this.threadFactory = null; return this; }
/** * NOTE: this is a BLOCKING method. Completely rebuild the internal cache by querying * for all needed data WITHOUT generating any events to send to listeners. * * @throws Exception errors */ public void rebuild() throws Exception { Preconditions.checkState(!executorService.isShutdown(), "cache has been closed"); ensurePath(); clear(); List<String> children = client.getChildren().forPath(path); for ( String child : children ) { String fullPath = ZKPaths.makePath(path, child); internalRebuildNode(fullPath); if ( rebuildTestExchanger != null ) { rebuildTestExchanger.exchange(new Object()); } } // this is necessary so that any updates that occurred while rebuilding are taken offerOperation(new RefreshOperation(this, RefreshMode.FORCE_GET_DATA_AND_STAT)); }
/** * @param client the client * @param path path to watch * @param cacheData if true, node contents are cached in addition to the stat * @param dataIsCompressed if true, data in the path is compressed * @param executorService ExecutorService to use for the PathChildrenCache's background thread. This getGroup should be single threaded, otherwise the cache may see inconsistent results. */ public PathChildrenCache(CuratorFramework client, String path, boolean cacheData, boolean dataIsCompressed, final ExecutorService executorService) { this(client, path, cacheData, dataIsCompressed, new CloseableExecutorService(executorService)); }
/** * @param client the client * @param leaderPath the path for this leadership group * @param executorService thread pool to use * @param listener listener */ public LeaderSelector(CuratorFramework client, String leaderPath, ExecutorService executorService, LeaderSelectorListener listener) { this(client, leaderPath, new CloseableExecutorService(executorService), listener); }
/** * Optional executor service to use for the cache's background thread * * @param executorService executor service * @return this */ @Override public ServiceCacheBuilder<T> executorService(ExecutorService executorService) { this.executorService = new CloseableExecutorService(executorService); this.threadFactory = null; return this; }
/** * @param client the client * @param leaderPath the path for this leadership group * @param listener listener */ public LeaderSelector(CuratorFramework client, String leaderPath, LeaderSelectorListener listener) { this(client, leaderPath, new CloseableExecutorService(Executors.newSingleThreadExecutor(defaultThreadFactory), true), listener); }
/** * @param client the client * @param path path to watch * @param cacheData if true, node contents are cached in addition to the stat * @param dataIsCompressed if true, data in the path is compressed * @param threadFactory factory to use when creating internal threads */ public PathChildrenCache(CuratorFramework client, String path, boolean cacheData, boolean dataIsCompressed, ThreadFactory threadFactory) { this(client, path, cacheData, dataIsCompressed, new CloseableExecutorService(Executors.newSingleThreadExecutor(threadFactory), true)); }
/** * @param client the client * @param path path to watch * @param cacheData if true, node contents are cached in addition to the stat */ public PathChildrenCache(CuratorFramework client, String path, boolean cacheData) { this(client, path, cacheData, false, new CloseableExecutorService(Executors.newSingleThreadExecutor(defaultThreadFactory), true)); }
/** * @param client the client * @param path path to watch * @param cacheData if true, node contents are cached in addition to the stat * @param threadFactory factory to use when creating internal threads */ public PathChildrenCache(CuratorFramework client, String path, boolean cacheData, ThreadFactory threadFactory) { this(client, path, cacheData, false, new CloseableExecutorService(Executors.newSingleThreadExecutor(threadFactory), true)); }
/** * @param client the client * @param path path to watch * @param mode caching mode * @deprecated use {@link #PathChildrenCache(CuratorFramework, String, boolean)} instead */ @Deprecated @SuppressWarnings("deprecation") public PathChildrenCache(CuratorFramework client, String path, PathChildrenCacheMode mode) { this(client, path, mode != PathChildrenCacheMode.CACHE_PATHS_ONLY, false, new CloseableExecutorService(Executors.newSingleThreadExecutor(defaultThreadFactory), true)); }
public PathChildrenCache make(CuratorFramework curator, String path) { return new PathChildrenCache( curator, path, cacheData, compressed, new CloseableExecutorService(exec, shutdownExecutorOnClose) ); }
public PathChildrenCache make(CuratorFramework curator, String path) { return new PathChildrenCache( curator, path, cacheData, compressed, new CloseableExecutorService(exec, shutdownExecutorOnClose) ); }
/** * @param client the client * @param path path to watch * @param mode caching mode * @param threadFactory factory to use when creating internal threads * @deprecated use {@link #PathChildrenCache(CuratorFramework, String, boolean, ThreadFactory)} instead */ @Deprecated @SuppressWarnings("deprecation") public PathChildrenCache(CuratorFramework client, String path, PathChildrenCacheMode mode, ThreadFactory threadFactory) { this(client, path, mode != PathChildrenCacheMode.CACHE_PATHS_ONLY, false, new CloseableExecutorService(Executors.newSingleThreadExecutor(threadFactory), true)); }