Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
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 ch.boye.httpclientandroidlib.impl.conn;
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;
34 import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
35 /* LogFactory removed by HttpClient for Android script. */
36 import ch.boye.httpclientandroidlib.HttpConnection;
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 ch.boye.httpclientandroidlib.conn.ClientConnectionManager#closeIdleConnections
45 *
46 * @since 4.0
47 *
48 * @deprecated no longer used
49 */
50 @Deprecated
51 public class IdleConnectionHandler {
53 public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
55 /** Holds connections and the time they were added. */
56 private final Map<HttpConnection,TimeValues> connectionToTimes;
59 public IdleConnectionHandler() {
60 super();
61 connectionToTimes = new HashMap<HttpConnection,TimeValues>();
62 }
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) {
74 long timeAdded = System.currentTimeMillis();
76 if (log.isDebugEnabled()) {
77 log.debug("Adding connection at: " + timeAdded);
78 }
80 connectionToTimes.put(connection, new TimeValues(timeAdded, validDuration, unit));
81 }
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 }
101 /**
102 * Removes all connections referenced by this handler.
103 */
104 public void removeAll() {
105 this.connectionToTimes.clear();
106 }
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) {
115 // the latest time for which connections will be closed
116 long idleTimeout = System.currentTimeMillis() - idleTime;
118 if (log.isDebugEnabled()) {
119 log.debug("Checking for connections, idle timeout: " + idleTimeout);
120 }
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 }
140 public void closeExpiredConnections() {
141 long now = System.currentTimeMillis();
142 if (log.isDebugEnabled()) {
143 log.debug("Checking for expired connections, now: " + now);
144 }
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 }
162 private static class TimeValues {
163 private final long timeAdded;
164 private final long timeExpires;
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 }