You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2015/05/30 08:22:07 UTC
svn commit: r1682582 - in /lucene/dev/branches/lucene6508/lucene/core/src:
java/org/apache/lucene/index/ java/org/apache/lucene/store/
test/org/apache/lucene/index/ test/org/apache/lucene/store/
Author: rmuir
Date: Sat May 30 06:22:07 2015
New Revision: 1682582
URL: http://svn.apache.org/r1682582
Log:
add back write.lock timeout (we can change default to 0 if we want/deprecate/whatever)
Added:
lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/store/SleepingLockWrapper.java (with props)
lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockWrapper.java
- copied, changed from r1682579, lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockFactory.java
Removed:
lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockFactory.java
Modified:
lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java
lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java
lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java
Modified: lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java?rev=1682582&r1=1682581&r2=1682582&view=diff
==============================================================================
--- lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java Sat May 30 06:22:07 2015
@@ -59,6 +59,7 @@ import org.apache.lucene.store.Lock;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.MergeInfo;
import org.apache.lucene.store.RateLimitedIndexOutput;
+import org.apache.lucene.store.SleepingLockWrapper;
import org.apache.lucene.store.TrackingDirectoryWrapper;
import org.apache.lucene.store.LockValidatingDirectoryWrapper;
import org.apache.lucene.util.Accountable;
@@ -753,8 +754,18 @@ public class IndexWriter implements Clos
public IndexWriter(Directory d, IndexWriterConfig conf) throws IOException {
conf.setIndexWriter(this); // prevent reuse by other instances
config = conf;
-
- writeLock = d.obtainLock(WRITE_LOCK_NAME);
+
+ // obtain the write.lock
+ long timeout = config.getWriteLockTimeout();
+ final Directory lockDir;
+ if (timeout == 0) {
+ // user doesn't want sleep/retries
+ lockDir = d;
+ } else {
+ lockDir = new SleepingLockWrapper(d, timeout);
+ }
+ writeLock = lockDir.obtainLock(WRITE_LOCK_NAME);
+
directory = d;
// nocommit: turn on carefully after we get other stuff going
// validatingDirectory = new LockValidatingDirectoryWrapper(d, writeLock);
Modified: lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java?rev=1682582&r1=1682581&r2=1682582&view=diff
==============================================================================
--- lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java (original)
+++ lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java Sat May 30 06:22:07 2015
@@ -86,6 +86,13 @@ public final class IndexWriterConfig ext
*/
public final static double DEFAULT_RAM_BUFFER_SIZE_MB = 16.0;
+ /**
+ * Default value for the write lock timeout (1,000 ms).
+ *
+ * @see #setDefaultWriteLockTimeout(long)
+ */
+ public static long WRITE_LOCK_TIMEOUT = 1000;
+
/** Default setting for {@link #setReaderPooling}. */
public final static boolean DEFAULT_READER_POOLING = false;
@@ -106,6 +113,24 @@ public final class IndexWriterConfig ext
/** Default value for whether calls to {@link IndexWriter#close()} include a commit. */
public final static boolean DEFAULT_COMMIT_ON_CLOSE = true;
+ /**
+ * Sets the default (for any instance) maximum time to wait for a write lock
+ * (in milliseconds).
+ */
+ public static void setDefaultWriteLockTimeout(long writeLockTimeout) {
+ WRITE_LOCK_TIMEOUT = writeLockTimeout;
+ }
+
+ /**
+ * Returns the default write lock timeout for newly instantiated
+ * IndexWriterConfigs.
+ *
+ * @see #setDefaultWriteLockTimeout(long)
+ */
+ public static long getDefaultWriteLockTimeout() {
+ return WRITE_LOCK_TIMEOUT;
+ }
+
// indicates whether this config instance is already attached to a writer.
// not final so that it can be cloned properly.
private SetOnce<IndexWriter> writer = new SetOnce<>();
@@ -236,7 +261,24 @@ public final class IndexWriterConfig ext
public MergeScheduler getMergeScheduler() {
return mergeScheduler;
}
+
+ /**
+ * Sets the maximum time to wait for a write lock (in milliseconds) for this
+ * instance. You can change the default value for all instances by calling
+ * {@link #setDefaultWriteLockTimeout(long)}. Note that the value can be zero,
+ * for no sleep/retry behavior.
+ *
+ * <p>Only takes effect when IndexWriter is first created. */
+ public IndexWriterConfig setWriteLockTimeout(long writeLockTimeout) {
+ this.writeLockTimeout = writeLockTimeout;
+ return this;
+ }
+ @Override
+ public long getWriteLockTimeout() {
+ return writeLockTimeout;
+ }
+
/**
* Set the {@link Codec}.
*
Modified: lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java?rev=1682582&r1=1682581&r2=1682582&view=diff
==============================================================================
--- lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java (original)
+++ lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java Sat May 30 06:22:07 2015
@@ -60,6 +60,9 @@ public class LiveIndexWriterConfig {
/** {@link MergeScheduler} to use for running merges. */
protected volatile MergeScheduler mergeScheduler;
+ /** Timeout when trying to obtain the write lock on init. */
+ protected volatile long writeLockTimeout;
+
/** {@link IndexingChain} that determines how documents are
* indexed. */
protected volatile IndexingChain indexingChain;
@@ -107,6 +110,7 @@ public class LiveIndexWriterConfig {
openMode = OpenMode.CREATE_OR_APPEND;
similarity = IndexSearcher.getDefaultSimilarity();
mergeScheduler = new ConcurrentMergeScheduler();
+ writeLockTimeout = IndexWriterConfig.WRITE_LOCK_TIMEOUT;
indexingChain = DocumentsWriterPerThread.defaultIndexingChain;
codec = Codec.getDefault();
if (codec == null) {
@@ -347,6 +351,15 @@ public class LiveIndexWriterConfig {
return mergeScheduler;
}
+ /**
+ * Returns allowed timeout when acquiring the write lock.
+ *
+ * @see IndexWriterConfig#setWriteLockTimeout(long)
+ */
+ public long getWriteLockTimeout() {
+ return writeLockTimeout;
+ }
+
/** Returns the current {@link Codec}. */
public Codec getCodec() {
return codec;
@@ -468,6 +481,8 @@ public class LiveIndexWriterConfig {
sb.append("openMode=").append(getOpenMode()).append("\n");
sb.append("similarity=").append(getSimilarity().getClass().getName()).append("\n");
sb.append("mergeScheduler=").append(getMergeScheduler()).append("\n");
+ sb.append("default WRITE_LOCK_TIMEOUT=").append(IndexWriterConfig.WRITE_LOCK_TIMEOUT).append("\n");
+ sb.append("writeLockTimeout=").append(getWriteLockTimeout()).append("\n");
sb.append("codec=").append(getCodec()).append("\n");
sb.append("infoStream=").append(getInfoStream().getClass().getName()).append("\n");
sb.append("mergePolicy=").append(getMergePolicy()).append("\n");
Added: lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/store/SleepingLockWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/store/SleepingLockWrapper.java?rev=1682582&view=auto
==============================================================================
--- lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/store/SleepingLockWrapper.java (added)
+++ lucene/dev/branches/lucene6508/lucene/core/src/java/org/apache/lucene/store/SleepingLockWrapper.java Sat May 30 06:22:07 2015
@@ -0,0 +1,109 @@
+package org.apache.lucene.store;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.util.ThreadInterruptedException;
+
+/**
+ * Directory that wraps another, and that sleeps and retries
+ * if obtaining the lock fails.
+ * <p>
+ * This is not a good idea.
+ */
+public final class SleepingLockWrapper extends FilterDirectory {
+
+ /**
+ * Pass this lockWaitTimeout to try forever to obtain the lock.
+ */
+ public static final long LOCK_OBTAIN_WAIT_FOREVER = -1;
+
+ /**
+ * How long {@link #obtainLock} waits, in milliseconds,
+ * in between attempts to acquire the lock.
+ */
+ public static long DEFAULT_POLL_INTERVAL = 1000;
+
+ private final long lockWaitTimeout;
+ private final long pollInterval;
+
+ /**
+ * Create a new SleepingLockFactory
+ * @param delegate underlying directory to wrap
+ * @param lockWaitTimeout length of time to wait in milliseconds
+ * or {@link #LOCK_OBTAIN_WAIT_FOREVER} to retry forever.
+ */
+ public SleepingLockWrapper(Directory delegate, long lockWaitTimeout) {
+ this(delegate, lockWaitTimeout, DEFAULT_POLL_INTERVAL);
+ }
+
+ /**
+ * Create a new SleepingLockFactory
+ * @param delegate underlying directory to wrap
+ * @param lockWaitTimeout length of time to wait in milliseconds
+ * or {@link #LOCK_OBTAIN_WAIT_FOREVER} to retry forever.
+ * @param pollInterval poll once per this interval in milliseconds until
+ * {@code lockWaitTimeout} is exceeded.
+ */
+ public SleepingLockWrapper(Directory delegate, long lockWaitTimeout, long pollInterval) {
+ super(delegate);
+ this.lockWaitTimeout = lockWaitTimeout;
+ this.pollInterval = pollInterval;
+ if (lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER) {
+ throw new IllegalArgumentException("lockWaitTimeout should be LOCK_OBTAIN_WAIT_FOREVER or a non-negative number (got " + lockWaitTimeout + ")");
+ }
+ if (pollInterval < 0) {
+ throw new IllegalArgumentException("pollInterval must be a non-negative number (got " + pollInterval + ")");
+ }
+ }
+
+ @Override
+ public Lock obtainLock(String lockName) throws IOException {
+ LockObtainFailedException failureReason = null;
+ long maxSleepCount = lockWaitTimeout / pollInterval;
+ long sleepCount = 0;
+
+ do {
+ try {
+ return in.obtainLock(lockName);
+ } catch (LockObtainFailedException failed) {
+ if (failureReason == null) {
+ failureReason = failed;
+ }
+ }
+ try {
+ Thread.sleep(pollInterval);
+ } catch (InterruptedException ie) {
+ throw new ThreadInterruptedException(ie);
+ }
+ } while (sleepCount++ < maxSleepCount || lockWaitTimeout == LOCK_OBTAIN_WAIT_FOREVER);
+
+ // we failed to obtain the lock in the required time
+ String reason = "Lock obtain timed out: " + this.toString();
+ if (failureReason != null) {
+ reason += ": " + failureReason;
+ }
+ throw new LockObtainFailedException(reason, failureReason);
+ }
+
+ @Override
+ public String toString() {
+ return "SleepingLockWrapper(" + in + ")";
+ }
+}
Modified: lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java?rev=1682582&r1=1682581&r2=1682582&view=diff
==============================================================================
--- lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java (original)
+++ lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java Sat May 30 06:22:07 2015
@@ -63,6 +63,8 @@ public class TestIndexWriterConfig exten
assertEquals(OpenMode.CREATE_OR_APPEND, conf.getOpenMode());
// we don't need to assert this, it should be unspecified
assertTrue(IndexSearcher.getDefaultSimilarity() == conf.getSimilarity());
+ assertEquals(IndexWriterConfig.getDefaultWriteLockTimeout(), conf.getWriteLockTimeout());
+ assertEquals(IndexWriterConfig.WRITE_LOCK_TIMEOUT, IndexWriterConfig.getDefaultWriteLockTimeout());
assertEquals(IndexWriterConfig.DEFAULT_MAX_BUFFERED_DELETE_TERMS, conf.getMaxBufferedDeleteTerms());
assertEquals(IndexWriterConfig.DEFAULT_RAM_BUFFER_SIZE_MB, conf.getRAMBufferSizeMB(), 0.0);
assertEquals(IndexWriterConfig.DEFAULT_MAX_BUFFERED_DOCS, conf.getMaxBufferedDocs());
@@ -177,6 +179,7 @@ public class TestIndexWriterConfig exten
@Test
public void testConstants() throws Exception {
// Tests that the values of the constants does not change
+ assertEquals(1000, IndexWriterConfig.WRITE_LOCK_TIMEOUT);
assertEquals(-1, IndexWriterConfig.DISABLE_AUTO_FLUSH);
assertEquals(IndexWriterConfig.DISABLE_AUTO_FLUSH, IndexWriterConfig.DEFAULT_MAX_BUFFERED_DELETE_TERMS);
assertEquals(IndexWriterConfig.DISABLE_AUTO_FLUSH, IndexWriterConfig.DEFAULT_MAX_BUFFERED_DOCS);
Copied: lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockWrapper.java (from r1682579, lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockFactory.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockWrapper.java?p2=lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockWrapper.java&p1=lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockFactory.java&r1=1682579&r2=1682582&rev=1682582&view=diff
==============================================================================
--- lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockFactory.java (original)
+++ lucene/dev/branches/lucene6508/lucene/core/src/test/org/apache/lucene/store/TestSleepingLockWrapper.java Sat May 30 06:22:07 2015
@@ -22,8 +22,8 @@ import java.nio.file.Path;
import org.apache.lucene.util.TestUtil;
-/** Simple tests for SleepingLockFactory */
-public class TestSleepingLockFactory extends BaseLockFactoryTestCase {
+/** Simple tests for SleepingLockWrapper */
+public class TestSleepingLockWrapper extends BaseLockFactoryTestCase {
@Override
protected Directory getDirectory(Path path) throws IOException {
@@ -33,11 +33,11 @@ public class TestSleepingLockFactory ext
int which = random().nextInt(3);
switch (which) {
case 0:
- return newDirectory(random(), new SleepingLockFactory(new SingleInstanceLockFactory(), lockWaitTimeout, pollInterval));
+ return new SleepingLockWrapper(newDirectory(random(), new SingleInstanceLockFactory()), lockWaitTimeout, pollInterval);
case 1:
- return newFSDirectory(path, new SleepingLockFactory(NativeFSLockFactory.INSTANCE, lockWaitTimeout, pollInterval));
+ return new SleepingLockWrapper(newFSDirectory(path), lockWaitTimeout, pollInterval);
default:
- return newFSDirectory(path, new SleepingLockFactory(SimpleFSLockFactory.INSTANCE, lockWaitTimeout, pollInterval));
+ return new SleepingLockWrapper(newFSDirectory(path), lockWaitTimeout, pollInterval);
}
}