Bug 181939 - [performance] RSE plugin activation happens too early and for non-active parts of RSE
Summary: [performance] RSE plugin activation happens too early and for non-active part...
Status: RESOLVED FIXED
Alias: None
Product: Target Management
Classification: Tools
Component: RSE (show other bugs)
Version: 2.0   Edit
Hardware: All All
: P2 normal (vote)
Target Milestone: 3.0   Edit
Assignee: David Dykstal CLA
QA Contact: Martin Oberhuber CLA
URL:
Whiteboard:
Keywords: plan
Depends on: 190231 217894 230400 174789 196936 196942 197036 218304 226550
Blocks:
  Show dependency tree
 
Reported: 2007-04-11 10:24 EDT by Uwe Stieber CLA
Modified: 2008-09-30 09:15 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Uwe Stieber CLA 2007-04-11 10:24:25 EDT
Almost all RSE plugins are activated even if in example no connection using SSH or FTP has been created. It needs to be inspected, why, if using a fresh workspace and active Remote Systems perspective, plugins like *.ssh, *.dstore and others are activated. Wherever possible, plugin activation should be delayed to real first use.

From our experience with similar issues tracked down in our product, problematic areas are:
- createExecutableExtension for extension points called even if not needed. A delegate pattern helps to solve those issues
- Static and final class variables initialisations
- Creating of object instances in constructors instead of having getter methods.

This defect is certainly nothing which can be solved in one shot. These things require constant awareness.
Comment 1 Martin Oberhuber CLA 2007-04-11 16:54:42 EDT
Even if I do the following:

* Launch RSE, create an SSH connection
* Switch to Resource perspective
* Create a local project with a linked folder backed by RSE EFS provider
* Quit and re-start Eclipse (showing Resource perspective)

I get ALL RSE plugins activated. I believe that in this case (SystemView not shown!) only the following plugins should be activated:

org.eclipse.rse.ui  (Required due to SubSystem base class - bug 176211)
  org.eclipse.rse.core
    org.eclipse.rse.services
org.eclipse.rse.subsystems.files.ssh
  org.eclipse.rse.subsystems.files.core
  org.eclipse.rse.connectorservice.ssh
  org.eclipse.rse.services.ssh

Plugins that are related to dstore, ftp, local, processes, shells should not be activated in this case. It looks like handling of the 
   org.eclipse.rse.ui.subsystemConfigurations
extension point activates too much.
Comment 2 Martin Oberhuber CLA 2007-05-11 17:49:00 EDT
First step: deferred class loading for org.eclipse.rse.core keystoreProviders extension point, checkin comment:
[181939] Deferred class loading for keystoreProviders
Comment 3 Martin Oberhuber CLA 2007-05-18 16:59:07 EDT
Need to look at this in RC1.
Comment 4 Martin Oberhuber CLA 2007-05-21 16:07:35 EDT
Dave -- I looked at this and it turns out that the problem is: When the RSEDOMImporter loads a profile, it wants to create a FilterPoolManager and to do so, it instantiates the ISubSystemConfiguration regardless of whether that filter has ever been shown or expanded in the UI.

Code should use the SubSystemConfigurationProxy wherever possible, and defer instantiation of the actual ISubsystemConfiguration to the latest possible time, such that plugins are only activated when really necessary.

Below is a stack backtrace from early startup of RSE. It's in the process of activating the processes plugin, although I've never seen a processes node or do not want to use it. I'd like to discuss this in the committer meeting, if you see any chance improving this situation.

