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/01/24 22:37:33 UTC

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

Author: olegk
Date: Wed Jan 24 13:37:32 2007
New Revision: 499577

URL: http://svn.apache.org/viewvc?view=rev&rev=499577
Log:
[HTTPCORE-28]: DefaultConnectingIOReactor now queues connect requests and registers sessions with the selector on the I/O thread

Added:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java   (with props)
Modified:
    jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/DefaultConnectingIOReactor.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestImpl.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/reactor/ConnectingIOReactor.java

Modified: jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?view=diff&rev=499577&r1=499576&r2=499577
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Wed Jan 24 13:37:32 2007
@@ -1,5 +1,8 @@
 Changes since release 4.0 Alpha 3
 -------------------
+* [HTTPCORE-28]: DefaultConnectingIOReactor now maintains a queue of connect 
+  requests and registers new sessions with the selector on the I/O thread.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 * [HTTPCORE-29] DefaultConnectingIOReactor changed to ensure IOExceptions 
   are correctly propagated to the caller, if an exception is thrown while 

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java?view=diff&rev=499577&r1=499576&r2=499577
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java Wed Jan 24 13:37:32 2007
@@ -46,21 +46,7 @@
             .setBooleanParameter(HttpConnectionParams.TCP_NODELAY, true)
             .setParameter(HttpProtocolParams.USER_AGENT, "Jakarta-HttpComponents-NIO/1.1");
 
-        ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, params);
-
-        SessionRequest[] reqs = new SessionRequest[3];
-        reqs[0] = ioReactor.connect(
-                new InetSocketAddress("www.yahoo.com", 80), 
-                null, 
-                new HttpHost("www.yahoo.com"));
-        reqs[1] = ioReactor.connect(
-                new InetSocketAddress("www.google.com", 80), 
-                null,
-                new HttpHost("www.google.ch"));
-        reqs[2] = ioReactor.connect(
-                new InetSocketAddress("www.apache.org", 80), 
-                null,
-                new HttpHost("www.apache.org"));
+        final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, params);
 
         BasicHttpProcessor httpproc = new BasicHttpProcessor();
         httpproc.addInterceptor(new RequestContent());
@@ -77,16 +63,38 @@
 
         handler.setEventListener(new EventLogger());
         
-        IOEventDispatch ioEventDispatch = new DefaultClientIOEventDispatch(handler, params);
+        final IOEventDispatch ioEventDispatch = new DefaultClientIOEventDispatch(handler, params);
+        
+        Thread t = new Thread(new Runnable() {
+         
+            public void run() {
+                try {
+                    ioReactor.execute(ioEventDispatch);
+                } catch (InterruptedIOException ex) {
+                    System.err.println("Interrupted");
+                } catch (IOException e) {
+                    System.err.println("I/O error: " + e.getMessage());
+                }
+                System.out.println("Shutdown");
+            }
+            
+        });
+        t.start();
+
+        SessionRequest[] reqs = new SessionRequest[3];
+        reqs[0] = ioReactor.connect(
+                new InetSocketAddress("www.yahoo.com", 80), 
+                null, 
+                new HttpHost("www.yahoo.com"));
+        reqs[1] = ioReactor.connect(
+                new InetSocketAddress("www.google.com", 80), 
+                null,
+                new HttpHost("www.google.ch"));
+        reqs[2] = ioReactor.connect(
+                new InetSocketAddress("www.apache.org", 80), 
+                null,
+                new HttpHost("www.apache.org"));
         
