100% agree with your examples. On Tue, Aug 17, 2021 at 1:21 PM Luke Cwik <[email protected]> wrote:
> I believe that all our ReadableState calls are point in time snapshots of > what the underlying state is plus any changes that happened within the > bundle already (e.g. you can see your own writes/appends/clears assuming > that the creation of the ReadableState happened after the mutation). > > Here are some example of what I think should happen: > > #1 > ReadableState<Boolean> maybePut = mapState.putIfAbsent(keyA, valueA) > ReadableState<T> read = mapState.get(keyA); // value should equal > "valueA" > > #2 > ReadableState<T> read = mapState.get(keyA); // read should equal prior > value > ReadableState<Boolean> maybePut = mapState.putIfAbsent(keyA, valueA); > > #3 > ReadableState<Boolean> maybePut = mapState.putIfAbsent(keyA, valueA); > // any calls to MapState put/remove for keyA can effectively drop the > write that would be pending via maybePut > // maybePut should also be resolved before the write happens to ensure > that it can return true/false truthfully if the state was empty > > #4 > ReadableState<Boolean> maybePut = mapState.putIfAbsent(keyA, valueA) > // in a future bundle for same key and window > ReadableState<T> read = mapState.get(keyA); // value should equal > "valueA" > > I think #1, #3, and #4 don't currently work and #2 doesn't work if the > mapState didn't contain keyA > > On Tue, Aug 17, 2021 at 12:28 PM Kenneth Knowles <[email protected]> wrote: > >> Can the change be observed in that case? I think the semantics should be >> that the timing of the actual write cannot be observed. >> >> Kenn >> >> On Tue, Aug 17, 2021 at 10:19 AM Luke Cwik <[email protected]> wrote: >> >>> Yeah, the "or state is committed" means that we should resolve it before >>> any additional writes but that only addresses part of the surprise I had. >>> >>> I would have expected that the putIfAbsent would force a resolution >>> before transitioning to process the next key and window pair regardless >>> whether the read() was invoked or there were additional writes. >>> >>> >>> On Mon, Aug 16, 2021 at 10:04 AM Kenneth Knowles <[email protected]> >>> wrote: >>> >>>> I think it is an implementation bug. The javadoc for putIfAbsent says >>>> "When {@code read()} is called on the result or state is committed, it >>>> forces a read of the map and reconciliation with any pending >>>> modifications." >>>> >>>> My reading of this is that the value changes for anything that happens >>>> after the call to putIfAbsent. It would be good to make this clear, that >>>> any subsequent observation of this cell should observe the new value. >>>> >>>> Kenn >>>> >>>> On Fri, Aug 13, 2021 at 9:32 AM Reuven Lax <[email protected]> wrote: >>>> >>>>> Yeah - I remember thinking that the computeIfAbsent/putIfAbsent >>>>> semantics were very weird. I almost would have preferred not having those >>>>> methods in MapState, even though they can be useful. >>>>> >>>>> On Fri, Aug 13, 2021 at 9:21 AM Luke Cwik <[email protected]> wrote: >>>>> >>>>>> I was surprised to see the MapState API for >>>>>> computeIfAbsent/putIfAbsent only performs the write if the ReadableState >>>>>> that is returned is resolved. >>>>>> >>>>>> For example: >>>>>> ReadableState<String> value = mapState.putIfAbsent("key", "new value >>>>>> maybe"); >>>>>> does nothing until >>>>>> value.read(); >>>>>> >>>>>> It would seem like an obvious mistake for developers to make to >>>>>> forget to do the value.read() when coming from the Java Map API which >>>>>> always performs the write. >>>>>> >>>>>
