Author: ggregory
Date: Thu Nov 22 00:36:10 2012
New Revision: 1412391

URL: http://svn.apache.org/viewvc?rev=1412391&view=rev
Log:
[IO-358][Tailer] InterruptedException while the thread is sleeping is silently 
ignored.

Modified:
    commons/proper/io/trunk/src/changes/changes.xml
    
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java
    
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java

Modified: commons/proper/io/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1412391&r1=1412390&r2=1412391&view=diff
==============================================================================
--- commons/proper/io/trunk/src/changes/changes.xml (original)
+++ commons/proper/io/trunk/src/changes/changes.xml Thu Nov 22 00:36:10 2012
@@ -46,7 +46,10 @@ The <action> type attribute can be add,u
 
   <body>
     <!-- The release date is the date RC is cut -->
-    <release version="2.5" date="201?-??-??" description="New features and bug 
fixes.">
+    <release version="2.5" date="201?-??-??" description="New features and bug 
fixes.">    
+      <action issue="IO-358" dev="ggregory" type="fix" due-to="mortenh">
+        [Tailer] InterruptedException while the thead is sleeping is silently 
ignored
+      </action>            
       <action issue="IO-353" dev="ggregory" type="add" due-to="ggregory">
         Add API IOUtils.copy(InputStream, OutputStream, int)
       </action>            

Modified: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java?rev=1412391&r1=1412390&r2=1412391&view=diff
==============================================================================
--- 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java 
(original)
+++ 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java 
Thu Nov 22 00:36:10 2012
@@ -40,8 +40,7 @@ import org.apache.commons.io.IOUtils;
  *      public void handle(String line) {
  *          System.out.println(line);
  *      }
- *  }
- * </pre>
+ *  }</pre>
  * 
  * <h2>2. Using a Tailer</h2>
  *
@@ -64,10 +63,9 @@ import org.apache.commons.io.IOUtils;
  *
  * <pre>
  *      TailerListener listener = new MyTailerListener();
- *      Tailer tailer = Tailer.create(file, listener, delay);
- * </pre>
+ *      Tailer tailer = Tailer.create(file, listener, delay);</pre>
  *      
- * <h3>2.2 Use an Executor</h3>
+ * <h3>2.2 Using an Executor</h3>
  * 
  * <pre>
  *      TailerListener listener = new MyTailerListener();
@@ -84,25 +82,32 @@ import org.apache.commons.io.IOUtils;
  * </pre>
  *      
  *      
- * <h3>2.3 Use a Thread</h3>
+ * <h3>2.3 Using a Thread</h3>
  * <pre>
  *      TailerListener listener = new MyTailerListener();
  *      Tailer tailer = new Tailer(file, listener, delay);
  *      Thread thread = new Thread(tailer);
  *      thread.setDaemon(true); // optional
- *      thread.start();
- * </pre>
+ *      thread.start();</pre>
  *
- * <h2>3. Stop Tailing</h3>
+ * <h2>3. Stopping a Tailer</h3>
  * <p>Remember to stop the tailer when you have done with it:</p>
  * <pre>
  *      tailer.stop();
  * </pre>
  *
+ * <h2>4. Interrupting a Tailer</h3>
+ * <p>You can interrupt the thread a tailer is running on by calling {@link 
Thread#interrupt()}.</p>
+ * <pre>
+ *      thread.interrupt();
+ * </pre>
+ * <p>If you interrupt a tailer, the tailer listener is called with the {@link 
InterruptedException}.</p>
+ * 
  * @see TailerListener
  * @see TailerListenerAdapter
  * @version $Id$
  * @since 2.0
+ * @since 2.5 Updated behavior and documentation for {@link Thread#interrupt()}
  */
 public class Tailer implements Runnable {
 
@@ -356,10 +361,7 @@ public class Tailer implements Runnable 
                     listener.fileNotFound();
                 }
                 if (reader == null) {
-                    try {
-                        Thread.sleep(delayMillis);
-                    } catch (InterruptedException e) {
-                    }
+                    Thread.sleep(delayMillis);
                 } else {
                     // The current position in the file
                     position = end ? file.length() : 0;
@@ -410,22 +412,27 @@ public class Tailer implements Runnable 
                 if (reOpen) {
                     IOUtils.closeQuietly(reader);
                 }
-                try {
-                    Thread.sleep(delayMillis);
-                } catch (InterruptedException e) {
-                }
+                Thread.sleep(delayMillis);
                 if (getRun() && reOpen) {
                     reader = new RandomAccessFile(file, RAF_MODE);
                     reader.seek(position);
                 }
             }
-        } catch (Exception e) {
-            listener.handle(e);
+        } catch (InterruptedException e) {            
+            Thread.currentThread().interrupt();
+            stop(e);
+        } catch (Exception e) {            
+            stop(e);
         } finally {
             IOUtils.closeQuietly(reader);
         }
     }
 
+    private void stop(Exception e) {
+        listener.handle(e);
+        stop();
+    }
+
     /**
      * Allows the tailer to complete its current loop and return.
      */

Modified: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java?rev=1412391&r1=1412390&r2=1412391&view=diff
==============================================================================
--- 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java
 (original)
+++ 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java
 Thu Nov 22 00:36:10 2012
@@ -199,7 +199,8 @@ public class TailerTest extends FileBase
         Thread.sleep(testDelayMillis);
         write(file, "Line five");
         assertEquals("4 line count", 0, listener.getLines().size());
-        assertNull("Should not generate Exception", listener.exception);
+        assertNotNull("Missing InterruptedException", listener.exception);
+        assertTrue("Unexpected Exception: " + listener.exception, 
listener.exception instanceof InterruptedException);
         assertEquals("Expected init to be called", 1 , listener.initialised);
         assertEquals("fileNotFound should not be called", 0 , 
listener.notFound);
         assertEquals("fileRotated should be be called", 1 , listener.rotated);
@@ -273,6 +274,33 @@ public class TailerTest extends FileBase
         assertEquals("fileRotated should be not be called", 0 , 
listener.rotated);
     }
 
+    /**
+     * Tests [IO-357][Tailer] InterruptedException while the thead is sleeping 
is silently ignored.
+     * 
+     * @throws Exception
+     */
+    public void testInterrupt() throws Exception {
+        final File file = new File(getTestDirectory(), "nosuchfile");
+        assertFalse("nosuchfile should not exist", file.exists());
+        final TestTailerListener listener = new TestTailerListener();
+        // Use a long delay to try to make sure the test thread calls 
interrupt() while the tailer thread is sleeping.
+        int delay = 1000;
+        int idle = 50; // allow time for thread to work
+        Tailer tailer = new Tailer(file, listener, delay, false, 4096);
+        Thread thread = new Thread(tailer);
+        thread.setDaemon(true);
+        thread.start();
+        Thread.sleep(idle);
+        thread.interrupt();
+        tailer = null;
+        Thread.sleep(delay + idle);
+        assertNotNull("Missing InterruptedException", listener.exception);
+        assertTrue("Unexpected Exception: " + listener.exception, 
listener.exception instanceof InterruptedException);
+        assertEquals("Expected init to be called", 1, listener.initialised);
+        assertTrue("fileNotFound should be called", listener.notFound > 0);
+        assertEquals("fileRotated should be not be called", 0, 
listener.rotated);
+    }
+
     public void testStopWithNoFileUsingExecutor() throws Exception {
         final File file = new File(getTestDirectory(),"nosuchfile");
         assertFalse("nosuchfile should not exist", file.exists());


Reply via email to