https://kotlinlang.org logo
#rx
Title
# rx
y

yougin

11/15/2019, 11:07 AM
I need to do some clean up just right after all the `Subscriber`s unsubscribe from my
Observable
,
doOnUnsubscribe
is invoked upon unsubscribe (dispose) by each of them. Is there a way to wait until everyone unsubscribes?
b

bezrukov

11/15/2019, 12:08 PM
Most likely your
Observable
is cold, so in fact
Subscribers
subscribe to different observables. So most likely you need to convert your cold observable to hot, for example by
replay().refCount()
and then share it between subscribers. After that doOnUnsubscribe will be called only when every subscribe unsubscribes
y

yougin

11/15/2019, 12:10 PM
@bezrukov It's hot, I've tried
replay().refCount()
but it doesn't seem to make any difference, i.e.
doOnDispose
is invoked for every subscriber
b

bezrukov

11/15/2019, 12:11 PM
What is order of operators do you use?
y

yougin

11/15/2019, 12:12 PM
This same idea just crossed my mind, I used to have
doOnDispose
right before
replay().refCount()
, trying to place it after these two
Nope, got the same behaviour
So, it's
Copy code
myObservable
        .doOnSubscribe { init() }
        .replay()
        .refCount()
        .doOnDispose { cleanUp() }
b

bezrukov

11/15/2019, 12:36 PM
tried it now, and it works:
Copy code
private val cold = Observable.interval(1, TimeUnit.SECONDS)
    .subscribeOn(<http://Schedulers.io|Schedulers.io>())
    .observeOn(<http://Schedulers.io|Schedulers.io>())

private val hot = cold.doOnDispose { println("Cold dispose") }
    .replay().refCount()
    .doOnDispose { println("Hot dispose") }

fun main() {
    val first = hot
        .subscribe {
            println("1 $it")
        }
    val second = hot
        .subscribe {
            println("2 $it")
        }

    Thread.sleep(5000)
    println("dispose first")
    first.dispose()
    Thread.sleep(5000)
    println("dispose second")
    second.dispose()
    Thread.sleep(3000)
}
It prints
Hot dispose
twice, but
Cold dispose
once
y

yougin

11/15/2019, 12:54 PM
@bezrukov thank you, makes sense to me now.