You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2007/09/15 13:23:27 UTC

svn commit: r575903 - in /jakarta/httpcomponents/httpcore/trunk: ./ module-nio/src/main/java/org/apache/http/impl/nio/reactor/ module-nio/src/test/java/org/apache/http/impl/nio/reactor/ module-nio/src/test/java/org/apache/http/mockup/

Author: olegk
Date: Sat Sep 15 04:23:26 2007
New Revision: 575903

URL: http://svn.apache.org/viewvc?rev=575903&view=rev
Log:
 HTTPCORE-109: Ensure I/O reactor shuts itself down in case of a fatal failure

Modified:
    jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpClient.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpServer.java

Modified: jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?rev=575903&r1=575902&r2=575903&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Sat Sep 15 04:23:26 2007
@@ -1,5 +1,10 @@
 Changes since release 4.0 Alpha 5
 
+* [HTTPCORE-109] Improved shutdown process of the I/O reactors in NIO modules. I/O 
+  reactors now attempt to terminate connections gracefully before shutting down the
+  underlying socket channels.
+  Oleg Kalnichevski <olegk at apache.org>
+
 * [HTTPCORE-107] allow sending and receiving of SIP messages
   Contributed by Roland Weber <rolandw at apache.org>
 

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java?rev=575903&r1=575902&r2=575903&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.java Sat Sep 15 04:23:26 2007
@@ -127,40 +127,50 @@
             this.threads[i].start();
         }
         
-        for (;;) {
+        try {
 
-            int readyCount;
-            try {
-                readyCount = this.selector.select(this.selectTimeout);
-            } catch (ClosedSelectorException ex) {
-                return;
-            } catch (InterruptedIOException ex) {
-                throw ex;
-            } catch (IOException ex) {
-                throw new IOReactorException("Unexpected selector failure", ex);
-            }
-            
-            if (this.status > ACTIVE) {
-                break;
-            }
-            processEvents(readyCount);
+            for (;;) {
 
-            // Verify I/O dispatchers
-            for (int i = 0; i < this.workerCount; i++) {
-                Worker worker = this.workers[i];
-                Thread thread = this.threads[i];
-                if (!thread.isAlive()) {
-                    Exception ex = worker.getException();
-                    if (ex instanceof IOReactorException) {
-                        throw (IOReactorException) ex;
-                    } else if (ex instanceof InterruptedIOException) {
-                        throw (InterruptedIOException) ex;
-                    } else if (ex instanceof RuntimeException) {
-                        throw (RuntimeException) ex;
-                    } else if (ex != null) {
-                        throw new IOReactorException(ex.getMessage(), ex);
+                int readyCount;
+                try {
+                    readyCount = this.selector.select(this.selectTimeout);
+                } catch (InterruptedIOException ex) {
+                    throw ex;
+                } catch (IOException ex) {
+                    throw new IOReactorException("Unexpected selector failure", ex);
+                }
+                
+                if (this.status > ACTIVE) {
+                    break;
+                }
+                processEvents(readyCount);
+
+                // Verify I/O dispatchers
+                for (int i = 0; i < this.workerCount; i++) {
+                    Worker worker = this.workers[i];
+                    Thread thread = this.threads[i];
+                    if (!thread.isAlive()) {
+                        Exception ex = worker.getException();
+                        if (ex instanceof IOReactorException) {
+                            throw (IOReactorException) ex;
+                        } else if (ex instanceof InterruptedIOException) {
+                            throw (InterruptedIOException) ex;
+                        } else if (ex instanceof RuntimeException) {
+                            throw (RuntimeException) ex;
+                        } else if (ex != null) {
+                            throw new IOReactorException(ex.getMessage(), ex);
+                        }
                     }
                 }
+            }
+
+        } catch (ClosedSelectorException ex) {
+        } finally {
+            // Shutdown
+            try {
+                shutdown(500);
+            } catch (IOException ex) {
+                throw new IOReactorException(ex.getMessage(), ex);
             }
         }
     }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java?rev=575903&r1=575902&r2=575903&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/reactor/TestDefaultIOReactors.java Sat Sep 15 04:23:26 2007
@@ -48,6 +48,7 @@
 import org.apache.http.nio.NHttpServiceHandler;
 import org.apache.http.nio.protocol.EventListener;
 import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
+import org.apache.http.nio.reactor.IOReactor;
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
@@ -187,4 +188,71 @@
         assertEquals(0, closedServerConns.getValue());
     }
     
+    public void testRuntimeException() throws Exception {
+
+        HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+            public void handle(
+                    final HttpRequest request, 
+                    final HttpResponse response, 
+                    final HttpContext context) throws HttpException, IOException {
+                throw new IllegalStateException("Oppsie!!!");
+            }
+            
+        };
+        
+        HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
+
+            public void initalizeContext(final HttpContext context, final Object attachment) {
+            }
+
+            public void finalizeContext(final HttpContext context) {
+            }
+
+            public HttpRequest submitRequest(final HttpContext context) {
+                Boolean b = ((Boolean) context.getAttribute("done"));
+                if (b == null) {
+                    BasicHttpRequest get = new BasicHttpRequest("GET", "/");
+                    context.setAttribute("done", Boolean.TRUE);
+                    return get;
+                } else {
+                    return null;
+                }
+            }
+            
+            public void handleResponse(final HttpResponse response, final HttpContext context) {
+            }
+            
+        };
+     
+        NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+                requestHandler, 
+                null,
+                new SimpleEventListener());
+        
+        NHttpClientHandler clientHandler = createHttpClientHandler(
+                requestExecutionHandler,
+                new SimpleEventListener());
+
+        this.server.start(serviceHandler);
+        this.client.start(clientHandler);
+        
+        InetSocketAddress serverAddress = (InetSocketAddress) this.server.getSocketAddress();
+        
+        this.client.openConnection(
+                new InetSocketAddress("localhost", serverAddress.getPort()), 
+                null);
+     
+        this.server.join(20000);
+        
+        Exception ex = this.server.getException();
+        assertNotNull(ex);
+        assertTrue(ex instanceof IllegalStateException);
+        // I/O reactor shut down itself
+        assertEquals(IOReactor.SHUT_DOWN, this.server.getStatus());
+        
+        this.client.shutdown();
+        this.server.shutdown();
+    }
+
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpClient.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpClient.java?rev=575903&r1=575902&r2=575903&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpClient.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpClient.java Sat Sep 15 04:23:26 2007
@@ -74,13 +74,29 @@
         this.thread = new IOReactorThread(clientHandler);
         this.thread.start();
     }
