// It's important that this be the _only_ thread removing things from pendingDynamicCloses! // This is single-threaded, but I tried a multi-threaded approach and didn't see any performance // gains, so // there's no good justification for the complexity. I suspect that the locking on things like // DefaultSolrCoreState // essentially create a single-threaded process anyway. @Override public void run() { while (!container.isShutDown()) { synchronized (solrCores.getModifyLock()) { // need this so we can wait and be awoken. try { solrCores.getModifyLock().wait(); } catch (InterruptedException e) { // Well, if we've been told to stop, we will. Otherwise, continue on and check to see if // there are // any cores to close. } } for (SolrCore removeMe = solrCores.getCoreToClose(); removeMe != null && !container.isShutDown(); removeMe = solrCores.getCoreToClose()) { try { removeMe.close(); } finally { solrCores.removeFromPendingOps(removeMe.getName()); } } } }
/** Stops all cores. */ public void shutdown() { log.info("Shutting down CoreContainer instance=" + System.identityHashCode(this)); isShutDown = true; ExecutorUtil.shutdownAndAwaitTermination(coreContainerWorkExecutor); if (isZooKeeperAware()) { cancelCoreRecoveries(); zkSys.zkController.publishNodeAsDown(zkSys.zkController.getNodeName()); } try { if (coreAdminHandler != null) coreAdminHandler.shutdown(); } catch (Exception e) { log.warn("Error shutting down CoreAdminHandler. Continuing to close CoreContainer.", e); } try { // First wake up the closer thread, it'll terminate almost immediately since it checks // isShutDown. synchronized (solrCores.getModifyLock()) { solrCores.getModifyLock().notifyAll(); // wake up anyone waiting } if (backgroundCloser != null) { // Doesn't seem right, but tests get in here without initializing the core. try { backgroundCloser.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); if (log.isDebugEnabled()) { log.debug("backgroundCloser thread was interrupted before finishing"); } } } // Now clear all the cores that are being operated upon. solrCores.close(); // It's still possible that one of the pending dynamic load operation is waiting, so wake it // up if so. // Since all the pending operations queues have been drained, there should be nothing to do. synchronized (solrCores.getModifyLock()) { solrCores.getModifyLock().notifyAll(); // wake up the thread } } finally { try { if (shardHandlerFactory != null) { shardHandlerFactory.close(); } } finally { try { if (updateShardHandler != null) { updateShardHandler.close(); } } finally { // we want to close zk stuff last zkSys.close(); } } } // It should be safe to close the authorization plugin at this point. try { if (authorizationPlugin != null) { authorizationPlugin.plugin.close(); } } catch (IOException e) { log.warn("Exception while closing authorization plugin.", e); } // It should be safe to close the authentication plugin at this point. try { if (authenticationPlugin != null) { authenticationPlugin.plugin.close(); authenticationPlugin = null; } } catch (Exception e) { log.warn("Exception while closing authentication plugin.", e); } org.apache.lucene.util.IOUtils.closeWhileHandlingException(loader); // best effort }