public void run() {
            log.info("Starting cluster monitor thread " + getName());
            // Pings must happen in a separate thread from this to handle timeouts
            // By using a cached thread pool we ensured that 1) a single thread will be used
            // for all pings when there are no problems (important because it ensures that
            // any thread local connections are reused) 2) a new thread will be started to execute
            // new pings when a ping is not responding
            ExecutorService pingExecutor = Executors.newCachedThreadPool(ThreadFactoryFactory.getDaemonThreadFactory("search.ping"));
            while (!closed.get()) {
                try {
                    log.finest("Activating ping");
                    ping(pingExecutor);
                    synchronized (nodeManager) {
                        if ( ! skipNextWait)
                            nodeManager.wait(configuration.getCheckInterval());
                        skipNextWait = false;
                    }
                }
                catch (Throwable e) {
                    if (closed.get() && e instanceof InterruptedException) {
                        break;
                    } else if ( ! (e instanceof Exception) ) {
                        log.log(Level.WARNING,"Error in monitor thread, will quit", e);
                        break;
                    } else {
                        log.log(Level.WARNING,"Exception in monitor thread", e);
                    }
                }
            }
            pingExecutor.shutdown();
            try {
                if ( ! pingExecutor.awaitTermination(10, TimeUnit.SECONDS)) {
                    log.warning("Timeout waiting for ping executor to terminate");
                }
            } catch (InterruptedException e) { }
            log.info("Stopped cluster monitor thread " + getName());
        }
Must be called when this goes out of use
container-search/src/main/java/com/yahoo/search/cluster/ClusterMonitor.java