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 import 'dart:math' show max; |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 import 'package:analyzer/file_system/file_system.dart'; | 21 import 'package:analyzer/file_system/file_system.dart'; |
22 import 'package:analyzer/instrumentation/instrumentation.dart'; | 22 import 'package:analyzer/instrumentation/instrumentation.dart'; |
23 import 'package:analyzer/source/package_map_provider.dart'; | 23 import 'package:analyzer/source/package_map_provider.dart'; |
24 import 'package:analyzer/src/generated/ast.dart'; | 24 import 'package:analyzer/src/generated/ast.dart'; |
25 import 'package:analyzer/src/generated/element.dart'; | 25 import 'package:analyzer/src/generated/element.dart'; |
26 import 'package:analyzer/src/generated/engine.dart'; | 26 import 'package:analyzer/src/generated/engine.dart'; |
27 import 'package:analyzer/src/generated/java_engine.dart'; | 27 import 'package:analyzer/src/generated/java_engine.dart'; |
28 import 'package:analyzer/src/generated/sdk.dart'; | 28 import 'package:analyzer/src/generated/sdk.dart'; |
29 import 'package:analyzer/src/generated/source.dart'; | 29 import 'package:analyzer/src/generated/source.dart'; |
30 import 'package:analyzer/src/generated/source_io.dart'; | 30 import 'package:analyzer/src/generated/source_io.dart'; |
| 31 import 'package:analyzer/src/generated/utilities_general.dart'; |
31 | 32 |
32 | 33 |
33 typedef void OptionUpdater(AnalysisOptionsImpl options); | 34 typedef void OptionUpdater(AnalysisOptionsImpl options); |
34 | 35 |
35 | 36 |
36 /** | 37 /** |
37 * Enum representing reasons why analysis might be done for a given file. | 38 * Enum representing reasons why analysis might be done for a given file. |
38 */ | 39 */ |
39 class AnalysisDoneReason { | 40 class AnalysisDoneReason { |
40 /** | 41 /** |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 contextAnalysisDoneCompleters[context] = completer; | 663 contextAnalysisDoneCompleters[context] = completer; |
663 } | 664 } |
664 return completer.future; | 665 return completer.future; |
665 } | 666 } |
666 | 667 |
667 /** | 668 /** |
668 * Perform the next available [ServerOperation]. | 669 * Perform the next available [ServerOperation]. |
669 */ | 670 */ |
670 void performOperation() { | 671 void performOperation() { |
671 assert(performOperationPending); | 672 assert(performOperationPending); |
| 673 PerformanceTag.UNKNOWN.makeCurrent(); |
672 performOperationPending = false; | 674 performOperationPending = false; |
673 if (!running) { | 675 if (!running) { |
674 // An error has occurred, or the connection to the client has been | 676 // An error has occurred, or the connection to the client has been |
675 // closed, since this method was scheduled on the event queue. So | 677 // closed, since this method was scheduled on the event queue. So |
676 // don't do anything. Instead clear the operation queue. | 678 // don't do anything. Instead clear the operation queue. |
677 operationQueue.clear(); | 679 operationQueue.clear(); |
678 return; | 680 return; |
679 } | 681 } |
680 // prepare next operation | 682 // prepare next operation |
681 ServerOperation operation = operationQueue.take(); | 683 ServerOperation operation = operationQueue.take(); |
682 if (operation == null) { | 684 if (operation == null) { |
683 // This can happen if the operation queue is cleared while the operation | 685 // This can happen if the operation queue is cleared while the operation |
684 // loop is in progress. No problem; we just need to exit the operation | 686 // loop is in progress. No problem; we just need to exit the operation |
685 // loop and wait for the next operation to be added. | 687 // loop and wait for the next operation to be added. |
| 688 ServerPerformanceStatistics.idle.makeCurrent(); |
686 return; | 689 return; |
687 } | 690 } |
688 sendStatusNotification(operation); | 691 sendStatusNotification(operation); |
689 // perform the operation | 692 // perform the operation |
690 try { | 693 try { |
691 operation.perform(this); | 694 operation.perform(this); |
692 } catch (exception, stackTrace) { | 695 } catch (exception, stackTrace) { |
693 AnalysisEngine.instance.logger.logError("${exception}\n${stackTrace}"); | 696 AnalysisEngine.instance.logger.logError("${exception}\n${stackTrace}"); |
694 if (rethrowExceptions) { | 697 if (rethrowExceptions) { |
695 throw new AnalysisException( | 698 throw new AnalysisException( |
696 'Unexpected exception during analysis', | 699 'Unexpected exception during analysis', |
697 new CaughtException(exception, stackTrace)); | 700 new CaughtException(exception, stackTrace)); |
698 } | 701 } |
699 sendServerErrorNotification(exception, stackTrace, fatal: true); | 702 sendServerErrorNotification(exception, stackTrace, fatal: true); |
700 shutdown(); | 703 shutdown(); |
701 } finally { | 704 } finally { |
702 if (!operationQueue.isEmpty) { | 705 if (!operationQueue.isEmpty) { |
| 706 ServerPerformanceStatistics.intertask.makeCurrent(); |
703 _schedulePerformOperation(); | 707 _schedulePerformOperation(); |
704 } else { | 708 } else { |
705 sendStatusNotification(null); | 709 sendStatusNotification(null); |
706 if (_onAnalysisCompleteCompleter != null) { | 710 if (_onAnalysisCompleteCompleter != null) { |
707 _onAnalysisCompleteCompleter.complete(); | 711 _onAnalysisCompleteCompleter.complete(); |
708 _onAnalysisCompleteCompleter = null; | 712 _onAnalysisCompleteCompleter = null; |
709 } | 713 } |
| 714 ServerPerformanceStatistics.idle.makeCurrent(); |
710 } | 715 } |
711 } | 716 } |
712 } | 717 } |
713 | 718 |
714 /** | 719 /** |
715 * Trigger reanalysis of all files from disk. | 720 * Trigger reanalysis of all files from disk. |
716 */ | 721 */ |
717 void reanalyze() { | 722 void reanalyze() { |
718 // Clear any operations that are pending. | 723 // Clear any operations that are pending. |
719 operationQueue.clear(); | 724 operationQueue.clear(); |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 UriResolver resourceResolver = new ResourceUriResolver(resourceProvider); | 1242 UriResolver resourceResolver = new ResourceUriResolver(resourceProvider); |
1238 List<UriResolver> resolvers = packageUriResolver != null ? | 1243 List<UriResolver> resolvers = packageUriResolver != null ? |
1239 <UriResolver>[dartResolver, packageUriResolver, resourceResolver] : | 1244 <UriResolver>[dartResolver, packageUriResolver, resourceResolver] : |
1240 <UriResolver>[dartResolver, resourceResolver]; | 1245 <UriResolver>[dartResolver, resourceResolver]; |
1241 return new SourceFactory(resolvers); | 1246 return new SourceFactory(resolvers); |
1242 } | 1247 } |
1243 } | 1248 } |
1244 | 1249 |
1245 | 1250 |
1246 /** | 1251 /** |
| 1252 * Container with global [AnalysisServer] performance statistics. |
| 1253 */ |
| 1254 class ServerPerformanceStatistics { |
| 1255 /** |
| 1256 * The [PerformanceTag] for time spent in |
| 1257 * PerformAnalysisOperation._updateIndex. |
| 1258 */ |
| 1259 static PerformanceTag index = new PerformanceTag('index'); |
| 1260 |
| 1261 /** |
| 1262 * The [PerformanceTag] for time spent in |
| 1263 * PerformAnalysisOperation._sendNotices. |
| 1264 */ |
| 1265 static PerformanceTag notices = new PerformanceTag('notices'); |
| 1266 |
| 1267 /** |
| 1268 * The [PerformanceTag] for time spent performing a _DartIndexOperation. |
| 1269 */ |
| 1270 static PerformanceTag indexOperation = new PerformanceTag('indexOperation'); |
| 1271 |
| 1272 /** |
| 1273 * The [PerformanceTag] for time spent between calls to |
| 1274 * AnalysisServer.performOperation when the server is not idle. |
| 1275 */ |
| 1276 static PerformanceTag intertask = new PerformanceTag('intertask'); |
| 1277 |
| 1278 /** |
| 1279 * The [PerformanceTag] for time spent between calls to |
| 1280 * AnalysisServer.performOperation when the server is idle. |
| 1281 */ |
| 1282 static PerformanceTag idle = new PerformanceTag('idle'); |
| 1283 } |
| 1284 |
| 1285 |
| 1286 /** |
1247 * A class used by [AnalysisServer] to record performance information | 1287 * A class used by [AnalysisServer] to record performance information |
1248 * such as request latency. | 1288 * such as request latency. |
1249 */ | 1289 */ |
1250 class ServerPerformance { | 1290 class ServerPerformance { |
1251 | 1291 |
1252 /** | 1292 /** |
1253 * The creation time and the time when performance information | 1293 * The creation time and the time when performance information |
1254 * started to be recorded here. | 1294 * started to be recorded here. |
1255 */ | 1295 */ |
1256 int startTime = new DateTime.now().millisecondsSinceEpoch; | 1296 int startTime = new DateTime.now().millisecondsSinceEpoch; |
(...skipping 28 matching lines...) Expand all Loading... |
1285 new DateTime.now().millisecondsSinceEpoch - | 1325 new DateTime.now().millisecondsSinceEpoch - |
1286 request.clientRequestTime; | 1326 request.clientRequestTime; |
1287 requestLatency += latency; | 1327 requestLatency += latency; |
1288 maxLatency = max(maxLatency, latency); | 1328 maxLatency = max(maxLatency, latency); |
1289 if (latency > 150) { | 1329 if (latency > 150) { |
1290 ++slowRequestCount; | 1330 ++slowRequestCount; |
1291 } | 1331 } |
1292 } | 1332 } |
1293 } | 1333 } |
1294 } | 1334 } |
OLD | NEW |