Proper set of operators to log execution time with disposals on timeouts

Viewed 17

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.

0 Answers
Related