Bug 191365 - Plug-ins view should populate its content in the background
Summary: Plug-ins view should populate its content in the background
Status: VERIFIED FIXED
Alias: None
Product: PDE
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.4 M5   Edit
Assignee: Les Jones CLA
QA Contact:
URL:
Whiteboard:
Keywords: bugday, contributed
Depends on: 215734 216339
Blocks: 200102
  Show dependency tree
 
Reported: 2007-06-06 16:53 EDT by Pascal Rapicault CLA
Modified: 2008-02-05 16:18 EST (History)
6 users (show)

See Also:
baumanbr: review+


Attachments
mylyn/context/zip (838 bytes, application/octet-stream)
2007-10-26 14:47 EDT, Chris Aniszczyk CLA
no flags Details
JUnit Test to perform automated execution of scenario (7.48 KB, application/x-zip-compressed)
2007-10-29 09:22 EDT, Les Jones CLA
no flags Details
Patch to initialise the PDE on opening of the perspective (1.69 KB, text/plain)
2007-10-29 09:24 EDT, Les Jones CLA
no flags Details
Patch to initialise in the background. (10.47 KB, patch)
2007-10-30 08:09 EDT, Les Jones CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pascal Rapicault CLA 2007-06-06 16:53:34 EDT
3.3 I20070525-1350
When I start on an empty workspace, open the plug-in development perspective, reveal the "plug-ins" view. You will notice that eclipse is unresponsive while the target is being initialized (note that this is a guess).
It could be beneficial to populate the view in the background.
Comment 1 Remy Suen CLA 2007-10-02 23:40:37 EDT
Should the view use a deferred content provider instead? I guess the question is whether the cause really is because of the initialization and calculation or not.
Comment 2 Brian Bauman CLA 2007-10-03 00:19:39 EDT
The problem is definitely initialization.  Since PDE hasn't needed to start up until loading that view, it is upon the view opening that PDE goes out and reads the files on the file system for the target platform.

With the extension registry work (which Pascal has asked for and not yet received performance data for), the time to do this should be just about cut in half.  Since the old initialization needed to read both Manifests and plugin.xmls, the new initialization will only read Manifests and read the plugin.xmls when it needs extension information (which it doesn't for this view).  The result should be half the time waiting.

If this is still a problem in the current build, we can look at other means to fix this problem.
Comment 3 Alex Fitzpatrick CLA 2007-10-26 11:39:40 EDT
This is a scalability issue effecting RSA/RSD/RSM/RAD, RSD for example has upwards of 1200 plugins and populating the plug-ins view can take several minutes while the entire UI is hung. (Long enough for me to fire up bugzilla and find this existing bug.)

For customers extending Eclipse this will give an extremely negative experience.
Comment 4 Chris Aniszczyk CLA 2007-10-26 12:23:23 EDT
patches welcome! :D
Comment 5 Alex Fitzpatrick CLA 2007-10-26 12:31:24 EDT
... and then they wonder why we don't log issues as quickly as we could ...
Comment 6 Chris Aniszczyk CLA 2007-10-26 14:35:47 EDT
Alex, welcome to open-source. 

If this is critical to you, please provide a patch or wait until it gets addressed. If there's a patch, the bug will get addressed quickly. The PDE team would love to help everyone it can, but it's not like we have an army of committers.
Comment 7 Chris Aniszczyk CLA 2007-10-26 14:47:03 EDT
adding Mylyn context to help people get started
Comment 8 Chris Aniszczyk CLA 2007-10-26 14:47:13 EDT
Created attachment 81288 [details]
mylyn/context/zip
Comment 9 Chris Aniszczyk CLA 2007-10-26 15:04:36 EDT
We'll target for 3.4, maybe a clever use of DeferredTreeContentManager would help here.
Comment 10 Les Jones CLA 2007-10-29 09:22:15 EDT
Created attachment 81445 [details]
JUnit Test to perform automated execution of scenario

To use this, import the archive into eclipse and run the JUnit (plug-in) test. Included in the archive are two launchers one for Eclipse, the other for RSA. They are not in any way special and you could just as easily create a new launcher.

The test will always succeed (except for a catastrophic failure in Eclipse - e.g. missing PDE) and will output some timing results to System.out. To mimic user think time, some pauses have been introduced. 

The three figures relate to :
1) The time to show the "Plug-ins" view
2) The total time to run the test
3) The total time to run the test, less the additional delays.
Comment 11 Les Jones CLA 2007-10-29 09:24:07 EDT
Created attachment 81446 [details]
Patch to initialise the PDE on opening of the perspective
Comment 12 Les Jones CLA 2007-10-29 09:37:17 EDT
I have just attached a couple of files to this bug; as a result of a little lateral thinking N.B this fix does not in anyway improve the actual performance of the PDE initialisation.

