mirror of https://github.com/apache/lucene.git
SOLR-647: refcount cores
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@686780 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0ab15a39be
commit
de8c642def
|
@ -359,6 +359,9 @@ Changes in runtime behavior
|
||||||
different syntax. The solrj classes: MultiCore{Request/Response/Params} have been
|
different syntax. The solrj classes: MultiCore{Request/Response/Params} have been
|
||||||
renamed: CoreAdmin{Request/Response/Params} (hossman, ryan, Henri Biestro)
|
renamed: CoreAdmin{Request/Response/Params} (hossman, ryan, Henri Biestro)
|
||||||
|
|
||||||
|
3. SOLR-647: reference count the SolrCore uses to prevent a premature
|
||||||
|
close while a core is still in use. (Henri Biestro, Noble Paul, yonik)
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
1. SOLR-276: improve JSON writer speed. (yonik)
|
1. SOLR-276: improve JSON writer speed. (yonik)
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.solr.common.params.SolrParams;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.core.CoreContainer;
|
import org.apache.solr.core.CoreContainer;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
|
import org.apache.solr.core.CoreDescriptor;
|
||||||
import org.apache.solr.request.BinaryResponseWriter;
|
import org.apache.solr.request.BinaryResponseWriter;
|
||||||
import org.apache.solr.request.QueryResponseWriter;
|
import org.apache.solr.request.QueryResponseWriter;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
|
@ -54,38 +55,46 @@ import org.apache.solr.servlet.SolrRequestParsers;
|
||||||
*/
|
*/
|
||||||
public class EmbeddedSolrServer extends SolrServer
|
public class EmbeddedSolrServer extends SolrServer
|
||||||
{
|
{
|
||||||
|
protected final CoreContainer coreContainer;
|
||||||
protected final CoreContainer multicore; // either cores
|
protected final String coreName;
|
||||||
protected final SolrCore core; // or single core
|
|
||||||
protected final String coreName; // use CoreContainer registry
|
|
||||||
|
|
||||||
private final SolrRequestParsers _parser;
|
private final SolrRequestParsers _parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the other constructor using a CoreContainer and a name.
|
||||||
|
* @param core
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public EmbeddedSolrServer( SolrCore core )
|
public EmbeddedSolrServer( SolrCore core )
|
||||||
{
|
{
|
||||||
if ( core == null ) {
|
if ( core == null ) {
|
||||||
throw new NullPointerException("SolrCore instance required");
|
throw new NullPointerException("SolrCore instance required");
|
||||||
}
|
}
|
||||||
this.core = core;
|
CoreDescriptor dcore = core.getCoreDescriptor();
|
||||||
if (core.getCoreDescriptor() != null) {
|
if (dcore == null)
|
||||||
this.multicore = core.getCoreDescriptor().getMultiCore();
|
throw new NullPointerException("CoreDescriptor required");
|
||||||
this.coreName = core.getCoreDescriptor().getName();
|
|
||||||
} else {
|
CoreContainer cores = dcore.getCoreContainer();
|
||||||
this.multicore = null;
|
if (cores == null)
|
||||||
this.coreName = null;
|
throw new NullPointerException("CoreContainer required");
|
||||||
}
|
|
||||||
|
coreName = dcore.getName();
|
||||||
|
coreContainer = cores;
|
||||||
_parser = new SolrRequestParsers( null );
|
_parser = new SolrRequestParsers( null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbeddedSolrServer( CoreContainer multicore, String coreName )
|
/**
|
||||||
|
* Creates a SolrServer.
|
||||||
|
* @param coreContainer the core container
|
||||||
|
* @param coreName the core name
|
||||||
|
*/
|
||||||
|
public EmbeddedSolrServer( CoreContainer coreContainer, String coreName )
|
||||||
{
|
{
|
||||||
if ( multicore == null ) {
|
if ( coreContainer == null ) {
|
||||||
throw new NullPointerException("CoreContainer instance required");
|
throw new NullPointerException("CoreContainer instance required");
|
||||||
}
|
}
|
||||||
this.core = null;
|
this.coreContainer = coreContainer;
|
||||||
this.multicore = multicore;
|
|
||||||
this.coreName = coreName == null? "" : coreName;
|
this.coreName = coreName == null? "" : coreName;
|
||||||
|
|
||||||
_parser = new SolrRequestParsers( null );
|
_parser = new SolrRequestParsers( null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +107,10 @@ public class EmbeddedSolrServer extends SolrServer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for cores action
|
// Check for cores action
|
||||||
SolrCore core = this.core;
|
SolrCore core = coreContainer.getCore( coreName );
|
||||||
if( core == null )
|
|
||||||
core = multicore.getCore( coreName );
|
|
||||||
// solr-647
|
|
||||||
//else
|
|
||||||
// core = core.open();
|
|
||||||
if( core == null ) {
|
if( core == null ) {
|
||||||
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
|
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
|
||||||
coreName == null? "No core": "No such core: " + coreName );
|
"No such core: " + coreName );
|
||||||
}
|
}
|
||||||
|
|
||||||
SolrParams params = request.getParams();
|
SolrParams params = request.getParams();
|
||||||
|
@ -126,14 +130,13 @@ public class EmbeddedSolrServer extends SolrServer
|
||||||
}
|
}
|
||||||
// Perhaps the path is to manage the cores
|
// Perhaps the path is to manage the cores
|
||||||
if( handler == null &&
|
if( handler == null &&
|
||||||
multicore != null &&
|
coreContainer != null &&
|
||||||
path.equals( multicore.getAdminPath() ) ) {
|
path.equals( coreContainer.getAdminPath() ) ) {
|
||||||
handler = multicore.getMultiCoreHandler();
|
handler = coreContainer.getMultiCoreHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( handler == null ) {
|
if( handler == null ) {
|
||||||
// solr-647
|
core.close();
|
||||||
// core.close();
|
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+path );
|
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +161,7 @@ public class EmbeddedSolrServer extends SolrServer
|
||||||
throw new SolrServerException( ex );
|
throw new SolrServerException( ex );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
// solr-647
|
core.close();
|
||||||
// core.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,6 @@ public class LargeVolumeEmbeddedTest extends LargeVolumeTestBase {
|
||||||
@Override
|
@Override
|
||||||
protected SolrServer createNewSolrServer()
|
protected SolrServer createNewSolrServer()
|
||||||
{
|
{
|
||||||
return new EmbeddedSolrServer( h.getCore() );
|
return new EmbeddedSolrServer( h.getCoreContainer(), "" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,6 @@ public class SolrExampleEmbeddedTest extends SolrExampleTests {
|
||||||
@Override
|
@Override
|
||||||
protected SolrServer createNewSolrServer()
|
protected SolrServer createNewSolrServer()
|
||||||
{
|
{
|
||||||
return new EmbeddedSolrServer( h.getCore() );
|
return new EmbeddedSolrServer( h.getCoreContainer(), "" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,7 @@ import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
@ -36,6 +34,7 @@ import javax.xml.xpath.XPathConstants;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.util.DOMUtil;
|
import org.apache.solr.common.util.DOMUtil;
|
||||||
import org.apache.solr.common.util.XML;
|
import org.apache.solr.common.util.XML;
|
||||||
|
import org.apache.solr.common.util.StrUtils;
|
||||||
import org.apache.solr.handler.admin.CoreAdminHandler;
|
import org.apache.solr.handler.admin.CoreAdminHandler;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
import org.apache.solr.schema.IndexSchema;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -51,7 +50,7 @@ public class CoreContainer
|
||||||
{
|
{
|
||||||
protected static Logger log = Logger.getLogger(CoreContainer.class.getName());
|
protected static Logger log = Logger.getLogger(CoreContainer.class.getName());
|
||||||
|
|
||||||
protected final Map<String, CoreDescriptor> cores = new LinkedHashMap<String, CoreDescriptor>();
|
protected final Map<String, SolrCore> cores = new LinkedHashMap<String, SolrCore>();
|
||||||
protected boolean persistent = false;
|
protected boolean persistent = false;
|
||||||
protected String adminPath = null;
|
protected String adminPath = null;
|
||||||
protected String managementPath = null;
|
protected String managementPath = null;
|
||||||
|
@ -69,7 +68,6 @@ public class CoreContainer
|
||||||
public static class Initializer {
|
public static class Initializer {
|
||||||
protected String solrConfigFilename = null;
|
protected String solrConfigFilename = null;
|
||||||
protected boolean abortOnConfigurationError = true;
|
protected boolean abortOnConfigurationError = true;
|
||||||
protected String managementPath = null;
|
|
||||||
|
|
||||||
public boolean isAbortOnConfigurationError() {
|
public boolean isAbortOnConfigurationError() {
|
||||||
return abortOnConfigurationError;
|
return abortOnConfigurationError;
|
||||||
|
@ -87,14 +85,6 @@ public class CoreContainer
|
||||||
this.solrConfigFilename = solrConfigFilename;
|
this.solrConfigFilename = solrConfigFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getManagementPath() {
|
|
||||||
return managementPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setManagementPath(String managementPath) {
|
|
||||||
this.managementPath = managementPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
// core container instantiation
|
// core container instantiation
|
||||||
public CoreContainer initialize() throws IOException, ParserConfigurationException, SAXException {
|
public CoreContainer initialize() throws IOException, ParserConfigurationException, SAXException {
|
||||||
CoreContainer cores = null;
|
CoreContainer cores = null;
|
||||||
|
@ -116,16 +106,13 @@ public class CoreContainer
|
||||||
solrConfigFilename = cores.getConfigFile().getName();
|
solrConfigFilename = cores.getConfigFile().getName();
|
||||||
} else {
|
} else {
|
||||||
// perform compatibility init
|
// perform compatibility init
|
||||||
cores = new CoreContainer();
|
cores = new CoreContainer(new SolrResourceLoader(instanceDir));
|
||||||
cores.loader = new SolrResourceLoader(instanceDir);
|
|
||||||
SolrConfig cfg = solrConfigFilename == null ? new SolrConfig() : new SolrConfig(solrConfigFilename);
|
SolrConfig cfg = solrConfigFilename == null ? new SolrConfig() : new SolrConfig(solrConfigFilename);
|
||||||
CoreDescriptor dcore = new CoreDescriptor(cores);
|
CoreDescriptor dcore = new CoreDescriptor(cores, "", cfg.getResourceLoader().getInstanceDir());
|
||||||
dcore.init("", cfg.getResourceLoader().getInstanceDir());
|
|
||||||
SolrCore singlecore = new SolrCore(null, null, cfg, null, dcore);
|
SolrCore singlecore = new SolrCore(null, null, cfg, null, dcore);
|
||||||
dcore.setCore(singlecore);
|
|
||||||
abortOnConfigurationError = cfg.getBool(
|
abortOnConfigurationError = cfg.getBool(
|
||||||
"abortOnConfigurationError", abortOnConfigurationError);
|
"abortOnConfigurationError", abortOnConfigurationError);
|
||||||
cores.register(dcore);
|
cores.register("", singlecore, false);
|
||||||
cores.setPersistent(false);
|
cores.setPersistent(false);
|
||||||
solrConfigFilename = cfg.getName();
|
solrConfigFilename = cfg.getName();
|
||||||
}
|
}
|
||||||
|
@ -147,6 +134,14 @@ public class CoreContainer
|
||||||
this.load(dir, configFile);
|
this.load(dir, configFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal CoreContainer constructor.
|
||||||
|
* @param loader the CoreContainer resource loader
|
||||||
|
*/
|
||||||
|
public CoreContainer(SolrResourceLoader loader) {
|
||||||
|
this.loader = loader;
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Initialization / Cleanup
|
// Initialization / Cleanup
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
@ -184,12 +179,15 @@ public class CoreContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core", XPathConstants.NODESET);
|
NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core", XPathConstants.NODESET);
|
||||||
synchronized (cores) {
|
|
||||||
for (int i=0; i<nodes.getLength(); i++) {
|
for (int i=0; i<nodes.getLength(); i++) {
|
||||||
Node node = nodes.item(i);
|
Node node = nodes.item(i);
|
||||||
try {
|
try {
|
||||||
CoreDescriptor p = new CoreDescriptor(this);
|
String names = DOMUtil.getAttr(node, "name", null);
|
||||||
p.init(DOMUtil.getAttr(node, "name", null), DOMUtil.getAttr(node, "instanceDir", null));
|
List<String> aliases = StrUtils.splitSmart(names,',');
|
||||||
|
String name = aliases.get(0);
|
||||||
|
CoreDescriptor p = new CoreDescriptor(this, name, DOMUtil.getAttr(node, "instanceDir", null));
|
||||||
|
|
||||||
// deal with optional settings
|
// deal with optional settings
|
||||||
String opt = DOMUtil.getAttr(node, "config", null);
|
String opt = DOMUtil.getAttr(node, "config", null);
|
||||||
if (opt != null) {
|
if (opt != null) {
|
||||||
|
@ -199,12 +197,15 @@ public class CoreContainer
|
||||||
if (opt != null) {
|
if (opt != null) {
|
||||||
p.setSchemaName(opt);
|
p.setSchemaName(opt);
|
||||||
}
|
}
|
||||||
CoreDescriptor old = cores.get(p.getName());
|
|
||||||
if (old != null && old.getName() != null && old.getName().equals(p.getName())) {
|
SolrCore core = create(p);
|
||||||
throw new RuntimeException( cfg.getName() +
|
|
||||||
" registers multiple cores to the same name: " + p.name);
|
for (int a=1; a<aliases.size(); a++) {
|
||||||
|
core.open();
|
||||||
|
register(aliases.get(i), core, false);
|
||||||
}
|
}
|
||||||
p.setCore(create(p));
|
|
||||||
|
register(name, core, false);
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
SolrConfig.severeErrors.add( ex );
|
SolrConfig.severeErrors.add( ex );
|
||||||
|
@ -212,7 +213,7 @@ public class CoreContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
finally {
|
finally {
|
||||||
if (cfgis != null) {
|
if (cfgis != null) {
|
||||||
try { cfgis.close(); } catch (Exception xany) {}
|
try { cfgis.close(); } catch (Exception xany) {}
|
||||||
|
@ -225,12 +226,9 @@ public class CoreContainer
|
||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
synchronized(cores) {
|
synchronized(cores) {
|
||||||
for(CoreDescriptor descriptor : cores.values()) {
|
for(SolrCore core : cores.values()) {
|
||||||
SolrCore core = descriptor.getCore();
|
|
||||||
if( core != null ) {
|
|
||||||
core.close();
|
core.close();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
cores.clear();
|
cores.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,39 +238,43 @@ public class CoreContainer
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------- CoreDescriptor related methods ---------------
|
|
||||||
/**
|
/**
|
||||||
* Registers a SolrCore descriptor in the registry.
|
* Registers a SolrCore descriptor in the registry.
|
||||||
* @param descr the Solr core descriptor
|
* @return a previous core having the same name if it existed and returnPrev==true
|
||||||
* @return a previous descriptor having the same name if it existed, null otherwise
|
|
||||||
*/
|
*/
|
||||||
public CoreDescriptor register( CoreDescriptor descr ) {
|
public SolrCore register(String name, SolrCore core, boolean returnPrev) {
|
||||||
if( descr == null ) {
|
if( core == null ) {
|
||||||
throw new RuntimeException( "Can not register a null core." );
|
throw new RuntimeException( "Can not register a null core." );
|
||||||
}
|
}
|
||||||
String name = descr.getName();
|
|
||||||
if( name == null ||
|
if( name == null ||
|
||||||
name.indexOf( '/' ) >= 0 ||
|
name.indexOf( '/' ) >= 0 ||
|
||||||
name.indexOf( '\\' ) >= 0 ){
|
name.indexOf( '\\' ) >= 0 ){
|
||||||
throw new RuntimeException( "Invalid core name: "+name );
|
throw new RuntimeException( "Invalid core name: "+name );
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreDescriptor old = null;
|
SolrCore old = null;
|
||||||
synchronized (cores) {
|
synchronized (cores) {
|
||||||
old = cores.put(name, descr);
|
old = cores.put(name, core);
|
||||||
|
core.setName(name);
|
||||||
}
|
}
|
||||||
if( old == null ) {
|
|
||||||
|
|
||||||
|
if( old == null || old == core) {
|
||||||
log.info( "registering core: "+name );
|
log.info( "registering core: "+name );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.info( "replacing core: "+name );
|
log.info( "replacing core: "+name );
|
||||||
|
if (!returnPrev) {
|
||||||
|
old.close();
|
||||||
|
}
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new core based on a descriptor.
|
* Creates a new core based on a descriptor but does not register it.
|
||||||
*
|
*
|
||||||
* @param dcore a core descriptor
|
* @param dcore a core descriptor
|
||||||
* @return the newly created core
|
* @return the newly created core
|
||||||
|
@ -293,10 +295,6 @@ public class CoreContainer
|
||||||
SolrConfig config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
|
SolrConfig config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
|
||||||
IndexSchema schema = new IndexSchema(config, dcore.getSchemaName(), null);
|
IndexSchema schema = new IndexSchema(config, dcore.getSchemaName(), null);
|
||||||
SolrCore core = new SolrCore(dcore.getName(), null, config, schema, dcore);
|
SolrCore core = new SolrCore(dcore.getName(), null, config, schema, dcore);
|
||||||
dcore.setCore(core);
|
|
||||||
|
|
||||||
// Register the new core
|
|
||||||
CoreDescriptor old = this.register(dcore);
|
|
||||||
return core;
|
return core;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,36 +302,38 @@ public class CoreContainer
|
||||||
* @return a Collection of registered SolrCores
|
* @return a Collection of registered SolrCores
|
||||||
*/
|
*/
|
||||||
public Collection<SolrCore> getCores() {
|
public Collection<SolrCore> getCores() {
|
||||||
java.util.List<SolrCore> l = new java.util.ArrayList<SolrCore>();
|
List<SolrCore> lst = new ArrayList<SolrCore>();
|
||||||
synchronized (cores) {
|
synchronized (cores) {
|
||||||
for(CoreDescriptor descr : this.cores.values()) {
|
lst.addAll(this.cores.values());
|
||||||
if (descr.getCore() != null)
|
|
||||||
l.add(descr.getCore());
|
|
||||||
}
|
}
|
||||||
}
|
return lst;
|
||||||
return l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a Collection of registered CoreDescriptors
|
* @return a Collection of the names that cores are mapped to
|
||||||
*/
|
*/
|
||||||
public Collection<CoreDescriptor> getDescriptors() {
|
public Collection<String> getCoreNames() {
|
||||||
java.util.List<CoreDescriptor> l = new java.util.ArrayList<CoreDescriptor>();
|
List<String> lst = new ArrayList<String>();
|
||||||
synchronized (cores) {
|
synchronized (cores) {
|
||||||
l.addAll(cores.values());
|
lst.addAll(this.cores.keySet());
|
||||||
}
|
}
|
||||||
return l;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the CoreDescriptor registered under that name
|
* @return a Collection of the names that a specific core is mapped to.
|
||||||
*/
|
*/
|
||||||
public CoreDescriptor getDescriptor(String name) {
|
public Collection<String> getCoreNames(SolrCore core) {
|
||||||
|
List<String> lst = new ArrayList<String>();
|
||||||
synchronized (cores) {
|
synchronized (cores) {
|
||||||
return cores.get( name );
|
for (Map.Entry<String,SolrCore> entry : cores.entrySet()) {
|
||||||
|
if (core == entry.getValue()) {
|
||||||
|
lst.add(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------- Core name related methods ---------------
|
// ---------------- Core name related methods ---------------
|
||||||
/**
|
/**
|
||||||
|
@ -348,12 +348,14 @@ public class CoreContainer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void reload(String name) throws ParserConfigurationException, IOException, SAXException {
|
public void reload(String name) throws ParserConfigurationException, IOException, SAXException {
|
||||||
|
SolrCore core;
|
||||||
synchronized(cores) {
|
synchronized(cores) {
|
||||||
CoreDescriptor dcore = cores.get(name);
|
core = cores.get(name);
|
||||||
if (dcore == null)
|
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name );
|
|
||||||
create(new CoreDescriptor(dcore));
|
|
||||||
}
|
}
|
||||||
|
if (core == null)
|
||||||
|
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name );
|
||||||
|
|
||||||
|
register(name, create(core.getCoreDescriptor()), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -367,36 +369,27 @@ public class CoreContainer
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Can not swap unnamed cores." );
|
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Can not swap unnamed cores." );
|
||||||
}
|
}
|
||||||
synchronized( cores ) {
|
synchronized( cores ) {
|
||||||
CoreDescriptor c0 = cores.get(n0);
|
SolrCore c0 = cores.get(n0);
|
||||||
|
SolrCore c1 = cores.get(n1);
|
||||||
if (c0 == null)
|
if (c0 == null)
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + n0 );
|
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + n0 );
|
||||||
CoreDescriptor c1 = cores.get(n1);
|
|
||||||
if (c1 == null)
|
if (c1 == null)
|
||||||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + n1 );
|
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + n1 );
|
||||||
cores.put(n0, c1);
|
cores.put(n0, c1);
|
||||||
cores.put(n1, c0);
|
cores.put(n1, c0);
|
||||||
|
|
||||||
c0.setName(n1);
|
c0.setName(n1);
|
||||||
if (c0.getCore() != null)
|
|
||||||
c0.getCore().setName(n1);
|
|
||||||
c1.setName(n0);
|
c1.setName(n0);
|
||||||
if (c1.getCore() != null)
|
|
||||||
c1.getCore().setName(n0);
|
|
||||||
log.info( "swaped: "+c0.getName() + " with " + c1.getName() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes & closes a registered core. */
|
|
||||||
public void remove( String name ) {
|
log.info("swaped: "+n0 + " with " + n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes and returns registered core w/o decrementing it's reference count */
|
||||||
|
public SolrCore remove( String name ) {
|
||||||
synchronized(cores) {
|
synchronized(cores) {
|
||||||
CoreDescriptor dcore = cores.remove( name );
|
return cores.remove( name );
|
||||||
if (dcore == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SolrCore core = dcore.getCore();
|
|
||||||
if (core != null) {
|
|
||||||
core.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,15 +401,10 @@ public class CoreContainer
|
||||||
*/
|
*/
|
||||||
public SolrCore getCore(String name) {
|
public SolrCore getCore(String name) {
|
||||||
synchronized(cores) {
|
synchronized(cores) {
|
||||||
CoreDescriptor dcore = cores.get(name);
|
SolrCore core = cores.get(name);
|
||||||
SolrCore core = null;
|
if (core != null)
|
||||||
if (dcore != null)
|
core.open(); // increment the ref count while still synchronized
|
||||||
core = dcore.getCore();
|
|
||||||
return core;
|
return core;
|
||||||
// solr-647
|
|
||||||
// if (core != null)
|
|
||||||
// return core.open();
|
|
||||||
// return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,16 +425,13 @@ public class CoreContainer
|
||||||
public SolrCore getAdminCore() {
|
public SolrCore getAdminCore() {
|
||||||
synchronized (cores) {
|
synchronized (cores) {
|
||||||
SolrCore core = adminCore != null ? adminCore.get() : null;
|
SolrCore core = adminCore != null ? adminCore.get() : null;
|
||||||
// solr-647
|
|
||||||
// if (core != null)
|
|
||||||
// core = core.open();
|
|
||||||
if (core == null) {
|
|
||||||
for (CoreDescriptor descr : this.cores.values()) {
|
|
||||||
core = descr.getCore();
|
|
||||||
// solr-647
|
|
||||||
// if (core != null)
|
|
||||||
// core = core.open();
|
|
||||||
if (core != null) {
|
if (core != null) {
|
||||||
|
core.open();
|
||||||
|
} else {
|
||||||
|
for (SolrCore c : cores.values()) {
|
||||||
|
if (c != null) {
|
||||||
|
core = c;
|
||||||
|
core.open();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,7 +512,6 @@ public class CoreContainer
|
||||||
file = tmpFile = File.createTempFile("solr", ".xml", configFile.getParentFile());
|
file = tmpFile = File.createTempFile("solr", ".xml", configFile.getParentFile());
|
||||||
}
|
}
|
||||||
java.io.FileOutputStream out = new java.io.FileOutputStream(file);
|
java.io.FileOutputStream out = new java.io.FileOutputStream(file);
|
||||||
synchronized(cores) {
|
|
||||||
Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
|
Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
|
||||||
persist(writer);
|
persist(writer);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
|
@ -541,7 +525,6 @@ public class CoreContainer
|
||||||
fileCopy(tmpFile, configFile);
|
fileCopy(tmpFile, configFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch(java.io.FileNotFoundException xnf) {
|
catch(java.io.FileNotFoundException xnf) {
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, xnf);
|
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, xnf);
|
||||||
}
|
}
|
||||||
|
@ -578,20 +561,35 @@ public class CoreContainer
|
||||||
writer.write('\'');
|
writer.write('\'');
|
||||||
writer.write(">\n");
|
writer.write(">\n");
|
||||||
|
|
||||||
|
Map<SolrCore, LinkedList<String>> aliases = new HashMap<SolrCore,LinkedList<String>>();
|
||||||
|
|
||||||
synchronized(cores) {
|
synchronized(cores) {
|
||||||
for (Map.Entry<String, CoreDescriptor> entry : cores.entrySet()) {
|
for (Map.Entry<String, SolrCore> entry : cores.entrySet()) {
|
||||||
persist(writer, entry.getValue());
|
String name = entry.getKey();
|
||||||
|
LinkedList<String> a = aliases.get(entry.getValue());
|
||||||
|
if (a==null) a = new LinkedList<String>();
|
||||||
|
if (name.equals(entry.getValue().getName())) {
|
||||||
|
a.addFirst(name);
|
||||||
|
} else {
|
||||||
|
a.addLast(name);
|
||||||
|
}
|
||||||
|
aliases.put(entry.getValue(), a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<SolrCore, LinkedList<String>> entry : aliases.entrySet()) {
|
||||||
|
persist(writer, entry.getValue(), entry.getKey().getCoreDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
writer.write("</cores>\n");
|
writer.write("</cores>\n");
|
||||||
writer.write("</solr>\n");
|
writer.write("</solr>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Writes the cores configuration node for a given core. */
|
/** Writes the cores configuration node for a given core. */
|
||||||
void persist(Writer writer, CoreDescriptor dcore) throws IOException {
|
void persist(Writer writer, List<String> aliases, CoreDescriptor dcore) throws IOException {
|
||||||
writer.write(" <core");
|
writer.write(" <core");
|
||||||
writer.write (" name='");
|
writer.write (" name='");
|
||||||
XML.escapeAttributeValue(dcore.getName(), writer);
|
XML.escapeAttributeValue(StrUtils.join(aliases,','), writer);
|
||||||
writer.write("' instanceDir='");
|
writer.write("' instanceDir='");
|
||||||
XML.escapeAttributeValue(dcore.getInstanceDir(), writer);
|
XML.escapeAttributeValue(dcore.getInstanceDir(), writer);
|
||||||
writer.write('\'');
|
writer.write('\'');
|
||||||
|
|
|
@ -28,22 +28,17 @@ public class CoreDescriptor implements Cloneable {
|
||||||
protected String instanceDir;
|
protected String instanceDir;
|
||||||
protected String configName;
|
protected String configName;
|
||||||
protected String schemaName;
|
protected String schemaName;
|
||||||
protected SolrCore core = null;
|
|
||||||
private final CoreContainer coreContainer;
|
private final CoreContainer coreContainer;
|
||||||
|
|
||||||
public CoreDescriptor(CoreContainer coreContainer) {
|
public CoreDescriptor(CoreContainer coreContainer, String name, String instanceDir) {
|
||||||
this.coreContainer = coreContainer;
|
this.coreContainer = coreContainer;
|
||||||
}
|
this.name = name;
|
||||||
|
|
||||||
/** Initialize defaults from instance directory. */
|
|
||||||
public void init(String name, String instanceDir) {
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new RuntimeException("Core needs a name");
|
throw new RuntimeException("Core needs a name");
|
||||||
}
|
}
|
||||||
if (instanceDir == null) {
|
if (instanceDir == null) {
|
||||||
throw new NullPointerException("Missing required \'instanceDir\'");
|
throw new NullPointerException("Missing required \'instanceDir\'");
|
||||||
}
|
}
|
||||||
this.name = name;
|
|
||||||
if (!instanceDir.endsWith("/")) instanceDir = instanceDir + "/";
|
if (!instanceDir.endsWith("/")) instanceDir = instanceDir + "/";
|
||||||
this.instanceDir = instanceDir;
|
this.instanceDir = instanceDir;
|
||||||
this.configName = getDefaultConfigName();
|
this.configName = getDefaultConfigName();
|
||||||
|
@ -51,10 +46,10 @@ public class CoreDescriptor implements Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CoreDescriptor(CoreDescriptor descr) {
|
public CoreDescriptor(CoreDescriptor descr) {
|
||||||
this.name = descr.name;
|
|
||||||
this.instanceDir = descr.instanceDir;
|
this.instanceDir = descr.instanceDir;
|
||||||
this.configName = descr.configName;
|
this.configName = descr.configName;
|
||||||
this.schemaName = descr.schemaName;
|
this.schemaName = descr.schemaName;
|
||||||
|
this.name = descr.name;
|
||||||
coreContainer = descr.coreContainer;
|
coreContainer = descr.coreContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,16 +68,6 @@ public class CoreDescriptor implements Cloneable {
|
||||||
return this.instanceDir + "data/";
|
return this.instanceDir + "data/";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@return the core name. */
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the core name. */
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@return the core instance directory. */
|
/**@return the core instance directory. */
|
||||||
public String getInstanceDir() {
|
public String getInstanceDir() {
|
||||||
return instanceDir;
|
return instanceDir;
|
||||||
|
@ -112,15 +97,12 @@ public class CoreDescriptor implements Cloneable {
|
||||||
return this.schemaName;
|
return this.schemaName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SolrCore getCore() {
|
/**@return the initial core name */
|
||||||
return core;
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCore(SolrCore core) {
|
public CoreContainer getCoreContainer() {
|
||||||
this.core = core;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoreContainer getMultiCore() {
|
|
||||||
return coreContainer;
|
return coreContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,15 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public final class SolrCore {
|
public final class SolrCore implements SolrInfoMBean {
|
||||||
public static final String version="1.0";
|
public static final String version="1.0";
|
||||||
|
|
||||||
public static Logger log = Logger.getLogger(SolrCore.class.getName());
|
public static Logger log = Logger.getLogger(SolrCore.class.getName());
|
||||||
|
@ -479,8 +481,9 @@ public final class SolrCore {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
} // end synchronized
|
} // end synchronized
|
||||||
}
|
|
||||||
|
|
||||||
|
infoRegistry.put("core", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -570,15 +573,38 @@ public final class SolrCore {
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this core current usage count
|
||||||
|
private final AtomicInteger refCount = new AtomicInteger(1);
|
||||||
|
|
||||||
|
final void open() {
|
||||||
|
refCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close all resources allocated by the core.
|
* Close all resources allocated by the core.
|
||||||
* 1. searcher
|
* 1. searcher
|
||||||
* 2. updateHandler
|
* 2. updateHandler
|
||||||
* 3. all CloseHooks will be notified
|
* 3. all CloseHooks will be notified
|
||||||
* 4. All MBeans will be unregistered from MBeanServer if JMX was enabled
|
* 4. All MBeans will be unregistered from MBeanServer if JMX was enabled
|
||||||
|
* <p>
|
||||||
|
* This should always be called when the core is obtained through:
|
||||||
|
* @see CoreContainer.getCore
|
||||||
|
* @see CoreContainer.getAdminCore
|
||||||
|
* </p>
|
||||||
|
* The actual close is performed if the core usage count is 1.
|
||||||
|
* (A core is created with a usage count of 1).
|
||||||
|
* If usage count is > 1, the usage count is decreased by 1.
|
||||||
|
* If usage count is < 0, this is an error and a runtime exception is thrown.
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
log.info(logid+" CLOSING SolrCore!");
|
int count = refCount.decrementAndGet();
|
||||||
|
if (count > 0) return;
|
||||||
|
if (count < 0) {
|
||||||
|
//throw new RuntimeException("Too many closes on " + this);
|
||||||
|
log.severe("Too many close {count:"+count+"} on " + this + ". Please report this exception to solr-user@lucene.apache.org");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info(logid+" CLOSING SolrCore " + this);
|
||||||
try {
|
try {
|
||||||
infoRegistry.clear();
|
infoRegistry.clear();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -606,12 +632,18 @@ public final class SolrCore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isClosed() {
|
/** Current core usage count. */
|
||||||
return _searcher == null;
|
public int getOpenCount() {
|
||||||
|
return refCount.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/** Whether this core is closed. */
|
||||||
protected void finalize() { close(); }
|
public boolean isClosed() {
|
||||||
|
return refCount.get() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this can cause an extra close
|
||||||
|
// protected void finalize() { close(); }
|
||||||
|
|
||||||
private List<CloseHook> closeHooks = null;
|
private List<CloseHook> closeHooks = null;
|
||||||
|
|
||||||
|
@ -1380,6 +1412,45 @@ public final class SolrCore {
|
||||||
public CoreDescriptor getCoreDescriptor() {
|
public CoreDescriptor getCoreDescriptor() {
|
||||||
return coreDescriptor;
|
return coreDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// SolrInfoMBean stuff: Statistics and Module Info
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return SolrCore.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return "SolrCore";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category getCategory() {
|
||||||
|
return Category.CORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSourceId() {
|
||||||
|
return "$Id:$";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSource() {
|
||||||
|
return "$URL:$";
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL[] getDocs() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedList getStatistics() {
|
||||||
|
NamedList lst = new SimpleOrderedMap();
|
||||||
|
lst.add("coreName", name==null ? "(null)" : name);
|
||||||
|
lst.add("startTime", new Date(startTime));
|
||||||
|
lst.add("refCount", getOpenCount());
|
||||||
|
lst.add("aliases", getCoreDescriptor().getCoreContainer().getCoreNames(this));
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -90,9 +90,8 @@ public abstract class CoreAdminHandler extends RequestHandlerBase
|
||||||
|
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case CREATE: {
|
case CREATE: {
|
||||||
CoreDescriptor dcore = new CoreDescriptor(cores);
|
String name = params.get(CoreAdminParams.NAME);
|
||||||
dcore.init(params.get(CoreAdminParams.NAME),
|
CoreDescriptor dcore = new CoreDescriptor(cores, name, params.get(CoreAdminParams.INSTANCE_DIR));
|
||||||
params.get(CoreAdminParams.INSTANCE_DIR));
|
|
||||||
|
|
||||||
// fillup optional parameters
|
// fillup optional parameters
|
||||||
String opts = params.get(CoreAdminParams.CONFIG);
|
String opts = params.get(CoreAdminParams.CONFIG);
|
||||||
|
@ -104,6 +103,7 @@ public abstract class CoreAdminHandler extends RequestHandlerBase
|
||||||
dcore.setSchemaName(opts);
|
dcore.setSchemaName(opts);
|
||||||
|
|
||||||
SolrCore core = cores.create(dcore);
|
SolrCore core = cores.create(dcore);
|
||||||
|
cores.register(name, core,false);
|
||||||
rsp.add("core", core.getName());
|
rsp.add("core", core.getName());
|
||||||
do_persist = cores.isPersistent();
|
do_persist = cores.isPersistent();
|
||||||
break;
|
break;
|
||||||
|
@ -112,9 +112,8 @@ public abstract class CoreAdminHandler extends RequestHandlerBase
|
||||||
case STATUS: {
|
case STATUS: {
|
||||||
NamedList<Object> status = new SimpleOrderedMap<Object>();
|
NamedList<Object> status = new SimpleOrderedMap<Object>();
|
||||||
if( cname == null ) {
|
if( cname == null ) {
|
||||||
for (CoreDescriptor d : cores.getDescriptors()) {
|
for (SolrCore core : cores.getCores()) {
|
||||||
cname = d.getName();
|
status.add(core.getName(), getCoreStatus( cores, cname ) );
|
||||||
status.add(d.getName(), getCoreStatus( cores, cname ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -172,8 +171,7 @@ public abstract class CoreAdminHandler extends RequestHandlerBase
|
||||||
info.add("index", LukeRequestHandler.getIndexInfo(searcher.get().getReader(), false));
|
info.add("index", LukeRequestHandler.getIndexInfo(searcher.get().getReader(), false));
|
||||||
searcher.decref();
|
searcher.decref();
|
||||||
} finally {
|
} finally {
|
||||||
// solr-647
|
core.close();
|
||||||
// core.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -21,6 +21,9 @@ import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.common.util.XML;
|
import org.apache.solr.common.util.XML;
|
||||||
import org.apache.solr.core.SolrConfig;
|
import org.apache.solr.core.SolrConfig;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
|
import org.apache.solr.core.CoreContainer;
|
||||||
|
import org.apache.solr.core.CoreDescriptor;
|
||||||
|
import org.apache.solr.core.SolrResourceLoader;
|
||||||
import org.apache.solr.handler.XmlUpdateRequestHandler;
|
import org.apache.solr.handler.XmlUpdateRequestHandler;
|
||||||
import org.apache.solr.request.LocalSolrQueryRequest;
|
import org.apache.solr.request.LocalSolrQueryRequest;
|
||||||
import org.apache.solr.request.QueryResponseWriter;
|
import org.apache.solr.request.QueryResponseWriter;
|
||||||
|
@ -32,6 +35,7 @@ import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
@ -60,7 +64,7 @@ import java.util.Map;
|
||||||
* @version $Id:$
|
* @version $Id:$
|
||||||
*/
|
*/
|
||||||
public class TestHarness {
|
public class TestHarness {
|
||||||
|
protected CoreContainer container;
|
||||||
private SolrCore core;
|
private SolrCore core;
|
||||||
private XPath xpath = XPathFactory.newInstance().newXPath();
|
private XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
private DocumentBuilder builder;
|
private DocumentBuilder builder;
|
||||||
|
@ -123,8 +127,19 @@ public class TestHarness {
|
||||||
public TestHarness( String dataDirectory,
|
public TestHarness( String dataDirectory,
|
||||||
SolrConfig solrConfig,
|
SolrConfig solrConfig,
|
||||||
IndexSchema indexSchema) {
|
IndexSchema indexSchema) {
|
||||||
|
this("", new Initializer("", dataDirectory, solrConfig, indexSchema));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestHarness(String coreName, CoreContainer.Initializer init) {
|
||||||
try {
|
try {
|
||||||
core = new SolrCore( null, dataDirectory, solrConfig, indexSchema, null);
|
container = init.initialize();
|
||||||
|
if (coreName == null)
|
||||||
|
coreName = "";
|
||||||
|
// get the core & decrease its refcount:
|
||||||
|
// the container holds the core for the harness lifetime
|
||||||
|
core = container.getCore(coreName);
|
||||||
|
if (core != null)
|
||||||
|
core.close();
|
||||||
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
|
|
||||||
updater = new XmlUpdateRequestHandler();
|
updater = new XmlUpdateRequestHandler();
|
||||||
|
@ -134,6 +149,42 @@ public class TestHarness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a container based on infos needed to create one core
|
||||||
|
static class Initializer extends CoreContainer.Initializer {
|
||||||
|
String coreName;
|
||||||
|
String dataDirectory;
|
||||||
|
SolrConfig solrConfig;
|
||||||
|
IndexSchema indexSchema;
|
||||||
|
public Initializer(String coreName,
|
||||||
|
String dataDirectory,
|
||||||
|
SolrConfig solrConfig,
|
||||||
|
IndexSchema indexSchema) {
|
||||||
|
if (coreName == null)
|
||||||
|
coreName = "";
|
||||||
|
this.coreName = coreName;
|
||||||
|
this.dataDirectory = dataDirectory;
|
||||||
|
this.solrConfig = solrConfig;
|
||||||
|
this.indexSchema = indexSchema;
|
||||||
|
}
|
||||||
|
public String getCoreName() {
|
||||||
|
return coreName;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public CoreContainer initialize() {
|
||||||
|
CoreContainer container = new CoreContainer(new SolrResourceLoader(SolrResourceLoader.locateInstanceDir()));
|
||||||
|
CoreDescriptor dcore = new CoreDescriptor(container, coreName, solrConfig.getResourceLoader().getInstanceDir());
|
||||||
|
dcore.setConfigName(solrConfig.getResourceName());
|
||||||
|
dcore.setSchemaName(indexSchema.getResourceName());
|
||||||
|
SolrCore core = new SolrCore( null, dataDirectory, solrConfig, indexSchema, dcore);
|
||||||
|
container.register(coreName, core, false);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CoreContainer getCoreContainer() {
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
public SolrCore getCore() {
|
public SolrCore getCore() {
|
||||||
return core;
|
return core;
|
||||||
}
|
}
|
||||||
|
@ -153,8 +204,6 @@ public class TestHarness {
|
||||||
StringReader req = new StringReader(xml);
|
StringReader req = new StringReader(xml);
|
||||||
StringWriter writer = new StringWriter(32000);
|
StringWriter writer = new StringWriter(32000);
|
||||||
|
|
||||||
// This relies on the fact that SolrCore.getSolrCore() uses the
|
|
||||||
// last instantiated SolrCore.
|
|
||||||
updater.doLegacyUpdate(req, writer);
|
updater.doLegacyUpdate(req, writer);
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
|
@ -321,7 +370,17 @@ public class TestHarness {
|
||||||
* Shuts down and frees any resources
|
* Shuts down and frees any resources
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
core.close();
|
if (container != null) {
|
||||||
|
for (SolrCore c : container.getCores()) {
|
||||||
|
if (c.getOpenCount() > 1)
|
||||||
|
throw new RuntimeException("SolrCore.getOpenCount()=="+core.getOpenCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container != null) {
|
||||||
|
container.shutdown();
|
||||||
|
container = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,13 +24,14 @@ import org.apache.solr.request.SolrRequestHandler;
|
||||||
import org.apache.solr.util.AbstractSolrTestCase;
|
import org.apache.solr.util.AbstractSolrTestCase;
|
||||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.*;
|
||||||
public class SolrCoreTest extends AbstractSolrTestCase {
|
public class SolrCoreTest extends AbstractSolrTestCase {
|
||||||
|
|
||||||
public String getSchemaFile() { return "schema.xml"; }
|
public String getSchemaFile() { return "schema.xml"; }
|
||||||
public String getSolrConfigFile() { return "solrconfig.xml"; }
|
public String getSolrConfigFile() { return "solrconfig.xml"; }
|
||||||
|
|
||||||
public void testRequestHandlerRegistry() {
|
public void testRequestHandlerRegistry() {
|
||||||
// property values defined in build.xml
|
|
||||||
SolrCore core = h.getCore();
|
SolrCore core = h.getCore();
|
||||||
|
|
||||||
EmptyRequestHandler handler1 = new EmptyRequestHandler();
|
EmptyRequestHandler handler1 = new EmptyRequestHandler();
|
||||||
|
@ -46,7 +47,8 @@ public class SolrCoreTest extends AbstractSolrTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testClose() throws Exception {
|
public void testClose() throws Exception {
|
||||||
SolrCore core = h.getCore();
|
final CoreContainer cores = h.getCoreContainer();
|
||||||
|
SolrCore core = cores.getCore("");
|
||||||
|
|
||||||
ClosingRequestHandler handler1 = new ClosingRequestHandler();
|
ClosingRequestHandler handler1 = new ClosingRequestHandler();
|
||||||
handler1.inform( core );
|
handler1.inform( core );
|
||||||
|
@ -56,10 +58,116 @@ public class SolrCoreTest extends AbstractSolrTestCase {
|
||||||
assertNull( old ); // should not be anything...
|
assertNull( old ); // should not be anything...
|
||||||
assertEquals( core.getRequestHandlers().get( path ), handler1 );
|
assertEquals( core.getRequestHandlers().get( path ), handler1 );
|
||||||
core.close();
|
core.close();
|
||||||
|
cores.shutdown();
|
||||||
assertTrue("Handler not closed", handler1.closed == true);
|
assertTrue("Handler not closed", handler1.closed == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRefCount() throws Exception {
|
||||||
|
SolrCore core = h.getCore();
|
||||||
|
assertTrue("Refcount != 1", core.getOpenCount() == 1);
|
||||||
|
|
||||||
|
final CoreContainer cores = h.getCoreContainer();
|
||||||
|
SolrCore c1 = cores.getCore("");
|
||||||
|
assertTrue("Refcount != 2", core.getOpenCount() == 2);
|
||||||
|
|
||||||
|
ClosingRequestHandler handler1 = new ClosingRequestHandler();
|
||||||
|
handler1.inform( core );
|
||||||
|
|
||||||
|
String path = "/this/is A path /that won't be registered!";
|
||||||
|
SolrRequestHandler old = core.registerRequestHandler( path, handler1 );
|
||||||
|
assertNull( old ); // should not be anything...
|
||||||
|
assertEquals( core.getRequestHandlers().get( path ), handler1 );
|
||||||
|
|
||||||
|
SolrCore c2 = cores.getCore("");
|
||||||
|
c1.close();
|
||||||
|
assertTrue("Refcount < 1", core.getOpenCount() >= 1);
|
||||||
|
assertTrue("Handler is closed", handler1.closed == false);
|
||||||
|
|
||||||
|
c1 = cores.getCore("");
|
||||||
|
assertTrue("Refcount < 2", core.getOpenCount() >= 2);
|
||||||
|
assertTrue("Handler is closed", handler1.closed == false);
|
||||||
|
|
||||||
|
c2.close();
|
||||||
|
assertTrue("Refcount < 1", core.getOpenCount() >= 1);
|
||||||
|
assertTrue("Handler is closed", handler1.closed == false);
|
||||||
|
|
||||||
|
c1.close();
|
||||||
|
cores.shutdown();
|
||||||
|
assertTrue("Refcount != 0", core.getOpenCount() == 0);
|
||||||
|
assertTrue("Handler not closed", core.isClosed() && handler1.closed == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testRefCountMT() throws Exception {
|
||||||
|
SolrCore core = h.getCore();
|
||||||
|
assertTrue("Refcount != 1", core.getOpenCount() == 1);
|
||||||
|
|
||||||
|
final ClosingRequestHandler handler1 = new ClosingRequestHandler();
|
||||||
|
handler1.inform(core);
|
||||||
|
String path = "/this/is A path /that won't be registered!";
|
||||||
|
SolrRequestHandler old = core.registerRequestHandler(path, handler1);
|
||||||
|
assertNull(old); // should not be anything...
|
||||||
|
assertEquals(core.getRequestHandlers().get(path), handler1);
|
||||||
|
|
||||||
|
final int LOOP = 100;
|
||||||
|
final int MT = 16;
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(MT);
|
||||||
|
List<Callable<Integer>> callees = new ArrayList<Callable<Integer>>(MT);
|
||||||
|
final CoreContainer cores = h.getCoreContainer();
|
||||||
|
for (int i = 0; i < MT; ++i) {
|
||||||
|
Callable<Integer> call = new Callable<Integer>() {
|
||||||
|
void yield(int n) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(0, (n % 13 + 1) * 10);
|
||||||
|
} catch (InterruptedException xint) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer call() {
|
||||||
|
SolrCore core = null;
|
||||||
|
int r = 0;
|
||||||
|
try {
|
||||||
|
for (int l = 0; l < LOOP; ++l) {
|
||||||
|
r += 1;
|
||||||
|
core = cores.getCore("");
|
||||||
|
// sprinkle concurrency hinting...
|
||||||
|
yield(l);
|
||||||
|
assertTrue("Refcount < 1", core.getOpenCount() >= 1);
|
||||||
|
yield(l);
|
||||||
|
assertTrue("Refcount > 17", core.getOpenCount() <= 17);
|
||||||
|
yield(l);
|
||||||
|
assertTrue("Handler is closed", handler1.closed == false);
|
||||||
|
yield(l);
|
||||||
|
core.close();
|
||||||
|
core = null;
|
||||||
|
yield(l);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
} finally {
|
||||||
|
if (core != null)
|
||||||
|
core.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
callees.add(call);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Future<Integer>> results = service.invokeAll(callees);
|
||||||
|
for (Future<Integer> result : results) {
|
||||||
|
assertTrue("loop=" + result.get() +" < " + LOOP, result.get() >= LOOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
cores.shutdown();
|
||||||
|
assertTrue("Refcount != 0", core.getOpenCount() == 0);
|
||||||
|
assertTrue("Handler not closed", core.isClosed() && handler1.closed == true);
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
assertTrue("Running for too long...", service.awaitTermination(60, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ClosingRequestHandler extends EmptyRequestHandler implements SolrCoreAware {
|
class ClosingRequestHandler extends EmptyRequestHandler implements SolrCoreAware {
|
||||||
boolean closed = false;
|
boolean closed = false;
|
||||||
|
|
||||||
|
|
|
@ -285,6 +285,9 @@ public class SolrDispatchFilter implements Filter
|
||||||
if( solrReq != null ) {
|
if( solrReq != null ) {
|
||||||
solrReq.close();
|
solrReq.close();
|
||||||
}
|
}
|
||||||
|
if (core != null) {
|
||||||
|
core.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
<%-- $Name: $ --%>
|
<%-- $Name: $ --%>
|
||||||
|
|
||||||
<%@ page import="java.util.Date" %>
|
<%@ page import="java.util.Date" %>
|
||||||
|
<%@ page import="java.util.List" %>
|
||||||
|
<%@ page import="java.util.Collection" %>
|
||||||
|
|
||||||
<%-- jsp:include page="header.jsp"/ --%>
|
<%-- jsp:include page="header.jsp"/ --%>
|
||||||
<%-- do a verbatim include so we can use the local vars --%>
|
<%-- do a verbatim include so we can use the local vars --%>
|
||||||
|
@ -52,15 +54,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<%-- List the cores (that arent this one) so we can switch --%>
|
<%-- List the cores (that arent this one) so we can switch --%>
|
||||||
<% org.apache.solr.core.CoreContainer multicore = (org.apache.solr.core.CoreContainer)request.getAttribute("org.apache.solr.CoreContainer");
|
<% org.apache.solr.core.CoreContainer cores = (org.apache.solr.core.CoreContainer)request.getAttribute("org.apache.solr.CoreContainer");
|
||||||
if (multicore!=null) {
|
if (cores!=null) {
|
||||||
java.util.Collection<SolrCore> cores = multicore.getCores();
|
Collection<String> names = cores.getCoreNames();
|
||||||
if (cores.size() > 1) {%><tr><td><strong>Cores:</strong><br></td><td><%
|
if (names.size() > 1) {%><tr><td><strong>Cores:</strong><br></td><td><%
|
||||||
java.util.Iterator<SolrCore> icore = cores.iterator();
|
for (String name : names) {
|
||||||
while (icore.hasNext()) {
|
%>[<a href="../../<%=name%>/admin/"><%=name%></a>]<%
|
||||||
SolrCore acore = icore.next();
|
|
||||||
if (acore == core) continue;
|
|
||||||
%>[<a href="../../<%=acore.getName()%>/admin/"><%=acore.getName()%></a>]<%
|
|
||||||
}%></td></tr><%
|
}%></td></tr><%
|
||||||
}}%>
|
}}%>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue