-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IndexOutOfBoundsException updating a JTable - multi-threaded race condition? #5
Comments
Ok, so FS2's dynamic gui elements are riddled with race conditions and mistakes, but they're fiercely complicated, even in theory. Most of them are caught so they dont do any damage and they self correct as time goes on. I have a feeling if you say this one is close to program startup that the indexnode is requesting the file lists (an upload from the client) before the gui has initialised. The file transfers then finish after the gui has initialised so the gui receives the "transfer complete" event, but there's nothing to update in the table of transfers. I'm not sure what the elegant fix is for this. I'll ponder for a while. |
On the plus though, you can see that at least this was anticipated and caught :) |
No worries; I'm just raising all the bugs I can find. And NullRef == bug :) |
Only if it's uncaught :D Stacktraces are not necessarily bugs. On Mon, Aug 6, 2012 at 11:53 PM, Matt Turner notifications@github.comwrote:
|
Hah, totally decided to take a look at this and then immediately decided it wasn't worth it! Swing is a bit of a nightmare. |
:)
I'm inclined for 1, 3, or 4. Four is easy. I'm doing it right now :D |
I'm not sure what the current architecture of the GUI is with relation to the underlying components, but I think it would be sensible to basically have an FS2 service running, and the GUI slapped on top of it on a strict set of API calls. To simply things, the GUI should only (effectively) poll the service and update itself based on the returns. Getting some clean separation in the architecture should keep the performance high as well as isolating the gui behaviour, meaning much more simple code and removing all of those nasty potential race conditions. |
That is essentially how it's architected, but there are also events which allow the gui to update only when needed. Each of FS2's subsystems are reasonably isolated, for example the servers and indexers don't care if the gui is present or not and will issue events to anything listening. The gui bugs stem primarily from swing's table and tree models being so hard to drive and so my code is error prone. This artefact, however, is not one of those bugs and does not stem from a lack of separation between gui and service but in fact because of it. The event dispatch in this case doesn't care about whether the GUI is able to handle the event. It's just reporting facts. The uploads table was coded with the assumption that if a transfer ended, it must have started and therefore must be in the table. Next time we have a beer I need to verbally fight you for that comment though. It took me a long time to draft and redraft this final paragraph. |
Steps
Actual
2012.08.06 23:16:07 INFO: Now exporting shares on port 41234
2012.08.06 23:16:07 INFO: Checking for updates...
2012.08.06 23:16:07 INFO: Refresh complete (share Default download directory on magrathea)
2012.08.06 23:16:07 INFO: The indexnode at http://127.0.0.1:1337 is now known as 'magrathea'
2012.08.06 23:16:08 WARNING: Couldn't remove from uploads table: java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(EventQueue.java:1045)
at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1347)
at client.gui.Utilities.dispatch(Utilities.java:248)
at client.gui.Utilities.dispatch(Utilities.java:272)
at client.shareserver.ShareServer$UploadsTableModel.transferEnded(ShareServer.java:185)
at client.shareserver.ShareServer$HttpEventsImpl.transferEnded(ShareServer.java:271)
at common.HttpUtil$HttpTransferInfo.transferComplete(HttpUtil.java:293)
at common.HttpFileHandler.handle(HttpFileHandler.java:106)
at common.httpserver.Filter$Chain.doFilter(Filter.java:34)
at client.indexnode.IndexNodeOnlyFilter.doFilter(IndexNodeOnlyFilter.java:46)
at common.httpserver.Filter$Chain.doFilter(Filter.java:36)
at common.FS2Filter.doFilter(FS2Filter.java:92)
at common.httpserver.Filter$Chain.doFilter(Filter.java:36)
at common.httpserver.impl.ExchangeImpl.(ExchangeImpl.java:123)
at common.httpserver.impl.ServerImpl$1$1.run(ServerImpl.java:128)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
Caused by: java.lang.IndexOutOfBoundsException: Invalid range
at javax.swing.DefaultRowSorter.rowsDeleted(DefaultRowSorter.java:880)
at javax.swing.JTable.notifySorter(JTable.java:4278)
at javax.swing.JTable.sortedTableChanged(JTable.java:4122)
at javax.swing.JTable.tableChanged(JTable.java:4399)
at client.shareserver.ShareServer$UploadsTableModel$2.run(ShareServer.java:190)
at client.gui.Utilities$1.run(Utilities.java:241)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:216)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:647)
at java.awt.EventQueue.access$000(EventQueue.java:96)
at java.awt.EventQueue$1.run(EventQueue.java:608)
at java.awt.EventQueue$1.run(EventQueue.java:606)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:617)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
The text was updated successfully, but these errors were encountered: