Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 69761

Summary: [Decorators] Lightweight decorator does not work properly when objectState is changed too fast
Product: [Eclipse Project] Platform Reporter: Serge Yuschenko <Serge_Yuschenko>
Component: DocAssignee: Tod Creasey <Tod_Creasey>
Status: CLOSED FIXED QA Contact:
Severity: enhancement    
Priority: P2 CC: andrea_covas, eclipse, michaelvanmeekeren, ryanman
Version: 3.0Keywords: helpwanted
Target Milestone: 3.1 M3   
Hardware: PC   
OS: Windows 98   
Whiteboard:

Description Serge Yuschenko CLA 2004-07-09 16:29:03 EDT
I use a lightweight decorator in my plugin to indicate a connection point
status (DISCONNECTED/CONNECTED/BUSY) in the TreeViewer (or TableViewer). BUSY 
is an intermediate state between CONNECTED/DISCONNECTED. On every state change I
call viewer.update( connection, null ) method. If BUSY state lasts long enough
the decoration goes all the way DISCONNECTED->BUSY->CONNECTED (or back). If 
BUSY state is short the decoration gets stuck on BUSY.

I figured out that the problem starts in DecorationScheduler.isDecorationReady( 
Object element ) when the method is called from 
DecorationManager.prepareDecoration(). When an object state is BUSY the 
isDecorationReady() returns false and the object is queued for "BUSY 
decoration". Then if state changed to CONNECTED too soon the isDecorationReady
() for the same object returns true since the object is still in the 
resultCache. I.e. "CONNECTED decoration" request is discarded despite the fact 
that the objectState has changed. I guess in this case it would be logical to 
discard previous decoration request as outdated and replace it with the new one.

The workaround for this problem is to add artificial delay in my connect
()/disconnect() methods. It works as long as software and hardware don't 
change. I'm afraid that in some circumstances current delay may not be enough, 
but making it too long will annoy user.

If it helps I can provide a simple plugin demonstrating this behaviour.
Comment 1 Tod Creasey CLA 2004-07-12 10:33:34 EDT
This would need some new API to invalidate current results - if a change in 
state occurs before update does this could result in a stale decorations.
Comment 2 Tod Creasey CLA 2004-07-21 13:59:06 EDT
Thinking more about this I am not sure that we can safely do this and get the 
timing right as this would add a potential thrid point of entry into the cache 
(one to schedule, a clear on an update and then this one).

If you know you have requested an update and it has not come back then you 
know it is invalid - what you may want to do is repost the label update after 
you get it.

I'll leave this open as there may be a better way but I don't have a safe 
solution to this issue.
Comment 3 Serge Yuschenko CLA 2004-07-21 17:31:01 EDT
What do you mean by "has not come back"? As far as I understand the whole idea 
of decoration is to do the job asynchronously to a thread calling update(). The 
TreeViewer.update( element, null ) comes back right away while decoration job 
is still in progress. What I'm missing?

About the problem... What if instead of invalidating an outdated decoration we 
leave it there and add a new one if decoration definitions are different. In 
this case proper decoration will be shown sooner or later. The obvious drawback 
of this approach is that a decoration definition queue for each cached object 
has to be added. Just an idea...
Comment 4 Tod Creasey CLA 2004-07-22 08:50:31 EDT
I mean that the request has occured but you have not got the label update 
notification yet (i.e. decorations are still being calculated).

The main concern I have is performance. If someone continuously has to 
invalidate possible cached results it is possible to end up with a lot of 
extra computation going on. This can get really bad on something like a 
Resource Navigator.

The decorators now are updated as a result of resource deltas in most viewers -
 I assume your update does not. 

Your could also fire an update when your state change occurs using a job that 
blocks on a scheduling rule using DecoratorManager.FAMILY_DECORATE. I 
understand this is not API currently but I am not adverse to promoting it if 
that can solve this issue.
Comment 5 Serge Yuschenko CLA 2004-07-22 18:02:03 EDT
Thanks for the advice. Now I understand what you're saying. That's right, I 
have to take a synchronous approach. I think in my case instead of 
synchronizing with a decorating thread it would be even better (less tangle) 
just to implement a ILabelDecorator on my own. I didn't do this at the 
beginning mostly because of ubiquitous encouragement to use lightweight 
decorator wherever it is possible, and secondly because I tried to avoid 
dealing with images.

Maybe it would be helpful to add a caveat about lightweight decorator timing 
issue in documentation.
Comment 6 Tod Creasey CLA 2004-07-26 07:53:33 EDT
Thats a fine idea Serge - we should add a section on this to the ISV doc.
Comment 7 Tod Creasey CLA 2004-08-30 12:03:51 EDT
*** Bug 68600 has been marked as a duplicate of this bug. ***
Comment 8 Tod Creasey CLA 2004-10-29 13:11:33 EDT
Doc has been released 
to /org.eclipse.platform.doc.isv/guide/workbench_advext_decorators.htm for 
build >20041029
Comment 9 Tod Creasey CLA 2005-05-10 14:54:11 EDT
Marking as closed.