Recovery: change check for finished to a ref count check

we current check that the recovery is not finished when people access the status local variables. This is wrong and we should check for the refcount being > 0 as it is OK to use the status after it has marked as finished but there are still on going, in-flight reference to it.

Relates to #8092

Closes #8271
This commit is contained in:
Boaz Leskes 2014-10-29 08:33:26 +01:00
parent 4ebbb657d8
commit 8eac79c2f3

View file

@ -102,7 +102,7 @@ public class RecoveryStatus extends AbstractRefCounted {
} }
public InternalIndexShard indexShard() { public InternalIndexShard indexShard() {
ensureNotFinished(); ensureRefCount();
return indexShard; return indexShard;
} }
@ -115,7 +115,7 @@ public class RecoveryStatus extends AbstractRefCounted {
} }
public Store store() { public Store store() {
ensureNotFinished(); ensureRefCount();
return store; return store;
} }
@ -146,7 +146,7 @@ public class RecoveryStatus extends AbstractRefCounted {
/** renames all temporary files to their true name, potentially overriding existing files */ /** renames all temporary files to their true name, potentially overriding existing files */
public void renameAllTempFiles() throws IOException { public void renameAllTempFiles() throws IOException {
ensureNotFinished(); ensureRefCount();
Iterator<String> tempFileIterator = tempFileNames.iterator(); Iterator<String> tempFileIterator = tempFileNames.iterator();
final Directory directory = store.directory(); final Directory directory = store.directory();
while (tempFileIterator.hasNext()) { while (tempFileIterator.hasNext()) {
@ -222,7 +222,7 @@ public class RecoveryStatus extends AbstractRefCounted {
} }
public IndexOutput getOpenIndexOutput(String key) { public IndexOutput getOpenIndexOutput(String key) {
ensureNotFinished(); ensureRefCount();
return openIndexOutputs.get(key); return openIndexOutputs.get(key);
} }
@ -236,7 +236,7 @@ public class RecoveryStatus extends AbstractRefCounted {
/** remove and {@link org.apache.lucene.store.IndexOutput} for a given file. It is the caller's responsibility to close it */ /** remove and {@link org.apache.lucene.store.IndexOutput} for a given file. It is the caller's responsibility to close it */
public IndexOutput removeOpenIndexOutputs(String name) { public IndexOutput removeOpenIndexOutputs(String name) {
ensureNotFinished(); ensureRefCount();
return openIndexOutputs.remove(name); return openIndexOutputs.remove(name);
} }
@ -248,7 +248,7 @@ public class RecoveryStatus extends AbstractRefCounted {
* at a later stage * at a later stage
*/ */
public IndexOutput openAndPutIndexOutput(String fileName, StoreFileMetaData metaData, Store store) throws IOException { public IndexOutput openAndPutIndexOutput(String fileName, StoreFileMetaData metaData, Store store) throws IOException {
ensureNotFinished(); ensureRefCount();
String tempFileName = getTempNameForFile(fileName); String tempFileName = getTempNameForFile(fileName);
// add first, before it's created // add first, before it's created
tempFileNames.add(tempFileName); tempFileNames.add(tempFileName);
@ -284,9 +284,9 @@ public class RecoveryStatus extends AbstractRefCounted {
return shardId + " [" + recoveryId + "]"; return shardId + " [" + recoveryId + "]";
} }
private void ensureNotFinished() { private void ensureRefCount() {
if (finished.get()) { if (refCount() <= 0) {
throw new ElasticsearchException("RecoveryStatus is used after it was finished. Probably a mismatch between incRef/decRef calls"); throw new ElasticsearchException("RecoveryStatus is used but it's refcount is 0. Probably a mismatch between incRef/decRef calls");
} }
} }