You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am not sure whether it is a bug, intended behaviour or (leaking?) implementation detail, so posting it in the form of code snippet first, sorry for the inconvenience.
Consider the following subscriber:
private class TrivialSubscriber : Subscriber<Int> {
private val executor = Executors.newSingleThreadExecutor()
private var subscription: Subscription? = null
override fun onSubscribe(s: Subscription) {
subscription = s
subscription!!.request(1) // Initial request
}
override fun onNext(integer: Int) {
// "async" consumption
executor.submit {
println("Received $integer")
subscription!!.request(1) // Consumed -> request one more
}
}
override fun onError(t: Throwable) {}
override fun onComplete() {
executor.shutdown()
}
}
With map operator, the whole emitter output is firstly buffered, and only then mapped and collected. Thus the output looks like this (0 output is omitted):
Emitted: 1
Emitted: 2
...
Emitted: 9
Mapped 1
Received 1
...
Mapped 9
Received 9
If one removes map (which seems to be a trivial nop-op), the output changes drastically:
Emitted: 1
Received 1
...
Emitted: 9
Received 9
changing both the order of events and memory usage pattern. Is it an intended behaviour? Could you please elaborate on why it is happening or point out the relevant part of the documentation?
"If there is a create(FlowableOnSubscribe, BackpressureStrategy) type source up in the chain, it is recommended to use subscribeOn(scheduler, false) instead to avoid same-pool deadlock because requests may pile up behind an eager/blocking emitter."
If one removes map (which seems to be a trivial nop-op), the output changes drastically
We detect FlowableCreate directly upstream and use subscribeOn(scheduler, false) to preemptively workaround certain use cases.
publicfinalFlowable<T> subscribeOn(@NonNullSchedulerscheduler) {
Objects.requireNonNull(scheduler, "scheduler is null");
returnsubscribeOn(scheduler, !(thisinstanceofFlowableCreate));
}
Thanks, makes sense.
Just curious, could you please clarify, why you prefered this instanceof FlowableCreate check instead of traversing HasUpstreamPublisher and checking it with instanceof?
I am not sure whether it is a bug, intended behaviour or (leaking?) implementation detail, so posting it in the form of code snippet first, sorry for the inconvenience.
Consider the following subscriber:
and the following usage:
With
map
operator, the wholeemitter
output is firstly buffered, and only then mapped and collected. Thus the output looks like this (0
output is omitted):If one removes
map
(which seems to be a trivial nop-op), the output changes drastically:changing both the order of events and memory usage pattern. Is it an intended behaviour? Could you please elaborate on why it is happening or point out the relevant part of the documentation?
Please note that this is a watered-down reproducer of Kotlin/kotlinx.coroutines#1766
The text was updated successfully, but these errors were encountered: