@@ -22,12 +22,12 @@ import 'package:language_server_protocol/protocol_custom_generated.dart';
2222/// Represents a message from DTD (Dart Tooling Daemon).
2323final class DtdMessage extends MessageObject {
2424 final lsp.IncomingMessage message;
25- final Completer <Map <String , Object ?>> completer ;
25+ final Completer <Map <String , Object ?>> responseCompleter ;
2626 final OperationPerformanceImpl performance;
2727
2828 DtdMessage ({
2929 required this .message,
30- required this .completer ,
30+ required this .responseCompleter ,
3131 required this .performance,
3232 });
3333
@@ -67,7 +67,11 @@ final class LspMessage extends MessageObject {
6767 }
6868}
6969
70- /// Represents a message from a client, can be an IDE, DTD etc.
70+ /// A message from a client.
71+ ///
72+ /// The message can be either a request, a notification, or a response.
73+ ///
74+ /// The client can be an IDE, a command-line tool, or DTD.
7175sealed class MessageObject {}
7276
7377/// The [MessageScheduler] receives messages from all clients of the
@@ -81,8 +85,8 @@ final class MessageScheduler {
8185 /// The [AnalysisServer] associated with the scheduler.
8286 late final AnalysisServer server;
8387
84- /// A queue of incoming messages from all the clients of the [AnalysisServer] .
85- final ListQueue <MessageObject > _incomingMessages = ListQueue <MessageObject >();
88+ /// The messages that have been received and are waiting to be handled .
89+ final ListQueue <MessageObject > _pendingMessages = ListQueue <MessageObject >();
8690
8791 /// Whether the [MessageScheduler] is idle or is processing messages.
8892 bool isActive = false ;
@@ -156,7 +160,9 @@ final class MessageScheduler {
156160 }
157161 if (message is LspMessage ) {
158162 var msg = message.message;
159- // Responses do not go on the queue.
163+ // Responses do not go on the queue because there might be an active
164+ // message that can't complete until the response is received. If the
165+ // response was added to the queue then this process could deadlock.
160166 if (msg is lsp.ResponseMessage ) {
161167 (server as LspAnalysisServer ).handleMessage (msg, null );
162168 return ;
@@ -191,7 +197,7 @@ final class MessageScheduler {
191197 return ;
192198 }
193199 }
194- var lspRequests = _incomingMessages .whereType <LspMessage >().where (
200+ var lspRequests = _pendingMessages .whereType <LspMessage >().where (
195201 (m) => m.isRequest,
196202 );
197203 if (lspRequests.isNotEmpty) {
@@ -229,7 +235,7 @@ final class MessageScheduler {
229235 }
230236 }
231237 // Cancel any other similar requests that are in the queue.
232- var lspRequests = _incomingMessages .whereType <LspMessage >().where (
238+ var lspRequests = _pendingMessages .whereType <LspMessage >().where (
233239 (m) => m.isRequest,
234240 );
235241 for (var queueMsg in lspRequests) {
@@ -243,10 +249,10 @@ final class MessageScheduler {
243249 }
244250 }
245251 }
246- _incomingMessages .addLast (message);
252+ _pendingMessages .addLast (message);
247253 if (_currentMessage == null ) {
248254 testView? .messageLog.add ('Entering process messages loop' );
249- _currentMessage = _incomingMessages .removeFirst ();
255+ _currentMessage = _pendingMessages .removeFirst ();
250256 processMessages ();
251257 }
252258 }
@@ -277,32 +283,34 @@ final class MessageScheduler {
277283 server.dtd! .processMessage (
278284 message.message,
279285 message.performance,
280- message.completer ,
286+ message.responseCompleter ,
281287 completer,
282288 );
283289 }
284290
285- // Blocking here with an await on the future was intended to prevent unwanted
286- // interleaving but was found to cause a significant performance regression.
287- // For more context see: https://github.com/dart-lang/sdk/issues/60440.
288- // To re-disable interleaving, set [allowOverlappingHandlers] to `false`.
291+ // Blocking here with an await on the future was intended to prevent
292+ // unwanted interleaving but was found to cause a significant
293+ // performance regression. For more context see:
294+ // https://github.com/dart-lang/sdk/issues/60440. To re-disable
295+ // interleaving, set [allowOverlappingHandlers] to `false`.
289296 if (! allowOverlappingHandlers) {
290297 await completer.future;
291298 }
292299
293- // NOTE that this message is not accurate if [allowOverlappingHandlers] is `true`
294- // as in that case we're not blocking anymore and the future may not be complete.
295- // TODO(pq): if not awaited, consider adding a `then` so we can track when the future completes
296- // but note that we may see some flakiness in tests as message handling gets
297- // non-deterministically interleaved.
300+ // This message is not accurate if [allowOverlappingHandlers] is `true`
301+ // because in that case we're not blocking anymore and the future might
302+ // not be complete.
303+ // TODO(pq): if not awaited, consider adding a `then` so we can track
304+ // when the future completes. But note that we may see some flakiness in
305+ // tests as message handling gets non-deterministically interleaved.
298306 testView? .messageLog.add (
299307 ' Complete ${message .runtimeType }: ${message .toString ()}' ,
300308 );
301- if (_incomingMessages .isEmpty) {
309+ if (_pendingMessages .isEmpty) {
302310 _currentMessage = null ;
303311 testView? .messageLog.add ('Exit process messages loop' );
304312 } else {
305- _currentMessage = _incomingMessages .removeFirst ();
313+ _currentMessage = _pendingMessages .removeFirst ();
306314 }
307315 }
308316 } catch (error, stackTrace) {
@@ -458,7 +466,7 @@ final class MessageScheduler {
458466 }
459467 }
460468 // Cancel any other refactor requests that are in the queue.
461- var lspRequests = _incomingMessages .whereType <LspMessage >().where (
469+ var lspRequests = _pendingMessages .whereType <LspMessage >().where (
462470 (m) =>
463471 m.isRequest &&
464472 (m.message as lsp.RequestMessage ).method ==
@@ -467,7 +475,7 @@ final class MessageScheduler {
467475 for (var queueMsg in lspRequests) {
468476 checkAndCancelRefactor (queueMsg);
469477 }
470- var renameRequests = _incomingMessages .whereType <LspMessage >().where (
478+ var renameRequests = _pendingMessages .whereType <LspMessage >().where (
471479 (m) =>
472480 m.isRequest &&
473481 (m.message as lsp.RequestMessage ).method ==
0 commit comments