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