Andrea,

The code you contributed has been committed to the 2.0 branch. Many
thanks for this contribution. 

http://cvs.apache.org/viewcvs.cgi/jakarta-commons/httpclient/src/contrib/org/apache/commons/httpclient/contrib/pool/Attic/

I have applied some minor corrections to the source code to make it a
little more compatible with the overall coding and formating guidelines.
There's still potential for improvement: some additional javadocs would
be nice; comments and debug logs should ideally be translated from
Italian to English. So, feel free to submit incremental patches ;-)

If you would like the authorship attribution for this code, please
consider signing the CLA

http://www.apache.org/licenses/
http://www.apache.org/licenses/cla.txt

Cheers,

Oleg


On Thu, 2004-05-06 at 15:10, Andrea Fabris wrote:
> Hello Everybody!
> I'm Andrea from italy, and i'm very interested about the jakarta httpclient.
> I tried it and i find it very easy to use, but i found (i wrote about it 
> some time ago) a bug in the multithredconnectionmanger.
> It seems that the opened connections are tested for closure only when 
> they ahve to be given back from the pool to the client. In this way, 
> after some time where the connections are not used, the connections are 
> still open but the are in CLOSE_WAIT state: they are shut down when a 
> client request for a new connection form the pool, but the pool finds 
> the old conenction in a "CLOSE_WAIT" state, so it shuts down the 
> conenction and creates a new one.
> Now, int this manner there could be a wate of resources, if nobody uses 
> connections for a long time.
> I have seen that something has been done (in cvs) about auto closing 
> idle connection, but i still think that the multithreaded connection 
> manager needs a reimplementation.
> I think that could be a great idea to reimplement the manager using 
> commons pool as a base.
> Simply, the manager has to trak a list of open pools based on 
> GenericObjectPool: every pool in the manager (one for each host) must be 
> created using a factory that manages the connection life-cycle in the 
> pool (in the common pool framework).
> I attach the code i've written, so you can take a look at it.
> 
> Regards
> Andrea Fabris
> 
> Errore Apertura DB
> 
> ______________________________________________________________________
> package org.apache.commons.httpclient.pool;
> 
> import org.apache.commons.pool.PoolableObjectFactory;
> import org.apache.commons.httpclient.HttpConnection;
> import org.apache.commons.httpclient.HostConfiguration;
> import org.apache.commons.logging.*;
> 
> /**
>  * <p>Title: </p>
>  * <p>Description: </p>
>  * <p>Copyright: Copyright (c) 2004</p>
>  * <p>Company: </p>
>  * @author not attributable
>  * @version 1.0
>  */
> 
> public class PoolableHttpConnectionFactory implements PoolableObjectFactory {
> 
>   private HostConfiguration connConf;
>   private HttpPoolConnectionManager manager;
>   private static Log log = LogFactory.getLog(PoolableHttpConnectionFactory.class);
> 
>   public PoolableHttpConnectionFactory(HostConfiguration hc, 
> HttpPoolConnectionManager manager) {
>     connConf = hc;
>     this.manager = manager;
>   }
> 
>   /**
>    * Create a new connection using the HostConfiguration passed in the Factory
>    * @return a new connection
>    */
>   public Object makeObject() {
>     log.debug("<PoolableHttpConnectionFactory - makeObject> Inizio metodo");
>     HttpConnection conn = new HttpConnection(connConf);
>     conn.setHttpConnectionManager(manager);
>     log.debug("<PoolableHttpConnectionFactory - makeObject> Fine metodo");
>     return conn;
>   }
> 
>   public void destroyObject(Object in) {
>     log.debug("<PoolableHttpConnectionFactory - destroyObject> Inizio metodo");
>     if (in != null) {
>       log.debug("<PoolableHttpConnectionFactory - destroyObject> Connection not 
> null");
>       HttpConnection conn = (HttpConnection) in;
>       if (conn.isOpen()) {
>         log.debug("<PoolableHttpConnectionFactory - destroyObject> Closing 
> connection");
>         conn.close();
>       }
>       in = null;
>       log.debug("<PoolableHttpConnectionFactory - destroyObject> Fine metodo");
>     }
>   }
> 
>   public boolean validateObject(Object in) {
>     log.debug("<PoolableHttpConnectionFactory - validateObject> Inizio metodo");
>     boolean result = false;
>     if (in != null) {
>       HttpConnection conn = (HttpConnection) in;
>       if (conn.isOpen())
>         log.debug("<PoolableHttpConnectionFactory - validateObject> Connection 
> opened: valid connection");
>         result = true;
>     }
>     log.debug("<PoolableHttpConnectionFactory - validateObject> Inizio metodo");
>     return result;
>   }
> 
>   public void activateObject(Object in) {
>     log.debug("<PoolableHttpConnectionFactory - activateObject> No action");
>   }
> 
>   public void passivateObject(Object in){
>     log.debug("<PoolableHttpConnectionFactory - passivateObject> No action");
>   }
> }
> 
> ______________________________________________________________________
> package org.apache.commons.httpclient.pool;
> 
> import org.apache.commons.pool.impl.GenericObjectPool;
> 
> /**
>  * <p>Title: </p>
>  * <p>Description: </p>
>  * <p>Copyright: Copyright (c) 2004</p>
>  * <p>Company: </p>
>  * @author not attributable
>  * @version 1.0
>  */
> 
> public class HttpPoolConnectionManagerConfiguration {
>     private final long DEFAULT_TIMEOUT = 2000;
>     private final int DEFAULT_MAX_CONNECTIONS_PERHOST = 20;
>     private final long DEFAULT_EVICTION_TIME = 1000;
>     private final int DEFAULT_NUM_TEST_PEREVICTION = 3;
>     protected GenericObjectPool.Config poolconfig;
> 
>     /**
>      * Default constructor
>      * It initializes the pool configuration with default values
>      */
>     public HttpPoolConnectionManagerConfiguration() {
>       poolconfig = new GenericObjectPool.Config();
>       //pool configuration
>       poolconfig.maxActive = DEFAULT_MAX_CONNECTIONS_PERHOST;
>       //eviction thread
>       poolconfig.minEvictableIdleTimeMillis = DEFAULT_TIMEOUT;
>       poolconfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
>       poolconfig.timeBetweenEvictionRunsMillis = DEFAULT_EVICTION_TIME;
>       poolconfig.numTestsPerEvictionRun = DEFAULT_NUM_TEST_PEREVICTION;
>       poolconfig.testWhileIdle = true;
>     }
> 
>     /**
>      * Sets the maximum number of connections that could be idle in the pool
>      * @param max max idle connection in the pool
>      */
>     public void setMaxIdle(int max) {
>       poolconfig.maxIdle = max;
>     }
> 
>     /**
>      * Sets the maximum number of connections that could be idle in the pool
>      * @param min min idle connection pool
>      */
>     public void setMinIdle(int min) {
>       poolconfig.minIdle = min;
>     }
> 
>     /**
>      * Sets if the connection has to be tested for validity before being returned to 
> the pool
>      * @param test true if the connection has to be tested before being returned to 
> the pool
>      */
>     public void setTestOnReturn(boolean test) {
>       poolconfig.testOnReturn = test;
>     }
> 
>     /**
>      * Sets if the connection has to be tested for validity before being borrowed 
> from the pool
>      * @param test true if the connection has to be tested before being borrowed 
> from the pool
>      */
>     public void setTestOnBorrow(boolean test) {
>       poolconfig.testOnBorrow = test;
>     }
> 
>     /**
>      * Sets how many milliseconds the client can wait for a connection from the pool
>      * @param wait maximum wait time
>      */
>     public void setMaxWait(long wait) {
>       poolconfig.maxWait = wait;
>     }
> 
>     /**
>      * Set the maximum number of connection allowed in the pool
>      * @param max max connection in the pool
>      */
>     public void setMaxActive(int max) {
>       poolconfig.maxActive = max;
>     }
> 
>     /**
>      * Sets how many milliseconds an dle connection could remain in the pool before 
> being closed
>      * @param timeout maximum idle time
>      */
>     public void setPoolIdleTime(long timeout) {
>       poolconfig.minEvictableIdleTimeMillis = timeout;
>     }
> 
>     /**
>      * Sets the time (in milliseconds) between two runs of the check thred in the 
> pool
>      * @param time
>      */
>     public void setPoolCheckTime(long time) {
>       poolconfig.timeBetweenEvictionRunsMillis = time;
>     }
> 
>     /**
>      * Sets how meny tests have to be perfomrmed during the eviction run
>      * @param test int
>      */
>     public void setTestPerCheck(int test) {
>       poolconfig.numTestsPerEvictionRun = test;
>     }
> }
> 
> ______________________________________________________________________
> package org.apache.commons.httpclient.pool;
> 
> import java.util.*;
> 
> import org.apache.commons.httpclient.*;
> import org.apache.commons.logging.*;
> import org.apache.commons.pool.impl.*;
> 
> /**
>  * <p>Title: </p>
>  * <p>Description: </p>
>  * <p>Copyright: Copyright (c) 2004</p>
>  * <p>Company: </p>
>  * @author not attributable
>  * @version 1.0
>  */
> 
> public class HttpPoolConnectionManager
>     implements HttpConnectionManager {
> 
>   private HashMap poolsMap = new HashMap();
>   private static Log log = LogFactory.getLog(HttpPoolConnectionManager.class);
>   private static int DEFAULT_MAX_CONNECTIONS = 100;
> 
>   HttpPoolConnectionManagerConfiguration config;
>   private int maxConnections;
> 
>   public HttpPoolConnectionManager() {
>     config = new HttpPoolConnectionManagerConfiguration();
>     maxConnections = DEFAULT_MAX_CONNECTIONS;
>   }
> 
>   /**
>    * HttpPoolConnectionManager
>    *
>    * @param configuration HttpPoolConnectionManager
>    */
>   public HttpPoolConnectionManager(HttpPoolConnectionManagerConfiguration
>                                    configuration) {
>     config = configuration;
>     maxConnections = DEFAULT_MAX_CONNECTIONS;
>   }
> 
>   public HttpConnection getConnection(HostConfiguration hostConfiguration) {
>     try {
>       return getConnection(hostConfiguration, -1);
>     } catch (HttpException ex) {
>       log.error("<HttpPoolConnectionManager - getConnection> " + ex.toString());
>       return null;
>     }
>   }
> 
>   public HttpConnection getConnection(HostConfiguration hostConfiguration,
>                                       long timeout)
>       throws HttpException {
>     log.debug("<HttpConnectionManager - getConnection> Inizio metodo");
>     //Ottengo la "chiave"
>     String key = hostConfiguration.getHost() + ":" + hostConfiguration.getPort();
>     log.debug("<HttpConnectionManager - getConnection> Pool [" + key + "]");
>     GenericObjectPool pool = null;
>     synchronized (this) {
>       pool = (GenericObjectPool) poolsMap.get(key);
>       if (pool == null) {
>         //creo pool e ottengo connessione
>         log.debug("<HttpConnectionManager - getConnection> Pool da creare");
>         config.setMaxWait(timeout);
>         GenericObjectPool newpool = new GenericObjectPool(new
>             PoolableHttpConnectionFactory(hostConfiguration, this),
>             config.poolconfig);
>         poolsMap.put(key, newpool);
>         log.debug("<HttpConnectionManager - getConnection> Fine metodo");
>         try {
>           return (HttpConnection) newpool.borrowObject();
>         } catch (Exception ex) {
>           log.error("<HttpConnectionManager - getConnection> " + ex.toString());
>           throw new HttpException(ex.getMessage());
>         }
>       }
>     }
>     //pool in cache
>     log.debug("<HttpConnectionManager - getConnection> Pool gi usato");
>     log.debug("<HttpConnectionManager - getConnection> Fine metodo");
>     try {
>       return (HttpConnection) (pool).borrowObject();
>     } catch (Exception ex) {
>       log.error("<HttpConnectionManager - getConnection> " + ex.toString());
>       throw new HttpException(ex.getMessage());
>     }
>   }
> 
>   public void releaseConnection(HttpConnection conn) {
>     log.debug("<HttpConnectionManager - releaseConnection> Inizio metodo");
>     String key = conn.getHost() + ":" + conn.getPort();
>     log.debug("<HttpConnectionManager - releaseConnection> Pool [" + key + "]");
>     if (poolsMap.containsKey(key)) {
>       GenericObjectPool pool = (GenericObjectPool) poolsMap.get(key);
>       try {
>         pool.returnObject(conn);
>       } catch (Exception ex) {
>         log.error("<HttpPoolConnectionManager - releaseConnection> " +
>                   ex.toString());
>       }
>     }
>     log.debug("<HttpConnectionManager - releaseConnection> Fine metodo");
>   }
> 
>   public void finalize() {
>     log.debug("<HttpPoolConnectionManager - finalize> Inizio metodo");
>     if (this.poolsMap != null) {
>       Iterator keyiter = this.poolsMap.keySet().iterator();
>       while (keyiter.hasNext()) {
>         String key = (String) keyiter.next();
>         log.debug("<HttpPoolConnectionManager - finalize> Destroying [" + key +
>                   "]");
>         GenericObjectPool pool = (GenericObjectPool)this.poolsMap.get(key);
>         try {
>           pool.close();
>           this.poolsMap.put(key, null);
>         } catch (Exception ex) {
>           log.error("<HttpPoolConnectionManager - finalize> " + ex.toString());
>         }
>       }
>       this.poolsMap = null;
>     }
>     log.debug("<HttpPoolConnectionManager - finalize> Fine metodo");
>   }
> 
>   public void shutdown() {
>     log.debug("<HttpPoolConnectionManager - shutdown> Inizio metodo");
>     Iterator keyiter = this.poolsMap.keySet().iterator();
>     while (keyiter.hasNext()) {
>       String key = (String) keyiter.next();
>       log.debug("<HttpPoolConnectionManager - shutdown> Destroying [" + key +
>                 "]");
>       GenericObjectPool pool = (GenericObjectPool)this.poolsMap.get(key);
>       try {
>         pool.close();
>         this.poolsMap.put(key, null);
>       } catch (Exception ex) {
>         log.error("<HttpPoolConnectionManager - shutdown> " + ex.toString());
>       }
>     }
>     this.poolsMap = null;
>     log.debug("<HttpPoolConnectionManager - shutdown> Fine metodo");
>   }
> }
> 
> 
> ______________________________________________________________________
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to