https://kotlinlang.org logo
Title
n

niqo01

04/08/2021, 3:06 AM
Is there a way to use
retry
based on a valid emitted value and not based on exception occuring? My emitted value looks like this
public sealed class BillingClientState{
        public object Initializing: BillingClientState()
        public data class Available(val client: BillingClient): BillingClientState()
        public object Unavailable: BillingClientState()
        public object Disconnected: BillingClientState()
    }
I want rety when Disconnected is triggered
e

ephemient

04/08/2021, 3:28 AM
one option:
.onEach { check(it !is Disconnected) }.retry(...)
probably could build something less throw-y worth
.transformWhile
fun <T> Flow<T>.retryWhen(predicate: suspend (T) -> Boolean) = transformWhile { if (predicate(it)) { emitAll(retryWhen(predicate)); false } else { emit(it); true } }
💯 3
untested, and of course you'd likely want some way to limit attempts, but that's an idea at least
a

Arun Joseph

01/21/2023, 9:13 PM
Any idea how would limit attempts? I tried using a recursive
retryWhen
but did not work.
e

ephemient

01/21/2023, 9:21 PM
should work if you add a counter and guard,
fun <T> Flow<T>.retryWhen(retries: Int = Int.MAX_VALUE, predicate: suspend (T) -> Boolean): Flow<T> {
    require(retries >= 0)
    return if (retries == 0) this else transformWhile {
        if (predicate(it)) {
            emitAll(retryWhen(retries - 1, predicate))
            false
        } else {
            emit(it)
            true
        }
    }
}
a

Arun Joseph

01/21/2023, 9:25 PM
Thanks a lot for a quick reply, will try this.