Skip to content

Commit 487df12

Browse files
srawlinsCommit Queue
authored and
Commit Queue
committed
[beta] Remove delay in removing file overlays.
Issue 50960. Revert delaying removing file overlays. This reverts 6de7ea7 This hurts our external users, and I got an impression that the scenario for which we designed it initially is not the way our internal developers works now. Bug: #50960 Change-Id: I9b1ecf4860146d67963c5c99ecefc581e1526a89 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278883 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278993 Reviewed-by: Siva Annamalai <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent a6909c6 commit 487df12

File tree

4 files changed

+16
-191
lines changed

4 files changed

+16
-191
lines changed

pkg/analysis_server/lib/src/legacy_analysis_server.dart

+15-66
Original file line numberDiff line numberDiff line change
@@ -319,34 +319,6 @@ class LegacyAnalysisServer extends AnalysisServer {
319319
final StreamController _onAnalysisSetChangedController =
320320
StreamController.broadcast(sync: true);
321321

322-
/// Key: a file path for which removing of the overlay was requested.
323-
/// Value: a timer that will remove the overlay, or cancelled.
324-
///
325-
/// This helps for analysis server running remotely, with slow remote file
326-
/// systems, in the following scenario:
327-
/// 1. User edits file, IDE sends "add overlay".
328-
/// 2. User saves file, IDE saves file locally, sends "remove overlay".
329-
/// 3. The remove server reads the file on "remove overlay". But the content
330-
/// of the file on the remove machine is not the same as it is locally,
331-
/// and not what the user looks in the IDE. So, analysis results, such
332-
/// as semantic highlighting, are inconsistent with the local file content.
333-
/// 4. (after a few seconds) The file is synced to the remove machine,
334-
/// the watch event happens, server reads the file, sends analysis
335-
/// results that are consistent with the local file content.
336-
///
337-
/// We try to prevent the inconsistency between moments (3) and (4).
338-
/// It is not wrong, we are still in the eventual consistency, but we
339-
/// want to keep the inconsistency time shorter.
340-
///
341-
/// To do this we keep the last overlay content on "remove overlay",
342-
/// and wait for the next watch event in (4). But there might be race
343-
/// condition, and when it happens, we still want to get to the eventual
344-
/// consistency, so on timer we remove the overlay anyway.
345-
final Map<String, Timer> _pendingFilesToRemoveOverlay = {};
346-
347-
@visibleForTesting
348-
Duration pendingFilesRemoveOverlayDelay = const Duration(seconds: 10);
349-
350322
/// An optional manager to handle file systems which may not always be
351323
/// available.
352324
final DetachableFileSystemManager? detachableFileSystemManager;
@@ -458,11 +430,7 @@ class LegacyAnalysisServer extends AnalysisServer {
458430
cancellationTokens[id]?.cancel();
459431
}
460432

461-
Future<void> dispose() async {
462-
for (var timer in _pendingFilesToRemoveOverlay.values) {
463-
timer.cancel();
464-
}
465-
}
433+
Future<void> dispose() async {}
466434

467435
/// The socket from which requests are being read has been closed.
468436
void done() {}
@@ -747,7 +715,7 @@ class LegacyAnalysisServer extends AnalysisServer {
747715
} catch (_) {}
748716

749717
// Prepare the new contents.
750-
String newContents;
718+
String? newContents;
751719
if (change is AddContentOverlay) {
752720
newContents = change.content;
753721
} else if (change is ChangeContentOverlay) {
@@ -766,29 +734,25 @@ class LegacyAnalysisServer extends AnalysisServer {
766734
'Invalid overlay change')));
767735
}
768736
} else if (change is RemoveContentOverlay) {
769-
_pendingFilesToRemoveOverlay.remove(file)?.cancel();
770-
_pendingFilesToRemoveOverlay[file] = Timer(
771-
pendingFilesRemoveOverlayDelay,
772-
() {
773-
_pendingFilesToRemoveOverlay.remove(file);
774-
resourceProvider.removeOverlay(file);
775-
_changeFileInDrivers(file);
776-
},
777-
);
778-
return;
737+
newContents = null;
779738
} else {
780739
// Protocol parsing should have ensured that we never get here.
781740
throw AnalysisException('Illegal change type');
782741
}
783742