+
+    public int getStatus() {
+        return this.ioReactor.getStatus();
+    }
+    
+    public void join(long timeout) throws InterruptedException {
+        if (this.thread != null) {
+            this.thread.join(timeout);
+        }
+    }
+    
+    public Exception getException() {
+        if (this.thread != null) {
+            return this.thread.getException();
+        } else {
+            return null;
+        }
+    }
     
     public void shutdown() throws IOException {
         this.ioReactor.shutdown();
         try {
-            if (this.thread != null) {
-                this.thread.join(500);
-            }
+            join(500);
         } catch (InterruptedException ignore) {
         }
     }
@@ -88,6 +104,8 @@
     private class IOReactorThread extends Thread {
 
         private final NHttpClientHandler clientHandler;
+
+        private volatile Exception ex;
         
         public IOReactorThread(final NHttpClientHandler clientHandler) {
             super();
@@ -98,8 +116,14 @@
             try {
                 execute(this.clientHandler);
             } catch (IOException ex) {
-                ex.printStackTrace();
+                this.ex = ex;
+            } catch (RuntimeException ex) {
+                this.ex = ex;
             }
+        }
+        
+        public Exception getException() {
+            return this.ex;
         }
 
     }    

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpServer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpServer.java?rev=575903&r1=575902&r2=575903&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpServer.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/mockup/TestHttpServer.java Sat Sep 15 04:23:26 2007
@@ -94,12 +94,28 @@
         this.thread.start();
     }
     
+    public int getStatus() {
+        return this.ioReactor.getStatus();
+    }
+    
+    public void join(long timeout) throws InterruptedException {
+        if (this.thread != null) {
+            this.thread.join(timeout);
+        }
+    }
+    
+    public Exception getException() {
+        if (this.thread != null) {
+            return this.thread.getException();
+        } else {
+            return null;
+        }
+    }
+    
     public void shutdown() throws IOException {
         this.ioReactor.shutdown();
         try {
-            if (this.thread != null) {
-                this.thread.join(500);
-            }
+            join(500);
         } catch (InterruptedException ignore) {
         }
     }
@@ -108,6 +124,8 @@
 
         private final NHttpServiceHandler serviceHandler;
         
+        private volatile Exception ex;
+        
         public IOReactorThread(final NHttpServiceHandler serviceHandler) {
             super();
             this.serviceHandler = serviceHandler;
@@ -117,8 +135,14 @@
             try {
                 execute(this.serviceHandler);
             } catch (IOException ex) {
-                ex.printStackTrace();
+                this.ex = ex;
+            } catch (RuntimeException ex) {
+                this.ex = ex;
             }
+        }
+        
+        public Exception getException() {
+            return this.ex;
         }
 
     }