From 3d44cb65137d3a52cc15a435bf718bbe29c29d08 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 21 Aug 2019 15:55:06 +0200 Subject: [PATCH] [platform] scheduling initial VFS refresh once from a b/g thread (IDEA-218043) GitOrigin-RevId: ba960134e3138d8686ecabbbd971edc0531d20a2 --- .../util/indexing/UnindexedFilesUpdater.java | 50 +++++++++------ .../ide/startup/impl/StartupManagerImpl.java | 64 ------------------- .../project/impl/ProjectManagerImpl.java | 6 -- 3 files changed, 30 insertions(+), 90 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java index 5713f3d327d7..93fb16d72da9 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java @@ -1,24 +1,10 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.indexing; import com.intellij.ProjectTopics; import com.intellij.diagnostic.PerformanceWatcher; import com.intellij.ide.IdeBundle; -import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; @@ -27,12 +13,16 @@ import com.intellij.openapi.project.CacheUpdateRunner; import com.intellij.openapi.project.DumbModeTask; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.impl.ProjectLifecycleListener; import com.intellij.openapi.roots.CollectingContentIterator; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater; -import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.newvfs.RefreshQueue; +import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -45,12 +35,10 @@ public class UnindexedFilesUpdater extends DumbModeTask { private final FileBasedIndexImpl myIndex = (FileBasedIndexImpl)FileBasedIndex.getInstance(); private final Project myProject; - private final StartupManager myStartupManager; private final PushedFilePropertiesUpdater myPusher; public UnindexedFilesUpdater(final Project project) { myProject = project; - myStartupManager = StartupManager.getInstance(myProject); myPusher = PushedFilePropertiesUpdater.getInstance(myProject); project.getMessageBus().connect(this).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() { @Override @@ -84,7 +72,7 @@ public class UnindexedFilesUpdater extends DumbModeTask { if (!ApplicationManager.getApplication().isUnitTestMode()) { // full VFS refresh makes sense only after it's loaded, i.e. after scanning files to index is finished - ((StartupManagerImpl)myStartupManager).scheduleInitialVfsRefresh(); + scheduleInitialVfsRefresh(); } if (files.isEmpty()) { @@ -103,6 +91,28 @@ public class UnindexedFilesUpdater extends DumbModeTask { if (trackResponsiveness) snapshot.logResponsivenessSinceCreation("Unindexed files update"); } + private void scheduleInitialVfsRefresh() { + ProjectRootManagerEx.getInstanceEx(myProject).markRootsForRefresh(); + + Application app = ApplicationManager.getApplication(); + if (!app.isCommandLine()) { + long sessionId = VirtualFileManager.getInstance().asyncRefresh(null); + MessageBusConnection connection = app.getMessageBus().connect(); + connection.subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener() { + @Override + public void afterProjectClosed(@NotNull Project project) { + if (project == myProject) { + RefreshQueue.getInstance().cancelSession(sessionId); + connection.disconnect(); + } + } + }); + } + else { + VirtualFileManager.getInstance().syncRefresh(); + } + } + private void indexFiles(ProgressIndicator indicator, List files) { CacheUpdateRunner.processFiles(indicator, files, myProject, content -> myIndex.indexFileContent(myProject, content)); } diff --git a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java index cfcae33dbe93..c7408c53d4d7 100644 --- a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java @@ -26,22 +26,17 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.BackgroundTaskUtil; -import com.intellij.openapi.project.DumbModeTask; import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.DumbServiceImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.impl.ProjectLifecycleListener; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.impl.local.FileWatcher; import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; -import com.intellij.openapi.vfs.newvfs.RefreshQueue; import com.intellij.project.ProjectKt; import com.intellij.ui.GuiUtils; import com.intellij.util.PathUtil; @@ -49,7 +44,6 @@ import com.intellij.util.SmartList; import com.intellij.util.TimeoutUtil; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.io.storage.HeavyProcessLatch; -import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; @@ -79,7 +73,6 @@ public class StartupManagerImpl extends StartupManagerEx implements Disposable { private volatile boolean myStartupActivitiesPassed; private final Project myProject; - private boolean myInitialRefreshScheduled; private ScheduledFuture myBackgroundPostStartupScheduledFuture; public StartupManagerImpl(@NotNull Project project) { @@ -316,33 +309,6 @@ public class StartupManagerImpl extends StartupManagerEx implements Disposable { } } - public void scheduleInitialVfsRefresh() { - GuiUtils.invokeLaterIfNeeded(() -> { - if (myProject.isDisposed() || myInitialRefreshScheduled) return; - - myInitialRefreshScheduled = true; - ProjectRootManagerEx.getInstanceEx(myProject).markRootsForRefresh(); - - Application app = ApplicationManager.getApplication(); - if (!app.isCommandLine()) { - long sessionId = VirtualFileManager.getInstance().asyncRefresh(null); - MessageBusConnection connection = app.getMessageBus().connect(); - connection.subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener() { - @Override - public void afterProjectClosed(@NotNull Project project) { - if (project == myProject) { - RefreshQueue.getInstance().cancelSession(sessionId); - connection.disconnect(); - } - } - }); - } - else { - VirtualFileManager.getInstance().syncRefresh(); - } - }, ModalityState.defaultModalityState()); - } - private void checkFsSanity() { try { String path = myProject.getProjectFilePath(); @@ -418,36 +384,6 @@ public class StartupManagerImpl extends StartupManagerEx implements Disposable { }); } - public void startCacheUpdate() { - if (myProject.isDisposed()) return; - - try { - DumbServiceImpl dumbService = DumbServiceImpl.getInstance(myProject); - - if (!ApplicationManager.getApplication().isUnitTestMode()) { - // pre-startup activities have registered dumb tasks that load VFS (scanning files to index) - // only after these tasks pass does VFS refresh make sense - dumbService.queueTask(new DumbModeTask() { - @Override - public void performInDumbMode(@NotNull ProgressIndicator indicator) { - scheduleInitialVfsRefresh(); - } - - @Override - public String toString() { - return "initial refresh"; - } - }); - } - } - catch (ProcessCanceledException e) { - throw e; - } - catch (Throwable e) { - LOG.error(e); - } - } - private void runActivities(@NotNull Deque activities, @NotNull String phaseName) { Activity activity = StartUpMeasurer.start(phaseName); Runnable runnable; diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index 2d41cf73ec9b..d711fcd7fe1a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -420,12 +420,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(project); startupManager.runStartupActivities(); - - // Startup activities (e.g. the one in FileBasedIndexProjectHandler) have scheduled dumb mode to begin "later" - // Now we schedule-and-wait to the same event queue to guarantee that the dumb mode really begins now: - // Post-startup activities should not ever see unindexed and at the same time non-dumb state - TransactionGuard.getInstance().submitTransactionAndWait(startupManager::startCacheUpdate); - startupManager.runPostStartupActivitiesFromExtensions(); GuiUtils.invokeLaterIfNeeded(() -> {