| OLD | NEW |
| 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; | 5 library analysis.server; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:math' show max; |
| 9 | 10 |
| 10 import 'package:analysis_server/src/analysis_logger.dart'; | 11 import 'package:analysis_server/src/analysis_logger.dart'; |
| 11 import 'package:analysis_server/src/channel/channel.dart'; | 12 import 'package:analysis_server/src/channel/channel.dart'; |
| 12 import 'package:analysis_server/src/context_manager.dart'; | 13 import 'package:analysis_server/src/context_manager.dart'; |
| 13 import 'package:analysis_server/src/operation/operation.dart'; | 14 import 'package:analysis_server/src/operation/operation.dart'; |
| 14 import 'package:analysis_server/src/operation/operation_analysis.dart'; | 15 import 'package:analysis_server/src/operation/operation_analysis.dart'; |
| 15 import 'package:analysis_server/src/operation/operation_queue.dart'; | 16 import 'package:analysis_server/src/operation/operation_queue.dart'; |
| 16 import 'package:analysis_server/src/protocol.dart' hide Element; | 17 import 'package:analysis_server/src/protocol.dart' hide Element; |
| 17 import 'package:analysis_server/src/services/correction/namespace.dart'; | 18 import 'package:analysis_server/src/services/correction/namespace.dart'; |
| 18 import 'package:analysis_server/src/services/index/index.dart'; | 19 import 'package:analysis_server/src/services/index/index.dart'; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 new HashMap<AnalysisService, Set<String>>(); | 161 new HashMap<AnalysisService, Set<String>>(); |
| 161 | 162 |
| 162 /** | 163 /** |
| 163 * A table mapping [AnalysisContext]s to the completers that should be | 164 * A table mapping [AnalysisContext]s to the completers that should be |
| 164 * completed when analysis of this context is finished. | 165 * completed when analysis of this context is finished. |
| 165 */ | 166 */ |
| 166 Map<AnalysisContext, Completer<AnalysisDoneReason>> contextAnalysisDoneComplet
ers = | 167 Map<AnalysisContext, Completer<AnalysisDoneReason>> contextAnalysisDoneComplet
ers = |
| 167 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>(); | 168 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>(); |
| 168 | 169 |
| 169 /** | 170 /** |
| 171 * Performance information before initial analysis is complete. |
| 172 */ |
| 173 ServerPerformance performanceDuringStartup = new ServerPerformance(); |
| 174 |
| 175 /** |
| 176 * Performance information after initial analysis is complete |
| 177 * or `null` if the initial analysis is not yet complete |
| 178 */ |
| 179 ServerPerformance performanceAfterStartup; |
| 180 |
| 181 /** |
| 182 * The class into which performance information is currently being recorded. |
| 183 * During startup, this will be the same as [performanceDuringStartup] |
| 184 * and after startup is complete, this switches to [performanceAfterStartup]. |
| 185 */ |
| 186 ServerPerformance _performance; |
| 187 |
| 188 /** |
| 170 * The option possibly set from the server initialization which disables error
notifications. | 189 * The option possibly set from the server initialization which disables error
notifications. |
| 171 */ | 190 */ |
| 172 bool _noErrorNotification; | 191 bool _noErrorNotification; |
| 173 | 192 |
| 174 /** | 193 /** |
| 175 * The [Completer] that completes when analysis is complete. | 194 * The [Completer] that completes when analysis is complete. |
| 176 */ | 195 */ |
| 177 Completer _onAnalysisCompleteCompleter; | 196 Completer _onAnalysisCompleteCompleter; |
| 178 | 197 |
| 179 /** | 198 /** |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 * | 237 * |
| 219 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are | 238 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are |
| 220 * propagated up the call stack. The default is true to allow analysis | 239 * propagated up the call stack. The default is true to allow analysis |
| 221 * exceptions to show up in unit tests, but it should be set to false when | 240 * exceptions to show up in unit tests, but it should be set to false when |
| 222 * running a full analysis server. | 241 * running a full analysis server. |
| 223 */ | 242 */ |
| 224 AnalysisServer(this.channel, this.resourceProvider, | 243 AnalysisServer(this.channel, this.resourceProvider, |
| 225 PackageMapProvider packageMapProvider, this.index, | 244 PackageMapProvider packageMapProvider, this.index, |
| 226 AnalysisServerOptions analysisServerOptions, this.defaultSdk, | 245 AnalysisServerOptions analysisServerOptions, this.defaultSdk, |
| 227 this.instrumentationService, {this.rethrowExceptions: true}) { | 246 this.instrumentationService, {this.rethrowExceptions: true}) { |
| 247 _performance = performanceDuringStartup; |
| 228 searchEngine = createSearchEngine(index); | 248 searchEngine = createSearchEngine(index); |
| 229 operationQueue = new ServerOperationQueue(); | 249 operationQueue = new ServerOperationQueue(); |
| 230 contextDirectoryManager = | 250 contextDirectoryManager = |
| 231 new ServerContextManager(this, resourceProvider, packageMapProvider); | 251 new ServerContextManager(this, resourceProvider, packageMapProvider); |
| 232 contextDirectoryManager.defaultOptions.incremental = true; | 252 contextDirectoryManager.defaultOptions.incremental = true; |
| 233 contextDirectoryManager.defaultOptions.incrementalApi = | 253 contextDirectoryManager.defaultOptions.incrementalApi = |
| 234 analysisServerOptions.enableIncrementalResolutionApi; | 254 analysisServerOptions.enableIncrementalResolutionApi; |
| 235 contextDirectoryManager.defaultOptions.incrementalValidation = | 255 contextDirectoryManager.defaultOptions.incrementalValidation = |
| 236 analysisServerOptions.enableIncrementalResolutionValidation; | 256 analysisServerOptions.enableIncrementalResolutionValidation; |
| 237 _noErrorNotification = analysisServerOptions.noErrorNotification; | 257 _noErrorNotification = analysisServerOptions.noErrorNotification; |
| 238 AnalysisEngine.instance.logger = new AnalysisLogger(); | 258 AnalysisEngine.instance.logger = new AnalysisLogger(); |
| 239 _onAnalysisStartedController = new StreamController.broadcast(); | 259 _onAnalysisStartedController = new StreamController.broadcast(); |
| 240 _onFileAnalyzedController = new StreamController.broadcast(); | 260 _onFileAnalyzedController = new StreamController.broadcast(); |
| 241 _onPriorityChangeController = | 261 _onPriorityChangeController = |
| 242 new StreamController<PriorityChangeEvent>.broadcast(); | 262 new StreamController<PriorityChangeEvent>.broadcast(); |
| 243 running = true; | 263 running = true; |
| 264 onAnalysisStarted.first.then((_) { |
| 265 onAnalysisComplete.then((_) { |
| 266 performanceAfterStartup = new ServerPerformance(); |
| 267 _performance = performanceAfterStartup; |
| 268 }); |
| 269 }); |
| 244 Notification notification = new ServerConnectedParams().toNotification(); | 270 Notification notification = new ServerConnectedParams().toNotification(); |
| 245 channel.sendNotification(notification); | 271 channel.sendNotification(notification); |
| 246 channel.listen(handleRequest, onDone: done, onError: error); | 272 channel.listen(handleRequest, onDone: done, onError: error); |
| 247 } | 273 } |
| 248 | 274 |
| 249 /** | 275 /** |
| 250 * The [Future] that completes when analysis is complete. | 276 * The [Future] that completes when analysis is complete. |
| 251 */ | 277 */ |
| 252 Future get onAnalysisComplete { | 278 Future get onAnalysisComplete { |
| 253 if (isAnalysisComplete()) { | 279 if (isAnalysisComplete()) { |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 } | 548 } |
| 523 // file-based source | 549 // file-based source |
| 524 File file = resourceProvider.getResource(path); | 550 File file = resourceProvider.getResource(path); |
| 525 return file.createSource(); | 551 return file.createSource(); |
| 526 } | 552 } |
| 527 | 553 |
| 528 /** | 554 /** |
| 529 * Handle a [request] that was read from the communication channel. | 555 * Handle a [request] that was read from the communication channel. |
| 530 */ | 556 */ |
| 531 void handleRequest(Request request) { | 557 void handleRequest(Request request) { |
| 558 _performance.logRequest(request); |
| 532 runZoned(() { | 559 runZoned(() { |
| 533 int count = handlers.length; | 560 int count = handlers.length; |
| 534 for (int i = 0; i < count; i++) { | 561 for (int i = 0; i < count; i++) { |
| 535 try { | 562 try { |
| 536 Response response = handlers[i].handleRequest(request); | 563 Response response = handlers[i].handleRequest(request); |
| 537 if (response == Response.DELAYED_RESPONSE) { | 564 if (response == Response.DELAYED_RESPONSE) { |
| 538 return; | 565 return; |
| 539 } | 566 } |
| 540 if (response != null) { | 567 if (response != null) { |
| 541 channel.sendResponse(response); | 568 channel.sendResponse(response); |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 * [packageUriResolver]. | 1171 * [packageUriResolver]. |
| 1145 */ | 1172 */ |
| 1146 SourceFactory _createSourceFactory(UriResolver packageUriResolver) { | 1173 SourceFactory _createSourceFactory(UriResolver packageUriResolver) { |
| 1147 List<UriResolver> resolvers = <UriResolver>[ | 1174 List<UriResolver> resolvers = <UriResolver>[ |
| 1148 new DartUriResolver(analysisServer.defaultSdk), | 1175 new DartUriResolver(analysisServer.defaultSdk), |
| 1149 new ResourceUriResolver(resourceProvider), | 1176 new ResourceUriResolver(resourceProvider), |
| 1150 packageUriResolver]; | 1177 packageUriResolver]; |
| 1151 return new SourceFactory(resolvers); | 1178 return new SourceFactory(resolvers); |
| 1152 } | 1179 } |
| 1153 } | 1180 } |
| 1181 |
| 1182 |
| 1183 /** |
| 1184 * A class used by [AnalysisServer] to record performance information |
| 1185 * such as request latency. |
| 1186 */ |
| 1187 class ServerPerformance { |
| 1188 |
| 1189 /** |
| 1190 * The creation time and the time when performance information |
| 1191 * started to be recorded here. |
| 1192 */ |
| 1193 int startTime = new DateTime.now().millisecondsSinceEpoch; |
| 1194 |
| 1195 /** |
| 1196 * The number of requests. |
| 1197 */ |
| 1198 int requestCount = 0; |
| 1199 |
| 1200 /** |
| 1201 * The total latency (milliseconds) for all recorded requests. |
| 1202 */ |
| 1203 int requestLatency = 0; |
| 1204 |
| 1205 /** |
| 1206 * The maximum latency (milliseconds) for all recorded requests. |
| 1207 */ |
| 1208 int maxLatency = 0; |
| 1209 |
| 1210 /** |
| 1211 * The number of requests with latency > 150 milliseconds. |
| 1212 */ |
| 1213 int slowRequestCount = 0; |
| 1214 |
| 1215 /** |
| 1216 * Log performation information about the given request. |
| 1217 */ |
| 1218 void logRequest(Request request) { |
| 1219 ++requestCount; |
| 1220 if (request.clientRequestTime != null) { |
| 1221 int latency = |
| 1222 new DateTime.now().millisecondsSinceEpoch - |
| 1223 request.clientRequestTime; |
| 1224 requestLatency += latency; |
| 1225 maxLatency = max(maxLatency, latency); |
| 1226 if (latency > 150) { |
| 1227 ++slowRequestCount; |
| 1228 } |
| 1229 } |
| 1230 } |
| 1231 } |
| OLD | NEW |