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

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

Issue 2957643002: Remove the unused operations queue (Closed)
Patch Set: Created 3 years, 6 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
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 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'dart:core'; 7 import 'dart:core';
8 import 'dart:io' as io; 8 import 'dart:io' as io;
9 import 'dart:math' show max; 9 import 'dart:math' show max;
10 10
11 import 'package:analysis_server/protocol/protocol.dart'; 11 import 'package:analysis_server/protocol/protocol.dart';
12 import 'package:analysis_server/protocol/protocol_generated.dart' 12 import 'package:analysis_server/protocol/protocol_generated.dart'
13 hide AnalysisOptions; 13 hide AnalysisOptions;
14 import 'package:analysis_server/src/analysis_logger.dart'; 14 import 'package:analysis_server/src/analysis_logger.dart';
15 import 'package:analysis_server/src/channel/channel.dart'; 15 import 'package:analysis_server/src/channel/channel.dart';
16 import 'package:analysis_server/src/collections.dart'; 16 import 'package:analysis_server/src/collections.dart';
17 import 'package:analysis_server/src/computer/computer_highlights.dart'; 17 import 'package:analysis_server/src/computer/computer_highlights.dart';
18 import 'package:analysis_server/src/computer/computer_highlights2.dart'; 18 import 'package:analysis_server/src/computer/computer_highlights2.dart';
19 import 'package:analysis_server/src/computer/computer_outline.dart'; 19 import 'package:analysis_server/src/computer/computer_outline.dart';
20 import 'package:analysis_server/src/computer/new_notifications.dart'; 20 import 'package:analysis_server/src/computer/new_notifications.dart';
21 import 'package:analysis_server/src/context_manager.dart'; 21 import 'package:analysis_server/src/context_manager.dart';
22 import 'package:analysis_server/src/domains/analysis/navigation.dart'; 22 import 'package:analysis_server/src/domains/analysis/navigation.dart';
23 import 'package:analysis_server/src/domains/analysis/navigation_dart.dart'; 23 import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
24 import 'package:analysis_server/src/domains/analysis/occurrences.dart'; 24 import 'package:analysis_server/src/domains/analysis/occurrences.dart';
25 import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart'; 25 import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
26 import 'package:analysis_server/src/operation/operation.dart';
27 import 'package:analysis_server/src/operation/operation_analysis.dart'; 26 import 'package:analysis_server/src/operation/operation_analysis.dart';
28 import 'package:analysis_server/src/operation/operation_queue.dart';
29 import 'package:analysis_server/src/plugin/notification_manager.dart'; 27 import 'package:analysis_server/src/plugin/notification_manager.dart';
30 import 'package:analysis_server/src/plugin/plugin_manager.dart'; 28 import 'package:analysis_server/src/plugin/plugin_manager.dart';
31 import 'package:analysis_server/src/plugin/plugin_watcher.dart'; 29 import 'package:analysis_server/src/plugin/plugin_watcher.dart';
32 import 'package:analysis_server/src/plugin/server_plugin.dart'; 30 import 'package:analysis_server/src/plugin/server_plugin.dart';
33 import 'package:analysis_server/src/protocol_server.dart' as server; 31 import 'package:analysis_server/src/protocol_server.dart' as server;
34 import 'package:analysis_server/src/server/diagnostic_server.dart'; 32 import 'package:analysis_server/src/server/diagnostic_server.dart';
35 import 'package:analysis_server/src/services/correction/namespace.dart'; 33 import 'package:analysis_server/src/services/correction/namespace.dart';
36 import 'package:analysis_server/src/services/index/index.dart'; 34 import 'package:analysis_server/src/services/index/index.dart';
37 import 'package:analysis_server/src/services/search/search_engine.dart'; 35 import 'package:analysis_server/src/services/search/search_engine.dart';
38 import 'package:analysis_server/src/services/search/search_engine_internal.dart' ; 36 import 'package:analysis_server/src/services/search/search_engine_internal.dart' ;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 * [CommunicationChannel] for analysis requests and process them. 95 * [CommunicationChannel] for analysis requests and process them.
98 */ 96 */
99 class AnalysisServer { 97 class AnalysisServer {
100 /** 98 /**
101 * The version of the analysis server. The value should be replaced 99 * The version of the analysis server. The value should be replaced
102 * automatically during the build. 100 * automatically during the build.
103 */ 101 */
104 static final String VERSION = '1.18.1'; 102 static final String VERSION = '1.18.1';
105 103
106 /** 104 /**
107 * The number of milliseconds to perform operations before inserting
108 * a 1 millisecond delay so that the VM and dart:io can deliver content
109 * to stdin. This should be removed once the underlying problem is fixed.
110 */
111 static int performOperationDelayFrequency = 25;
112
113 /**
114 * The options of this server instance. 105 * The options of this server instance.
115 */ 106 */
116 AnalysisServerOptions options; 107 AnalysisServerOptions options;
117 108
118 /** 109 /**
119 * The channel from which requests are received and to which responses should 110 * The channel from which requests are received and to which responses should
120 * be sent. 111 * be sent.
121 */ 112 */
122 final ServerCommunicationChannel channel; 113 final ServerCommunicationChannel channel;
123 114
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 * The object used to manage the SDK's known to this server. 179 * The object used to manage the SDK's known to this server.
189 */ 180 */
190 DartSdkManager sdkManager; 181 DartSdkManager sdkManager;
191 182
192 /** 183 /**
193 * The instrumentation service that is to be used by this analysis server. 184 * The instrumentation service that is to be used by this analysis server.
194 */ 185 */
195 final InstrumentationService instrumentationService; 186 final InstrumentationService instrumentationService;
196 187
197 /** 188 /**
198 * A queue of the operations to perform in this server.
199 */
200 ServerOperationQueue operationQueue;
201
202 /**
203 * True if there is a pending future which will execute [performOperation].
204 */
205 bool performOperationPending = false;
206
207 /**
208 * A set of the [ServerService]s to send notifications for. 189 * A set of the [ServerService]s to send notifications for.
209 */ 190 */
210 Set<ServerService> serverServices = new HashSet<ServerService>(); 191 Set<ServerService> serverServices = new HashSet<ServerService>();
211 192
212 /** 193 /**
213 * A set of the [GeneralAnalysisService]s to send notifications for. 194 * A set of the [GeneralAnalysisService]s to send notifications for.
214 */ 195 */
215 Set<GeneralAnalysisService> generalAnalysisServices = 196 Set<GeneralAnalysisService> generalAnalysisServices =
216 new HashSet<GeneralAnalysisService>(); 197 new HashSet<GeneralAnalysisService>();
217 198
218 /** 199 /**
219 * A table mapping [AnalysisService]s to the file paths for which these 200 * A table mapping [AnalysisService]s to the file paths for which these
220 * notifications should be sent. 201 * notifications should be sent.
221 */ 202 */
222 Map<AnalysisService, Set<String>> analysisServices = 203 Map<AnalysisService, Set<String>> analysisServices =
223 new HashMap<AnalysisService, Set<String>>(); 204 new HashMap<AnalysisService, Set<String>>();
224 205
225 /** 206 /**
226 * A table mapping [AnalysisContext]s to the completers that should be
227 * completed when analysis of this context is finished.
228 */
229 Map<AnalysisContext, Completer<AnalysisDoneReason>>
230 contextAnalysisDoneCompleters =
231 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>();
232
233 /**
234 * Performance information before initial analysis is complete. 207 * Performance information before initial analysis is complete.
235 */ 208 */
236 ServerPerformance performanceDuringStartup = new ServerPerformance(); 209 ServerPerformance performanceDuringStartup = new ServerPerformance();
237 210
238 /** 211 /**
239 * Performance information after initial analysis is complete 212 * Performance information after initial analysis is complete
240 * or `null` if the initial analysis is not yet complete 213 * or `null` if the initial analysis is not yet complete
241 */ 214 */
242 ServerPerformance performanceAfterStartup; 215 ServerPerformance performanceAfterStartup;
243 216
244 /** 217 /**
245 * A [RecentBuffer] of the most recent exceptions encountered by the analysis 218 * A [RecentBuffer] of the most recent exceptions encountered by the analysis
246 * server. 219 * server.
247 */ 220 */
248 final RecentBuffer<ServerException> exceptions = new RecentBuffer(10); 221 final RecentBuffer<ServerException> exceptions = new RecentBuffer(10);
249 222
250 /** 223 /**
251 * The class into which performance information is currently being recorded. 224 * The class into which performance information is currently being recorded.
252 * During startup, this will be the same as [performanceDuringStartup] 225 * During startup, this will be the same as [performanceDuringStartup]
253 * and after startup is complete, this switches to [performanceAfterStartup]. 226 * and after startup is complete, this switches to [performanceAfterStartup].
254 */ 227 */
255 ServerPerformance _performance; 228 ServerPerformance _performance;
256 229
257 /** 230 /**
258 * The [Completer] that completes when analysis is complete. 231 * The [Completer] that completes when analysis is complete.
259 */ 232 */
260 Completer _onAnalysisCompleteCompleter; 233 Completer _onAnalysisCompleteCompleter;
261 234
262 /** 235 /**
263 * The [Completer] that completes when the next operation is performed.
264 */
265 Completer _test_onOperationPerformedCompleter;
266
267 /**
268 * The controller that is notified when analysis is started. 236 * The controller that is notified when analysis is started.
269 */ 237 */
270 StreamController<bool> _onAnalysisStartedController; 238 StreamController<bool> _onAnalysisStartedController;
271 239
272 /** 240 /**
273 * The controller that is notified when a single file has been analyzed. 241 * The controller that is notified when a single file has been analyzed.
274 */ 242 */
275 StreamController<ChangeNotice> _onFileAnalyzedController; 243 StreamController<ChangeNotice> _onFileAnalyzedController;
276 244
277 /** 245 /**
278 * True if any exceptions thrown by analysis should be propagated up the call
279 * stack.
280 */
281 bool rethrowExceptions;
282
283 /**
284 * The next time (milliseconds since epoch) after which the analysis server
285 * should pause so that pending requests can be fetched by the system.
286 */
287 // Add 1 sec to prevent delay from impacting short running tests
288 int _nextPerformOperationDelayTime =
289 new DateTime.now().millisecondsSinceEpoch + 1000;
290
291 /**
292 * The content overlay for all analysis drivers. 246 * The content overlay for all analysis drivers.
293 */ 247 */
294 final nd.FileContentOverlay fileContentOverlay = new nd.FileContentOverlay(); 248 final nd.FileContentOverlay fileContentOverlay = new nd.FileContentOverlay();
295 249
296 /** 250 /**
297 * The current state of overlays from the client. This is used as the 251 * The current state of overlays from the client. This is used as the
298 * content cache for all contexts. 252 * content cache for all contexts.
299 */ 253 */
300 final ContentCache overlayState = new ContentCache(); 254 final ContentCache overlayState = new ContentCache();
301 255
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 this.channel, 344 this.channel,
391 this.resourceProvider, 345 this.resourceProvider,
392 PubPackageMapProvider packageMapProvider, 346 PubPackageMapProvider packageMapProvider,
393 this.index, 347 this.index,
394 this.serverPlugin, 348 this.serverPlugin,
395 this.options, 349 this.options,
396 this.sdkManager, 350 this.sdkManager,
397 this.instrumentationService, 351 this.instrumentationService,
398 {this.diagnosticServer, 352 {this.diagnosticServer,
399 ResolverProvider fileResolverProvider: null, 353 ResolverProvider fileResolverProvider: null,
400 ResolverProvider packageResolverProvider: null, 354 ResolverProvider packageResolverProvider: null})
401 this.rethrowExceptions: true})
402 : notificationManager = 355 : notificationManager =
403 new NotificationManager(channel, resourceProvider) { 356 new NotificationManager(channel, resourceProvider) {
404 _performance = performanceDuringStartup; 357 _performance = performanceDuringStartup;
405 358
406 pluginManager = new PluginManager( 359 pluginManager = new PluginManager(
407 resourceProvider, 360 resourceProvider,
408 _getByteStorePath(), 361 _getByteStorePath(),
409 sdkManager.defaultSdkDirectory, 362 sdkManager.defaultSdkDirectory,
410 notificationManager, 363 notificationManager,
411 instrumentationService); 364 instrumentationService);
412 PluginWatcher pluginWatcher = 365 PluginWatcher pluginWatcher =
413 new PluginWatcher(resourceProvider, pluginManager); 366 new PluginWatcher(resourceProvider, pluginManager);
414 367
415 defaultContextOptions.incremental = true; 368 defaultContextOptions.incremental = true;
416 defaultContextOptions.incrementalApi = 369 defaultContextOptions.incrementalApi =
417 options.enableIncrementalResolutionApi; 370 options.enableIncrementalResolutionApi;
418 defaultContextOptions.incrementalValidation = 371 defaultContextOptions.incrementalValidation =
419 options.enableIncrementalResolutionValidation; 372 options.enableIncrementalResolutionValidation;
420 defaultContextOptions.generateImplicitErrors = false; 373 defaultContextOptions.generateImplicitErrors = false;
421 operationQueue = new ServerOperationQueue();
422 374
423 { 375 {
424 String name = options.newAnalysisDriverLog; 376 String name = options.newAnalysisDriverLog;
425 StringSink sink = new NullStringSink(); 377 StringSink sink = new NullStringSink();
426 if (name != null) { 378 if (name != null) {
427 if (name == 'stdout') { 379 if (name == 'stdout') {
428 sink = io.stdout; 380 sink = io.stdout;
429 } else if (name.startsWith('file:')) { 381 } else if (name.startsWith('file:')) {
430 String path = name.substring('file:'.length); 382 String path = name.substring('file:'.length);
431 sink = new io.File(path).openWrite(mode: io.FileMode.APPEND); 383 sink = new io.File(path).openWrite(mode: io.FileMode.APPEND);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 Stream get onFileAnalyzed => _onFileAnalyzedController.stream; 488 Stream get onFileAnalyzed => _onFileAnalyzedController.stream;
537 489
538 /** 490 /**
539 * The stream that is notified when a single file has been changed. This 491 * The stream that is notified when a single file has been changed. This
540 * exists as a temporary stopgap for plugins, until the official plugin API is 492 * exists as a temporary stopgap for plugins, until the official plugin API is
541 * complete. 493 * complete.
542 */ 494 */
543 Stream get onFileChanged => _onFileChangedController.stream; 495 Stream get onFileChanged => _onFileChangedController.stream;
544 496
545 /** 497 /**
546 * The [Future] that completes when the next operation is performed.
547 */
548 Future get test_onOperationPerformed {
549 if (_test_onOperationPerformedCompleter == null) {
550 _test_onOperationPerformedCompleter = new Completer();
551 }
552 return _test_onOperationPerformedCompleter.future;
553 }
554
555 /**
556 * Return the total time the server's been alive. 498 * Return the total time the server's been alive.
557 */ 499 */
558 Duration get uptime { 500 Duration get uptime {
559 DateTime start = new DateTime.fromMillisecondsSinceEpoch( 501 DateTime start = new DateTime.fromMillisecondsSinceEpoch(
560 performanceDuringStartup.startTime); 502 performanceDuringStartup.startTime);
561 return new DateTime.now().difference(start); 503 return new DateTime.now().difference(start);
562 } 504 }
563 505
564 /** 506 /**
565 * Adds the given [ServerOperation] to the queue, but does not schedule
566 * operations execution.
567 */
568 void addOperation(ServerOperation operation) {
569 operationQueue.add(operation);
570 }
571
572 /**
573 * The socket from which requests are being read has been closed. 507 * The socket from which requests are being read has been closed.
574 */ 508 */
575 void done() { 509 void done() {
576 index?.stop(); 510 index?.stop();
577 running = false; 511 running = false;
578 } 512 }
579 513
580 /** 514 /**
581 * There was an error related to the socket from which requests are being 515 * There was an error related to the socket from which requests are being
582 * read. 516 * read.
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 */ 715 */
782 bool hasAnalysisSubscription(AnalysisService service, String file) { 716 bool hasAnalysisSubscription(AnalysisService service, String file) {
783 Set<String> files = analysisServices[service]; 717 Set<String> files = analysisServices[service];
784 return files != null && files.contains(file); 718 return files != null && files.contains(file);
785 } 719 }
786 720
787 /** 721 /**
788 * Return `true` if analysis is complete. 722 * Return `true` if analysis is complete.
789 */ 723 */
790 bool isAnalysisComplete() { 724 bool isAnalysisComplete() {
791 return operationQueue.isEmpty && !analysisDriverScheduler.isAnalyzing; 725 return !analysisDriverScheduler.isAnalyzing;
792 } 726 }
793 727
794 /** 728 /**
795 * Return `true` if the given path is a valid `FilePath`. 729 * Return `true` if the given path is a valid `FilePath`.
796 * 730 *
797 * This means that it is absolute and normalized. 731 * This means that it is absolute and normalized.
798 */ 732 */
799 bool isValidFilePath(String path) { 733 bool isValidFilePath(String path) {
800 return resourceProvider.absolutePathContext.isValid(path); 734 return resourceProvider.absolutePathContext.isValid(path);
801 } 735 }
802 736
803 /** 737 /**
804 * Perform the next available [ServerOperation].
805 */
806 void performOperation() {
807 assert(performOperationPending);
808 PerformanceTag.unknown.makeCurrent();
809 performOperationPending = false;
810 if (!running) {
811 // An error has occurred, or the connection to the client has been
812 // closed, since this method was scheduled on the event queue. So
813 // don't do anything. Instead clear the operation queue.
814 operationQueue.clear();
815 return;
816 }
817 // prepare next operation
818 ServerOperation operation = operationQueue.take();
819 if (operation == null) {
820 // This can happen if the operation queue is cleared while the operation
821 // loop is in progress. No problem; we just need to exit the operation
822 // loop and wait for the next operation to be added.
823 ServerPerformanceStatistics.idle.makeCurrent();
824 return;
825 }
826 sendStatusNotification(operation);
827 // perform the operation
828 try {
829 operation.perform(this);
830 } catch (exception, stackTrace) {
831 sendServerErrorNotification(
832 'Failed to perform operation: $operation', exception, stackTrace,
833 fatal: true);
834 if (rethrowExceptions) {
835 throw new AnalysisException('Unexpected exception during analysis',
836 new CaughtException(exception, stackTrace));
837 }
838 shutdown();
839 } finally {
840 if (_test_onOperationPerformedCompleter != null) {
841 _test_onOperationPerformedCompleter.complete(operation);
842 _test_onOperationPerformedCompleter = null;
843 }
844 if (!operationQueue.isEmpty) {
845 ServerPerformanceStatistics.intertask.makeCurrent();
846 _schedulePerformOperation();
847 } else {
848 if (generalAnalysisServices
849 .contains(GeneralAnalysisService.ANALYZED_FILES)) {
850 sendAnalysisNotificationAnalyzedFiles(this);
851 }
852 sendStatusNotification(null);
853 _scheduleAnalysisImplementedNotification();
854 if (_onAnalysisCompleteCompleter != null) {
855 _onAnalysisCompleteCompleter.complete();
856 _onAnalysisCompleteCompleter = null;
857 }
858 ServerPerformanceStatistics.idle.makeCurrent();
859 }
860 }
861 }
862
863 /**
864 * Trigger reanalysis of all files in the given list of analysis [roots], or 738 * Trigger reanalysis of all files in the given list of analysis [roots], or
865 * everything if the analysis roots is `null`. 739 * everything if the analysis roots is `null`.
866 */ 740 */
867 void reanalyze(List<Resource> roots) { 741 void reanalyze(List<Resource> roots) {
868 // Clear any operations that are pending.
869 if (roots == null) {
870 operationQueue.clear();
871 } else {
872 // TODO(brianwilkerson) All of the contexts returned by _getContexts will
873 // be null. If we are still using the operation queue, then this needs to
874 // be changed to use drivers.
875 // for (AnalysisContext context in _getContexts(roots)) {
876 // operationQueue.contextRemoved(context);
877 // }
878 }
879 // Instruct the contextDirectoryManager to rebuild all contexts from 742 // Instruct the contextDirectoryManager to rebuild all contexts from
880 // scratch. 743 // scratch.
881 contextManager.refresh(roots); 744 contextManager.refresh(roots);
882 } 745 }
883 746
884 /** 747 /**
885 * Schedule cache consistency validation in [context].
886 * The most of the validation must be done asynchronously.
887 */
888 void scheduleCacheConsistencyValidation(AnalysisContext context) {
889 if (context is InternalAnalysisContext) {
890 CacheConsistencyValidator validator = context.cacheConsistencyValidator;
891 List<Source> sources = validator.getSourcesToComputeModificationTimes();
892 // Compute modification times and notify the validator asynchronously.
893 new Future(() async {
894 try {
895 List<int> modificationTimes =
896 await resourceProvider.getModificationTimes(sources);
897 bool cacheInconsistencyFixed = validator
898 .sourceModificationTimesComputed(sources, modificationTimes);
899 if (cacheInconsistencyFixed) {
900 scheduleOperation(new PerformAnalysisOperation(context, false));
901 }
902 } catch (exception, stackTrace) {
903 sendServerErrorNotification(
904 'Failed to check cache consistency', exception, stackTrace);
905 }
906 });
907 }
908 }
909
910 /**
911 * Schedules execution of the given [ServerOperation].
912 */
913 void scheduleOperation(ServerOperation operation) {
914 addOperation(operation);
915 _schedulePerformOperation();
916 }
917
918 /**
919 * Schedules analysis of the given context.
920 */
921 void schedulePerformAnalysisOperation(AnalysisContext context) {
922 _onAnalysisStartedController.add(true);
923 scheduleOperation(new PerformAnalysisOperation(context, false));
924 }
925
926 /**
927 * This method is called when analysis of the given [AnalysisContext] is
928 * done.
929 */
930 void sendContextAnalysisDoneNotifications(
931 AnalysisContext context, AnalysisDoneReason reason) {
932 Completer<AnalysisDoneReason> completer =
933 contextAnalysisDoneCompleters.remove(context);
934 if (completer != null) {
935 completer.complete(reason);
936 }
937 }
938
939 /**
940 * Send the given [notification] to the client. 748 * Send the given [notification] to the client.
941 */ 749 */
942 void sendNotification(Notification notification) { 750 void sendNotification(Notification notification) {
943 channel.sendNotification(notification); 751 channel.sendNotification(notification);
944 } 752 }
945 753
946 /** 754 /**
947 * Send the given [response] to the client. 755 * Send the given [response] to the client.
948 */ 756 */
949 void sendResponse(Response response) { 757 void sendResponse(Response response) {
(...skipping 22 matching lines...) Expand all
972 .toNotification()); 780 .toNotification());
973 781
974 // remember the last few exceptions 782 // remember the last few exceptions
975 if (exception is CaughtException) { 783 if (exception is CaughtException) {
976 stackTrace ??= exception.stackTrace; 784 stackTrace ??= exception.stackTrace;
977 } 785 }
978 exceptions.add(new ServerException(message, exception, stackTrace, fatal)); 786 exceptions.add(new ServerException(message, exception, stackTrace, fatal));
979 } 787 }
980 788
981 /** 789 /**
982 * Send status notification to the client. The `operation` is the operation
983 * being performed or `null` if analysis is complete.
984 */
985 void sendStatusNotification(ServerOperation operation) {
986 // Only send status when subscribed.
987 if (!serverServices.contains(ServerService.STATUS)) {
988 return;
989 }
990 // Only send status when it changes
991 bool isAnalyzing = operation != null;
992 if (statusAnalyzing == isAnalyzing) {
993 return;
994 }
995 statusAnalyzing = isAnalyzing;
996 AnalysisStatus analysis = new AnalysisStatus(isAnalyzing);
997 channel.sendNotification(
998 new ServerStatusParams(analysis: analysis).toNotification());
999 }
1000
1001 /**
1002 * Send status notification to the client. The state of analysis is given by 790 * Send status notification to the client. The state of analysis is given by
1003 * the [status] information. 791 * the [status] information.
1004 */ 792 */
1005 void sendStatusNotificationNew(nd.AnalysisStatus status) { 793 void sendStatusNotificationNew(nd.AnalysisStatus status) {
1006 if (status.isAnalyzing) { 794 if (status.isAnalyzing) {
1007 _onAnalysisStartedController.add(true); 795 _onAnalysisStartedController.add(true);
1008 } 796 }
1009 if (_onAnalysisCompleteCompleter != null && !status.isAnalyzing) { 797 if (_onAnalysisCompleteCompleter != null && !status.isAnalyzing) {
1010 _onAnalysisCompleteCompleter.complete(); 798 _onAnalysisCompleteCompleter.complete();
1011 _onAnalysisCompleteCompleter = null; 799 _onAnalysisCompleteCompleter = null;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 } 912 }
1125 // Defer closing the channel and shutting down the instrumentation server so 913 // Defer closing the channel and shutting down the instrumentation server so
1126 // that the shutdown response can be sent and logged. 914 // that the shutdown response can be sent and logged.
1127 new Future(() { 915 new Future(() {
1128 instrumentationService.shutdown(); 916 instrumentationService.shutdown();
1129 channel.close(); 917 channel.close();
1130 }); 918 });
1131 } 919 }
1132 920
1133 /** 921 /**
1134 * Performs all scheduled analysis operations.
1135 */
1136 void test_performAllAnalysisOperations() {
1137 while (true) {
1138 ServerOperation operation = operationQueue.takeIf((operation) {
1139 return operation is PerformAnalysisOperation;
1140 });
1141 if (operation == null) {
1142 break;
1143 }
1144 operation.perform(this);
1145 }
1146 }
1147
1148 /**
1149 * Implementation for `analysis.updateContent`. 922 * Implementation for `analysis.updateContent`.
1150 */ 923 */
1151 void updateContent(String id, Map<String, dynamic> changes) { 924 void updateContent(String id, Map<String, dynamic> changes) {
1152 changes.forEach((file, change) { 925 changes.forEach((file, change) {
1153 // Prepare the new contents. 926 // Prepare the new contents.
1154 String oldContents = fileContentOverlay[file]; 927 String oldContents = fileContentOverlay[file];
1155 String newContents; 928 String newContents;
1156 if (change is AddContentOverlay) { 929 if (change is AddContentOverlay) {
1157 newContents = change.content; 930 newContents = change.content;
1158 } else if (change is ChangeContentOverlay) { 931 } else if (change is ChangeContentOverlay) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 } 1040 }
1268 1041
1269 _scheduleAnalysisImplementedNotification() async { 1042 _scheduleAnalysisImplementedNotification() async {
1270 Set<String> files = analysisServices[AnalysisService.IMPLEMENTED]; 1043 Set<String> files = analysisServices[AnalysisService.IMPLEMENTED];
1271 if (files != null) { 1044 if (files != null) {
1272 scheduleImplementedNotification(this, files); 1045 scheduleImplementedNotification(this, files);
1273 } 1046 }
1274 } 1047 }
1275 1048
1276 /** 1049 /**
1277 * Schedules [performOperation] execution.
1278 */
1279 void _schedulePerformOperation() {
1280 if (performOperationPending) {
1281 return;
1282 }
1283 /*
1284 * TODO (danrubel) Rip out this workaround once the underlying problem
1285 * is fixed. Currently, the VM and dart:io do not deliver content
1286 * on stdin in a timely manner if the event loop is busy.
1287 * To work around this problem, we delay for 1 millisecond
1288 * every 25 milliseconds.
1289 *
1290 * To disable this workaround and see the underlying problem,
1291 * set performOperationDelayFrequency to zero
1292 */
1293 int now = new DateTime.now().millisecondsSinceEpoch;
1294 if (now > _nextPerformOperationDelayTime &&
1295 performOperationDelayFrequency > 0) {
1296 _nextPerformOperationDelayTime = now + performOperationDelayFrequency;
1297 new Future.delayed(new Duration(milliseconds: 1), performOperation);
1298 } else {
1299 new Future(performOperation);
1300 }
1301 performOperationPending = true;
1302 }
1303
1304 /**
1305 * Listen for context events and invalidate index. 1050 * Listen for context events and invalidate index.
1306 * 1051 *
1307 * It is possible that this method will do more in the future, e.g. listening 1052 * It is possible that this method will do more in the future, e.g. listening
1308 * for summary information and linking pre-indexed packages into the index, 1053 * for summary information and linking pre-indexed packages into the index,
1309 * but for now we only invalidate project specific index information. 1054 * but for now we only invalidate project specific index information.
1310 */ 1055 */
1311 void _setupIndexInvalidation() { 1056 void _setupIndexInvalidation() {
1312 if (index == null) { 1057 if (index == null) {
1313 return; 1058 return;
1314 } 1059 }
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 /** 1512 /**
1768 * The [PerformanceTag] for time spent in server request handlers. 1513 * The [PerformanceTag] for time spent in server request handlers.
1769 */ 1514 */
1770 static PerformanceTag serverRequests = server.createChild('requests'); 1515 static PerformanceTag serverRequests = server.createChild('requests');
1771 1516
1772 /** 1517 /**
1773 * The [PerformanceTag] for time spent in split store microtasks. 1518 * The [PerformanceTag] for time spent in split store microtasks.
1774 */ 1519 */
1775 static PerformanceTag splitStore = new PerformanceTag('splitStore'); 1520 static PerformanceTag splitStore = new PerformanceTag('splitStore');
1776 } 1521 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/plugin/analysis/analysis_domain.dart ('k') | pkg/analysis_server/lib/src/domain_analysis.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698