Bug 546187 - [Quick Access] Extensions loaded too early / PluginsNotLoadedTest.testPluginsNotLoaded() fails on all platforms
Summary: [Quick Access] Extensions loaded too early / PluginsNotLoadedTest.testPlugins...
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.12   Edit
Hardware: All All
: P3 major (vote)
Target Milestone: 4.12 M1   Edit
Assignee: Mickael Istria CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 546276
Blocks: 162006 545544
  Show dependency tree
 
Reported: 2019-04-08 05:28 EDT by Andrey Loskutov CLA
Modified: 2020-03-19 10:21 EDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Loskutov CLA 2019-04-08 05:28:53 EDT
https://download.eclipse.org/eclipse/downloads/drops4/I20190407-1800/testresults/html/org.eclipse.jdt.text.tests_ep412I-unit-cen64-gtk3-java8_linux.gtk.x86_64_8.0.html

Wrong bundles loaded: - org.eclipse.debug.ui - org.eclipse.jdt.debug - org.eclipse.jdt.debug.ui - org.eclipse.ui.console 

junit.framework.AssertionFailedError: Wrong bundles loaded:
- org.eclipse.debug.ui
- org.eclipse.jdt.debug
- org.eclipse.jdt.debug.ui
- org.eclipse.ui.console

at junit.framework.Assert.fail(Assert.java:57)
at junit.framework.Assert.assertTrue(Assert.java:22)
at junit.framework.TestCase.assertTrue(TestCase.java:192)
at org.eclipse.jdt.text.tests.PluginsNotLoadedTest.testPluginsNotLoaded(PluginsNotLoadedTest.java:284)

