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

Side by Side Diff: runtime/bin/http_impl.dart

Issue 10693091: Fix HTTP client eviction timer bug (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class _HttpHeaders implements HttpHeaders { 5 class _HttpHeaders implements HttpHeaders {
6 _HttpHeaders() : _headers = new Map<String, List<String>>(); 6 _HttpHeaders() : _headers = new Map<String, List<String>>();
7 7
8 List<String> operator[](String name) { 8 List<String> operator[](String name) {
9 name = name.toLowerCase(); 9 name = name.toLowerCase();
10 return _headers[name]; 10 return _headers[name];
(...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 void shutdown() { 1953 void shutdown() {
1954 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { 1954 _openSockets.forEach((String key, Queue<_SocketConnection> connections) {
1955 while (!connections.isEmpty()) { 1955 while (!connections.isEmpty()) {
1956 _SocketConnection socketConn = connections.removeFirst(); 1956 _SocketConnection socketConn = connections.removeFirst();
1957 socketConn._socket.close(); 1957 socketConn._socket.close();
1958 } 1958 }
1959 }); 1959 });
1960 _activeSockets.forEach((_SocketConnection socketConn) { 1960 _activeSockets.forEach((_SocketConnection socketConn) {
1961 socketConn._socket.close(); 1961 socketConn._socket.close();
1962 }); 1962 });
1963 if (_evictionTimer != null) { 1963 if (_evictionTimer != null) _cancelEvictionTimer();
1964 _evictionTimer.cancel();
1965 }
1966 _shutdown = true; 1964 _shutdown = true;
1967 } 1965 }
1968 1966
1967 void _cancelEvictionTimer() {
1968 _evictionTimer.cancel();
1969 _evictionTimer = null;
1970 }
1971
1969 String _connectionKey(String host, int port) { 1972 String _connectionKey(String host, int port) {
1970 return "$host:$port"; 1973 return "$host:$port";
1971 } 1974 }
1972 1975
1973 HttpClientConnection _prepareHttpClientConnection( 1976 HttpClientConnection _prepareHttpClientConnection(
1974 String host, 1977 String host,
1975 int port, 1978 int port,
1976 String method, 1979 String method,
1977 String path, 1980 String path,
1978 [_HttpClientConnection connection]) { 1981 [_HttpClientConnection connection]) {
(...skipping 12 matching lines...) Expand all
1991 } 1994 }
1992 1995
1993 // Create a new connection if we are not re-using an existing one. 1996 // Create a new connection if we are not re-using an existing one.
1994 if (connection == null) { 1997 if (connection == null) {
1995 connection = new _HttpClientConnection(this); 1998 connection = new _HttpClientConnection(this);
1996 } 1999 }
1997 connection.onDetach = () => _activeSockets.remove(connection._socketConn); 2000 connection.onDetach = () => _activeSockets.remove(connection._socketConn);
1998 2001
1999 // If there are active connections for this key get the first one 2002 // If there are active connections for this key get the first one
2000 // otherwise create a new one. 2003 // otherwise create a new one.
2001 Queue socketConnections = _openSockets[_connectionKey(host, port)]; 2004 String key = _connectionKey(host, port);
2005 Queue socketConnections = _openSockets[key];
2002 if (socketConnections == null || socketConnections.isEmpty()) { 2006 if (socketConnections == null || socketConnections.isEmpty()) {
2003 Socket socket = new Socket(host, port); 2007 Socket socket = new Socket(host, port);
2004 // Until the connection is established handle connection errors 2008 // Until the connection is established handle connection errors
2005 // here as the HttpClientConnection object is not yet associated 2009 // here as the HttpClientConnection object is not yet associated
2006 // with the socket. 2010 // with the socket.
2007 socket.onError = (e) { 2011 socket.onError = (e) {
2008 // Report the error through the HttpClientConnection object to 2012 // Report the error through the HttpClientConnection object to
2009 // the client. 2013 // the client.
2010 connection._onError(e); 2014 connection._onError(e);
2011 }; 2015 };
2012 socket.onConnect = () { 2016 socket.onConnect = () {
2013 // When the connection is established, clear the error 2017 // When the connection is established, clear the error
2014 // callback as it will now be handled by the 2018 // callback as it will now be handled by the
2015 // HttpClientConnection object which will be associated with 2019 // HttpClientConnection object which will be associated with
2016 // the connected socket. 2020 // the connected socket.
2017 socket.onError = null; 2021 socket.onError = null;
2018 _SocketConnection socketConn = 2022 _SocketConnection socketConn =
2019 new _SocketConnection(host, port, socket); 2023 new _SocketConnection(host, port, socket);
2020 _activeSockets.add(socketConn); 2024 _activeSockets.add(socketConn);
2021 _connectionOpened(socketConn, connection); 2025 _connectionOpened(socketConn, connection);
2022 }; 2026 };
2023 } else { 2027 } else {
2024 _SocketConnection socketConn = socketConnections.removeFirst(); 2028 _SocketConnection socketConn = socketConnections.removeFirst();
2025 _activeSockets.add(socketConn); 2029 _activeSockets.add(socketConn);
2026 new Timer(0, (ignored) => _connectionOpened(socketConn, connection)); 2030 new Timer(0, (ignored) => _connectionOpened(socketConn, connection));
2027 2031
2028 // Get rid of eviction timer if there are no more active connections. 2032 // Get rid of eviction timer if there are no more active connections.
2029 if (socketConnections.isEmpty()) { 2033 if (socketConnections.isEmpty()) _openSockets.remove(key);
2030 _evictionTimer.cancel(); 2034 if (_openSockets.isEmpty()) _cancelEvictionTimer();
2031 _evictionTimer = null;
2032 }
2033 } 2035 }
2034 2036
2035 return connection; 2037 return connection;
2036 } 2038 }
2037 2039
2038 void _returnSocketConnection(_SocketConnection socketConn) { 2040 void _returnSocketConnection(_SocketConnection socketConn) {
2039 // Mark socket as returned to unregister from the old connection. 2041 // Mark socket as returned to unregister from the old connection.
2040 socketConn._markReturned(); 2042 socketConn._markReturned();
2041 2043
2042 // If the HTTP client is beeing shutdown don't return the connection. 2044 // If the HTTP client is beeing shutdown don't return the connection.
2043 if (_shutdown) { 2045 if (_shutdown) {
2044 socketConn._socket.close(); 2046 socketConn._socket.close();
2045 return; 2047 return;
2046 }; 2048 };
2047 2049
2048 String key = _connectionKey(socketConn._host, socketConn._port); 2050 String key = _connectionKey(socketConn._host, socketConn._port);
2049 2051
2050 // Get or create the connection list for this key. 2052 // Get or create the connection list for this key.
2051 Queue sockets = _openSockets[key]; 2053 Queue sockets = _openSockets[key];
2052 if (sockets == null) { 2054 if (sockets == null) {
2053 sockets = new Queue(); 2055 sockets = new Queue();
2054 _openSockets[key] = sockets; 2056 _openSockets[key] = sockets;
2055 } 2057 }
2056 2058
2057 // If there is currently no eviction timer start one. 2059 // If there is currently no eviction timer start one.
2058 if (_evictionTimer == null) { 2060 if (_evictionTimer == null) {
2059 void _handleEviction(Timer timer) { 2061 void _handleEviction(Timer timer) {
2060 Date now = new Date.now(); 2062 Date now = new Date.now();
2063 List<String> emptyKeys = new List<String>();
2061 _openSockets.forEach( 2064 _openSockets.forEach(
2062 void _(String key, Queue<_SocketConnection> connections) { 2065 void _(String key, Queue<_SocketConnection> connections) {
2063 // As returned connections are added at the head of the 2066 // As returned connections are added at the head of the
2064 // list remove from the tail. 2067 // list remove from the tail.
2065 while (!connections.isEmpty()) { 2068 while (!connections.isEmpty()) {
2066 _SocketConnection socketConn = connections.last(); 2069 _SocketConnection socketConn = connections.last();
2067 if (socketConn._idleTime(now).inMilliseconds > 2070 if (socketConn._idleTime(now).inMilliseconds >
2068 DEFAULT_EVICTION_TIMEOUT) { 2071 DEFAULT_EVICTION_TIMEOUT) {
2069 connections.removeLast(); 2072 connections.removeLast();
2070 socketConn._socket.close(); 2073 socketConn._socket.close();
2074 if (connections.isEmpty()) emptyKeys.add(key);
2071 } else { 2075 } else {
2072 break; 2076 break;
2073 } 2077 }
2074 } 2078 }
2075 }); 2079 });
2080
2081 // Remove the keys for which here are no more open connections.
2082 emptyKeys.forEach((String key) => _openSockets.remove(key));
2083
2084 // If all connections where evicted cancel the eviction timer.
2085 if (_openSockets.isEmpty()) _cancelEvictionTimer();
2076 } 2086 }
2077 _evictionTimer = new Timer.repeating(10000, _handleEviction); 2087 _evictionTimer = new Timer.repeating(10000, _handleEviction);
2078 } 2088 }
2079 2089
2080 // Return connection. 2090 // Return connection.
2081 _activeSockets.remove(socketConn); 2091 _activeSockets.remove(socketConn);
2082 sockets.addFirst(socketConn); 2092 sockets.addFirst(socketConn);
2083 } 2093 }
2084 2094
2085 Function _onOpen; 2095 Function _onOpen;
(...skipping 14 matching lines...) Expand all
2100 2110
2101 2111
2102 class _RedirectInfo implements RedirectInfo { 2112 class _RedirectInfo implements RedirectInfo {
2103 const _RedirectInfo(int this.statusCode, 2113 const _RedirectInfo(int this.statusCode,
2104 String this.method, 2114 String this.method,
2105 Uri this.location); 2115 Uri this.location);
2106 final int statusCode; 2116 final int statusCode;
2107 final String method; 2117 final String method;
2108 final Uri location; 2118 final Uri location;
2109 } 2119 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698