1) added the following statics to Lock:
public static long WRITE_LOCK_TIMEOUT = 1000; public static long COMMIT_LOCK_TIMEOUT = 10000; public static long LOCK_POLL_INTERVAL = 1000;
2) added the following method to Lock:
/** Attempt to obtain an exclusive lock within amount
* of time given. Currently polls once per second until
* lockWaitTimeout is passed.
* @param lockWaitTimeout length of time to wait in ms
* @return true if lock was obtained
* @throws IOException if lock wait times out or obtain() throws an IOException
*/
public boolean obtain(long lockWaitTimeout) throws IOException
3) added the following method to Lock.With:
/** Constructs an executor that will grab the named lock. */ public With(Lock lock, long lockWaitTimeout)
4) cleaned up Lock.With to use the new obtain(long) method on Lock.
5) changed callers obtaining "write.lock" to pass Lock.WRITE_LOCK_TIMEOUT
6) changed callers obtaining "commit.lock" to pass Lock.COMMIT_LOCK_TIMEOUT
The net effect is to expose the timeout and change the write.lock to have a 1 second timeout as a default instead of immediately throwing an IOException.
So that there can be a review and comment period, I won't plan to check it in Wednesday of next week.
Scott
? lock.diff
? lib/JavaCC.zip
? src/java/org/apache/lucene/analysis/.nbattrs
? src/java/org/apache/lucene/search/.nbattrs
Index: src/java/org/apache/lucene/index/IndexReader.java
===================================================================
RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/IndexReader.java,v
retrieving revision 1.16
diff -u -b -B -r1.16 IndexReader.java
--- src/java/org/apache/lucene/index/IndexReader.java 1 May 2003 19:50:17 -0000
1.16
+++ src/java/org/apache/lucene/index/IndexReader.java 8 Aug 2003 19:53:03 -0000
@@ -100,7 +100,7 @@
/** Returns an IndexReader reading the index in the given Directory. */
public static IndexReader open(final Directory directory) throws IOException{
synchronized (directory) { // in- & inter-process sync
- return (IndexReader)new Lock.With(directory.makeLock("commit.lock")) {
+ return (IndexReader)new Lock.With(directory.makeLock("commit.lock"),
Lock.COMMIT_LOCK_TIMEOUT) {
public Object doBody() throws IOException {
SegmentInfos infos = new SegmentInfos();
infos.read(directory);
@@ -255,7 +255,7 @@
public final synchronized void delete(int docNum) throws IOException {
if (writeLock == null) {
Lock writeLock = directory.makeLock("write.lock");
- if (!writeLock.obtain()) // obtain write lock
+ if (!writeLock.obtain(Lock.WRITE_LOCK_TIMEOUT)) // obtain write lock
throw new IOException("Index locked for write: " + writeLock);
this.writeLock = writeLock;
}
Index: src/java/org/apache/lucene/index/IndexWriter.java
===================================================================
RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/IndexWriter.java,v
retrieving revision 1.13
diff -u -b -B -r1.13 IndexWriter.java
--- src/java/org/apache/lucene/index/IndexWriter.java 11 Jul 2003 22:13:13 -0000
1.13
+++ src/java/org/apache/lucene/index/IndexWriter.java 8 Aug 2003 19:53:03 -0000
@@ -141,12 +141,12 @@
analyzer = a;
Lock writeLock = directory.makeLock("write.lock");
- if (!writeLock.obtain()) // obtain write lock
+ if (!writeLock.obtain(Lock.WRITE_LOCK_TIMEOUT)) // obtain write lock
throw new IOException("Index locked for write: " + writeLock);
this.writeLock = writeLock; // save it
synchronized (directory) { // in- & inter-process sync
- new Lock.With(directory.makeLock("commit.lock")) {
+ new Lock.With(directory.makeLock("commit.lock"), Lock.COMMIT_LOCK_TIMEOUT) {
public Object doBody() throws IOException {
if (create)
segmentInfos.write(directory);
@@ -365,7 +365,7 @@
directory));
synchronized (directory) { // in- & inter-process sync
- new Lock.With(directory.makeLock("commit.lock")) {
+ new Lock.With(directory.makeLock("commit.lock"), Lock.COMMIT_LOCK_TIMEOUT) {
public Object doBody() throws IOException {
segmentInfos.write(directory); // commit before deleting
deleteSegments(segmentsToDelete); // delete now-unused segments
Index: src/java/org/apache/lucene/index/SegmentReader.java
===================================================================
RCS file:
/home/cvs/jakarta-lucene/src/java/org/apache/lucene/index/SegmentReader.java,v
retrieving revision 1.8
diff -u -b -B -r1.8 SegmentReader.java
--- src/java/org/apache/lucene/index/SegmentReader.java 1 May 2003 01:09:15 -0000
1.8
+++ src/java/org/apache/lucene/index/SegmentReader.java 8 Aug 2003 19:53:03 -0000
@@ -119,7 +119,7 @@
final synchronized void doClose() throws IOException {
if (deletedDocsDirty) {
synchronized (directory) { // in- & inter-process sync
- new Lock.With(directory.makeLock("commit.lock")) {
+ new Lock.With(directory.makeLock("commit.lock"), Lock.COMMIT_LOCK_TIMEOUT) {
public Object doBody() throws IOException {
deletedDocs.write(directory, segment + ".tmp");
directory.renameFile(segment + ".tmp", segment + ".del");
Index: src/java/org/apache/lucene/store/Lock.java
===================================================================
RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/store/Lock.java,v
retrieving revision 1.3
diff -u -b -B -r1.3 Lock.java
--- src/java/org/apache/lucene/store/Lock.java 1 May 2003 19:50:17 -0000 1.3
+++ src/java/org/apache/lucene/store/Lock.java 8 Aug 2003 19:53:03 -0000
@@ -70,12 +70,41 @@
*/
public abstract class Lock {
- /** Attempt to obtain exclusive access.
- *
+ public static long WRITE_LOCK_TIMEOUT = 1000;
+ public static long COMMIT_LOCK_TIMEOUT = 10000;
+ public static long LOCK_POLL_INTERVAL = 1000;
+
+ /** Attempt to obtain exclusive access and immediately return
+ * upon success or failure.
* @return true iff exclusive access is obtained
*/
public abstract boolean obtain() throws IOException;
+ /** Attempt to obtain an exclusive lock within amount
+ * of time given. Currently polls once per second until
+ * lockWaitTimeout is passed.
+ * @param lockWaitTimeout length of time to wait in ms
+ * @return true if lock was obtained
+ * @throws IOException if lock wait times out or obtain() throws an IOException
+ */
+ public boolean obtain(long lockWaitTimeout) throws IOException {
+ boolean locked = obtain();
+ int maxSleepCount = (int)(lockWaitTimeout / LOCK_POLL_INTERVAL);
+ int sleepCount = 0;
+ while (!locked) {
+ if (++sleepCount == maxSleepCount) {
+ throw new IOException("Lock obtain timed out");
+ }
+ try {
+ Thread.sleep(LOCK_POLL_INTERVAL);
+ } catch (InterruptedException e) {
+ throw new IOException(e.toString());
+ }
+ locked = obtain();
+ }
+ return locked;
+ }
+
/** Release exclusive access. */
public abstract void release();
@@ -87,12 +116,21 @@
/** Utility class for executing code with exclusive access. */
public abstract static class With {
private Lock lock;
- private int sleepInterval = 1000;
- private int maxSleeps = 10;
+ private long lockWaitTimeout;
+
+ /** Constructs an executor that will grab the named lock.
+ * Defaults lockWaitTimeout to Lock.COMMIT_LOCK_TIMEOUT.
+ * @deprecated Kept only to avoid breaking existing code.
+ */
+ public With(Lock lock)
+ {
+ this(lock, COMMIT_LOCK_TIMEOUT);
+ }
/** Constructs an executor that will grab the named lock. */
- public With(Lock lock) {
+ public With(Lock lock, long lockWaitTimeout) {
this.lock = lock;
+ this.lockWaitTimeout = lockWaitTimeout;
}
/** Code to execute with exclusive access. */
@@ -100,26 +138,13 @@
/** Calls [EMAIL PROTECTED] #doBody} while <i>lock</i> is obtained. Blocks if
lock
* cannot be obtained immediately. Retries to obtain lock once per second
- * until it is obtained, or until it has tried ten times. */
+ * until it is obtained, or until it has tried ten times. Lock is released when
+ * [EMAIL PROTECTED] #doBody} exits. */
public Object run() throws IOException {
boolean locked = false;
try {
- locked = lock.obtain();
- int sleepCount = 0;
- while (!locked) {
- if (++sleepCount == maxSleeps) {
- throw new IOException("Timed out waiting for: " + lock);
- }
- try {
- Thread.sleep(sleepInterval);
- } catch (InterruptedException e) {
- throw new IOException(e.toString());
- }
- locked = lock.obtain();
- }
-
+ locked = lock.obtain(lockWaitTimeout);
return doBody();
-
} finally {
if (locked)
lock.release();--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
