I disagree with this interpretation. Observable says

> Implementations in this library mark themselves as invalid when the first
> invalidation event occurs. They do not generate anymore invalidation events
> until their value is recomputed and valid again.


And ObservableValue says

An ObservableValue generates two types of events: ... An invalidation event
> is generated if the current value is not valid anymore.


Implementations in this library mark themselves as invalid when the first
> invalidation event occurs. They do not generate any more invalidation
> events until their value is recomputed and valid again.


It's clear that the validity is with respect to the value, not the
listener. There is 1 value and it is either valid or invalid.

If we want to define validity on a per-listener basis, the docs would need
to be changed too. I don't know how much sense it makes practically because
I don't think anyone used them with this intention in mind. It could be a
middleground to bridge the current "negligence"  with the stricter docs,
but it's a more fundamental change conceptually.

On Wed, Oct 6, 2021 at 8:02 PM Michael Strauß <michaelstr...@gmail.com>
wrote:

> The documentation of `Observable` states that "an implementation [...]
> may support lazy evaluation" and that "implementations [...] should
> strive to generate as few events as possible".
> This seems to me like it would be within spec to fire an invalidation
> event for every single change. It would also be within spec to fire
> redundant invalidation events only in certain scenarios (like adding a
> listener).
>
> The problem could also be approached from a different angle: what does
> it mean for a property to be "valid"?
> As implemented, the "valid" state is an opaque and unknowable
> implementation detail. We could re-define "valid" to mean: valid from
> the perspective of an InvalidationListener.
> A newly-added InvalidationListener wouldn't know that the property is
> invalid (and has no way of knowing), and can therefore reasonably
> assume that, from its perspective, the property is valid. It would
> receive an invalidation event when the property value is changed.
> From the perspective of pre-existing listeners, however, the property
> could well have been invalid all the time, so they won't receive an
> invalidation event.
>
> On Wed, Oct 6, 2021 at 2:16 AM Kevin Rushforth
> <kevin.rushfo...@oracle.com> wrote:
> >
> > Given that the intention of InvalidationListener was to be a
> > light-weight way to listen to properties without causing a binding chain
> > to be revalidated, it does seem reasonable to me that the listener is
> > only fired on the valid --> invalid transition, which is the specified
> > behavior, even if the implementation doesn't currently do that in all
> cases.
> >
> > The two related questions then are:
> >
> > 1. Should adding an invalidation listener to property do an immediate
> > get(), which will ensure that the property is then valid? This will
> > force an eager evaluation of the property and "arm" the property to fire
> > an invalidation even the next time it is invalidated.
> >
> > 2. Should adding an invalidation listener to a currently invalid
> > property cause the listener to be called (either immediately or the next
> > time the object is invalidated)?
> >
> > I think the ideal answer to both questions is "no", although I share
> > John's concern that changing this behavior for InvalidationListeners
> > could break applications. So the question is: how likely do we think
> > that changing this behavior will break existing applications?
> >
> > I think it's something we can and should consider changing. Unless there
> > are serious concerns, I would support changing this behavior as part of
> > avoiding eager evaluation when using invalidation listeners. It would
> > need to be well tested (of course), and would need a CSR describing the
> > compatibility risk, and should probably get a release note.
> >
> > Any concerns in doing this?
> >
> > On the related question, I like the idea of nulling out the current
> > value when a property is bound.
> >
> > -- Kevin
> >
> >
> > On 9/11/2021 9:41 AM, Nir Lisker wrote:
> > > I think that we need your input on this to move it forward.
> > >
> > > On Fri, Sep 3, 2021 at 7:49 AM Nir Lisker <nlis...@gmail.com
> > > <mailto:nlis...@gmail.com>> wrote:
> > >
> > >         so the value field should perhaps be nulled out when bound.
> > >
> > >
> > >     There was a PR for something like that in the old repo:
> > >     https://github.com/javafxports/openjdk-jfx/pull/110
> > >     <
> https://urldefense.com/v3/__https://github.com/javafxports/openjdk-jfx/pull/110__;!!ACWV5N9M2RV99hQ!bIbtLsC0tg02c9a_lgKnM1Xta2USX8QkKRL4imOUSw8xshJsVquOeulplJR7dfEzQUf6$
> >
> > >
> > >     On Fri, Sep 3, 2021 at 5:35 AM John Hendrikx <hj...@xs4all.nl
> > >     <mailto:hj...@xs4all.nl>> wrote:
> > >
> > >
> > >
> > >         On 02/09/2021 11:57, Nir Lisker wrote:
> > >         >     So in order
> > >         >     to make sure that a new interested invalidation listener
> > >         does not miss
> > >         >     the fact that a property was *already* invalid, the
> > >         easiest solution
> > >         >     might have been to revalidate it upon registration of a
> > >         new listener
> > >         >
> > >         >
> > >         > But why does an invalidation listener need to know the past
> > >         state of the
> > >         > property? It is only interested in the valid -> invalid
> > >         transition. If
> > >         > the property was invalid then the listener (in theory)
> > >         shouldn't receive
> > >         > any events anyway on subsequent invalidations. (I understand
> > >         that you
> > >         > don't justify this, I'm posing it as a general question.)
> > >
> > >         Strictly speaking, no, if users are using InvalidationListener
> > >         correctly
> > >         then this is definitely correct behavior. I'm not really
> > >         advocating a
> > >         change, and I'd even prefer that it be brought in line with the
> > >         documentation.
> > >
> > >         I think however that many users are not using it correctly and
> > >         expect an
> > >         invalidation event always the next time the value changes (and
> > >         their
> > >         listener will read that value, validating it again), making it
> > >         act like
> > >         a light-weight ChangeListener. I know that I probably have
> > >         written code
> > >         that made that assumption, and would in the past not even
> > >         think twice
> > >         about replacing a change with an invalidation listener or vice
> > >         versa if
> > >         that happened to be a better fit. Which is sort of what
> > >         happened as well
> > >         in the bidirectional binding PR, and the issue slipped past
> > >         the author
> > >         and two reviewers.
> > >
> > >         > I suggest that we split the problem into 2: one is the case
> > >         where the
> > >         > property was valid when the listener was attached, and the
> > >         other is when
> > >         > it was invalid.
> > >         > * A valid starting state. In this case attaching a listener
> > >         shouldn't
> > >         > need to do anything. A subsequent invalidation event will be
> > >         sent
> > >         > regardless. Currently, it is calling get() redundantly.
> > >
> > >         True, the call to get is redundant in this case. Ugly too,
> > >         calling get
> > >         and discarding its result, while the intention is to force the
> > >         property
> > >         to become valid.
> > >
> > >         > * An invalid starting state. In this case the documentation
> > >         says that
> > >         > nothing needs to happen, but get() is called anyway. Here,
> the
> > >         > difference is that a subsequent invalidation event is sent
> > >         in one case
> > >         > and not in the other. The only way to advance here is to
> > >         make a design
> > >         > decision on what should happen, at least that's how I see it.
> > >
> > >         The docs are even more specific I think, they say no more
> > >         events will be
> > >         generated until it becomes valid -- it doesn't leave any
> > >         option open
> > >         that it could generate events if it wanted to.
> > >
> > >         > As to the implementation of a possible solution, suppose we
> > >         add the
> > >         > isValid method. Upon attaching an invalidation listener, if
> > >         the property
> > >         > is valid, we can skip the get() call. That solves the valid
> > >         starting
> > >         > state issue. The question is what to do if the property is
> > >         not valid.
> > >         >
> > >         > I also noticed an odd design choice in the implementation of
> > >         properties:
> > >         > the value field does not update if the property is bound,
> > >         instead, the
> > >         > result of the binding is returned and the value field holds
> > >         an outdated
> > >         > value (until the property is unbound).
> > >
> > >         Yeah, that might not be a wise decision as that can lead to
> > >         memory being
> > >         referenced that users might expect to be freed. I didn't see
> > >         anywhere
> > >         defined what will happen to the value of the property when it
> > >         is unbound
> > >         again. The current implementation will keep its last value
> > >         (during the
> > >         unbind it will take the last value and assign it to its own
> value
> > >         field), so the value field should perhaps be nulled out when
> > >         bound.
> > >
> > >         --John
> > >
> >
>

Reply via email to