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

Side by Side Diff: pkg/analysis_server/lib/src/get_handler.dart

Issue 861153003: improve measurement of completion performance (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: slightly adjust text Created 5 years, 11 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library analysis_server.src.get_handler; 5 library analysis_server.src.get_handler;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'dart:math'; 10 import 'dart:math';
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 * Contents of overlay files. 138 * Contents of overlay files.
139 */ 139 */
140 final Map<int, String> _overlayContents = <int, String>{}; 140 final Map<int, String> _overlayContents = <int, String>{};
141 141
142 /** 142 /**
143 * Initialize a newly created handler for GET requests. 143 * Initialize a newly created handler for GET requests.
144 */ 144 */
145 GetHandler(this._server, this._printBuffer); 145 GetHandler(this._server, this._printBuffer);
146 146
147 /** 147 /**
148 * Return the active [CompletionDomainHandler]
149 * or `null` if either analysis server is not running
150 * or there is no completion domain handler.
151 */
152 CompletionDomainHandler get _completionDomainHandler {
153 AnalysisServer analysisServer = _server.analysisServer;
154 if (analysisServer == null) {
155 return null;
156 }
157 return analysisServer.handlers.firstWhere(
158 (h) => h is CompletionDomainHandler,
159 orElse: () => null);
160 }
161
162 /**
148 * Handle a GET request received by the HTTP server. 163 * Handle a GET request received by the HTTP server.
149 */ 164 */
150 void handleGetRequest(HttpRequest request) { 165 void handleGetRequest(HttpRequest request) {
151 String path = request.uri.path; 166 String path = request.uri.path;
152 if (path == STATUS_PATH) { 167 if (path == STATUS_PATH) {
153 _returnServerStatus(request); 168 _returnServerStatus(request);
154 } else if (path == '/status2') { 169 } else if (path == '/status2') {
155 _returnServerStatus2(request); 170 _returnServerStatus2(request);
156 } else if (path == AST_PATH) { 171 } else if (path == AST_PATH) {
157 _returnAst(request); 172 _returnAst(request);
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 response.write('<p>$count files found</p>'); 581 response.write('<p>$count files found</p>');
567 response.write('</body>'); 582 response.write('</body>');
568 response.write('</html>'); 583 response.write('</html>');
569 response.close(); 584 response.close();
570 } 585 }
571 586
572 /** 587 /**
573 * Return a response displaying code completion information. 588 * Return a response displaying code completion information.
574 */ 589 */
575 void _returnCompletionInfo(HttpRequest request) { 590 void _returnCompletionInfo(HttpRequest request) {
576 var refresh = request.requestedUri.queryParameters['refresh']; 591 String value = request.requestedUri.queryParameters['index'];
577 var maxCount = request.requestedUri.queryParameters['maxCount']; 592 int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
578 HttpResponse response = request.response; 593 _writeResponse(request, (StringBuffer buffer) {
579 response.statusCode = HttpStatus.OK; 594 _writePage(buffer, 'Code Completion - Status', [], (StringBuffer buffer) {
580 response.headers.contentType = _htmlContent; 595 _writeCompletionPerformanceDetail(buffer, index);
581 response.write('<html>'); 596 _writeCompletionPerformanceList(buffer);
582 response.write('<head>'); 597 });
583 response.write('<title>Dart Analysis Server - Completion Stats</title>'); 598 });
584 response.write('<style>');
585 response.write('td.right {text-align: right;}');
586 response.write('</style>');
587 if (refresh is String) {
588 int seconds = int.parse(refresh, onError: (_) => 5);
589 response.write('<meta http-equiv="refresh" content="$seconds">');
590 }
591 response.write('</head>');
592 response.write('<body>');
593 _writeCompletionInfo(response, maxCount);
594 response.write('<p>&nbsp</p>');
595 response.write('<p>Try ');
596 response.write('<a href="?refresh=5">?refresh=5</a>');
597 response.write(' to refresh every 5 seconds</p>');
598 response.write('<p>and ');
599 response.write('<a href="?maxCount=50">?maxCount=50</a>');
600 response.write(' to keep the last 50 performance measurements</p>');
601 response.write('</body>');
602 response.write('</html>');
603 response.close();
604 } 599 }
605 600
606 /** 601 /**
607 * Return a response containing information about a single source file in the 602 * Return a response containing information about a single source file in the
608 * cache. 603 * cache.
609 */ 604 */
610 void _returnContextInfo(HttpRequest request) { 605 void _returnContextInfo(HttpRequest request) {
611 AnalysisServer analysisServer = _server.analysisServer; 606 AnalysisServer analysisServer = _server.analysisServer;
612 if (analysisServer == null) { 607 if (analysisServer == null) {
613 return _returnFailure(request, 'Analysis server not running'); 608 return _returnFailure(request, 'Analysis server not running');
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 buffer.write('</p>'); 1076 buffer.write('</p>');
1082 }, (StringBuffer buffer) { 1077 }, (StringBuffer buffer) {
1083 _writeSubscriptionMap( 1078 _writeSubscriptionMap(
1084 buffer, 1079 buffer,
1085 AnalysisService.VALUES, 1080 AnalysisService.VALUES,
1086 analysisServer.analysisServices); 1081 analysisServer.analysisServices);
1087 }); 1082 });
1088 } 1083 }
1089 1084
1090 /** 1085 /**
1091 * Append code completion information. 1086 * Write performance information about a specific completion request
1087 * to the given [buffer] object.
1092 */ 1088 */
1093 void _writeCompletionInfo(HttpResponse response, maxCount) { 1089 void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
1094 response.write('<h1>Code Completion</h1>'); 1090 CompletionDomainHandler handler = _completionDomainHandler;
1095 AnalysisServer analysisServer = _server.analysisServer; 1091 CompletionPerformance performance;
1096 if (analysisServer == null) { 1092 if (handler != null) {
1097 response.write('<p>Not running</p>'); 1093 List<CompletionPerformance> list = handler.performanceList;
1094 if (list != null && list.isNotEmpty) {
1095 performance = list[max(0, min(list.length - 1, index))];
1096 }
1097 }
1098 if (performance == null) {
1099 buffer.write('<h3>Completion Performance Detail</h3>');
1100 buffer.write('<p>No completions yet</p>');
1098 return; 1101 return;
1099 } 1102 }
1100 CompletionDomainHandler handler = analysisServer.handlers.firstWhere( 1103 buffer.write(
1101 (h) => h is CompletionDomainHandler, 1104 '<h3>Completion Performance Detail - ${performance.startTimeAndMs}</h3>' );
1102 orElse: () => null); 1105 buffer.write('<table>');
1103 if (handler == null) { 1106 _writeRow2(buffer, ['Elapsed', '', 'Operation'], header: true);
1104 response.write('<p>No code completion</p>');
1105 return;
1106 }
1107 if (maxCount is String) {
1108 int count = int.parse(maxCount, onError: (_) => 0);
1109 handler.performanceListMaxLength = count;
1110 }
1111 CompletionPerformance performance = handler.performance;
1112 if (performance == null) {
1113 response.write('<p>No performance stats yet</p>');
1114 return;
1115 }
1116 response.write('<h2>Last Completion Performance</h2>');
1117 response.write('<table>');
1118 _writeRow(response, ['Elapsed', '', 'Operation'], header: true);
1119 performance.operations.forEach((OperationPerformance op) { 1107 performance.operations.forEach((OperationPerformance op) {
1120 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???'; 1108 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
1121 _writeRow(response, [elapsed, '&nbsp;&nbsp;', op.name]); 1109 _writeRow2(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
1122 }); 1110 });
1123 if (handler.priorityChangedPerformance == null) { 1111 if (handler.priorityChangedPerformance == null) {
1124 response.write('<p>No priorityChanged caching</p>'); 1112 buffer.write('<p>No priorityChanged caching</p>');
1125 } else { 1113 } else {
1126 int len = handler.priorityChangedPerformance.operations.length; 1114 int len = handler.priorityChangedPerformance.operations.length;
1127 if (len > 0) { 1115 if (len > 0) {
1128 var op = handler.priorityChangedPerformance.operations[len - 1]; 1116 var op = handler.priorityChangedPerformance.operations[len - 1];
1129 if (op != null) { 1117 if (op != null) {
1130 _writeRow(response, ['&nbsp;', '&nbsp;', '&nbsp;']); 1118 _writeRow2(buffer, ['&nbsp;', '&nbsp;', '&nbsp;']);
1131 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???'; 1119 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
1132 _writeRow(response, [elapsed, '&nbsp;&nbsp;', op.name]); 1120 _writeRow2(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
1133 } 1121 }
1134 } 1122 }
1135 } 1123 }
1136 response.write('</table>'); 1124 buffer.write('</table>');
1137 if (handler.performanceList.length > 0) {
1138 response.write('<h2>Last Completion Summary</h2>');
1139 response.write('<table>');
1140 _writeRow(
1141 response,
1142 [
1143 'Start Time',
1144 '',
1145 'First (ms)',
1146 '',
1147 'Complete (ms)',
1148 '',
1149 '# Notifications',
1150 '',
1151 '# Suggestions',
1152 '',
1153 'Snippet'],
1154 header: true);
1155 handler.performanceList.forEach((CompletionPerformance performance) {
1156 _writeRow(
1157 response,
1158 [
1159 performance.start,
1160 '&nbsp;&nbsp;',
1161 performance.firstNotificationInMilliseconds,
1162 '&nbsp;&nbsp;',
1163 performance.elapsedInMilliseconds,
1164 '&nbsp;&nbsp;',
1165 performance.notificationCount,
1166 '&nbsp;&nbsp;',
1167 performance.suggestionCount,
1168 '&nbsp;&nbsp;',
1169 performance.snippet]);
1170 });
1171 response.write('</table>');
1172 }
1173 } 1125 }
1174 1126
1175 /** 1127 /**
1128 * Write a table showing summary information for the last several
1129 * completion requests to the given [buffer] object.
1130 */
1131 void _writeCompletionPerformanceList(StringBuffer buffer) {
1132 CompletionDomainHandler handler = _completionDomainHandler;
1133 buffer.write('<h3>Completion Performance</h3>');
1134 if (handler == null) {
1135 return;
1136 }
1137 buffer.write('<table>');
1138 _writeRow2(
1139 buffer,
1140 [
1141 'Start Time',
1142 '',
1143 'First (ms)',
1144 '',
1145 'Complete (ms)',
1146 '',
1147 '# Notifications',
1148 '',
1149 '# Suggestions',
1150 '',
1151 'Snippet'],
1152 header: true);
1153 int index = 0;
1154 for (CompletionPerformance performance in handler.performanceList) {
1155 String link = _makeLink(COMPLETION_PATH, {
1156 'index': '$index'
1157 }, '${performance.startTimeAndMs}');
1158 _writeRow2(
1159 buffer,
1160 [
1161 link,
1162 '&nbsp;&nbsp;',
1163 performance.firstNotificationInMilliseconds,
1164 '&nbsp;&nbsp;',
1165 performance.elapsedInMilliseconds,
1166 '&nbsp;&nbsp;',
1167 performance.notificationCount,
1168 '&nbsp;&nbsp;',
1169 performance.suggestionCount,
1170 '&nbsp;&nbsp;',
1171 HTML_ESCAPE.convert(performance.snippet)]);
1172 ++index;
1173 }
1174 ;
1175 buffer.write('</table>');
1176 buffer.write('''
1177 <p><strong>First (ms)</strong> - the number of milliseconds
1178 from when completion received the request until the first notification
1179 with completion results was queued for sending back to the client.
1180 <p><strong>Complete (ms)</strong> - the number of milliseconds
1181 from when completion received the request until the final notification
1182 with completion results was queued for sending back to the client.
1183 <p><strong># Notifications</strong> - the total number of notifications
1184 sent to the client with completion results for this request.
1185 <p><strong># Suggestions</strong> - the number of suggestions
1186 sent to the client in the first notification, followed by a comma,
1187 followed by the number of suggestions send to the client
1188 in the last notification. If there is only one notification,
1189 then there will be only one number in this column.''');
1190 }
1191
1192 /**
1176 * Generate a table showing the cache values corresponding to the given 1193 * Generate a table showing the cache values corresponding to the given
1177 * [descriptors], using [getState] to get the cache state corresponding to 1194 * [descriptors], using [getState] to get the cache state corresponding to
1178 * each descriptor, and [getValue] to get the cached value corresponding to 1195 * each descriptor, and [getValue] to get the cached value corresponding to
1179 * each descriptor. Append the resulting HTML to the given [buffer]. The 1196 * each descriptor. Append the resulting HTML to the given [buffer]. The
1180 * [linkParameters] will be used if the value is too large to be displayed on 1197 * [linkParameters] will be used if the value is too large to be displayed on
1181 * the current page and needs to be linked to a separate page. 1198 * the current page and needs to be linked to a separate page.
1182 */ 1199 */
1183 void _writeDescriptorTable(StringBuffer buffer, 1200 void _writeDescriptorTable(StringBuffer buffer,
1184 List<DataDescriptor> descriptors, CacheState getState(DataDescriptor), dyn amic 1201 List<DataDescriptor> descriptors, CacheState getState(DataDescriptor), dyn amic
1185 getValue(DataDescriptor), Map<String, String> linkParameters) { 1202 getValue(DataDescriptor), Map<String, String> linkParameters) {
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 } else if (value is Element) { 1628 } else if (value is Element) {
1612 String link = 1629 String link =
1613 _makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString()); 1630 _makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
1614 buffer.write('<i>$link</i>'); 1631 buffer.write('<i>$link</i>');
1615 } else { 1632 } else {
1616 buffer.write(HTML_ESCAPE.convert(value.toString())); 1633 buffer.write(HTML_ESCAPE.convert(value.toString()));
1617 buffer.write(' <i>(${value.runtimeType.toString()})</i>'); 1634 buffer.write(' <i>(${value.runtimeType.toString()})</i>');
1618 } 1635 }
1619 } 1636 }
1620 } 1637 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698