View Javadoc

1   /*
2    * ====================================================================
3    *
4    *  Licensed to the Apache Software Foundation (ASF) under one or more
5    *  contributor license agreements.  See the NOTICE file distributed with
6    *  this work for additional information regarding copyright ownership.
7    *  The ASF licenses this file to You under the Apache License, Version 2.0
8    *  (the "License"); you may not use this file except in compliance with
9    *  the License.  You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *  Unless required by applicable law or agreed to in writing, software
14   *  distributed under the License is distributed on an "AS IS" BASIS,
15   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *  See the License for the specific language governing permissions and
17   *  limitations under the License.
18   * ====================================================================
19   *
20   * This software consists of voluntary contributions made by many
21   * individuals on behalf of the Apache Software Foundation.  For more
22   * information on the Apache Software Foundation, please see
23   * <http://www.apache.org/>.
24   *
25   */
26  package org.apache.http.impl.conn;
27  
28  import java.io.IOException;
29  import java.util.HashMap;
30  import java.util.Map;
31  import java.util.Map.Entry;
32  import java.util.concurrent.TimeUnit;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  import org.apache.http.HttpConnection;
37  
38  // Currently only used by AbstractConnPool
39  /**
40   * A helper class for connection managers to track idle connections.
41   *
42   * <p>This class is not synchronized.</p>
43   *
44   * @see org.apache.http.conn.ClientConnectionManager#closeIdleConnections
45   *
46   * @since 4.0
47   *
48   * @deprecated (4.1)  no longer used
49   */
50  @Deprecated
51  public class IdleConnectionHandler {
52  
53      private final Log log = LogFactory.getLog(getClass());
54  
55      /** Holds connections and the time they were added. */
56      private final Map<HttpConnection,TimeValues> connectionToTimes;
57  
58  
59      public IdleConnectionHandler() {
60          super();
61          connectionToTimes = new HashMap<HttpConnection,TimeValues>();
62      }
63  
64      /**
65       * Registers the given connection with this handler.  The connection will be held until
66       * {@link #remove} or {@link #closeIdleConnections} is called.
67       *
68       * @param connection the connection to add
69       *
70       * @see #remove
71       */
72      public void add(HttpConnection connection, long validDuration, TimeUnit unit) {
73  
74          long timeAdded = System.currentTimeMillis();
75  
76          if (log.isDebugEnabled()) {
77              log.debug("Adding connection at: " + timeAdded);
78          }
79  
80          connectionToTimes.put(connection, new TimeValues(timeAdded, validDuration, unit));
81      }
82  
83      /**
84       * Removes the given connection from the list of connections to be closed when idle.
85       * This will return true if the connection is still valid, and false
86       * if the connection should be considered expired and not used.
87       *
88       * @param connection
89       * @return True if the connection is still valid.
90       */
91      public boolean remove(HttpConnection connection) {
92          TimeValues times = connectionToTimes.remove(connection);
93          if(times == null) {
94              log.warn("Removing a connection that never existed!");
95              return true;
96          } else {
97              return System.currentTimeMillis() <= times.timeExpires;
98          }
99      }
100 
101     /**
102      * Removes all connections referenced by this handler.
103      */
104     public void removeAll() {
105         this.connectionToTimes.clear();
106     }
107 
108     /**
109      * Closes connections that have been idle for at least the given amount of time.
110      *
111      * @param idleTime the minimum idle time, in milliseconds, for connections to be closed
112      */
113     public void closeIdleConnections(long idleTime) {
114 
115         // the latest time for which connections will be closed
116         long idleTimeout = System.currentTimeMillis() - idleTime;
117 
118         if (log.isDebugEnabled()) {
119             log.debug("Checking for connections, idle timeout: "  + idleTimeout);
120         }
121 
122         for (Entry<HttpConnection, TimeValues> entry : connectionToTimes.entrySet()) {
123             HttpConnection conn = entry.getKey();
124             TimeValues times = entry.getValue();
125             long connectionTime = times.timeAdded;
126             if (connectionTime <= idleTimeout) {
127                 if (log.isDebugEnabled()) {
128                     log.debug("Closing idle connection, connection time: "  + connectionTime);
129                 }
130                 try {
131                     conn.close();
132                 } catch (IOException ex) {
133                     log.debug("I/O error closing connection", ex);
134                 }
135             }
136         }
137     }
138 
139 
140     public void closeExpiredConnections() {
141         long now = System.currentTimeMillis();
142         if (log.isDebugEnabled()) {
143             log.debug("Checking for expired connections, now: "  + now);
144         }
145 
146         for (Entry<HttpConnection, TimeValues> entry : connectionToTimes.entrySet()) {
147             HttpConnection conn = entry.getKey();
148             TimeValues times = entry.getValue();
149             if(times.timeExpires <= now) {
150                 if (log.isDebugEnabled()) {
151                     log.debug("Closing connection, expired @: "  + times.timeExpires);
152                 }
153                 try {
154                     conn.close();
155                 } catch (IOException ex) {
156                     log.debug("I/O error closing connection", ex);
157                 }
158             }
159         }
160     }
161 
162     private static class TimeValues {
163         private final long timeAdded;
164         private final long timeExpires;
165 
166         /**
167          * @param now The current time in milliseconds
168          * @param validDuration The duration this connection is valid for
169          * @param validUnit The unit of time the duration is specified in.
170          */
171         TimeValues(long now, long validDuration, TimeUnit validUnit) {
172             this.timeAdded = now;
173             if(validDuration > 0) {
174                 this.timeExpires = now + validUnit.toMillis(validDuration);
175             } else {
176                 this.timeExpires = Long.MAX_VALUE;
177             }
178         }
179     }
180 }