Defer expensive project reference computation during selection changes#3871
Conversation
CloseUnrelatedProjectsAction.getSelectedResources() calls computeRelated() which triggers buildConnectedComponents() and getReferencedProjects() for every project in the workspace. This is expensive because it can trigger classpath container resolution. Previously, the inherited updateSelection() called getSelectedResources() on every selection change, causing this expensive computation to run on the UI thread during startup and navigation. This blocked the IDE. Override updateSelection() to perform only a cheap enablement check: verify the selection contains at least one open IProject. The expensive computeRelated() call is deferred to getSelectedResources(), which is only invoked when the action is actually executed via run(). This is correct because getSelectedResources() already handles the selectionDirty flag and recomputes projectsToClose lazily when needed. Fixes eclipse-platform#2636
|
I also looked for other actions but I only found BuildAction which does work only on selection projects and this is empty during startup. The CloseUnrelatedProjectsAction was different because getSelectedResources() was overridden to compute the full workspace project graph regardless of what was selected |
|
@vogella this causes the menu action to stay enabled after the first run.
Old behavior: New behavior: Is this intentional? What does the phrase
mean? Why menu item stays in an obsolete state? First RCPTT test failure is observed on platform staging on April 24th. |
|
I have a look.... |
…ed projects After PR eclipse-platform#3871, updateSelection() only checked whether the user selection contained an open project, so the action stayed enabled even when no unrelated projects were left to close. PR eclipse-platform#3871 was needed because the prior check was triggering buildConnectedComponents() on every selection change, which calls IProject#getReferencedProjects() across the workspace and can resolve classpath containers, blocking the IDE. Cache the workspace project graph and invalidate it from resourceChanged() when project open state or description changes. The expensive graph build now runs at most once per project-state change rather than once per selection event, while updateSelection() can again ask whether any open unrelated project actually exists. Selection-time work is reduced to a non-mutating scan of the cached graph. Add CloseUnrelatedProjectsActionEnablementTest covering the regression scenario reported on PR eclipse-platform#3871: A and B linked, C unrelated; after closing C, selecting B must disable the action.
…ed projects After PR eclipse-platform#3871, updateSelection() only checked whether the selection contained an open project, so the action stayed enabled even when no unrelated projects were left to close. PR eclipse-platform#3871 avoided calling buildConnectedComponents() on every selection change, since IProject#getReferencedProjects() can resolve classpath containers and block the IDE. Cache the workspace project graph and invalidate it from resourceChanged() on project open/description changes. The graph is now built at most once per project-state change rather than once per selection event, while updateSelection() can again check whether any open unrelated project exists. Add CloseUnrelatedProjectsActionEnablementTest covering the regression.
…ed projects After PR eclipse-platform#3871, updateSelection() only checked whether the selection contained an open project, so the action stayed enabled even when no unrelated projects were left to close. PR eclipse-platform#3871 avoided calling buildConnectedComponents() on every selection change, since IProject#getReferencedProjects() can resolve classpath containers and block the IDE. Cache the workspace project graph and invalidate it from resourceChanged() on project open/description changes. The graph is now built at most once per project-state change rather than once per selection event, while updateSelection() can again check whether any open unrelated project exists. Add CloseUnrelatedProjectsActionEnablementTest covering the regression.
…n changes" This reverts commit 3aaea37e05f6d0e2ff90db5b2030dca8b1a98c83 and the follow-up Javadoc fix in 3b23ac5. The override of updateSelection() introduced in #3871 left CloseUnrelatedProjectsAction enabled after the last unrelated project was closed, because the cheap enablement check no longer consulted the project graph. Restoring the previous behavior is the simplest fix while a follow-up addresses the original UI-thread cost separately. Refs #2636
CloseUnrelatedProjectsAction.getSelectedResources() calls computeRelated() which triggers buildConnectedComponents() and getReferencedProjects() for every project in the workspace. This is expensive because it can trigger classpath container resolution.
Previously, the inherited updateSelection() called getSelectedResources() on every selection change, causing this expensive computation to run on the UI thread during startup and navigation. This blocked the IDE.
Override updateSelection() to perform only a cheap enablement check: verify the selection contains at least one open IProject. The expensive computeRelated() call is deferred to getSelectedResources(), which is only invoked when the action is actually executed via run(). This is correct because getSelectedResources() already handles the selectionDirty flag and recomputes projectsToClose lazily when needed.
Fixes #2636