Djuro
03/01/2024, 10:42 AMMutableValue or similar that doesn't reemit the same value. I am interested if there is something provided by the lib that has this behaviour.
I noticed that `MutableValue`'s compareAndSet reemit the same values. Is there if not that, then at least an atomic get that uses a mutex/lock so that I could perform a check before I update my MutableValue ?Arkadii Ivanov
03/01/2024, 11:29 AMDjuro
03/01/2024, 12:07 PMFlow.distinctUntilChanged()Arkadii Ivanov
03/01/2024, 12:21 PMMutableValue#compareAndSet specifically mentions "the comparison is preformed by reference". Though, I'm open to consider using equals instead, similarly to MutableStateFlow. The original idea was to replicate Rx BehaviorSubject . WDYT?
Currently there is no out-of-the-box way of achieving the desired behaviour. Though, since it's a state holder (not suitable for events in general), it shouldn't really matter and the UI should handle it just fine.Djuro
03/01/2024, 12:36 PMStateFlow also. As you mentioned, since it is a state holder in most cases, no need to emit the same value twiceArkadii Ivanov
03/01/2024, 1:01 PMDjuro
03/01/2024, 1:27 PMValue as a state holder. State is gradually being updated. It depends on a couple of api requests.
I use subscribe to observe these states and when specific new state is observed, then I update it to the new one. There is even one case where I need to wait for an api response before I update the state. Now for the last state (let's call it Complete) It has for example a List<String> representing the data. State can go from Complete to Complete again. Whenever Complete is collected it will trigger a check to see if this list has changed. If it has changed, update the state, otherwise don't do it.
When using for example
value.update{
if(conditionSatisfied) newState
else it
}
It will reemit itself there and Component subscribed to this value change will end up in an infinite loop causing an ANR.
I can use value on its own and do a check but this check should be done atomically to avoid race conditions IMO.
At the moment I do the check using the value I got when subscribed
newObservedValue.getFilteredValue().takeIf { it != newObservedValue )?.let{
value.compareAndSet(newObservedValue, it)
}
This works now, the only thing I am scared of is race condition leading to an invalid state in the endArkadii Ivanov
03/01/2024, 1:36 PMComponent subscribed to this value change will end up in an infinite loop causing an ANR.
This sounds scary, and I believe you might be doing something wrong. I wouldn't recommend relying on the equality behaviour here.
Usually in such cases I recommend using StateFlow or Rx, and do something like map { it.useful_part_of_the_state }.distinctUntilChanged(). So that the semantics is explicitly defined in the code.Djuro
03/01/2024, 1:39 PMValue API in this case then, or maybe just convert it using the snippet you providedArkadii Ivanov
03/01/2024, 1:47 PM