Hey guys, We're developing a GUI'd application with guice.
I recently discovered a horrifying and rather tragic behavior within our software, *once in a while* it will enter deadlock when running under a couple specific situations. I've got this deadlock down to a contention between two resources: - The JavaFX thread --specifically, we've written a method called runImmedlatelyOnFX. the source code can be found here <https://gist.github.com/Groostav/2944cb86e87848399924>, but its effectively draining the fx job queue. - A singleton's constructor. The scenario is: 1. Worker-Thread requests and instance of singleton-class B from guice. 2. Guice acquires some kind of mutex to indicate that its constructing a singleton, and calls the Class-B constructor on Worker-Thread. 3. the JavaFX application thread requests an instance of singleton-class B from guice. *It's blocked by guice pending the result from Worker-Thread's Class-B-Construtor call*. 4. The constructor for singleton-class B calls runImmediatelyOnFX. *It's blocked until the JavaFX thread executes its enqueued job* *and we have deadlock.* So I don't think it will be too helpful to get into a deep discussion about our usage of JavaFX, but I'm wondering if anybody else has run into this problem, and if there's some miracle solution I'm not aware of. The two things I can employ to mitigate/solve this problem: - There is one overt use case for this runImmediately business, and it has to do with loading fxml documents (typically done in constructors). If I make our UI code a little bit more flexible about when it actually gets an instanced view tree (read: in a callback rather than in the ctor), we can reduce the number of ctor's that block on runImmediately() quite significantly. - I can use use Quantem's enterNestedEventLoop() <http://grepcode.com/file/repo1.maven.org/maven2/net.java.openjfx.backport/openjfx-78-backport/1.8.0-ea-b96.1/com/sun/javafx/tk/Toolkit.java#Toolkit.enterNestedEventLoop%28java.lang.Object%29> to give the appearance of running immediately on the javaFX thread without actually blocking the javaFX thread. This will likely defeat the purpose of the method for some use cases, so the old "enqueue the job and wait" strategy will have to remain available for them, but it will likely be sufficient for most of the callers. Is there something I'm missing? Is there some architectural master stroke somebody can fill me in on to deal with this problem quickly and easily? One of the things I'm looking to do now is start failing integration tests when they notice the potential for this deadlock. My plan for this is to have SyncingUtilitles.runImmediatelyOnFXThread and guice singletons act like resource acquisitions, with each checking to see if the thread they're running on has already acquired the other. If they have, they would log some kind of warning that they may be entering deadlock. logging a warning will fail our cucumber performance tests and our ranorex UI automation tests, which should prevent us from pushing new code with these issues. I haven't started writing that provision listener, is it technically possible? Thanks for any help! -Geoff -- You received this message because you are subscribed to the Google Groups "google-guice" group. To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+unsubscr...@googlegroups.com. To post to this group, send email to google-guice@googlegroups.com. Visit this group at http://groups.google.com/group/google-guice. To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/2b89be39-c127-45e0-871d-4e46b42812ae%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.