You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by mi...@apache.org on 2009/11/15 19:35:06 UTC

svn commit: r836387 - in /lucene/java/branches/lucene_2_9_back_compat_tests/src: java/org/apache/lucene/util/ThreadInterruptedException.java test/org/apache/lucene/index/TestIndexWriter.java

Author: mikemccand
Date: Sun Nov 15 18:35:06 2009
New Revision: 836387

URL: http://svn.apache.org/viewvc?rev=836387&view=rev
Log:
LUCENE-2053 (on back compat branch): fix intermittent bug in unit test

Added:
    lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/lucene/util/ThreadInterruptedException.java   (with props)
Modified:
    lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/lucene/index/TestIndexWriter.java

Added: lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/lucene/util/ThreadInterruptedException.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/lucene/util/ThreadInterruptedException.java?rev=836387&view=auto
==============================================================================
--- lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/lucene/util/ThreadInterruptedException.java (added)
+++ lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/lucene/util/ThreadInterruptedException.java Sun Nov 15 18:35:06 2009
@@ -0,0 +1,30 @@
+package org.apache.lucene.util;
+
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+
+/**
+ * Thrown by lucene on detecting that Thread.interrupt() had
+ * been called.  Unlike Java's InterruptedException, this
+ * exception is not checked..
+ */
+
+public final class ThreadInterruptedException extends RuntimeException {
+  public ThreadInterruptedException(InterruptedException ie) {
+    super(ie);
+  }
+}

Propchange: lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/lucene/util/ThreadInterruptedException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/lucene/index/TestIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=836387&r1=836386&r2=836387&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/lucene/index/TestIndexWriter.java (original)
+++ lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/lucene/index/TestIndexWriter.java Sun Nov 15 18:35:06 2009
@@ -67,6 +67,7 @@
 import org.apache.lucene.util.UnicodeUtil;
 import org.apache.lucene.util._TestUtil;
 import org.apache.lucene.util.Version;
+import org.apache.lucene.util.ThreadInterruptedException;
 
 /**
  *
@@ -4347,26 +4348,61 @@
   private class IndexerThreadInterrupt extends Thread {
     volatile boolean failed;
     volatile boolean finish;
+
+    boolean allowInterrupt = false;
+
     public void run() {
       RAMDirectory dir = new RAMDirectory();
       IndexWriter w = null;
+      boolean first = true;
       while(!finish) {
         try {
-          //IndexWriter.unlock(dir);
-          w = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
-          ((ConcurrentMergeScheduler) w.getMergeScheduler()).setSuppressExceptions();
-          //w.setInfoStream(System.out);
-          w.setMaxBufferedDocs(2);
-          w.setMergeFactor(2);
-          Document doc = new Document();
-          doc.add(new Field("field", "some text contents", Field.Store.YES, Field.Index.ANALYZED));
-          for(int i=0;i<100;i++) {
-            w.addDocument(doc);
-            w.commit();
+
+          while(true) {
+            if (w != null) {
+              w.close();
+            }
+            w = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
+
+            //((ConcurrentMergeScheduler) w.getMergeScheduler()).setSuppressExceptions();
+            if (!first && !allowInterrupt) {
+              // tell main thread it can interrupt us any time,
+              // starting now
+              allowInterrupt = true;
+            }
+
+            w.setMaxBufferedDocs(2);
+            w.setMergeFactor(2);
+            Document doc = new Document();
+            doc.add(new Field("field", "some text contents", Field.Store.YES, Field.Index.ANALYZED));
+            for(int i=0;i<100;i++) {
+              w.addDocument(doc);
+              w.commit();
+            }
+            w.close();
+            _TestUtil.checkIndex(dir);
+            IndexReader.open(dir, true).close();
+
+            if (first && !allowInterrupt) {
+              // Strangely, if we interrupt a thread before
+              // all classes are loaded, the class loader
+              // seems to do scary things with the interrupt
+              // status.  In java 1.5, it'll throw an
+              // incorrect ClassNotFoundException.  In java
+              // 1.6, it'll silently clear the interrupt.
+              // So, on first iteration through here we
+              // don't open ourselves up for interrupts
+              // until we've done the above loop.
+              allowInterrupt = true;
+              first = false;
+            }
           }
-        } catch (RuntimeException re) {
+        } catch (ThreadInterruptedException re) {
           Throwable e = re.getCause();
           assertTrue(e instanceof InterruptedException);
+          if (finish) {
+            break;
+          }
           
           // Make sure IW cleared the interrupted bit
           if (interrupted()) {
@@ -4375,26 +4411,12 @@
             failed = true;
             break;
           }
+
         } catch (Throwable t) {
           System.out.println("FAILED; unexpected exception");
           t.printStackTrace(System.out);
           failed = true;
           break;
-        } finally {
-          try {
-            // Clear interrupt if pending
-            synchronized(this) {
-              interrupted();
-              if (w != null) {
-                w.close();
-              }
-            }
-          } catch (Throwable t) {
-            System.out.println("FAILED; unexpected exception during close");
-            t.printStackTrace(System.out);
-            failed = true;
-            break;
-          }
         }
       }
 
@@ -4423,21 +4445,28 @@
     IndexerThreadInterrupt t = new IndexerThreadInterrupt();
     t.setDaemon(true);
     t.start();
-    for(int i=0;i<100;i++) {
+    
+    // issue 100 interrupts to child thread
+    int i = 0;
+    while(i < 100) {
       Thread.sleep(1);
-      synchronized(t) {
+
+      if (t.allowInterrupt) {
+        i++;
+        t.allowInterrupt = false;
         t.interrupt();
       }
+      if (!t.isAlive()) {
+        break;
+      }
     }
+    t.allowInterrupt = false;
     t.finish = true;
-    synchronized(t) {
-      t.interrupt();
-    }
+    t.interrupt();
     t.join();
     assertFalse(t.failed);
   }
 
-
   public void testIndexStoreCombos() throws Exception {
     MockRAMDirectory dir = new MockRAMDirectory();
     IndexWriter w = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);



RE: svn commit: r836387 - in /lucene/java/branches/lucene_2_9_back_compat_tests/src: java/org/apache/lucene/util/ThreadInterruptedException.java test/org/apache/lucene/index/TestIndexWriter.java

Posted by Uwe Schindler <uw...@thetaphi.de>.
In the backwards branch there was no need to add the there not existing
ThreadInterruptedException class (in the BW branch only src/test, but never
src/java should be updated). Catching RuntimeException would have been
enough. But it doesn't matter, that was only what I thought first - don't
touch it.

Uwe

-----
Uwe Schindler
H.-H.-Meier-Allee 63, D-28213 Bremen
http://www.thetaphi.de
eMail: uwe@thetaphi.de

> -----Original Message-----
> From: mikemccand@apache.org [mailto:mikemccand@apache.org]
> Sent: Sunday, November 15, 2009 7:35 PM
> To: java-commits@lucene.apache.org
> Subject: svn commit: r836387 - in
> /lucene/java/branches/lucene_2_9_back_compat_tests/src:
> java/org/apache/lucene/util/ThreadInterruptedException.java
> test/org/apache/lucene/index/TestIndexWriter.java
> 
> Author: mikemccand
> Date: Sun Nov 15 18:35:06 2009
> New Revision: 836387
> 
> URL: http://svn.apache.org/viewvc?rev=836387&view=rev
> Log:
> LUCENE-2053 (on back compat branch): fix intermittent bug in unit test
> 
> Added:
> 
> lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/luce
> ne/util/ThreadInterruptedException.java   (with props)
> Modified:
> 
> lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/luce
> ne/index/TestIndexWriter.java
> 
> Added:
> lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/luce
> ne/util/ThreadInterruptedException.java
> URL:
> http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9_back_compat_t
> ests/src/java/org/apache/lucene/util/ThreadInterruptedException.java?rev=8
> 36387&view=auto
> ==========================================================================
> ====
> ---
> lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/luce
> ne/util/ThreadInterruptedException.java (added)
> +++
> lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/luce
> ne/util/ThreadInterruptedException.java Sun Nov 15 18:35:06 2009
> @@ -0,0 +1,30 @@
> +package org.apache.lucene.util;
> +
> +/**
> + * 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
> + * <p/>
> + * http://www.apache.org/licenses/LICENSE-2.0
> + * <p/>
> + * 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.
> + */
> +
> +/**
> + * Thrown by lucene on detecting that Thread.interrupt() had
> + * been called.  Unlike Java's InterruptedException, this
> + * exception is not checked..
> + */
> +
> +public final class ThreadInterruptedException extends RuntimeException {
> +  public ThreadInterruptedException(InterruptedException ie) {
> +    super(ie);
> +  }
> +}
> 
> Propchange:
> lucene/java/branches/lucene_2_9_back_compat_tests/src/java/org/apache/luce
> ne/util/ThreadInterruptedException.java
> --------------------------------------------------------------------------
> ----
>     svn:eol-style = native
> 
> Modified:
> lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/luce
> ne/index/TestIndexWriter.java
> URL:
> http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9_back_compat_t
> ests/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=836387&r1=8
> 36386&r2=836387&view=diff
> ==========================================================================
> ====
> ---
> lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/luce
> ne/index/TestIndexWriter.java (original)
> +++
> lucene/java/branches/lucene_2_9_back_compat_tests/src/test/org/apache/luce
> ne/index/TestIndexWriter.java Sun Nov 15 18:35:06 2009
> @@ -67,6 +67,7 @@
>  import org.apache.lucene.util.UnicodeUtil;
>  import org.apache.lucene.util._TestUtil;
>  import org.apache.lucene.util.Version;
> +import org.apache.lucene.util.ThreadInterruptedException;
> 
>  /**
>   *
> @@ -4347,26 +4348,61 @@
>    private class IndexerThreadInterrupt extends Thread {
>      volatile boolean failed;
>      volatile boolean finish;
> +
> +    boolean allowInterrupt = false;
> +
>      public void run() {
>        RAMDirectory dir = new RAMDirectory();
>        IndexWriter w = null;
> +      boolean first = true;
>        while(!finish) {
>          try {
> -          //IndexWriter.unlock(dir);
> -          w = new IndexWriter(dir, new WhitespaceAnalyzer(),
> IndexWriter.MaxFieldLength.UNLIMITED);
> -          ((ConcurrentMergeScheduler)
> w.getMergeScheduler()).setSuppressExceptions();
> -          //w.setInfoStream(System.out);
> -          w.setMaxBufferedDocs(2);
> -          w.setMergeFactor(2);
> -          Document doc = new Document();
> -          doc.add(new Field("field", "some text contents",
> Field.Store.YES, Field.Index.ANALYZED));
> -          for(int i=0;i<100;i++) {
> -            w.addDocument(doc);
> -            w.commit();
> +
> +          while(true) {
> +            if (w != null) {
> +              w.close();
> +            }
> +            w = new IndexWriter(dir, new WhitespaceAnalyzer(),
> IndexWriter.MaxFieldLength.UNLIMITED);
> +
> +            //((ConcurrentMergeScheduler)
> w.getMergeScheduler()).setSuppressExceptions();
> +            if (!first && !allowInterrupt) {
> +              // tell main thread it can interrupt us any time,
> +              // starting now
> +              allowInterrupt = true;
> +            }
> +
> +            w.setMaxBufferedDocs(2);
> +            w.setMergeFactor(2);
> +            Document doc = new Document();
> +            doc.add(new Field("field", "some text contents",
> Field.Store.YES, Field.Index.ANALYZED));
> +            for(int i=0;i<100;i++) {
> +              w.addDocument(doc);
> +              w.commit();
> +            }
> +            w.close();
> +            _TestUtil.checkIndex(dir);
> +            IndexReader.open(dir, true).close();
> +
> +            if (first && !allowInterrupt) {
> +              // Strangely, if we interrupt a thread before
> +              // all classes are loaded, the class loader
> +              // seems to do scary things with the interrupt
> +              // status.  In java 1.5, it'll throw an
> +              // incorrect ClassNotFoundException.  In java
> +              // 1.6, it'll silently clear the interrupt.
> +              // So, on first iteration through here we
> +              // don't open ourselves up for interrupts
> +              // until we've done the above loop.
> +              allowInterrupt = true;
> +              first = false;
> +            }
>            }
> -        } catch (RuntimeException re) {
> +        } catch (ThreadInterruptedException re) {
>            Throwable e = re.getCause();
>            assertTrue(e instanceof InterruptedException);
> +          if (finish) {
> +            break;
> +          }
> 
>            // Make sure IW cleared the interrupted bit
>            if (interrupted()) {
> @@ -4375,26 +4411,12 @@
>              failed = true;
>              break;
>            }
> +
>          } catch (Throwable t) {
>            System.out.println("FAILED; unexpected exception");
>            t.printStackTrace(System.out);
>            failed = true;
>            break;
> -        } finally {
> -          try {
> -            // Clear interrupt if pending
> -            synchronized(this) {
> -              interrupted();
> -              if (w != null) {
> -                w.close();
> -              }
> -            }
> -          } catch (Throwable t) {
> -            System.out.println("FAILED; unexpected exception during
> close");
> -            t.printStackTrace(System.out);
> -            failed = true;
> -            break;
> -          }
>          }
>        }
> 
> @@ -4423,21 +4445,28 @@
>      IndexerThreadInterrupt t = new IndexerThreadInterrupt();
>      t.setDaemon(true);
>      t.start();
> -    for(int i=0;i<100;i++) {
> +
> +    // issue 100 interrupts to child thread
> +    int i = 0;
> +    while(i < 100) {
>        Thread.sleep(1);
> -      synchronized(t) {
> +
> +      if (t.allowInterrupt) {
> +        i++;
> +        t.allowInterrupt = false;
>          t.interrupt();
>        }
> +      if (!t.isAlive()) {
> +        break;
> +      }
>      }
> +    t.allowInterrupt = false;
>      t.finish = true;
> -    synchronized(t) {
> -      t.interrupt();
> -    }
> +    t.interrupt();
>      t.join();
>      assertFalse(t.failed);
>    }
> 
> -
>    public void testIndexStoreCombos() throws Exception {
>      MockRAMDirectory dir = new MockRAMDirectory();
>      IndexWriter w = new IndexWriter(dir, new WhitespaceAnalyzer(), true,
> IndexWriter.MaxFieldLength.UNLIMITED);
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-dev-help@lucene.apache.org