Chromium Code Reviews| Index: pkg/analysis_server/lib/src/analysis_server.dart |
| diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart |
| index af8c32eb0f8222ccb7850c817e7e32e3c3322286..479ce801048c8cde1086d7b6d7be612cbffc1028 100644 |
| --- a/pkg/analysis_server/lib/src/analysis_server.dart |
| +++ b/pkg/analysis_server/lib/src/analysis_server.dart |
| @@ -12,6 +12,7 @@ import 'package:analysis_server/src/protocol.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/error.dart'; |
| import 'package:analyzer/src/generated/java_core.dart'; |
| +import 'package:analyzer/src/generated/source.dart'; |
| /** |
| * Instances of the class [AnalysisServer] implement a server that listens on a |
| @@ -44,6 +45,11 @@ class AnalysisServer { |
| static const String CONNECTED_NOTIFICATION = 'server.connected'; |
| /** |
| + * The event name of the status notification. |
| + */ |
| + static const String STATUS_NOTIFICATION = 'server.status'; |
| + |
| + /** |
| * The channel from which requests are received and to which responses should |
| * be sent. |
| */ |
| @@ -83,6 +89,11 @@ class AnalysisServer { |
| final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>(); |
| /** |
| + * The time at which a status message was sent to the client. |
| + */ |
| + final Stopwatch statusStopwatch = new Stopwatch(); |
| + |
| + /** |
| * Initialize a newly created server to receive requests from and send |
| * responses to the given [channel]. |
| */ |
| @@ -168,10 +179,11 @@ class AnalysisServer { |
| // |
| List<ChangeNotice> notices = null; |
| String contextId; |
| + AnalysisResult result; |
| try { |
| AnalysisContext context = contextWorkQueue[0]; |
| contextId = contextIdMap[context]; |
| - AnalysisResult result = context.performAnalysisTask(); |
| + result = context.performAnalysisTask(); |
| notices = result.changeNotices; |
| } finally { |
| if (notices == null) { |
| @@ -189,6 +201,7 @@ class AnalysisServer { |
| _scheduleTask(); |
| } |
| } |
| + sendStatusNotification(result); |
| if (notices != null) { |
| sendNotices(contextId, notices); |
| } |
| @@ -209,6 +222,44 @@ class AnalysisServer { |
| } |
| } |
| + /** |
| + * Send status notification to the client. |
| + */ |
| + void sendStatusNotification(AnalysisResult result) { |
| + Notification notification = new Notification(STATUS_NOTIFICATION); |
| + if (result.changeNotices != null) { |
| + // Throttle status messages to at most 1 every half second |
| + if (!statusStopwatch.isRunning) { |
| + statusStopwatch.start(); |
| + } else if (statusStopwatch.elapsedMilliseconds > 500) { |
| + statusStopwatch.reset(); |
| + } else { |
| + return; |
|
Paul Berry
2014/05/23 15:56:45
This technique for throttling status notifications
|
| + } |
| + String shortMessage = 'Analyzing'; |
| + String longMessage = 'Analyzing'; |
| + if (result.changeNotices.length > 0) { |
| + ChangeNotice notice = result.changeNotices[0]; |
| + if (notice != null) { |
| + shortMessage = 'Analyzing ${notice.source.shortName}'; |
|
Paul Berry
2014/05/23 15:56:45
Similar concern here. As you've arranged things,
|
| + longMessage = 'Analyzing ${notice.source.fullName}'; |
| + } |
| + } |
| + // TODO(danrubel): improve message once AnalysisResult can provide |
| + // something more human readable |
| + notification.params['shortMessage'] = shortMessage; |
| + notification.params['longMessage'] = longMessage; |
| + notification.params['isAnalyzing'] = true; |
| + } else { |
| + // Reset to ensure notification when analysis starts again |
| + statusStopwatch..stop()..reset(); |
| + notification.params['shortMessage'] = 'Analysis complete'; |
| + notification.params['longMessage'] = 'Analysis complete'; |
| + notification.params['isAnalyzing'] = false; |
| + } |
| + channel.sendNotification(notification); |
| + } |
| + |
| static Map<String, Object> errorToJson(AnalysisError analysisError) { |
| // TODO(paulberry): move this function into the AnalysisError class. |