Some tweaks to MessageScheduler page.
Show active and completed messages in tabular form.
Change-Id: I9cfb98d4dfa9b90ac76e1579f50e7f04554847c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/459385
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
diff --git a/pkg/analysis_server/lib/src/scheduler/message_scheduler.dart b/pkg/analysis_server/lib/src/scheduler/message_scheduler.dart
index f019fd8..d3cac44 100644
--- a/pkg/analysis_server/lib/src/scheduler/message_scheduler.dart
+++ b/pkg/analysis_server/lib/src/scheduler/message_scheduler.dart
@@ -130,6 +130,7 @@
         // response was added to the queue then this process could deadlock.
         listener?.addActiveMessage(message);
         (server as LspAnalysisServer).handleMessage(msg, null);
+        listener?.messageCompleted(message);
         return;
       } else if (msg is lsp.NotificationMessage) {
         var method = msg.method;
@@ -142,6 +143,7 @@
           // aren't provided because the request was cancelled.
           listener?.addActiveMessage(message);
           _processCancellation(msg);
+          listener?.messageCompleted(message);
           return;
         } else if (method == lsp.Method.textDocument_didChange) {
           // Document change notifications are _not_ handled immediately, but
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index b0d05a2..a26102c 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -177,7 +177,7 @@
     <div class="container">
       <span class="masthead-logo">
       <span class="mega-octicon octicon-dashboard"></span>
-        ${site.title} Diagnostics
+        ${site.title} Insights
       </span>
 
       <nav class="masthead-nav">
diff --git a/pkg/analysis_server/lib/src/status/pages/message_scheduler_page.dart b/pkg/analysis_server/lib/src/status/pages/message_scheduler_page.dart
index f7588a1..3fd0e05 100644
--- a/pkg/analysis_server/lib/src/status/pages/message_scheduler_page.dart
+++ b/pkg/analysis_server/lib/src/status/pages/message_scheduler_page.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 
 import 'package:analysis_server/src/scheduler/message_scheduler.dart';
 import 'package:analysis_server/src/scheduler/scheduler_tracking_listener.dart';
@@ -35,17 +36,20 @@
       return;
     }
 
-    void writeData(MessageData data, {required bool isActive}) {
-      p(data.message.id);
-      buf.write('<blockquote>');
-      p('Pending messages ahead of this: ${data.pendingMessageCount}');
+    void writeRow(MessageData data, {required bool isActive}) {
       var pendingDuration = (data.activeTime ?? now) - data.pendingTime;
-      p('Time spent on pending queue: $pendingDuration');
+      buf.writeln('<tr>');
+      buf.writeln('<td>${data.message.id}</td>');
+      buf.writeln('<td>${data.pendingMessageCount}</td>');
+      buf.writeln('<td>$pendingDuration</td>');
       if (isActive) {
-        p('Active messages ahead of this: ${data.activeMessageCount}');
-        p('Time spent running: ${now - data.activeTime!}');
+        buf.writeln('<td>${data.activeMessageCount}</td>');
+        buf.writeln('<td>${now - data.activeTime!}</td>');
+      } else {
+        buf.writeln('<td>-</td>');
+        buf.writeln('<td>-</td>');
       }
-      buf.write('</blockquote>');
+      buf.writeln('</tr>');
     }
 
     var (:pending, :active) = listener.pendingAndActiveMessages;
@@ -57,9 +61,14 @@
       pending.sort(
         (first, second) => first.pendingTime.compareTo(second.pendingTime),
       );
+      buf.writeln('<table>');
+      buf.writeln(
+        '<tr><th>Message ID</th><th>Pending Ahead</th><th>Time in Pending</th><th>Active Ahead</th><th>Time Running</th></tr>',
+      );
       for (var data in pending) {
-        writeData(data, isActive: false);
+        writeRow(data, isActive: false);
       }
+      buf.writeln('</table>');
     }
 
     h3('Active messages');
@@ -69,15 +78,35 @@
       active.sort(
         (first, second) => first.activeTime!.compareTo(second.activeTime!),
       );
+      buf.writeln('<table>');
+      buf.writeln(
+        '<tr><th>Message ID</th><th>Pending Ahead</th><th>Time in Pending</th><th>Active Ahead</th><th>Time Running</th></tr>',
+      );
       for (var data in active) {
-        writeData(data, isActive: true);
+        writeRow(data, isActive: true);
       }
+      buf.writeln('</table>');
     }
 
     var lines = listener.completedMessageLog;
     if (lines.isNotEmpty) {
       h3('Completed messages');
-      p(lines.join('\n'), style: 'white-space: pre');
+      buf.writeln('<table>');
+      buf.writeln(
+        '<tr><th>Message</th><th>Pending Count</th><th>Active Count</th><th>Pending Duration</th><th>Active Duration</th><th>Cancelled</th></tr>',
+      );
+      for (var line in lines) {
+        var data = jsonDecode(line) as Map<String, dynamic>;
+        buf.writeln('<tr>');
+        buf.writeln('<td>${data['message']}</td>');
+        buf.writeln('<td>${data['pendingMessageCount']}</td>');
+        buf.writeln('<td>${data['activeMessageCount']}</td>');
+        buf.writeln('<td>${data['pendingDuration']}</td>');
+        buf.writeln('<td>${data['activeDuration']}</td>');
+        buf.writeln('<td>${data['wasCancelled']}</td>');
+        buf.writeln('</tr>');
+      }
+      buf.writeln('</table>');
     }
   }
 }