The patch initialises the underlying PDE model at the point the PDE perspective is opened. It does this as a background job, so the user can continue to use Eclipse. I think, if you've gone into the PDE perspective you're very likely to tigger the initialisation pretty soon anyway, e.g. via showing the plug-ins view or by creating a plug-in. If your workspace has a plug-in already then initialisation appears to take place anyway.

Therefore, by performing the initialisation in the background when the perspective is opened, we are reducing the impact on the user by utilising their 'think time' and therefore creating the perception of a better performing product.

By using the test plugin that I have also attached, I got the following figures:
* For Eclipse 3.4 (I20071023-0800) on Vista (about 150 plugins) the average time to open the view dropped from 975ms to 375ms.
* For RSA 7003 on Vista (about 2100 plugins!) the average time to open the view dropped from 6633ms to 1417ms.

The other reason for considering this change is that I perceive it to be of considerably less impact than re-working the view to utilise deferred logic, or to rework the initialisation to be a more optimal implementation and therefore would be more likely to be capable of being included in 3.4 with little or no impact.

Thoughts?
Comment 13 Les Jones CLA 2007-10-29 09:48:03 EDT
To be clear about the figures in my previous post; the average times relate to multiple executions showing the plug-ins view, with each execution starting a new process using a completely new workspace. The average is not merely open/close/open/close/etc of the plug-ins view, nor is it the time to open the view on an already initialised workspace. 
Comment 14 Les Jones CLA 2007-10-29 12:16:27 EDT
Obviously, it should be noted that this fix, that I've supplied, performs an 'eager load' of the plug-in data; this is contrary to the normal 'lazy load' behaviour of Eclipse. Therefore, I fully understand if this fix may not be acceptable for inclusion into the product.
Comment 15 Brian Bauman CLA 2007-10-29 16:52:13 EDT
Hey Les, I appreciate the effort you put into this bug.  This is a good though and definitely a valid way to try to solve the problem.  Unfortunately, like you said above the "eager" loading is not optimal.  There are two problems with this approach.

1. It is not uncommon to accidentally enter a perspective you don't intend to use.  I had this problem with the "Planning" view when Chris was introducing me to Mylan (which rocks).  If the user accidentally entered the perspective, we would initialize PDE which creates a bunch of models/data the user may never use.

2. Though most people use the Plug-ins view in the PDE perspective, I know some plug-in developers that work in the java perspective.  They can then open individual views which they need.  For users doing this, they would still see a problem.

The good news, I think I have a theory on how this can be done.  In the PluginsContentProvider.getChildren(), before calling PluginModelManager.getAllModels(), we should first check to see if the PluginModelManager.isInitialized().  If not, then I would return an empty array (or something more creative) and kick off the initialization job.  When the job is finished, it could then go back and refresh the Plug-ins View.  I have not tried any of this, but this is how I might look at doing it.  It would be lazy loading and completely local to the Plug-ins View itself.  

I haven't looked into this at all, so there might be  better solutions like DeferredTreeContentManager like Chris pointed out.
Comment 16 Les Jones CLA 2007-10-30 08:09:30 EDT
Created attachment 81573 [details]
Patch to initialise in the background.

Brian, I liked your idea so much that I've attached a patch. (Built on I20071023, subsequently tested successfully on HEAD).

When opening the view, it checks to see if the PDE is initialised, if it's not it starts off a job that will refresh the view on completion (with disposal checks of course). Didn't need to move to a DeferredTreeContentManager to effect this change.

Interestingly, I spotted a race condition in the use of the PDE's PluginModelManager.isInitialized() that I have also fixed (for this scenario).
Comment 17 Chris Aniszczyk CLA 2007-10-30 10:43:25 EDT
nice!
Comment 18 Brian Bauman CLA 2007-11-01 18:29:10 EDT
Oh my gosh, it is so pretty!  I thought the idea was simple but you definitely made it elegant and super polished.  I liked returning the string saying the view is initializing, that was a very nice touch.

Good catch on the race condition.

I am still doing some testing, but thought I would mention the few little things I modified.  These are all pretty minor so I have made the modifications in my workspace and you don't need to redo your patch.

First a really minor change, if you use JobChangeAdapter instead of IJobChangeListener you can save a few lines of code and make it look just a little more elegant.

During testing I was able to create an NPE when I created a plug-in project, closed the project, restarted, and reopened the project.  There is a code path in initializeTable function that will call addWorkspaceBundleToState.  This function had a reference to fEntries which has not been initialized yet causing the NPE.  

And lastly, when I thought about it more I figured it would be nice to do something similar to this for the other PDE view (Plug-in Dependencies).  So I am trying to make the initialization Job more reusable.

Again, very nice!
Comment 19 Les Jones CLA 2007-11-02 03:50:49 EDT
Totally agree with the IJobChangeListener vs JobChangeAdapter; much neater.

As for the other "fEntries causing an NPE" issue; I'd toyed with the idea of keeping the early initialisation of fEntries and altering the way that isInitialized() worked (i.e. using a flag). Once I thought it through I wasn't too keen and prompted for the approach in the patch. Shame I missed the addWorkspaceBundleToState() call though :-(  Good job you caught it.
Comment 20 Chris Aniszczyk CLA 2007-12-11 14:18:03 EST
Should we do this for M5?
Comment 21 Brian Bauman CLA 2007-12-11 14:50:43 EST
(In reply to comment #20)
> Should we do this for M5?

Yes, if I was on top of things we should have done this for M4.  Sorry Les, I will make sure this gets in.
Comment 22 Les Jones CLA 2007-12-11 15:42:49 EST
No worries; I guess since it's not an API change that it'll easily make it in for 3.4 proper even if it's postponed beyond M4?
Comment 23 Brian Bauman CLA 2007-12-11 16:14:02 EST
I don't foresee running into any problems postponing until M5.
Comment 24 Les Jones CLA 2008-01-17 12:27:10 EST
*ping*  ... just checking this hasn't fallen off the radar ;-)
Comment 25 Brian Bauman CLA 2008-01-17 13:33:41 EST
> *ping*  ... just checking this hasn't fallen off the radar ;-)

Funny you ask, I was working on this last night and am just finishing up some last testing before I release it.  I hope to get it wrapped up by the end of the day :)
Comment 26 Alex Fitzpatrick CLA 2008-01-17 13:43:26 EST
... and there was much rejoicing ...

:-)

Thanks Brian!
Comment 27 Brian Bauman CLA 2008-01-21 16:42:43 EST
Unfortunately, there is a bit of a hold up with the discovery of blocking bug 215734.  I can find a work around that is not very elegant, but I am holding off in the hope 215734 will be fixed.

In the mean time, I went ahead and fixed the race condition which Les found.  Thanks a lot Les for spending as much time as you did to make sure this was perfect!
Comment 28 Brian Bauman CLA 2008-01-31 18:36:59 EST
OK, after a long delay, this is all in HEAD now.  After some rough wrist watch calculations, I found DeferredTreeContentManager was a 2 seconds or so quicker than running an initialization job and refreshing the view (with ~1000 bundles).

With the enhancements in DeferredTreeContentManager, we can update the count properly after the PendingUpdateAdapter is removed, so the don't have to hack away at the item count.  This makes the code much nicer and allows us to do this the right way.

I took a look at the Plug-in Dependencies View to see if we could do the same thing.  What I found was it would butcher the code for no improvements.  Since the Plug-in Dependencies View is not displayed by default, users most often have to go through the Open View menu, which seems to trigger PDE's initialization.  This means that by the time the view is opened, PDE is initialized 99% of the time.  So the is not much performance to be gained there and therefore did not update it.

So without much further ado, the Plug-ins View will now populate in the background when PDE is not already initialized.

Thanks Les for your help on this bug.  I appreciate your patience with reviewing this one.  Finding that race condition was very impressive :)
Comment 29 Brian Bauman CLA 2008-02-05 16:18:11 EST
Verified on I20080204-0010