SOLR-4597: Because of Windows, we have to wait to delete the data dir after the SolrCore is closed.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1457816 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Robert Miller 2013-03-18 15:36:40 +00:00
parent edc777e22e
commit dfc1718c4c
4 changed files with 58 additions and 13 deletions

View File

@ -70,14 +70,16 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
// has close(Directory) been called on this?
public boolean closeDirectoryCalled = false;
public boolean doneWithDir = false;
private boolean deleteAfterCoreClose = false;
public Set<CacheValue> removeEntries = new HashSet<CacheValue>();
public Set<CacheValue> closeEntries = new HashSet<CacheValue>();
public void setDeleteOnClose(boolean deleteOnClose) {
public void setDeleteOnClose(boolean deleteOnClose, boolean deleteAfterCoreClose) {
if (deleteOnClose) {
removeEntries.add(this);
}
this.deleteOnClose = deleteOnClose;
this.deleteAfterCoreClose = deleteAfterCoreClose;
}
@Override
@ -94,6 +96,8 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
protected Map<Directory,CacheValue> byDirectoryCache = new IdentityHashMap<Directory,CacheValue>();
protected Map<Directory,List<CloseListener>> closeListeners = new HashMap<Directory,List<CloseListener>>();
protected Set<CacheValue> removeEntries = new HashSet<CacheValue>();
private Double maxWriteMBPerSecFlush;
@ -187,6 +191,11 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
byDirectoryCache.clear();
byPathCache.clear();
for (CacheValue val : removeEntries) {
log.info("Removing directory: " + val.path);
removeDirectory(val);
}
}
}
@ -246,6 +255,9 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
// get a sub path to close us later
if (otherCacheValue.path.startsWith(cacheValue.path) && !otherCacheValue.closeDirectoryCalled) {
// we let the sub dir remove and close us
if (!otherCacheValue.deleteAfterCoreClose && cacheValue.deleteAfterCoreClose) {
otherCacheValue.deleteAfterCoreClose = true;
}
otherCacheValue.removeEntries.addAll(cacheValue.removeEntries);
otherCacheValue.closeEntries.addAll(cacheValue.closeEntries);
cacheValue.closeEntries.clear();
@ -255,12 +267,15 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
}
for (CacheValue val : cacheValue.removeEntries) {
try {
log.info("Removing directory: " + val.path);
removeDirectory(val);
} catch (Throwable t) {
SolrException.log(log, "Error removing directory", t);
if (!val.deleteAfterCoreClose) {
try {
log.info("Removing directory: " + val.path);
removeDirectory(val);
} catch (Throwable t) {
SolrException.log(log, "Error removing directory", t);
}
} else {
removeEntries.add(val);
}
}
@ -426,23 +441,33 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
@Override
public void remove(String path) throws IOException {
remove(path, false);
}
@Override
public void remove(Directory dir) throws IOException {
remove(dir, false);
}
@Override
public void remove(String path, boolean deleteAfterCoreClose) throws IOException {
synchronized (this) {
CacheValue val = byPathCache.get(normalize(path));
if (val == null) {
throw new IllegalArgumentException("Unknown directory " + path);
}
val.setDeleteOnClose(true);
val.setDeleteOnClose(true, deleteAfterCoreClose);
}
}
@Override
public void remove(Directory dir) throws IOException {
public void remove(Directory dir, boolean deleteAfterCoreClose) throws IOException {
synchronized (this) {
CacheValue val = byDirectoryCache.get(dir);
if (val == null) {
throw new IllegalArgumentException("Unknown directory " + dir);
}
val.setDeleteOnClose(true);
val.setDeleteOnClose(true, deleteAfterCoreClose);
}
}

View File

@ -92,6 +92,26 @@ public abstract class DirectoryFactory implements NamedListInitializedPlugin,
*/
public abstract void remove(Directory dir) throws IOException;
/**
* Removes the Directory's persistent storage.
* For example: A file system impl may remove the
* on disk directory.
* @throws IOException If there is a low-level I/O error.
*
*/
public abstract void remove(Directory dir, boolean afterCoreClose) throws IOException;
/**
* This remove is special in that it may be called even after
* the factory has been closed. Remove only makes sense for
* persistent directory factories.
*
* @param path to remove
* @param afterCoreClose whether to wait until after the core is closed.
* @throws IOException If there is a low-level I/O error.
*/
public abstract void remove(String path, boolean afterCoreClose) throws IOException;
/**
* This remove is special in that it may be called even after
* the factory has been closed. Remove only makes sense for

View File

@ -578,7 +578,7 @@ public class CoreAdminHandler extends RequestHandlerBase {
if (params.getBool(CoreAdminParams.DELETE_DATA_DIR, false)) {
try {
core.getDirectoryFactory().remove(core.getDataDir());
core.getDirectoryFactory().remove(core.getDataDir(), true);
} catch (Exception e) {
SolrException.log(log, "Failed to flag data dir for removal for core:"
+ core.getName() + " dir:" + core.getDataDir());

View File

@ -20,8 +20,8 @@ package org.apache.solr.client.solrj;
import java.io.File;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION;
import org.apache.solr.client.solrj.request.CoreAdminRequest.Unload;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.request.CoreAdminRequest.Unload;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.response.CoreAdminResponse;