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

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

Issue 176893003: Only use one timer to handle HttpServer::idleTimeout. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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') | no next file » | 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 53159bbe3b7185a3ad175dc1939c6c99caeca2c5..5bc5b97cae902e5b01162391de71b196bc53bc52 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1895,24 +1895,22 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> {
static const _CLOSING = 2;
static const _DETACHED = 3;
- int _state = _IDLE;
-
final Socket _socket;
final _HttpServer _httpServer;
final _HttpParser _httpParser;
+ int _state = _IDLE;
StreamSubscription _subscription;
Timer _idleTimer;
final Uint8List _headersBuffer = new Uint8List(_HEADERS_BUFFER_SIZE);
-
+ bool _idleMark = false;
Future _streamFuture;
_HttpConnection(this._socket, this._httpServer)
: _httpParser = new _HttpParser.requestParser() {
- _startTimeout();
_httpParser.listenToStream(_socket);
_subscription = _httpParser.listen(
(incoming) {
- _stopTimeout();
+ _httpServer._markActive(this);
// If the incoming was closed, close the connection.
incoming.dataDone.then((closing) {
if (closing) destroy();
@@ -1937,7 +1935,8 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> {
!_httpParser.upgrade &&
!_httpServer.closed) {
_state = _IDLE;
- _startTimeout();
+ _idleMark = false;
+ _httpServer._markIdle(this);
// Resume the subscription for incoming requests as the
// request is now processed.
_subscription.resume();
@@ -1962,21 +1961,13 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> {
});
}
- void _startTimeout() {
- assert(_state == _IDLE);
- _stopTimeout();
- if (_httpServer.idleTimeout == null) return;
- _idleTimer = new Timer(_httpServer.idleTimeout, () {
- destroy();
- });
+ void markIdle() {
+ _idleMark = true;
}
- void _stopTimeout() {
- if (_idleTimer != null) _idleTimer.cancel();
- }
+ bool get isMarkedIdle => _idleMark;
void destroy() {
- _stopTimeout();
if (_state == _CLOSING || _state == _DETACHED) return;
_state = _CLOSING;
_socket.destroy();
@@ -1984,7 +1975,6 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> {
}
Future<Socket> detachSocket() {
- _stopTimeout();
_state = _DETACHED;
// Remove connection from server.
_httpServer._connectionClosed(this);
@@ -2009,7 +1999,8 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> {
class _HttpServer extends Stream<HttpRequest> implements HttpServer {
String serverHeader;
- Duration idleTimeout = const Duration(seconds: 120);
+ Duration _idleTimeout;
+ Timer _idleTimer;
static Future<HttpServer> bind(address, int port, int backlog) {
return ServerSocket.bind(address, port, backlog: backlog).then((socket) {
@@ -2036,11 +2027,34 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
_HttpServer._(this._serverSocket, this._closeServer) {
_controller = new StreamController<HttpRequest>(sync: true,
onCancel: close);
+ idleTimeout = const Duration(seconds: 120);
}
_HttpServer.listenOn(this._serverSocket) : _closeServer = false {
_controller = new StreamController<HttpRequest>(sync: true,
onCancel: close);
+ idleTimeout = const Duration(seconds: 120);
+ }
+
+ Duration get idleTimeout => _idleTimeout;
+
+ void set idleTimeout(Duration duration) {
+ if (_idleTimer != null) {
+ _idleTimer.cancel();
+ _idleTimer = null;
+ }
+ _idleTimeout = duration;
+ if (_idleTimeout != null) {
+ _idleTimer = new Timer.periodic(_idleTimeout, (_) {
+ for (var idle in _idleConnections.toList()) {
+ if (idle.isMarkedIdle) {
+ idle.destroy();
+ } else {
+ idle.markIdle();
+ }
+ }
+ });
+ }
}
StreamSubscription<HttpRequest> listen(void onData(HttpRequest event),
@@ -2052,7 +2066,7 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
socket.setOption(SocketOption.TCP_NODELAY, true);
// Accept the client connection.
_HttpConnection connection = new _HttpConnection(socket, this);
- _connections.add(connection);
+ _idleConnections.add(connection);
},
onError: (error) {
// Ignore HandshakeExceptions as they are bound to a single request,
@@ -2076,15 +2090,15 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
} else {
result = new Future.value();
}
+ idleTimeout = null;
if (force) {
- for (var c in _connections.toList()) {
- c.destroy();
- }
- assert(_connections.isEmpty);
- } else {
- for (var c in _connections.where((c) => c._isIdle).toList()) {
+ for (var c in _activeConnections.toList()) {
c.destroy();
}
+ assert(_activeConnections.isEmpty);
+ }
+ for (var c in _idleConnections.toList()) {
+ c.destroy();
}
_maybeCloseSessionManager();
return result;
@@ -2092,7 +2106,8 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
void _maybeCloseSessionManager() {
if (closed &&
- _connections.isEmpty &&
+ _idleConnections.isEmpty &&
+ _activeConnections.isEmpty &&
_sessionManagerInstance != null) {
_sessionManagerInstance.close();
_sessionManagerInstance = null;
@@ -2120,10 +2135,21 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
}
void _connectionClosed(_HttpConnection connection) {
- _connections.remove(connection);
+ // Remove itself from either idle or active connections.
+ connection.unlink();
_maybeCloseSessionManager();
}
+ void _markIdle(_HttpConnection connection) {
+ _activeConnections.remove(connection);
+ _idleConnections.add(connection);
+ }
+
+ void _markActive(_HttpConnection connection) {
+ _idleConnections.remove(connection);
+ _activeConnections.add(connection);
+ }
+
_HttpSessionManager get _sessionManager {
// Lazy init.
if (_sessionManagerInstance == null) {
@@ -2134,17 +2160,19 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
HttpConnectionsInfo connectionsInfo() {
HttpConnectionsInfo result = new HttpConnectionsInfo();
- result.total = _connections.length;
- _connections.forEach((_HttpConnection conn) {
+ result.total = _activeConnections.length + _idleConnections.length;
+ _activeConnections.forEach((_HttpConnection conn) {
if (conn._isActive) {
result.active++;
- } else if (conn._isIdle) {
- result.idle++;
} else {
assert(conn._isClosing);
result.closing++;
}
});
+ _idleConnections.forEach((_HttpConnection conn) {
+ result.idle++;
+ assert(conn._isIdle);
+ });
return result;
}
@@ -2159,10 +2187,11 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
final bool _closeServer;
// Set of currently connected clients.
- final LinkedList<_HttpConnection> _connections
+ final LinkedList<_HttpConnection> _activeConnections
+ = new LinkedList<_HttpConnection>();
+ final LinkedList<_HttpConnection> _idleConnections
= new LinkedList<_HttpConnection>();
StreamController<HttpRequest> _controller;
- // TODO(ajohnsen): Use close queue?
}
« no previous file with comments | « sdk/lib/io/http.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698