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