This is a recent regression, starts with I20190406-1800.
Comment 1 Andrey Loskutov CLA 2019-04-08 05:32:07 EDT
Caused by bug 545544. Mickael, please take a look. Sounds like we activate too much due Quick Access contribution.
Comment 2 Mickael Istria CLA 2019-04-08 05:43:07 EDT
I guess I'll just comment them out those bundles from the list of bundles that should not be loaded.
The test case is not really much testing JDT though and it's very prone to failures.
Comment 3 Dani Megert CLA 2019-04-08 05:44:45 EDT
(In reply to Andrey Loskutov from comment #1)
> Caused by bug 545544. Mickael, please take a look.
This needs to be fixed for M1 or the change must be reverted for M1.
Comment 4 Dani Megert CLA 2019-04-08 05:46:34 EDT
(In reply to Mickael Istria from comment #2)
> I guess I'll just comment them out those bundles from the list of bundles
> that should not be loaded.
> The test case is not really much testing JDT though and it's very prone to
> failures.
The test tests that no unnecessary bundles are loaded. For example, one must not load Debug when no Debug activity has been started.
Comment 5 Eclipse Genie CLA 2019-04-08 05:50:51 EDT
New Gerrit change created: https://git.eclipse.org/r/140199
Comment 6 Mickael Istria CLA 2019-04-08 05:54:58 EDT
(In reply to Dani Megert from comment #4)
> The test tests that no unnecessary bundles are loaded. For example, one must
> not load Debug when no Debug activity has been started.

Quick Access extension for Debug starts a debug activity (suggesting launch configuration) whenever Quick Access is triggered. So it seems fine to just assume those bundles can already be loaded as part of this test (similarly to how some other bundles are commented or programatically added to the list of loaded plugins.
Comment 7 Mickael Istria CLA 2019-04-08 05:57:11 EDT
(In reply to Dani Megert from comment #4)
> The test tests that no unnecessary bundles are loaded. For example, one must
> not load Debug when no Debug activity has been started.

Also, I think this is fundamentally not functional here: as the test can be part of a Suite and we don't have the guarantee its 1st one to be executed, there is no way to know what was loaded by previous actions.
Such a step should either run in a standalone manner, or start a new fresh Eclipse instance to be reliable.
Comment 8 Dani Megert CLA 2019-04-08 06:10:44 EDT
(In reply to Mickael Istria from comment #7)
> (In reply to Dani Megert from comment #4)
> > The test tests that no unnecessary bundles are loaded. For example, one must
> > not load Debug when no Debug activity has been started.
Well, assume many projects in the release train use the new extension in a similar way, we end up loading everything at start. That is a no go.


> Also, I think this is fundamentally not functional here:
It currently works in the suite used on the build machine. And yes, if you add it to some other suite that before loads tons of stuff, the test will fail.
Comment 9 Mickael Istria CLA 2019-04-08 06:18:18 EDT
Here is the stack showing how early are loaded Quick Access extensions

Thread [main] (Suspended (breakpoint at line 22 in DebugQuickAccessProvider))	
	DebugQuickAccessProvider.<init>() line: 22	
	NativeConstructorAccessorImpl.newInstance0(Constructor<?>, Object[]) line: not available [native method]	
	NativeConstructorAccessorImpl.newInstance(Object[]) line: 62	
	DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45	
	Constructor<T>.newInstance(Object...) line: 490	
	EquinoxRegistryStrategy(RegistryStrategyOSGI).createExecutableExtension(RegistryContributor, String, String) line: 206	
	ExtensionRegistry.createExecutableExtension(RegistryContributor, String, String) line: 934	
	ConfigurationElement.createExecutableExtension(String) line: 246	
	ConfigurationElementHandle.createExecutableExtension(String) line: 63	
	QuickAccessExtensionManager.lambda$1(IConfigurationElement) line: 41	
	671187578.apply(Object) line: not available	
	ReferencePipeline$3$1.accept(P_OUT) line: 195	
	ReferencePipeline$2$1.accept(P_OUT) line: 177	
	Spliterators$ArraySpliterator<T>.forEachRemaining(Consumer<? super T>) line: 948	
	ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).copyInto(Sink<P_IN>, Spliterator<P_IN>) line: 484	
	ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).wrapAndCopyInto(S, Spliterator<P_IN>) line: 474	
	ReduceOps$3(ReduceOps$ReduceOp<T,R,S>).evaluateSequential(PipelineHelper<T>, Spliterator<P_IN>) line: 913	
	ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).evaluate(TerminalOp<E_OUT,R>) line: 234	
	ReferencePipeline$3(ReferencePipeline<P_IN,P_OUT>).collect(Collector<? super P_OUT,A,R>) line: 578	
	QuickAccessExtensionManager.getProviders() line: 49	
	SearchField.createControls(Composite, MApplication, MWindow) line: 195	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
	Method.invoke(Object, Object...) line: 566	
	MethodRequestor.execute() line: 58	
	InjectorImpl.processAnnotated(Class<Annotation>, Object, Class<?>, PrimaryObjectSupplier, PrimaryObjectSupplier, ArrayList<Class<?>>) line: 1001	
	InjectorImpl.internalInject(Object, PrimaryObjectSupplier, PrimaryObjectSupplier) line: 139	
	InjectorImpl.internalMake(Class<?>, PrimaryObjectSupplier, PrimaryObjectSupplier) line: 411	
	InjectorImpl.make(Class<T>, PrimaryObjectSupplier, PrimaryObjectSupplier) line: 347	
	ContextInjectionFactory.make(Class<T>, IEclipseContext, IEclipseContext) line: 227	
	ReflectionContributionFactory.createFromBundle(Bundle, IEclipseContext, IEclipseContext, URI) line: 94	
	ReflectionContributionFactory.doCreate(String, IEclipseContext, IEclipseContext) line: 60	
	ReflectionContributionFactory.create(String, IEclipseContext, IEclipseContext) line: 37	
	ToolControlRenderer.createWidget(MUIElement, Object) line: 129	
	PartRenderingEngine.createWidget(MUIElement, Object) line: 1015	
	PartRenderingEngine.safeCreateGui(MUIElement, Object, IEclipseContext) line: 675	
	PartRenderingEngine.safeCreateGui(MUIElement) line: 781	
	PartRenderingEngine.access$0(PartRenderingEngine, MUIElement) line: 752	
	PartRenderingEngine$2.run() line: 746	
	SafeRunner.run(ISafeRunnable) line: 45	
	PartRenderingEngine.createGui(MUIElement) line: 730	
	PartRenderingEngine.subscribeChildrenHandler(Event) line: 311	
	GeneratedMethodAccessor13.invoke(Object, Object[]) line: not available	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
	Method.invoke(Object, Object...) line: 566	
	MethodRequestor.execute() line: 58	
	EventObjectSupplier$DIEventHandler.handleEvent(Event) line: 91	
	EventHandlerWrapper.handleEvent(Event, Permission) line: 205	
	EventHandlerTracker.dispatchEvent(EventHandlerWrapper, Permission, int, Event) line: 203	
	EventHandlerTracker.dispatchEvent(Object, Object, int, Object) line: 1	
	EventManager.dispatchEvent(Set<Entry<K,V>>, EventDispatcher<K,V,E>, int, E) line: 233	
	ListenerQueue<K,V,E>.dispatchEventSynchronous(int, E) line: 151	
	EventAdminImpl.dispatchEvent(Event, boolean) line: 132	
	EventAdminImpl.sendEvent(Event) line: 75	
	EventComponent.sendEvent(Event) line: 44	
	EventBroker.send(String, Object) line: 55	
	UIEventPublisher.notifyChanged(Notification) line: 63	
	TrimBarImpl(BasicNotifierImpl).eNotify(Notification) line: 424	
	ElementContainerImpl$1(EcoreEList<E>).dispatchNotification(Notification) line: 249	
	ElementContainerImpl$1(NotifyingListImpl<E>).addUnique(int, E) line: 356	
	ElementContainerImpl$1(AbstractEList<E>).add(int, E) line: 340	
	ContributionsAnalyzer.processAddition(MTrimBar, MTrimContribution, List<MTrimElement>, HashSet<String>) line: 448	
	TrimBarRenderer.addTrimContributions(MTrimBar, ArrayList<MTrimContribution>, IEclipseContext, ExpressionContext) line: 171	
	TrimBarRenderer.processContents(MElementContainer<MUIElement>) line: 143	
	PartRenderingEngine.safeCreateGui(MUIElement, Object, IEclipseContext) line: 689	
	PartRenderingEngine.safeCreateGui(MUIElement) line: 781	
	PartRenderingEngine.access$0(PartRenderingEngine, MUIElement) line: 752	
	PartRenderingEngine$2.run() line: 746	
	SafeRunner.run(ISafeRunnable) line: 45	
	PartRenderingEngine.createGui(MUIElement) line: 730	
	PartRenderingEngine.subscribeTopicToBeRendered(Event) line: 160	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
	Method.invoke(Object, Object...) line: 566	
	MethodRequestor.execute() line: 58	
	EventObjectSupplier$DIEventHandler.handleEvent(Event) line: 91	
	EventHandlerWrapper.handleEvent(Event, Permission) line: 205	
	EventHandlerTracker.dispatchEvent(EventHandlerWrapper, Permission, int, Event) line: 203	
	EventHandlerTracker.dispatchEvent(Object, Object, int, Object) line: 1	
	EventManager.dispatchEvent(Set<Entry<K,V>>, EventDispatcher<K,V,E>, int, E) line: 233	
	ListenerQueue<K,V,E>.dispatchEventSynchronous(int, E) line: 151	
	EventAdminImpl.dispatchEvent(Event, boolean) line: 132	
	EventAdminImpl.sendEvent(Event) line: 75	
	EventComponent.sendEvent(Event) line: 44	
	EventBroker.send(String, Object) line: 55	
	UIEventPublisher.notifyChanged(Notification) line: 63	
	TrimBarImpl(BasicNotifierImpl).eNotify(Notification) line: 424	
	TrimBarImpl(UIElementImpl).setToBeRendered(boolean) line: 307	
	CoolBarToTrimManager.update(boolean) line: 616	
	WorkbenchWindow.updateActionBars() line: 2508	
	WorkbenchWindow.largeUpdateEnd() line: 2561	
	Workbench.largeUpdateEnd() line: 3326	
	WorkbenchWindow.fillActionBars(int) line: 2758	
	WorkbenchWindow.setup() line: 791	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
	Method.invoke(Object, Object...) line: 566	
	MethodRequestor.execute() line: 58	
	InjectorImpl.processAnnotated(Class<Annotation>, Object, Class<?>, PrimaryObjectSupplier, PrimaryObjectSupplier, ArrayList<Class<?>>) line: 1001	
	InjectorImpl.internalInject(Object, PrimaryObjectSupplier, PrimaryObjectSupplier) line: 139	
	InjectorImpl.inject(Object, PrimaryObjectSupplier) line: 95	
	ContextInjectionFactory.inject(Object, IEclipseContext) line: 83	
	Workbench.createWorkbenchWindow(IAdaptable, IPerspectiveDescriptor, MWindow, boolean) line: 1490	
	Workbench.openWorkbenchWindow(IAdaptable, IPerspectiveDescriptor, MWindow, boolean) line: 2530	
	Workbench.getWorkbenchPage(MPart) line: 1988	
	Workbench.setReference(MPart, IEclipseContext) line: 2036	
	Workbench.lambda$11(Event) line: 1927	
	1908505175.handleEvent(Event) line: not available	
	UIEventHandler.lambda$0(Event) line: 38	
	1264191370.run() line: not available	
	UISynchronizer(Synchronizer).syncExec(Runnable) line: 236	
	UISynchronizer.syncExec(Runnable) line: 147	
	Display.syncExec(Runnable) line: 6077	
	E4Application$1.syncExec(Runnable) line: 219	
	UIEventHandler.handleEvent(Event) line: 38	
	EventHandlerWrapper.handleEvent(Event, Permission) line: 205
Comment 10 Dani Megert CLA 2019-04-08 06:29:49 EDT
It looks like it already loads the stuff even if Quick Access was not yet invoked. Is that correct?
Comment 11 Andrey Loskutov CLA 2019-04-08 06:34:42 EDT
(In reply to Dani Megert from comment #10)
> It looks like it already loads the stuff even if Quick Access was not yet
> invoked. Is that correct?

Correct. We optimized QA before not to load proposals on UI thread, but the new extension is read on UI thread on very beginning of UI startup.

So the extension approach (QuickAccessExtensionManager.getProviders()) must go to the job, otherwise we will end in deadlock situations similar to bug 535679.
Comment 12 Mickael Istria CLA 2019-04-08 06:36:31 EDT
Yes, you're correct.
Quick Access implementation is really doing a lot of things early (when showing the Text field). I'll implement a lazy delegate approach for extensions here, but I think the Quick Access lifecycle overall could be refactored to be lazier and not take time at startup. But that's beyond what I can affort to implement for M1; lazy delegates should be enough for the moment.
Comment 13 Mickael Istria CLA 2019-04-08 06:40:58 EDT
(In reply to Andrey Loskutov from comment #11)
> So the extension approach (QuickAccessExtensionManager.getProviders()) must
> go to the job, otherwise we will end in deadlock situations similar to bug
> 535679.

Extensions are not supposed to take time to load nor require UI Thread, I don't think it's worth having them in the job.
The real issue is that the Table and the "quickAccessContents" are built at startup and require providers to be ready, and will dereference them (so the host plugins would be loaded).


> lazy delegates should be enough for the moment.

Unfortunately, it's not. The loading of quickAccessContents and table invokes some methods on the provider during startup. I'll try the harder fix: delaying creation of the quickAccessContents and family to delay dereference of providers.
Comment 14 Andrey Loskutov CLA 2019-04-08 06:44:21 EDT
Mickael, I think we should revert whatever causes the current test fail, reopen bug 162006 and check how we can contribute 3rd party extensions lazily and not in UI thread.
Comment 15 Lars Vogel CLA 2019-04-08 06:46:03 EDT
Just to add this in case this is not known to everybody:

Any plug-in specifying "Bundle-ActivationPolicy: lazy" in its MANIFEST.MF will load as soon as one of its classes is touched and its activator (if it exists) will be executed. Lots of platform platforms have lot processing time for the activators (I recently posted the times to the mailing list, let me know if I need to lookup the link).

This can result in delays during startup.

This is one the reasons why we are removing this "Bundle-ActivationPolicy: lazy" setting and activators since years from platform code. If the bundle is specifying OSGi services, which setting is mandatory.
Comment 16 Andrey Loskutov CLA 2019-04-08 06:51:35 EDT
(In reply to Lars Vogel from comment #15)
> This can result in delays during startup.

Not only that. Please check bug 535679 comment 1 why we've delayed QA values fetching and moved it out of UI thread. 

Now we have more or less same issue again. Since we don't know what the 3rd party contributors for QA will do, we should be very careful to avoid loading them on the very beginning of the UI thread lifecycle.
Comment 17 Dani Megert CLA 2019-04-08 06:56:50 EDT
The new extension point must make sure that clients can add their stuff but the client plug-in is not loaded until the entry is selected by the user. Think of menu contributions. We don't load every plug-in that contributes a menu. Only when the menu item is selected it triggers the loading of the plug-in. Same must hold for Quick Access.

I think this new extension point needs more thinking and I agree with comment 14 that best is to remove it for M1 and work on it for the next milestone.

Moving the loading of the extensions when needed by the user out of the UI thread can be done but this must be done on top of not loading the bundle.
Comment 18 Mickael Istria CLA 2019-04-08 07:01:51 EDT
> Mickael, I think we should revert whatever causes the current test fail,

> I think this new extension point needs more thinking and I agree with comment 14 that best is to remove it for M1 and work on it for the next milestone.

Can we wait 4 hours? I can try to just fix Quick Access to load less stuff at startup.

> The new extension point must make sure that clients can add their stuff but the client plug-in is not loaded until the entry is selected by the user. Think of menu contributions. We don't load every plug-in that contributes a menu. Only when the menu item is selected it triggers the loading of the plug-in. Same must hold for Quick Access.

I agree and am trying to fix that.

> reopen bug 162006 and check how we can contribute 3rd party extensions
> lazily and not in UI thread.
> [...]
> Not only that. Please check bug 535679 comment 1 why we've delayed QA values fetching and moved it out of UI thread. 

UI Thread or not is not the topic of the issue about bundle activation, it's about "lazily".
Comment 19 Lars Vogel CLA 2019-04-08 07:12:48 EDT
(In reply to Mickael Istria from comment #18)
> Can we wait 4 hours? I can try to just fix Quick Access to load less stuff
> at startup.

IMHO +1
Comment 20 Eclipse Genie CLA 2019-04-08 07:27:45 EDT
New Gerrit change created: https://git.eclipse.org/r/140203
Comment 21 Mickael Istria CLA 2019-04-08 07:28:28 EDT
Suggested patch https://git.eclipse.org/r/140203 should 
1. Fix the issue by not loading extensions eagerly
2. improve a bit the startup time by loading less classes and building less objects eagerly.
Comment 22 Lars Vogel CLA 2019-04-08 07:32:10 EDT
(In reply to Mickael Istria from comment #21)
> Suggested patch https://git.eclipse.org/r/140203 should 
> 1. Fix the issue by not loading extensions eagerly
> 2. improve a bit the startup time by loading less classes and building less
> objects eagerly.

Just for clarification, could we see issues like Bug 546117 with this approach?
Comment 23 Mickael Istria CLA 2019-04-08 07:38:44 EDT
(In reply to Lars Vogel from comment #22)
> Just for clarification, could we see issues like Bug 546117 with this
> approach?

Yes, if some plugins contribute content to quick access and those plugins a slow to start, then activation will delay loading of the extension and can freeze UI in the meantime.

This patch focus on the current issue (bundle loading).
For loading extensions out of the UI Thread, I think it can be a separate enhancment request.
Comment 24 Dani Megert CLA 2019-04-08 09:04:22 EDT
(In reply to Mickael Istria from comment #18)
> UI Thread or not is not the topic of the issue about bundle activation, 
Correct. That's what I tried to say in paragraph 3 in comment 17.

> it's about "lazily".
Where "lazy" means, only load when really needed by the user.
Comment 26 Lars Vogel CLA 2019-04-08 09:11:23 EDT
(In reply to Dani Megert from comment #24)
> Where "lazy" means, only load when really needed by the user.

See https://www.osgi.org/developer/design/lazy-start/. Without it developer would need to specify the correct start-level to run the activator or trigger it via the code.

It is also required if the bundle contributes OSGi services (only in Equinox, Felix behaves differently) but that comes AFAIK without performance overhead as long as slow activators are not involved.
Comment 27 Mickael Istria CLA 2019-04-08 09:13:12 EDT
Thanks guys for pushing a step forward for a better resolution.
Loading of extension would be even better not happening in UI Thread, to avoid possible UI Freezes when a plugin activation/classloading takes too long, but it's better being tracked in a separate ticket (as it's very probably that in case such issue happen, it's more profitable to work on the contributing plugin to improve its own startup.
Comment 28 Dani Megert CLA 2019-04-08 10:12:36 EDT
Sorry, but this is not a fix. We still have the problem that as soon as the user clicks into the Quick Access field or hits Ctrl+3 even in a completely empty workspace it loads Debug++. Again, imagine other contributors to your new extension point in the release train. This will load a lot of stuff that the user might never ever need. Not just a delay when loading that stuff but also wasting memory.
==> This is a no go.

Please revert this for M1 and work on a solution similar to menu and action contributions. The current solution is simply not ready for prime time.
Comment 29 Mickael Istria CLA 2019-04-08 10:39:30 EDT
(In reply to Dani Megert from comment #28)
> Sorry, but this is not a fix. We still have the problem that as soon as the
> user clicks into the Quick Access field or hits Ctrl+3 even in a completely
> empty workspace it loads Debug++. Again, imagine other contributors to your
> new extension point in the release train. This will load a lot of stuff that
> the user might never ever need.

If the use never ever need stuff, why is it installed in their IDE then?

> Please revert this for M1 and work on a solution similar to menu and action
> contributions. The current solution is simply not ready for prime time.

Quick Access is dynamic, and dynamic menus also load the plugins that contribute them. It's already similar. If you have a technical solution about how to create dynamic content without loading a class, I'm all ears.
I agree the extension point could also allow static content that would prevent from loading a plugin (just like static menus), but the user stories I see (inspired from VSCode) make static content not so interesting as addition as they bascially force to open pop-ups in the vast majority of cases -> poor UX.

If you want to revert it, please do it, and don't expect me to work on this topic ever again; or even better, mark all related bugs as WONTFIX because the constraint you're introducing here doesn't have a technical solution possible that would still make the feature profitable.
Comment 30 Andrey Loskutov CLA 2019-04-08 10:49:41 EDT
(In reply to Dani Megert from comment #28)
> Sorry, but this is not a fix. We still have the problem that as soon as the
> user clicks into the Quick Access field or hits Ctrl+3 even in a completely
> empty workspace it loads Debug++. Again, imagine other contributors to your
> new extension point in the release train. This will load a lot of stuff that
> the user might never ever need. Not just a delay when loading that stuff but
> also wasting memory.
> ==> This is a no go.
> 
> Please revert this for M1 and work on a solution similar to menu and action
> contributions. The current solution is simply not ready for prime time.

Dani, I think it is a bit too extreme.

Current Ctrl+3 (before the patches from 4.12) could do/load a lot of bundles anyway - see bug 535679 what we had before we patched 4.8. This was a "no go", but it was like this since 4.1 and nobody complained until we hit this in our internal product tests.

I think the last patch from Mickael is good, and I would love to see that we will move the extension creation out of UI thread for 4.12 as I've requested in comment 16 - but I really don't see why we should avoid loading of other bundles via QA if we already do this in QA since years, we just should not do it in UI thread.

So for me it would be OK to have this bug fixed once comment 16 is done - we are not there yet, but I don't this we should revert everything just because of that.
Comment 31 Dani Megert CLA 2019-04-08 10:55:38 EDT
(In reply to Mickael Istria from comment #29)
> (In reply to Dani Megert from comment #28)
> > Sorry, but this is not a fix. We still have the problem that as soon as the
> > user clicks into the Quick Access field or hits Ctrl+3 even in a completely
> > empty workspace it loads Debug++. Again, imagine other contributors to your
> > new extension point in the release train. This will load a lot of stuff that
> > the user might never ever need.
> 
> If the use never ever need stuff, why is it installed in their IDE then?
He downloaded a package that best matches his needs but he does not need everything. Even if he installs everything, it must only load things when needed.


> > Please revert this for M1 and work on a solution similar to menu and action
> > contributions. The current solution is simply not ready for prime time.
> 
> If you want to revert it, please do it, and don't expect me to work on this
> topic ever again; or even better, mark all related bugs as WONTFIX because
> the constraint you're introducing here doesn't have a technical solution
> possible that would still make the feature profitable.
I leave it up to you what you do with your extension point. As for Debug I will revert the changes for bug 545544 and consider adding it back when the loading problem is solved. I don't want Debug to be loaded just because of Quick Access.
Comment 32 Lars Vogel CLA 2019-04-08 10:56:45 EDT
Tone here is is a bit harsh, so I want to add the following. This is based on my working knowledge of the Eclipse process:

The correct process step is to bring it to the project leads/PMC, if two or more committers disagrees. As you both are discussing in our role as committer, the fact that Dani is also PMC member should not play a role (in theory, of course we can consider it). In instead of a revert discussion, please bring this change to the PMC.
Comment 33 Alexander Kurtakov CLA 2019-04-08 11:02:09 EDT
(In reply to Andrey Loskutov from comment #30)
> (In reply to Dani Megert from comment #28)
> > Sorry, but this is not a fix. We still have the problem that as soon as the
> > user clicks into the Quick Access field or hits Ctrl+3 even in a completely
> > empty workspace it loads Debug++. Again, imagine other contributors to your
> > new extension point in the release train. This will load a lot of stuff that
> > the user might never ever need. Not just a delay when loading that stuff but
> > also wasting memory.
> > ==> This is a no go.
> > 
> > Please revert this for M1 and work on a solution similar to menu and action
> > contributions. The current solution is simply not ready for prime time.
> 
> Dani, I think it is a bit too extreme.
> 
> Current Ctrl+3 (before the patches from 4.12) could do/load a lot of bundles
> anyway - see bug 535679 what we had before we patched 4.8. This was a "no
> go", but it was like this since 4.1 and nobody complained until we hit this
> in our internal product tests.
> 
> I think the last patch from Mickael is good, and I would love to see that we
> will move the extension creation out of UI thread for 4.12 as I've requested
> in comment 16 - but I really don't see why we should avoid loading of other
> bundles via QA if we already do this in QA since years, we just should not
> do it in UI thread.
> 
> So for me it would be OK to have this bug fixed once comment 16 is done - we
> are not there yet, but I don't this we should revert everything just because
> of that.

Mickael, would you please open a bug about moving loading out of UI and handle it for M2? To me this seems like the agreement so far.
Comment 34 Dani Megert CLA 2019-04-08 11:02:31 EDT
(In reply to Dani Megert from comment #31)
> I leave it up to you what you do with your extension point.
Just to be clear, I am not against that extension point and I am sure we can find a solution that works. For example only load once the search string matches some keywords that can be defined in the extension point. Mickael already pointed this out in comment 12.
Comment 35 Mickael Istria CLA 2019-04-08 11:05:09 EDT
I'm sorry that my tone was harsh. Dani's comment are totally relevant and useful, and unfortunately there is no possible trade-off for this feature (dynamic vs not-loading), so it really becomes purely a matter of personal opinions on what's the priority, where we can sometimes diverge ;)
Comment 36 Dani Megert CLA 2019-04-08 11:07:45 EDT
(In reply to Mickael Istria from comment #35)
> I'm sorry that my tone was harsh. Dani's comment are totally relevant and
> useful, and unfortunately there is no possible trade-off for this feature
> (dynamic vs not-loading), so it really becomes purely a matter of personal
> opinions on what's the priority, where we can sometimes diverge ;)

Sorry too.

I really think by adding some more attributes to the extension point we can delay the point where the extension is loaded. But it needs some more work.
Comment 37 Lars Vogel CLA 2019-04-08 11:10:04 EDT
Also sorry from my side, if I was harsh.

Code changes can be very emotional, happens to everyone. The great thing IMHO is that we all love Eclipse.
Comment 38 Lars Vogel CLA 2019-04-08 11:54:41 EDT
Also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=545544#c11
Comment 39 Alexander Fedorov CLA 2019-04-09 03:49:34 EDT
The imperative nature of QA implementation makes this problem hard to resolve:

We want items to be discovered early=>
The items need to be shown=>
QuickAccessProvider needs to be created=>
A chain of unwanted activations

Probably, we can try to transfer QuickAccess to declarative space using  org.eclipse.e4.ui.workbench.model.definition.enrichment 
this can allow us to have enougn information for UI without activating target bundles.

What do you think?
Comment 40 Mickael Istria CLA 2019-04-09 04:07:20 EDT
(In reply to Alexander Fedorov from comment #39)
> Probably, we can try to transfer QuickAccess to declarative space using 
> org.eclipse.e4.ui.workbench.model.definition.enrichment 
> this can allow us to have enougn information for UI without activating
> target bundles.
> 
> What do you think?

I don't think it would change much things: Going declarative would still require some logic to "populate" the model with declarative entries dynamically, and this logic most likely needs to use some interesting APIs from other bundles to compute the elements to show, and consuming those APIs would start generate activity and load bundle.
In the case of Debug, it would still need the ILaunchManager and DebugPluginImages classes to create the right entries in the model, thus loading the same bundles as current approach.

For "static" cases (no API needed, we just want to add 1 element), then we already have this covered in Quick Access through Commands, since defining a command will automatically make it available in Quick Acces.

The issue of loading extensions is inherent to how Quick Access work. For best UX, we want it to be a "flat" search engine. By flat I mean that we want all possible entries to be searchable without user making preliminary actions to narrow down the scope of the search. It's exactly the same case as searching all menus (including dynamic ones) at once, or searching the whole Project Explorer: it would expand all the possibilities and invoke all content providers, loading them.
I am really convinced that there is no possible technical solution to the combination of requirements "not instantiating dynamic providers" + "directly search all possible content from all providers", in the Quick Access or any other widget/workflow.
It's more a dilemna than a piece of code to write.
Comment 41 Dani Megert CLA 2019-04-09 04:16:46 EDT
How about a completely different approach? Interested parties can register their items when the items are known, e.g. Debug would register the recently used launch configs. Quick Access can save its state on exit and read it on start. That way, the launch config items can be found but only when the user selects the item it will load Debug. Just an idea.
Comment 42 Alexander Fedorov CLA 2019-04-09 04:25:25 EDT
(In reply to Dani Megert from comment #41)
> How about a completely different approach? Interested parties can register
> their items when the items are known, e.g. Debug would register the recently
> used launch configs. Quick Access can save its state on exit and read it on
> start. That way, the launch config items can be found but only when the user
> selects the item it will load Debug. Just an idea.

This is good, and may cover "my favorites" sceanario.

But the "discovery" scenario remains unresolved: we need to propose some "solution" from "not visited yet" functionality area by user "keyword".
Because initially user has "no idea how it is named here" problem.
Comment 43 Alexander Fedorov CLA 2019-04-09 04:34:44 EDT
(In reply to Mickael Istria from comment #40)
> (In reply to Alexander Fedorov from comment #39)
> > Probably, we can try to transfer QuickAccess to declarative space using 
> > org.eclipse.e4.ui.workbench.model.definition.enrichment 
> > this can allow us to have enougn information for UI without activating
> > target bundles.
> > 
> > What do you think?
> 
> I don't think it would change much things: Going declarative would still
> require some logic to "populate" the model with declarative entries
> dynamically, and this logic most likely needs to use some interesting APIs
> from other bundles to compute the elements to show, and consuming those APIs
> would start generate activity and load bundle.
> In the case of Debug, it would still need the ILaunchManager and
> DebugPluginImages classes to create the right entries in the model, thus
> loading the same bundles as current approach.

You are right, current Debug UI implementation is closer to Eclipse 2.0 and its hard to magically turn it to Eclipse 4.0 grade at once.

But honestly, the information you are looking for does not need all the power of Debug framework:
- launch type defintions from plugin.xml
- probably some area with existing .launch files

In other words: we can read(only!) launch configuration elements without creating instances and have a lot of lightweight info for UI. In the case of execution we can transfer the id to ILaunchManager and so on.

Yes, it may require much more modularity from org.eclipse.debug.*