@@ -23,15 +23,15 @@ import 'package:meta/meta.dart';
2323/// [AnalysisServer] .
2424///
2525/// Clients include IDE's (LSP and Legacy protocol), DTD, the Diagnostic server
26- /// and file wathcers . The [MessageScheduler] acts as a hub for all incoming
26+ /// and file watchers . The [MessageScheduler] acts as a hub for all incoming
2727/// messages and forwards the messages to the appropriate handlers.
2828final class MessageScheduler {
2929 /// A flag to allow disabling overlapping message handlers.
3030 static bool allowOverlappingHandlers = true ;
3131
3232 /// A view into the [MessageScheduler] used for testing.
3333 @visibleForTesting
34- MessageSchedulerTestView ? testView;
34+ MessageSchedulerListener ? testView;
3535
3636 /// The [AnalysisServer] associated with the scheduler.
3737 // TODO(brianwilkerson): Make this field private.
@@ -60,9 +60,7 @@ final class MessageScheduler {
6060 /// atomically and it was decided that it was cleaner for the scheduler to
6161 /// have the nullable reference to the server rather than the other way
6262 /// around.
63- MessageScheduler ({this .testView}) {
64- testView? .messageScheduler = this ;
65- }
63+ MessageScheduler ({this .testView});
6664
6765 /// Add the [message] to the end of the pending messages queue.
6866 ///
@@ -87,7 +85,7 @@ final class MessageScheduler {
8785 /// - The incoming [legacy.ANALYSIS_REQUEST_UPDATE_CONTENT] message cancels
8886 /// any rename files request that is in progress.
8987 void add (ScheduledMessage message) {
90- testView? .logAddMessage (message);
88+ testView? .addPendingMessage (message);
9189 if (message is LegacyMessage ) {
9290 var request = message.request;
9391 var method = request.method;
@@ -109,9 +107,7 @@ final class MessageScheduler {
109107 code: lsp.ErrorCodes .ContentModified .toJson (),
110108 reason: 'File content was modified' ,
111109 );
112- testView? .messageLog.add (
113- 'Canceled active request ${activeRequest .method }' ,
114- );
110+ testView? .cancelActiveMessage (activeMessage);
115111 }
116112 }
117113 }
@@ -157,9 +153,7 @@ final class MessageScheduler {
157153 var message = activeMessage.message as lsp.RequestMessage ;
158154 if (message.method == incomingMsgMethod) {
159155 activeMessage.cancellationToken? .cancel (reason: reason);
160- testView? .messageLog.add (
161- 'Canceled active request ${message .method }' ,
162- );
156+ testView? .cancelActiveMessage (activeMessage);
163157 }
164158 }
165159 }
@@ -168,9 +162,7 @@ final class MessageScheduler {
168162 var message = pendingMessage.message as lsp.RequestMessage ;
169163 if (message.method == msg.method) {
170164 pendingMessage.cancellationToken? .cancel (reason: reason);
171- testView? .messageLog.add (
172- 'Canceled pending request ${msg .method }' ,
173- );
165+ testView? .cancelPendingMessage (pendingMessage);
174166 }
175167 }
176168 }
@@ -186,18 +178,18 @@ final class MessageScheduler {
186178 /// Dispatch the first message in the queue to be executed.
187179 void processMessages () async {
188180 _isProcessing = true ;
189- testView? .messageLog. add ( 'Entering process messages loop' );
181+ testView? .startProcessingMessages ( );
190182 try {
191183 while (_pendingMessages.isNotEmpty) {
192184 var currentMessage = _pendingMessages.removeFirst ();
193185 _activeMessages.addLast (currentMessage);
186+ testView? .addActiveMessage (currentMessage);
194187 completer = Completer <void >();
195188 unawaited (
196189 completer.future.then ((_) {
197190 _activeMessages.remove (currentMessage);
198191 }),
199192 );
200- testView? .logHandleMessage (currentMessage);
201193 switch (currentMessage) {
202194 case LspMessage ():
203195 var lspMessage = currentMessage.message;
@@ -242,9 +234,7 @@ final class MessageScheduler {
242234 // TODO(pq): if not awaited, consider adding a `then` so we can track
243235 // when the future completes. But note that we may see some flakiness in
244236 // tests as message handling gets non-deterministically interleaved.
245- testView? .messageLog.add (
246- ' Complete ${currentMessage .runtimeType }: ${currentMessage .toString ()}' ,
247- );
237+ testView? .messageCompleted (currentMessage);
248238 }
249239 } catch (error, stackTrace) {
250240 server.instrumentationService.logException (
@@ -254,7 +244,7 @@ final class MessageScheduler {
254244 );
255245 }
256246 _isProcessing = false ;
257- testView? .messageLog. add ( 'Exit process messages loop' );
247+ testView? .endProcessingMessages ( );
258248 }
259249
260250 /// Set the [AnalysisServer] .
@@ -358,7 +348,7 @@ final class MessageScheduler {
358348 var request = activeMessage.message as lsp.RequestMessage ;
359349 if (request.id == params.id) {
360350 activeMessage.cancellationToken? .cancel ();
361- testView? .messageLog. add ( 'Canceled active request ${ request . method }' );
351+ testView? .cancelActiveMessage (activeMessage );
362352 return ;
363353 }
364354 }
@@ -368,9 +358,7 @@ final class MessageScheduler {
368358 var request = pendingMessage.message as lsp.RequestMessage ;
369359 if (request.id == params.id) {
370360 pendingMessage.cancellationToken? .cancel ();
371- testView? .messageLog.add (
372- 'Canceled pending request ${request .method }' ,
373- );
361+ testView? .cancelPendingMessage (pendingMessage);
374362 return ;
375363 }
376364 }
@@ -403,7 +391,10 @@ final class MessageScheduler {
403391 return path != null ? Uri .file (path) : null ;
404392 }
405393
406- void checkAndCancelRefactor (LspMessage lspMessage) {
394+ void checkAndCancelRefactor (
395+ LspMessage lspMessage, {
396+ required bool isActive,
397+ }) {
407398 var request = lspMessage.message as lsp.RequestMessage ;
408399 var execParams = _getCommandParams (request);
409400 if (execParams != null &&
@@ -414,14 +405,16 @@ final class MessageScheduler {
414405 lspMessage.cancellationToken? .cancel (
415406 code: lsp.ErrorCodes .ContentModified .toJson (),
416407 );
417- testView? .messageLog.add (
418- 'Canceled in progress request ${request .method }' ,
419- );
408+ if (isActive) {
409+ testView? .cancelActiveMessage (lspMessage);
410+ } else {
411+ testView? .cancelPendingMessage (lspMessage);
412+ }
420413 }
421414 }
422415 }
423416
424- void checkAndCancelRename (LspMessage lspMessage) {
417+ void checkAndCancelRename (LspMessage lspMessage, { required bool isActive} ) {
425418 var request = lspMessage.message as lsp.RequestMessage ;
426419 var renameParams = _getRenameParams (request);
427420 if (renameParams != null ) {
@@ -430,9 +423,11 @@ final class MessageScheduler {
430423 lspMessage.cancellationToken? .cancel (
431424 code: lsp.ErrorCodes .ContentModified .toJson (),
432425 );
433- testView? .messageLog.add (
434- 'Canceled in progress request ${request .method }' ,
435- );
426+ if (isActive) {
427+ testView? .cancelActiveMessage (lspMessage);
428+ } else {
429+ testView? .cancelPendingMessage (lspMessage);
430+ }
436431 }
437432 }
438433 }
@@ -441,37 +436,44 @@ final class MessageScheduler {
441436 if (activeMessage is LspMessage && activeMessage.isRequest) {
442437 var request = activeMessage.message as lsp.RequestMessage ;
443438 if (request.method == lsp.Method .workspace_executeCommand) {
444- checkAndCancelRefactor (activeMessage);
439+ checkAndCancelRefactor (activeMessage, isActive : true );
445440 } else if (request.method == lsp.Method .textDocument_rename) {
446- checkAndCancelRename (activeMessage);
441+ checkAndCancelRename (activeMessage, isActive : true );
447442 }
448443 }
449444 }
450445 for (var pendingMessage in _pendingMessages) {
451446 if (pendingMessage is LspMessage && pendingMessage.isRequest) {
452447 var request = pendingMessage.message as lsp.RequestMessage ;
453448 if (request.method == lsp.Method .workspace_executeCommand) {
454- checkAndCancelRefactor (pendingMessage);
449+ checkAndCancelRefactor (pendingMessage, isActive : false );
455450 } else if (request.method == lsp.Method .textDocument_rename) {
456- checkAndCancelRename (pendingMessage);
451+ checkAndCancelRename (pendingMessage, isActive : false );
457452 }
458453 }
459454 }
460455 }
461456}
462457
463- class MessageSchedulerTestView {
464- late final MessageScheduler messageScheduler;
458+ abstract class MessageSchedulerListener {
459+ /// Report that the [message] was added to the active message queue.
460+ void addActiveMessage (ScheduledMessage message);
465461
466- List <String > messageLog = < String > [];
462+ /// Report that the [message] was added to the pending message queue.
463+ void addPendingMessage (ScheduledMessage message);
467464
468- void logAddMessage (ScheduledMessage message) {
469- messageLog.add (
470- 'Incoming ${message is LspMessage ? message .message .runtimeType : message .runtimeType }: ${message .toString ()}' ,
471- );
472- }
465+ /// Report that an active [message] was cancelled.
466+ void cancelActiveMessage (ScheduledMessage message);
473467
474- void logHandleMessage (ScheduledMessage message) {
475- messageLog.add (' Start ${message .runtimeType }: ${message .toString ()}' );
476- }
468+ /// Report that a pending [message] was cancelled.
469+ void cancelPendingMessage (ScheduledMessage message);
470+
471+ /// Report that the loop that processes messages has stopped running.
472+ void endProcessingMessages ();
473+
474+ /// Report that the [message] has been completed.
475+ void messageCompleted (ScheduledMessage message);
476+
477+ /// Report that the loop that processes messages has started to run.
478+ void startProcessingMessages ();
477479}
0 commit comments