private void assertEnvIsLocked() { if (!closed.get() && locks != null) { for (Lock lock : locks) { try { lock.ensureValid(); } catch (IOException e) { logger.warn("lock assertion failed", e); throw new IllegalStateException("environment is not locked", e); } } } }
private boolean assertEnvIsLocked() { if (!closed.get() && locks != null) { for (Lock lock : locks) { try { assert lock.isLocked() : "Lock: " + lock + "is not locked"; } catch (IOException e) { logger.warn("lock assertion failed", e); return false; } } } return true; }
@Override public void close() { if (closed.compareAndSet(false, true) && locks != null) { for (Lock lock : locks) { try { logger.trace("releasing lock [{}]", lock); lock.close(); } catch (IOException e) { logger.trace("failed to release lock [{}]", e, lock); } } } }
private boolean assertEnvIsLocked() { if (!closed.get() && locks != null) { for (Lock lock : locks) { try { lock.ensureValid(); } catch (IOException e) { logger.warn("lock assertion failed", e); return false; } } } return true; }
@Override public void close() { if (closed.compareAndSet(false, true) && locks != null) { for (Lock lock : locks) { try { logger.trace("releasing lock [{}]", lock); lock.close(); } catch (IOException e) { logger.trace( (Supplier<?>) () -> new ParameterizedMessage("failed to release lock [{}]", lock), e); } } } }
public GeoOnlyIndexer(GeoSearchConfig config, Directory directory, String indexName) throws IOException { this.config = config; this.directory = directory; this.indexName = indexName; lock = directory.makeLock(indexName); if (!lock.obtain()) { throw new LockObtainFailedException("Index locked for write: " + indexName); } }
/** * Tries to acquire the WriteLock on this directory. this method is only valid if this IndexReader * is directory owner. * * @throws StaleReaderException if the index has changed since this reader was opened * @throws CorruptIndexException if the index is corrupt * @throws org.apache.lucene.store.LockObtainFailedException if another writer has this index open * (<code>write.lock</code> could not be obtained) * @throws IOException if there is a low-level IO error */ @Override protected void acquireWriteLock() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { if (readOnly) { // NOTE: we should not reach this code w/ the core // IndexReader classes; however, an external subclass // of IndexReader could reach this. ReadOnlySegmentReader.noWrite(); } if (segmentInfos != null) { ensureOpen(); if (stale) throw new StaleReaderException( "IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); if (writeLock == null) { Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME); if (!writeLock.obtain(IndexWriterConfig.WRITE_LOCK_TIMEOUT)) // obtain write lock throw new LockObtainFailedException("Index locked for write: " + writeLock); this.writeLock = writeLock; // we have to check whether index has changed since this reader was opened. // if so, this reader is no longer valid for // deletion if (SegmentInfos.readCurrentVersion(directory) > maxIndexVersion) { stale = true; this.writeLock.release(); this.writeLock = null; throw new StaleReaderException( "IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); } } } }
@Test public void testSimpleLocking() throws Exception { ByteBufferCache cache = new ByteBufferCache(40, 80, true); ByteBufferDirectory dir = new ByteBufferDirectory(cache); Lock lock = dir.makeLock("testlock"); assertThat(lock.isLocked(), equalTo(false)); assertThat(lock.obtain(200), equalTo(true)); assertThat(lock.isLocked(), equalTo(true)); try { assertThat(lock.obtain(200), equalTo(false)); assertThat("lock should be thrown", false, equalTo(true)); } catch (LockObtainFailedException e) { // all is well } lock.release(); assertThat(lock.isLocked(), equalTo(false)); dir.close(); cache.close(); }
/** * Commit changes resulting from delete, undeleteAll, or setNorm operations * * <p>If an exception is hit, then either no changes or all changes will have been committed to * the index (transactional semantics). * * @throws IOException if there is a low-level IO error */ @Override protected void doCommit(Map<String, String> commitUserData) throws IOException { if (hasChanges) { segmentInfos.setUserData(commitUserData); // Default deleter (for backwards compatibility) is // KeepOnlyLastCommitDeleter: IndexFileDeleter deleter = new IndexFileDeleter( directory, deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, segmentInfos, null, null); segmentInfos.updateGeneration(deleter.getLastSegmentInfos()); segmentInfos.changed(); // Checkpoint the state we are about to change, in // case we have to roll back: startCommit(); final List<SegmentInfo> rollbackSegments = segmentInfos.createBackupSegmentInfos(false); boolean success = false; try { for (int i = 0; i < subReaders.length; i++) subReaders[i].commit(); // Remove segments that contain only 100% deleted // docs: segmentInfos.pruneDeletedSegments(); // Sync all files we just wrote directory.sync(segmentInfos.files(directory, false)); segmentInfos.commit(directory); success = true; } finally { if (!success) { // Rollback changes that were made to // SegmentInfos but failed to get [fully] // committed. This way this reader instance // remains consistent (matched to what's // actually in the index): rollbackCommit(); // Recompute deletable files & remove them (so // partially written .del files, etc, are // removed): deleter.refresh(); // Restore all SegmentInfos (in case we pruned some) segmentInfos.rollbackSegmentInfos(rollbackSegments); } } // Have the deleter remove any now unreferenced // files due to this commit: deleter.checkpoint(segmentInfos, true); deleter.close(); maxIndexVersion = segmentInfos.getVersion(); if (writeLock != null) { writeLock.release(); // release write lock writeLock = null; } } hasChanges = false; }
/** * Closes this geoIndexer and releases any locks held * * @throws IOException */ public void close() throws IOException { lock.release(); }