784-
_pendingFilesToRemoveOverlay.remove(file)?.cancel();
785-
resourceProvider.setOverlay(
786-
file,
787-
content: newContents,
788-
modificationStamp: overlayModificationStamp++,
789-
);
743+
if (newContents != null) {
744+
resourceProvider.setOverlay(
745+
file,
746+
content: newContents,
747+
modificationStamp: overlayModificationStamp++,
748+
);
749+
} else {
750+
resourceProvider.removeOverlay(file);
751+
}
790752

791-
_changeFileInDrivers(file);
753+
for (var driver in driverMap.values) {
754+
driver.changeFile(file);
755+
}
792756

793757
// If the file did not exist, and is "overlay only", it still should be
794758
// analyzed. Add it to driver to which it should have been added.
@@ -826,12 +790,6 @@ class LegacyAnalysisServer extends AnalysisServer {
826790
// });
827791
}
828792

829-
void _changeFileInDrivers(String path) {
830-
for (var driver in driverMap.values) {
831-
driver.changeFile(path);
832-
}
833-
}
834-
835793
/// Returns `true` if there is a subscription for the given [service] and
836794
/// [file].
837795
bool _hasAnalysisServiceSubscription(AnalysisService service, String file) {
@@ -911,15 +869,6 @@ class ServerContextManagerCallbacks extends ContextManagerCallbacks {
911869

912870
@override
913871
void afterWatchEvent(WatchEvent event) {
914-
var path = event.path;
915-
916-
var pendingTimer = analysisServer._pendingFilesToRemoveOverlay.remove(path);
917-
if (pendingTimer != null) {
918-
pendingTimer.cancel();
919-
resourceProvider.removeOverlay(path);
920-
analysisServer._changeFileInDrivers(path);
921-
}
922-
923872
analysisServer._onAnalysisSetChangedController.add(null);
924873
}
925874

pkg/analysis_server/test/analysis/notification_errors_test.dart

-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class NotificationErrorsTest extends PubPackageAnalysisServerTest {
4545
void setUp() {
4646
registerLintRules();
4747
super.setUp();
48-
server.pendingFilesRemoveOverlayDelay = const Duration(milliseconds: 10);
4948
pedanticFolder = MockPackages.instance.addPedantic(resourceProvider);
5049
}
5150

@@ -407,9 +406,6 @@ void f() {
407406
}).toRequest('1'),
408407
);
409408

410-
// Wait for the timer to remove the overlay to fire.
411-
await Future.delayed(server.pendingFilesRemoveOverlayDelay);
412-
413409
await waitForTasksFinished();
414410
await pumpEventQueue(times: 5000);
415411

pkg/analysis_server/test/analysis_server_base.dart

-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ class ContextResolutionTest with ResourceProviderMixin {
183183
InstrumentationService.NULL_SERVICE,
184184
);
185185

186-
server.pendingFilesRemoveOverlayDelay = const Duration(milliseconds: 10);
187186
server.pluginManager = pluginManager;
188187
server.completionState.budgetDuration = const Duration(seconds: 30);
189188
}

pkg/analysis_server/test/domain_analysis_test.dart

+1-120
Original file line numberDiff line numberDiff line change
@@ -588,16 +588,13 @@ transforms: []
588588
notAnalyzed: [testFile.path],
589589
);
590590

591-
// Ask to remove the overlay, still active, start a timer.
591+
// Remove the overlay, now the file will be read.
592592
await handleSuccessfulRequest(
593593
AnalysisUpdateContentParams({
594594
testFile.path: RemoveContentOverlay(),
595595
}).toRequest('0'),
596596
);
597597

598-
// Wait for the timer to remove the overlay to fire.
599-
await Future.delayed(server.pendingFilesRemoveOverlayDelay);
600-
601598
// The file has errors.
602599
await _waitAnalysisComplete();
603600
_assertAnalyzedFiles(
@@ -607,66 +604,6 @@ transforms: []
607604
);
608605
}
609606

