Never resolve the target platform from PDELabelProvider - #2417
Draft
vogella wants to merge 1 commit into
Draft
Conversation
Opening the Dependencies page of a manifest editor could block the UI
thread for over a minute. The call chain is:
RequiresSection.initialize()
TableViewer.setInput()
PDELabelProvider.getImage(ImportObject)
ImportObject.isResolved() / getPlugin()
PluginRegistry.findModel(id, range)
PluginModelManager.findEntry()
getEntryTable()
initializeTable()
getExternalBundles()
TargetPlatformHelper.getWorkspaceTargetResolved()
The last step resolves the whole target platform. With an m2e Maven
location it runs a full MavenExecutionContext and bnd-wraps every
transitive artifact, while the UI thread holds both the entry table
monitor and the Maven location monitor, so every background job that
needs a model queues up behind it.
getEntryTable() is reached from findEntry, findModel, getActiveModels,
getAllModels, getState, getSystemBundleId and isEmpty, so the label
provider had several ways in, not just the one in the stack:
getObjectImage(ImportObject) isResolved(), getPlugin()
getObjectImage(PackageObject) ImportPackageObject.isResolved()
getObjectImage(IProductPlugin) TargetPlatformHelper.getState()
getObjectImage(IFeatureImport) FeatureImport.getPlugin()
getObjectImage(IFeaturePlugin) FeaturePlugin.getPluginBase()
getObjectText(IPluginBase) getSystemBundleInfo()
getObjectText(ImportObject) getSystemBundleInfo()
getObjectText(IPluginImport) findModel(), full name mode only
getObjectText(BundleDescription) findModel(), full name mode only
getObjectText(FeaturePlugin) getLabel(), full name mode only
getObjectText(ISiteBundle) findModel()
All of them are now guarded by arePluginModelsAvailable(), which builds
on the existing PluginModelManager.isInitialized() fast path. While the
models are unknown the plain, undecorated label is returned and
initialization is scheduled through the new
PluginModelManager.initializeInBackground(Runnable). Once it completes
the label provider fires a LabelProviderChangedEvent, so every viewer
sharing it repaints with the resolved state. Unresolved imports still
get the error overlay as soon as the models are there.
getSystemBundleInfo() also stopped assuming that system.bundle resolves;
it returned the plug-in base of a possibly null model.
initializeInBackground() is new but PluginModelManager lives in
org.eclipse.pde.internal.core, so this is not published API. Firing a
PluginModelDelta after initialization was rejected on purpose: it would
make PDERegistryStrategy create the extension registry, FeatureRebuilder
touch all feature projects and PluginsView add every entry one by one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opening the Dependencies page of a manifest editor could freeze the UI thread for over a minute.
RequiresSection.initialize()sets the viewer input, and every row asksPDELabelProviderfor a decoration, which callsPluginReference.isResolved()and ends up resolving the entire target platform.With an m2e Maven location that means a full
MavenExecutionContextplus a bnd wrap of every transitive artifact, all onmain, which holds both thePluginModelManagerentry table monitor and theMavenTargetLocationmonitor while doing it, so background jobs queue up behind the frozen editor.The label provider now checks the existing
PluginModelManager.isInitialized()before any registry lookup.While the models are unknown it returns the plain, undecorated label and schedules initialization through the new
PluginModelManager.initializeInBackground(Runnable); when that finishes it fires aLabelProviderChangedEvent, so every viewer sharing the provider repaints with the resolved state and unresolved imports get their error overlay as before.The editor opens immediately instead of blocking, and the same guard covers the ten other paths through
PDELabelProviderthat could reach the entry table, not just the one in the trace below.Manual check: fresh workspace, a target with an m2e Maven location using
dependencyDepth="infinite"and a cold~/.m2. The manifest editor opens right away with undecorated icons, and the decorations fill in once resolution finishes in the background.