Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Unified Diff: sdk/lib/io/http_impl.dart

Issue 15268004: Add timeouts to HttpClient. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update comment. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/io/http.dart ('k') | tests/standalone/io/http_client_timeout_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/http_impl.dart
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index b2d63b6a393a235fb017ba160bef1ed609b04a8e..1afbb43bdfdcab2087628ce3def5d9645a5ec65f 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1071,6 +1071,7 @@ class _HttpClientConnection {
StreamSubscription _subscription;
final _HttpClient _httpClient;
bool _dispose = false;
+ Timer _idleTimer;
bool closed = false;
Completer<_HttpIncoming> _nextResponseCompleter;
@@ -1285,6 +1286,22 @@ class _HttpClientConnection {
return isSecure ? "ssh:$host:$port" : "$host:$port";
}
+ void stopTimer() {
+ if (_idleTimer != null) {
+ _idleTimer.cancel();
+ _idleTimer = null;
+ }
+ }
+
+ void startTimer() {
+ assert(_idleTimer == null);
+ _idleTimer = new Timer(
+ _httpClient.idleTimeout,
+ () {
+ _idleTimer = null;
+ close();
+ });
+ }
}
class _ConnnectionInfo {
@@ -1296,7 +1313,6 @@ class _ConnnectionInfo {
class _HttpClient implements HttpClient {
// TODO(ajohnsen): Use eviction timeout.
- static const int DEFAULT_EVICTION_TIMEOUT = 60000;
bool _closing = false;
final Map<String, Set<_HttpClientConnection>> _idleConnections
@@ -1308,6 +1324,21 @@ class _HttpClient implements HttpClient {
Function _authenticate;
Function _authenticateProxy;
Function _findProxy = HttpClient.findProxyFromEnvironment;
+ Duration _idleTimeout = const Duration(seconds: 15);
+
+ Timer _noActiveTimer;
+
+ Duration get idleTimeout => _idleTimeout;
+
+ void set idleTimeout(Duration timeout) {
+ _idleTimeout = timeout;
+ var idle = _idleConnections.values.forEach(
+ (l) => l.forEach((c) {
+ // Reset timer. This is fine, as it's not happening often.
+ c.stopTimer();
+ c.startTimer();
+ }));
+ }
Future<HttpClientRequest> open(String method,
String host,
@@ -1485,15 +1516,17 @@ class _HttpClient implements HttpClient {
connection.close();
return;
}
- // TODO(ajohnsen): Listen for socket close events.
if (!_idleConnections.containsKey(connection.key)) {
_idleConnections[connection.key] = new LinkedHashSet();
}
_idleConnections[connection.key].add(connection);
+ connection.startTimer();
+ _updateTimers();
}
// Remove a closed connnection from the active set.
void _connectionClosed(_HttpClientConnection connection) {
+ connection.stopTimer();
_activeConnections.remove(connection);
if (_idleConnections.containsKey(connection.key)) {
_idleConnections[connection.key].remove(connection);
@@ -1501,6 +1534,24 @@ class _HttpClient implements HttpClient {
_idleConnections.remove(connection.key);
}
}
+ _updateTimers();
+ }
+
+ void _updateTimers() {
+ if (_activeConnections.isEmpty) {
+ if (!_idleConnections.isEmpty && _noActiveTimer == null) {
+ _noActiveTimer = new Timer(const Duration(milliseconds: 100), () {
+ _noActiveTimer = null;
+ if (_activeConnections.isEmpty) {
+ close();
+ _closing = false;
+ }
+ });
+ }
+ } else if (_noActiveTimer != null) {
+ _noActiveTimer.cancel();
+ _noActiveTimer = null;
+ }
}
// Get a new _HttpClientConnection, either from the idle pool or created from
@@ -1523,7 +1574,9 @@ class _HttpClient implements HttpClient {
if (_idleConnections[key].isEmpty) {
_idleConnections.remove(key);
}
+ connection.stopTimer();
_activeConnections.add(connection);
+ _updateTimers();
return new Future.value(new _ConnnectionInfo(connection, proxy));
}
return (isSecure && proxy.isDirect
« no previous file with comments | « sdk/lib/io/http.dart ('k') | tests/standalone/io/http_client_timeout_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698