-        try {
-            ioReactor.execute(ioEventDispatch);
-        } catch (InterruptedIOException ex) {
-            System.err.println("Interrupted");
-        } catch (IOException e) {
-            System.err.println("I/O error: " + e.getMessage());
-        }
-        System.out.println("Shutdown");
     }
     
     static class MyHttpRequestExecutionHandler implements HttpRequestExecutionHandler {
@@ -137,7 +145,11 @@
     
     static class EventLogger implements EventListener {
 
+        private int openNo = 0;
+        private int closedNo = 0;
+        
         public void connectionOpen(final InetAddress address) {
+            this.openNo++;
             System.out.println("Connection open: " + address);
         }
 
@@ -147,6 +159,10 @@
 
         public void connectionClosed(InetAddress address) {
             System.out.println("Connection closed: " + address);
+            this.closedNo++;
+            if (this.openNo == this.closedNo) {
+                System.exit(0);
+            }
         }
 
         public void fatalIOException(IOException ex) {

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/DefaultConnectingIOReactor.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/DefaultConnectingIOReactor.java?view=diff&rev=499577&r1=499576&r2=499577
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/DefaultConnectingIOReactor.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/DefaultConnectingIOReactor.java Wed Jan 24 13:37:32 2007
@@ -56,6 +56,7 @@
     
     private final HttpParams params;
     private final Selector selector;
+    private final SessionRequestQueue requestQueue;
     
     private long lastTimeoutCheck;
     
@@ -67,6 +68,7 @@
         }
         this.params = params;
         this.selector = Selector.open();
+        this.requestQueue = new SessionRequestQueue();
         this.lastTimeoutCheck = System.currentTimeMillis();
     }
 
@@ -80,6 +82,9 @@
             if (this.closed) {
                 break;
             }
+            
+            processSessionRequests();
+            
             if (readyCount > 0) {
                 processEvents(this.selector.selectedKeys());
             }
@@ -172,23 +177,37 @@
     public SessionRequest connect(
             final SocketAddress remoteAddress, 
             final SocketAddress localAddress,
-            final Object attachment) throws IOException {
-        SocketChannel socketChannel = SocketChannel.open();
-        socketChannel.configureBlocking(false);
-        if (localAddress != null) {
-            socketChannel.socket().bind(localAddress);
-        }
-        socketChannel.connect(remoteAddress);
-        SelectionKey key = socketChannel.register(this.selector, 0);
+            final Object attachment) {
 
         SessionRequestImpl sessionRequest = new SessionRequestImpl(
-                remoteAddress, localAddress, attachment, key);
+                remoteAddress, localAddress, attachment);
         sessionRequest.setConnectTimeout(HttpConnectionParams.getConnectionTimeout(this.params));
-
-        SessionRequestHandle requestHandle = new SessionRequestHandle(sessionRequest); 
-        key.attach(requestHandle);
-        key.interestOps(SelectionKey.OP_CONNECT);
+        
+        this.requestQueue.push(sessionRequest);
+        this.selector.wakeup();
+        
         return sessionRequest;
+    }
+    
+    private void processSessionRequests() throws IOException {
+        SessionRequestImpl request;
+        while ((request = this.requestQueue.pop()) != null) {
+            if (request.isCompleted()) {
+                continue;
+            }
+            SocketChannel socketChannel = SocketChannel.open();
+            socketChannel.configureBlocking(false);
+            if (request.getLocalAddress() != null) {
+                socketChannel.socket().bind(request.getLocalAddress());
+            }
+            socketChannel.connect(request.getRemoteAddress());
+            SelectionKey key = socketChannel.register(this.selector, 0);
+            request.setKey(key);
+
+            SessionRequestHandle requestHandle = new SessionRequestHandle(request); 
+            key.attach(requestHandle);
+            key.interestOps(SelectionKey.OP_CONNECT);
+        }
     }
 
     public void shutdown() throws IOException {

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestImpl.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestImpl.java?view=diff&rev=499577&r1=499576&r2=499577
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestImpl.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestImpl.java Wed Jan 24 13:37:32 2007
@@ -42,8 +42,8 @@
 class SessionRequestImpl implements SessionRequest {
 
     private volatile boolean completed;
+    private volatile SelectionKey key;
 
-    private final SelectionKey key;
     private final SocketAddress remoteAddress;
     private final SocketAddress localAddress;
     private final Object attachment;
@@ -56,19 +56,14 @@
     public SessionRequestImpl(
             final SocketAddress remoteAddress,
             final SocketAddress localAddress,
-            final Object attachment,
-            final SelectionKey key) {
+            final Object attachment) {
         super();
         if (remoteAddress == null) {
             throw new IllegalArgumentException("Remote address may not be null");
         }
-        if (key == null) {
-            throw new IllegalArgumentException("Selection key may not be null");
-        }
         this.remoteAddress = remoteAddress;
         this.localAddress = localAddress;
         this.attachment = attachment;
-        this.key = key;
         this.connectTimeout = 0;
     }
     
@@ -163,7 +158,9 @@
     public void setConnectTimeout(int timeout) {
         if (this.connectTimeout != timeout) {
             this.connectTimeout = timeout;
-            this.key.selector().wakeup();
+            if (this.key != null) {
+                this.key.selector().wakeup();
+            }
         }
     }
 
@@ -179,9 +176,15 @@
             }
         }
     }
+    
+    protected void setKey(final SelectionKey key) {
+        this.key = key;
+    }
 
     public void cancel() {
-        this.key.cancel();
+        if (this.key != null) {
+            this.key.cancel();
+        }
         this.completed = true;
         synchronized (this) {
             notifyAll();

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java?view=auto&rev=499577
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java Wed Jan 24 13:37:32 2007
@@ -0,0 +1,60 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.impl.reactor;
+
+import java.util.LinkedList;
+
+public class SessionRequestQueue {
+    
+    private final LinkedList list;
+    
+    public SessionRequestQueue() {
+        super();
+        this.list = new LinkedList();
+    }
+
+    public synchronized void push(final SessionRequestImpl entry) {
+        if (entry == null) {
+            return;
+        }
+        this.list.addLast(entry);
+    }
+
+    public synchronized SessionRequestImpl pop() {
+        if (!this.list.isEmpty()) {
+            return (SessionRequestImpl) this.list.removeFirst();
+        } else {
+            return null;
+        }
+    }
+    
+}

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/reactor/SessionRequestQueue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/reactor/ConnectingIOReactor.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/reactor/ConnectingIOReactor.java?view=diff&rev=499577&r1=499576&r2=499577
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/reactor/ConnectingIOReactor.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/reactor/ConnectingIOReactor.java Wed Jan 24 13:37:32 2007
@@ -31,13 +31,11 @@
 
 package org.apache.http.nio.reactor;
 
-import java.io.IOException;
 import java.net.SocketAddress;
 
 public interface ConnectingIOReactor extends IOReactor {
 
     SessionRequest connect(SocketAddress remoteAddress, 
-            SocketAddress localAddress, Object attachment) 
-        throws IOException;
+            SocketAddress localAddress, Object attachment);
         
 }