I need to log the time every time the upstream is subscribed to. That's fine, cause you can do
fun <T> Single<T>.markTime(name: () -> String): Single<T> = this
.doOnEvent { _, _ -> markElapsedTime(name() + "-on-event") }
However, this won't work for disposals. So we add
fun <T> Single<T>.markTime(name: () -> String): Single<T> = this
.doOnEvent { _, _ -> markElapsedTime(name() + "-on-event") }
.doOnDispose { markElapsedTime(name() + "-dispose") }
But this logs some events twice. How to avoid this? There seems to be no built-in rx operator which supports this. Not that doFinally won't work since it does the job only after downstream. We need to perform the action before calling downstream and be able to log disposals.
Of course you may do
fun <T> Single<T>.markTime(name: () -> String): Single<T> = compose {
var alreadyLogged = false
it.doOnEvent { _, _ ->
markElapsedTime(name())
alreadyLogged = true
}.doOnDispose { if (!alreadyLogged) markElapsedTime(name()) }
}
But this is a hack.