use of org.apache.lucene.store.AlreadyClosedException in project elasticsearch by elastic.
the class IndexShard method createNewEngine.
private Engine createNewEngine(EngineConfig config) {
synchronized (mutex) {
if (state == IndexShardState.CLOSED) {
throw new AlreadyClosedException(shardId + " can't create engine - shard is closed");
}
assert this.currentEngineReference.get() == null;
Engine engine = newEngine(config);
// call this before we pass the memory barrier otherwise actions that happen
onNewEngine(engine);
// inside the callback are not visible. This one enforces happens-before
this.currentEngineReference.set(engine);
}
// time elapses after the engine is created above (pulling the config settings) until we set the engine reference, during which
// settings changes could possibly have happened, so here we forcefully push any config changes to the new engine:
Engine engine = getEngineOrNull();
// engine could perhaps be null if we were e.g. concurrently closed:
if (engine != null) {
engine.onSettingsChanged();
}
return engine;
}
use of org.apache.lucene.store.AlreadyClosedException in project elasticsearch by elastic.
the class ShardCoreKeyMapTests method testAddingAClosedReader.
public void testAddingAClosedReader() throws Exception {
LeafReader reader;
try (Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir)) {
writer.addDocument(new Document());
try (DirectoryReader dirReader = ElasticsearchDirectoryReader.wrap(writer.getReader(), new ShardId("index1", "_na_", 1))) {
reader = dirReader.leaves().get(0).reader();
}
}
ShardCoreKeyMap map = new ShardCoreKeyMap();
try {
map.add(reader);
fail("Expected AlreadyClosedException");
} catch (AlreadyClosedException e) {
// What we wanted
}
assertEquals(0, map.size());
}
use of org.apache.lucene.store.AlreadyClosedException in project elasticsearch by elastic.
the class TranslogTests method testFatalIOExceptionsWhileWritingConcurrently.
public void testFatalIOExceptionsWhileWritingConcurrently() throws IOException, InterruptedException {
Path tempDir = createTempDir();
final FailSwitch fail = new FailSwitch();
TranslogConfig config = getTranslogConfig(tempDir);
Translog translog = getFailableTranslog(fail, config);
final int threadCount = randomIntBetween(1, 5);
Thread[] threads = new Thread[threadCount];
final Exception[] threadExceptions = new Exception[threadCount];
final CountDownLatch downLatch = new CountDownLatch(1);
final CountDownLatch added = new CountDownLatch(randomIntBetween(10, 100));
List<LocationOperation> writtenOperations = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < threadCount; i++) {
final int threadId = i;
threads[i] = new TranslogThread(translog, downLatch, 200, threadId, writtenOperations, threadExceptions) {
@Override
protected Translog.Location add(Translog.Operation op) throws IOException {
Translog.Location add = super.add(op);
added.countDown();
return add;
}
@Override
protected void afterAdd() throws IOException {
if (randomBoolean()) {
translog.sync();
}
}
};
threads[i].setDaemon(true);
threads[i].start();
}
downLatch.countDown();
added.await();
try (Translog.View view = translog.newView()) {
// this holds a reference to the current tlog channel such that it's not closed
// if we hit a tragic event. this is important to ensure that asserts inside the Translog#add doesn't trip
// otherwise our assertions here are off by one sometimes.
fail.failAlways();
for (int i = 0; i < threadCount; i++) {
threads[i].join();
}
boolean atLeastOneFailed = false;
for (Throwable ex : threadExceptions) {
if (ex != null) {
assertTrue(ex.toString(), ex instanceof IOException || ex instanceof AlreadyClosedException);
atLeastOneFailed = true;
}
}
if (atLeastOneFailed == false) {
try {
boolean syncNeeded = translog.syncNeeded();
translog.close();
assertFalse("should have failed if sync was needed", syncNeeded);
} catch (IOException ex) {
// boom now we failed
}
}
Collections.sort(writtenOperations, (a, b) -> a.location.compareTo(b.location));
assertFalse(translog.isOpen());
final Checkpoint checkpoint = Checkpoint.read(config.getTranslogPath().resolve(Translog.CHECKPOINT_FILE_NAME));
Iterator<LocationOperation> iterator = writtenOperations.iterator();
while (iterator.hasNext()) {
LocationOperation next = iterator.next();
if (checkpoint.offset < (next.location.translogLocation + next.location.size)) {
// drop all that haven't been synced
iterator.remove();
}
}
try (Translog tlog = new Translog(config, translog.getGeneration(), () -> SequenceNumbersService.UNASSIGNED_SEQ_NO)) {
Translog.Snapshot snapshot = tlog.newSnapshot();
if (writtenOperations.size() != snapshot.totalOperations()) {
for (int i = 0; i < threadCount; i++) {
if (threadExceptions[i] != null) {
logger.info("Translog exception", threadExceptions[i]);
}
}
}
assertEquals(writtenOperations.size(), snapshot.totalOperations());
for (int i = 0; i < writtenOperations.size(); i++) {
assertEquals("expected operation" + i + " to be in the previous translog but wasn't", tlog.currentFileGeneration() - 1, writtenOperations.get(i).location.generation);
Translog.Operation next = snapshot.next();
assertNotNull("operation " + i + " must be non-null", next);
assertEquals(next, writtenOperations.get(i).operation);
}
}
}
}
use of org.apache.lucene.store.AlreadyClosedException in project elasticsearch by elastic.
the class InternalEngineTests method testFailEngineOnRandomIO.
public void testFailEngineOnRandomIO() throws IOException, InterruptedException {
MockDirectoryWrapper wrapper = newMockDirectory();
final Path translogPath = createTempDir("testFailEngineOnRandomIO");
try (Store store = createStore(wrapper)) {
CyclicBarrier join = new CyclicBarrier(2);
CountDownLatch start = new CountDownLatch(1);
AtomicInteger controller = new AtomicInteger(0);
EngineConfig config = config(defaultSettings, store, translogPath, newMergePolicy(), IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, new ReferenceManager.RefreshListener() {
@Override
public void beforeRefresh() throws IOException {
}
@Override
public void afterRefresh(boolean didRefresh) throws IOException {
int i = controller.incrementAndGet();
if (i == 1) {
throw new MockDirectoryWrapper.FakeIOException();
} else if (i == 2) {
try {
start.await();
} catch (InterruptedException e) {
throw new AssertionError(e);
}
throw new ElasticsearchException("something completely different");
}
}
});
InternalEngine internalEngine = new InternalEngine(config);
int docId = 0;
final ParsedDocument doc = testParsedDocument(Integer.toString(docId), "test", null, testDocumentWithTextField(), new BytesArray("{}".getBytes(Charset.defaultCharset())), null);
Engine.Index index = randomBoolean() ? indexForDoc(doc) : randomAppendOnly(doc, false, docId);
internalEngine.index(index);
Runnable r = () -> {
try {
join.await();
} catch (Exception e) {
throw new AssertionError(e);
}
try {
internalEngine.refresh("test");
fail();
} catch (AlreadyClosedException ex) {
if (ex.getCause() != null) {
assertTrue(ex.toString(), ex.getCause() instanceof MockDirectoryWrapper.FakeIOException);
}
} catch (RefreshFailedEngineException ex) {
// fine
} finally {
start.countDown();
}
};
Thread t = new Thread(r);
Thread t1 = new Thread(r);
t.start();
t1.start();
t.join();
t1.join();
assertTrue(internalEngine.isClosed.get());
assertTrue(internalEngine.failedEngine.get() instanceof MockDirectoryWrapper.FakeIOException);
}
}
use of org.apache.lucene.store.AlreadyClosedException in project elasticsearch by elastic.
the class Engine method failEngine.
/**
* fail engine due to some error. the engine will also be closed.
* The underlying store is marked corrupted iff failure is caused by index corruption
*/
public void failEngine(String reason, @Nullable Exception failure) {
if (failEngineLock.tryLock()) {
store.incRef();
try {
if (failedEngine.get() != null) {
logger.warn((Supplier<?>) () -> new ParameterizedMessage("tried to fail engine but engine is already failed. ignoring. [{}]", reason), failure);
return;
}
// this must happen before we close IW or Translog such that we can check this state to opt out of failing the engine
// again on any caught AlreadyClosedException
failedEngine.set((failure != null) ? failure : new IllegalStateException(reason));
try {
// we just go and close this engine - no way to recover
closeNoLock("engine failed on: [" + reason + "]");
} finally {
logger.warn((Supplier<?>) () -> new ParameterizedMessage("failed engine [{}]", reason), failure);
// the shard is initializing
if (Lucene.isCorruptionException(failure)) {
try {
store.markStoreCorrupted(new IOException("failed engine (reason: [" + reason + "])", ExceptionsHelper.unwrapCorruption(failure)));
} catch (IOException e) {
logger.warn("Couldn't mark store corrupted", e);
}
}
eventListener.onFailedEngine(reason, failure);
}
} catch (Exception inner) {
if (failure != null)
inner.addSuppressed(failure);
// don't bubble up these exceptions up
logger.warn("failEngine threw exception", inner);
} finally {
store.decRef();
}
} else {
logger.debug((Supplier<?>) () -> new ParameterizedMessage("tried to fail engine but could not acquire lock - engine should be failed by now [{}]", reason), failure);
}
}
Aggregations