[...instantiates the ISubSystemConfiguration for processes]
SubSystemConfigurationProxy.getSubSystemConfiguration() line: 237	
SystemRegistry.getSubSystemConfiguration(String) line: 574	
RSEDOMImporter.getSubSystemConfiguration(String) line: 480	
RSEDOMImporter.restoreFilterPool(ISystemProfile, RSEDOMNode) line: 359	
RSEDOMImporter.restoreProfile(RSEDOM) line: 89	
RSEPersistenceManager.load(IRSEPersistenceProvider, String, long) line: 389	
RSEPersistenceManager.loadProfiles(IRSEPersistenceProvider, long) line: 369	
RSEPersistenceManager.restoreProfiles(IRSEPersistenceProvider, long) line: 230	
RSEPersistenceManager.restoreProfiles(long) line: 216	
SystemProfileManager.getDefault() line: 59	
SystemRegistry.getSystemProfileManager() line: 763	
SystemRegistry.getHostPools() line: 1623	
SystemRegistry.getHosts() line: 1664	
SystemRegistry.getSystemViewRoots() line: 267	
SystemViewRootInputAdapter.getChildren(IAdaptable, IProgressMonitor) line: 133	
SystemViewLabelAndContentProvider.getChildren(Object) line: 344	
SystemViewLabelAndContentProvider.getElements(Object) line: 366	
SystemView(StructuredViewer).getRawChildren(Object) line: 937	
SystemView(ColumnViewer).getRawChildren(Object) line: 650	
SystemView(AbstractTreeViewer).getRawChildren(Object) line: 1280	
SystemView(TreeViewer).getRawChildren(Object) line: 366	
SystemView(AbstractTreeViewer).getFilteredChildren(Object) line: 615	
SystemView(AbstractTreeViewer).getSortedChildren(Object) line: 581	
AbstractTreeViewer$1.run() line: 778	
BusyIndicator.showWhile(Display, Runnable) line: 67	
SystemView(AbstractTreeViewer).createChildren(Widget) line: 755	
SystemView(TreeViewer).createChildren(Widget) line: 615	
SystemView(SafeTreeViewer).createChildren(Widget) line: 119	
SystemView.createChildren(Widget) line: 5805	
SystemView(AbstractTreeViewer).internalInitializeTree(Control) line: 1441	
SystemView(TreeViewer).internalInitializeTree(Control) line: 804	
AbstractTreeViewer$5.run() line: 1428	
SystemView(StructuredViewer).preservingSelection(Runnable, boolean) line: 1368	
SystemView(TreeViewer).preservingSelection(Runnable, boolean) line: 378	
SystemView(StructuredViewer).preservingSelection(Runnable) line: 1330	
SystemView(AbstractTreeViewer).inputChanged(Object, Object) line: 1417	
SystemView(ContentViewer).setInput(Object) line: 251	
SystemView(StructuredViewer).setInput(Object) line: 1606	
SystemView.init() line: 425	
Comment 5 Martin Oberhuber CLA 2007-05-21 16:12:26 EDT
Perhaps we could define

public class SystemFilterPoolProxy implements ISystemFilterPool {
   ...
}

