-
Notifications
You must be signed in to change notification settings - Fork 48
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
swing.Publisher does not always notify all listeners #141
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8495?orig=1
|
Christoph Langguth (clangguth) said: Looks good so far, just two small comments:
|
Christoph Langguth (clangguth) said (edited on Apr 28, 2014 2:45:38 PM UTC): It's a minimally modified version of andy1138@bc80053 (changed test description and made sure that duplicate notifications are also covered) |
@andy1138 said: I've updated the code with your test, much better, thanks On containsItem, I think that if the item has been removed from 'listeners' then it should not be called, sounds like another bug waiting to happen. I then couldn't determine how long purgeReferences would take and guessed that in this case it wasn't needed so didn't want to call it. As for the name then I also could'nt come up with a good one :-). I did try making it protected but that prevented it being seen by publish(), the whole class is package[swing] protected so at least it's limiting who can use it. Happy to take suggestions of both name and visibility |
Christoph Langguth (clangguth) said: thanks again for the quick reaction! I think the test now covers all cases that could possibly go wrong :-) Concerning the logic (and therefore the code) of the publish() method, after diving into some of the hairy parts (like the ReferenceQueue and GC internals), here are my thoughts:
To summarize it in one sentence: the publish() method must ensure that every listener that was registered at the time of calling the method gets invoked exactly once. Therefore, I think that:
is actually the correct implementation. Thoughts? Thanks! :-) |
@andy1138 said: I've been distracted by work, and the 2nd part of this, but continuing on ... Interesting, I think of it the other way around. as a client when I've call deafTo() then I would not expect any new messages from that publisher. eg if I'm writing events to a file then I should be able to do { deafTo(); logger.close() } and not have to worry that the logger would be written to afterwards. While doing some 'lets find out what others do' I looked at the scala collection publisher (https://github.com/scala/scala/blob/v2.10.3/src/library/scala/collection/mutable/Publisher.scala#L50)
Longer term, I think this should be changed to use the collections version of Publisher, what do you think? Andy |
Perhaps related, I ran into this:
This my subclass of class ScrollBar(orientation0: Orientation.Value, value0: Int, blockIncrement0: Int, minimum0: Int, maximum0: Int)
extends swing.ScrollBar {
...
peer.addAdjustmentListener(new java.awt.event.AdjustmentListener {
def adjustmentValueChanged(e: java.awt.event.AdjustmentEvent): Unit =
publish(new swing.event.ValueChanged(me))
}) and I'm quite sure that the exception occurred because I was unregistering a reaction during a reaction callback. |
So here is something that had me scratch my head for quite some time. Sometimes, Reactors would not get notified by a publisher. This didn't happen very often, but often enough to break some functionality.
It turned out that it was caused by the mutable nature of the swing.Publisher#listeners. More precisely, it sometimes happens when a listener, in reaction to an event, decides to unsubscribe from the publisher, i.e., calls deafTo(). This immediately causes the listeners to change state, and therefore may lead to the for comprehension to terminate early, without notifying subsequent listeners.
I think that "if a specific event happens on a publisher, I'm not interested in that publisher anymore" is a valid and not terribly exotic use case for a Reactor, so I consider the current behavior a bug.
I'm attaching a scalatest class which triggers the bug (and also contains one possible solution).
The text was updated successfully, but these errors were encountered: