Community
Participate
Working Groups
The UI is blocked when expanding a node in the model browser results in a Resource being lazy-loaded. This could be avoided by returning a dummy result immediately ("loading..." text node), doing the loading in the background, and refreshing the node with the correct information once retrieved.
Actually, this is a larger problem. The UI freezing not only happens while lazy-loading a Resource, but also when Customizations, Facets and Queries are computed. This can all be solved by using virtual tables (style SWT.VIRTUAL), and background jobs to compute Facets, Queries and Customizations. I am changing the bug title to reflect this larger problem.
In fact, SWT.VIRTUAL does not really work for trees on Windows when there are many elements (see Bug 129457 - Virtual Tree very slow). Apparently, this is a limitation of the Win32 API. Under Windows, SWT creates a tree item for each element of the virtual tree, completely negating the benefit of using a virtual tree...
Precision : my previous comment relates to the utility of a lazy *content* provider. But in the MoDisco model browser, the bottleneck is also the *label* provider, since each element's text, image, font, etc. can be customized, and each customization (or Facet) can call queries which can potentially be slow. A lazy content provider can be useful in two cases : when there are many tree elements, or when each element can take a long time to load. - In the case of the MoDisco browser, there should never be too many tree elements under each node, since elements are partitioned by blocks of 1000 elements. This behavior must be kept because of Bug 129457, which prevents using a lazy content provider on Windows to have millions of tree elements. - But the lazy tree content provider can still be useful to solve the problem of nodes taking a long time to load. For example, in cases where expanding a node triggers the lazy-loading of a Resource, a lazy tree content provider would be useful, when implementing a background loading of the Resource, with the element being refreshed asynchronously, once the Resource is loaded JFace doesn't seem to have a "lazy label provider", but it does have IViewerLabelProvider, which should allow lazily updating the "label" (text, icon, font, color, etc.). Unfortunately, it doesn't seem to be accepted by the TreeViewer (Bug 328444 - TreeViewer doesn't accept IViewerLabelProvider as label provider).
The strategy I'll try to implement now is to stay synchronous as long as the computations terminate quickly (<100ms for example). And continue the computation asynchronously if it takes too long, so as to free the UI thread.
Created attachment 187443 [details] patch This patch implements the strategy mentioned above.
Created attachment 187444 [details] test project This project contains a big model referenced by a small one through a reference. The small model opens instantly. When the reference is shown, the big model is loaded in the background, and its instances appear progressively in the browser. The model browser remains responsive during the load of the referenced big model.
I tested further, and noticed that with the patch from Comment 5, the referenced model was loading without freezing the browser, but the total loading time was much longer (about 4 times longer on my 64MB model). I will continue to investigate with TPTP to see if this can be improved.
Created attachment 187639 [details] patch 2 I couldn't profile the browser with TPTP under Indigo, which was way too slow to be able to do anything useful, didn't work consistently, and then stopped working completely (it wouldn't even start anymore). So, I "profiled" the old fashioned way, by pausing the application under the debugger at regular intervals and looking at the stack trace to get a feeling for which parts of the code were taking a long time. I found out that the instances cache (MetaclassInstancesAdapter) was responsible for the long loading times. I modified it so that it doesn't track every single modification while a Resource is being loaded, but recomputes the whole cache only once at the end. This resulted in a x5 speed up. To know when to recompute the cache, MetaclassInstancesAdapter detects when a proxy EObject it contains is resolved, and sends a "resolved" message to the MetaclassInstancesAdapter of the Resource that was lazy-loaded to resolve the proxy. Committed in revision 3792.
Mark as fixed.
Patch committed.