610-
Future<void>
611-
test_fileSystem_changeFile_hasOverlay_removeOverlay_delayed() async {
612-
// Use long delay, so that it does not happen.
613-
server.pendingFilesRemoveOverlayDelay = const Duration(seconds: 300);
614-
615-
newFile(testFilePath, '');
616-
617-
// Add an overlay without errors.
618-
await handleSuccessfulRequest(
619-
AnalysisUpdateContentParams({
620-
testFile.path: AddContentOverlay(''),
621-
}).toRequest('0'),
622-
);
623-
624-
await setRoots(included: [workspaceRootPath], excluded: []);
625-
626-
// The test file (overlay) is analyzed, no errors.
627-
await _waitAnalysisComplete();
628-
_assertAnalyzedFiles(
629-
hasErrors: [],
630-
noErrors: [testFile.path],
631-
notAnalyzed: [],
632-
);
633-
634-
// Change the file, has errors.
635-
modifyFile(testFilePath, 'error');
636-
637-
// But the overlay is still present, so the file is not analyzed.
638-
await _waitAnalysisComplete();
639-
_assertAnalyzedFiles(
640-
hasErrors: [],
641-
notAnalyzed: [testFile.path],
642-
);
643-
644-
// Ask to remove the overlay, still active, start a timer.
645-
await handleSuccessfulRequest(
646-
AnalysisUpdateContentParams({
647-
testFile.path: RemoveContentOverlay(),
648-
}).toRequest('0'),
649-
);
650-
651-
// Long timer, so still not analyzed.
652-
await _waitAnalysisComplete();
653-
_assertAnalyzedFiles(
654-
hasErrors: [],
655-
notAnalyzed: [testFile.path],
656-
);
657-
658-
// Change the file again, has errors.
659-
newFile(testFilePath, 'error');
660-
661-
// The timer cancelled on the watch event, and the file analyzed.
662-
await _waitAnalysisComplete();
663-
_assertAnalyzedFiles(
664-
hasErrors: [testFile.path],
665-
noErrors: [],
666-
notAnalyzed: [],
667-
);
668-
}
669-
670607
Future<void> test_fileSystem_changeFile_packageConfigJsonFile() async {
671608
var aaaRootPath = '/packages/aaa';
672609
var a_path = '$aaaRootPath/lib/a.dart';
@@ -885,62 +822,6 @@ void f(A a) {}
885822
assertNoErrorsNotification(a_path);
886823
}
887824

888-
/// This test ensures that when an `addOverlay` cancels any pending
889-
/// `removeOverlay` timer, it also removes it, so that a subsequent watch
890-
/// event does not still try to process it.
891-
Future<void>
892-
test_fileSystem_removeOverlay_addOverlay_changeFile_changeOverlay() async {
893-
// Use long delay, so that it does not happen.
894-
server.pendingFilesRemoveOverlayDelay = const Duration(seconds: 300);
895-
896-
newFile(testFilePath, '');
897-
898-
// Add an overlay without errors.
899-
await handleSuccessfulRequest(
900-
AnalysisUpdateContentParams({
901-
testFile.path: AddContentOverlay(''),
902-
}).toRequest('0'),
903-
);
904-
905-
await setRoots(included: [workspaceRootPath], excluded: []);
906-
907-
// The test file (overlay) is analyzed, no errors.
908-
await _waitAnalysisComplete();
909-
_assertAnalyzedFiles(
910-
hasErrors: [],
911-
noErrors: [testFile.path],
912-
notAnalyzed: [],
913-
);
914-
915-
// Ask to remove the overlay, still active, start a timer.
916-
await handleSuccessfulRequest(
917-
AnalysisUpdateContentParams({
918-
testFile.path: RemoveContentOverlay(),
919-
}).toRequest('0'),
920-
);
921-
922-
// Re-add an overlay. Should cancel the timer and replace the overlay.
923-
await handleSuccessfulRequest(
924-
AnalysisUpdateContentParams({
925-
testFile.path: AddContentOverlay(''),
926-
}).toRequest('0'),
927-
);
928-
929-
// Change the file to trigger the watcher. Since the request above should
930-
// have cancelled (and removed) the timer, this should not do anything
931-
// (specifically, it should not remove the new overlay).
932-
modifyFile(testFilePath, 'error');
933-
934-
// The overlay should still be present, so we should be able to change it.
935-
await handleSuccessfulRequest(
936-
AnalysisUpdateContentParams({
937-
testFile.path: ChangeContentOverlay(
938-
[SourceEdit(0, 0, '//')],
939-
),
940-
}).toRequest('0'),
941-
);
942-
}
943-
944825
Future<void> test_setPriorityFiles() async {
945826
var a = getFile('$workspaceRootPath/foo/lib/a.dart');
946827
var b = getFile('$workspaceRootPath/foo/lib/b.dart');

0 commit comments

Comments
 (0)