and fill it with the values restored from the profile, such that methods like getName() are done by returning the restored values from the persistence provider; but at the time some real data is needed, the pool would need to create the actual real filter pool (activating the ISubSystemConfiguration and basically doing the work that is now in RSEDOMImporter#restoreFilterPool()).

How does that sound?
Comment 6 Martin Oberhuber CLA 2007-05-22 04:28:29 EDT
I tried setting a breakpoint in FTPFileSubSystemConfiguration.start() and launch RSE on a completely empty workspace. It turns out that even in this case, the FTP plugin is activated although it certainly has not been used and will not be used:

[...loading the ISubsystemConfiguration class...]
ConfigurationElementHandle.createExecutableExtension(String) line: 51	
SubSystemConfigurationProxy.getSubSystemConfiguration() line: 237	
SystemRegistry.getSubSystemConfigurations() line: 1515	
SystemProfile.getFilterPools() line: 105	
RSEDOMExporter.populateRSEDOM(RSEDOM, ISystemProfile, boolean) line: 114	
RSEDOMExporter.createRSEDOM(ISystemProfile, boolean) line: 86	
RSEPersistenceManager.save(ISystemProfile, boolean, long) line: 416	
[...]

I'm wondering whether we could fix this by introducing methods
  SystemProfile.getActiveFilterPools()
  SystemRegistry.getActiveSubSystemConfigurations()
that would just return those elements that have been activated already. This would lead to not activating/creating/storing those filter pools that are not needed.

Does this sound reasonable, or is there a flaw in the FilterPools design?
Comment 7 David Dykstal CLA 2007-05-22 10:08:54 EDT
I think this as risky for this release. The suggestion you make might work, but I cannot be sure at this point.

The problem stems from in part the way profiles are restored and there is very little in the way of late binding and resolution. The overall restore mechanism should allow for the restoration of objects with "proxies" to other objects that are resolved on first use or in a second pass over the profile.
Comment 8 Martin Oberhuber CLA 2007-05-22 12:49:33 EDT
My biggest question is, do you see such deferred activation as basically possible, or do you see any problems with the design as it is now? Any roadblocks you can think of that might make the deferred activation hard would be interesting.

Especially in the situation described in comment #6 I'd like to be able and avoid persisting data of subsystems that have never been activated before. Activating a subsystem for the sole purpose of persisting uninitialized data is useless.
Comment 9 David Dykstal CLA 2007-05-23 21:29:16 EDT
I think this is doable, it is just going to require some analysis to make sure that activation is done properly if delayed.

I want to defer this to the service release. I believe it is too risky to attempt now.
Comment 10 Martin Oberhuber CLA 2007-05-24 06:26:12 EDT
ok, so this is the first item planned for 2.0.1 :-)
Comment 11 Martin Oberhuber CLA 2007-07-18 03:49:37 EDT
[181939] avoid subsystem plugin activation just for enablement checking

Made one improvement in RSESystemTypeAdapter.isEnabled(Object) -- use the SubSystemConfigurationProxy rather than the actual SubSystemConfiguration for checking enablement of systemTypes.
Comment 12 Martin Oberhuber CLA 2007-07-18 08:46:54 EDT
[181939] avoid subsystem plugin activation just for enablement checking

SystemWidgetHelpers.getValidSystemTypes()
    -- Fixed another occasion of too eager loading
Comment 13 Martin Oberhuber CLA 2007-09-10 08:49:14 EDT
Will look at this for 3.0
Comment 14 Martin Oberhuber CLA 2008-02-12 16:21:30 EST
Here are some more dependent bugs on the way of avoiding UI activation for collapsed nodes: bug 190231, bug 218304.
Comment 15 Martin Oberhuber CLA 2008-04-10 12:41:37 EDT
More work for this has been completed as per bug 218304 comment 6.

When RSE is started on a fresh workspace with all plugins installed, the following plugins are no longer eagerly loaded as per RSE 3.0M6:
   org.eclipse.rse.files.ui
   org.eclipse.rse.processes.ui
   org.eclipse.rse.shells.ui

See the "depends on" bugs for further work to be done. Especially the New Connection Wizard seems to activate too many plugins, see bug 217894; and the "Launch Shell" action should be contributed declaratively, see bug 226550. Adding more stuff declaratively might be necessary in order to provide proper menus even when plugins are not loaded, or to avoid UI plugin loading when the context menu is opened on a Subsystem node.

Also, copying the migration notes for extenders here:

Migration Notes for Extenders:
------------------------------
Extenders which depend on their adapters being available BEFORE connect for
some reason (e.g. custom images, custom actions, especially custom filter
actions or icons) will need to provision themselves to eagerly load their UI
plugins which declare the adapters. Also, extenders need to ensure that they
properly call super.initializeSubSystem() where needed.
Comment 16 Martin Oberhuber CLA 2008-05-20 18:19:01 EDT
Bulk update of target milestone
Comment 17 David Dykstal CLA 2008-05-29 15:14:51 EDT
This looks like it will continue to be an umbrella work item. Moving to 3.0.1 to see what we can accomplish there.
Comment 18 Martin Oberhuber CLA 2008-09-30 09:15:20 EDT
This has been an RSE 3.0 plan item which has mostly been completed.
Individual bugs (as on the "depends on" list) are now being used for tracking further progress.