Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » NatTable » Update a Table with GroupByDataLayer on a Background Thread("Best practices" for safely updating a table with grouping on a backround thread.)
Update a Table with GroupByDataLayer on a Background Thread [message #1432008] Fri, 26 September 2014 13:21 Go to next message
Frank Mosebach is currently offline Frank MosebachFriend
Messages: 7
Registered: September 2014
Junior Member
Hi,

we're using the NatTable (v.1.1.0) in an eclipse RCP client application (platform version 4.3).

As we need to utilize the table's grouping features, we set up the table with a GroupByDataLayer as data layer. When constructing the GroupByDataLayer, we provide our own EventList implementation, because we need to propagate updates from an underlying data store that contains the actual "row objects" to the table's data model.

The workflow when the table is updated in response to changes in the underlying data store could be outlined as follows:

(1) The data store is updated (rows are added or removed) on a background thread.
(2) The EventList of the table's GroupByDataLayer receives a notification from the data store.
(3) The EventList updates its contents according to the received notification and forwards corresponding events to subscribed listeners using its ListEventAssembler. Concurrent access to the EventList from different threads is safeguarded using the "Glazed List" locking support.
(4) As the GroupByDataLayer's underlying TreeList listens to notifications emitted by the EventList, it updates itself accordingly and in turn notifies subscribed listeners.
(5) A listener that has been added to the TreeList puts a job on the SWT event queue that will fire a StructuralRefreshEvent from the GroupByDataLayer to make the table update its presentation.

The problem we're facing with this set-up is that we frequently get into situations where an exception is thrown, because the ui thread "sees" the table's data model in an inconsistent state while it is being updated on a background thread as described above.

For example, we get a NullPointerException on the ui thread with the following stack trace...
FourColorTree<T0>.indexOfNode(Element<T0>, byte) line: 818    
TreeList<E>.subtreeSize(int, boolean, boolean) line: 242    
TreeList<E>.subtreeSize(int, boolean) line: 249    
TreeList<E>.hasChildren(int) line: 310    
GlazedListTreeData<T>.hasChildren(int) line: 86    
GlazedListTreeRowModel<T>(AbstractTreeRowModel<T>).hasChildren(int) line: 55    
TreeLayer.getConfigLabelsByPosition(int, int) line: 137    
ViewportLayer(AbstractLayerTransform).getConfigLabelsByPosition(int, int) line: 316
...


...while data model is being updated on a background thread:
FourColorTree<T0>.convertIndexColor(int, byte, byte) line: 902
TreeList$FinderInserter.findOrInsertNode(int) line: 884    
TreeList$FinderInserter.access$1800(TreeList$FinderInserter, int) line: 857    
TreeList<E>.listChanged(ListEvent<Node<E>>) line: 495
ListEventAssembler$ListEventFormat.fire(EventList<E>, ListEvent<E>, ListEventListener<? super E>) line: 424    
ListEventAssembler$ListEventFormat.fire(Object, Object, Object) line: 421    
SequenceDependenciesEventPublisher$SubjectAndListener<Subject,Listener,Event>.firePendingEvent() line: 445    
SequenceDependenciesEventPublisher.fireEvent(Subject, Event, EventFormat<Subject,Listener,Event>) line: 344    
ListEventAssembler<E>.commitEvent() line: 317
...


Has anybody run into similar problems when updating a table with grouping from a background thread? What are your suggested "best practices" for the described scenario?
Re: Update a Table with GroupByDataLayer on a Background Thread [message #1432045 is a reply to message #1432008] Fri, 26 September 2014 14:26 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
If I understand correctly your issue is that the list is updated again while the update in the NatTable instance is still processed. So you have concurrent access to the list from the UI thread and the background thread.

Quote:
A listener that has been added to the TreeList puts a job on the SWT event queue that will fire a StructuralRefreshEvent from the GroupByDataLayer to make the table update its presentation.


I'm not sure if it would help, but why aren't you using the GlazedListsEventLayer? This layer is intended to do exactly what you are doing with your custom listener. The GlazedListsEventLayer for example adds a delay of 100ms to collect multiple events to fire only one refresh into NatTable instead of several that might collide.

[Updated on: Fri, 26 September 2014 14:51]

Report message to a moderator

Re: Update a Table with GroupByDataLayer on a Background Thread [message #1434015 is a reply to message #1432045] Mon, 29 September 2014 14:51 Go to previous messageGo to next message
Frank Mosebach is currently offline Frank MosebachFriend
Messages: 7
Registered: September 2014
Junior Member
Hi Dirk,

Quote:

If I understand correctly your issue is that the list is updated again while the update in the NatTable instance is still processed. So you have concurrent access to the list from the UI thread and the background thread.


Yes, exactly. And in order to get that right we need to know which particular measures must be taken when configuring the table (regarding its data providers etc.) for concurrent model updates.

We're obviously having some problems with concurrency , and it's not unlikely that the cause is in our code. Hence we just want to make sure that we're on track reagarding the table set-up.

Using the GlazedListsEventLayer, as you suggested, could possibly improve rendering performance but IMO does not solve our problems regarding inconsistent model state.

For example, when looking at the sources of GlazedListsDataProvider, which is employed by GroupByDataLayer as data provider, you can see that it guards concurrent access to the underlying list for two accessors (getRowObject, getDataValue), but not for other access paths. That's not entirely thread safe IMO.

Does that mean we need to implement our own data provider to achieve thread safety, or am I just overlooking something?

Thanks,
Frank
Re: Update a Table with GroupByDataLayer on a Background Thread [message #1434029 is a reply to message #1434015] Mon, 29 September 2014 15:10 Go to previous message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Well, to be honest, I'm not sure. But it sounds correct.

As you currently facing the issues, why don't you try to implement a custom IDataProvider that is completely thread safe, maybe based on the GlazedListsDataProvider. And if it solves your issue, contribute that solution?

I'm also not sure if GlazedListTreeData needs to be checked for concurrency issues, as the stack trace you posted initially are pointing to that.

Although, if you are using ThreadSafeList, most of the actions on the list should be thread safe.
But looking at the TreeList Javadoc,

Quote:
This class is thread ready but not thread safe.


How are you buildingthe TreeList.Format path? I know that in some of our examples there is a really lazy implementation that uses Collection.reverse() which sometimes hurts.
Previous Topic:GroupByModel does not save state when last column is ungrouped
Next Topic:F2 on a TextCellEditor with a NatTable with GroupBy Layer enabled
Goto Forum:
  


Current Time: Tue Apr 23 07:02:24 GMT 2024

Powered by FUDForum. Page generated in 0.03640 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top