Avoiding same-pool deadlocks when using Flowable in Reactive Extensions

那年仲夏 提交于 2020-01-25 08:58:45

问题


While subscribing to a Reactive Extensions Flowable stream, I noticed the stream halts/hangs (no more future items are emitted, and no error is returned) after 128 items have been returned.

val download: Flowable<DownloadedRecord> = sensor.downloadRecords()
download
    .doOnComplete { Log.i( "TEST", "Finished!" ) }
    .subscribe(
        { record ->
            Log.i( "TEST", "Got record: ${record.record.id}; left: ${record.recordsLeft}" )
        },
        { error ->
            Log.i( "TEST", "Error while downloading records: $error" )
        } )

Most likely, this is related to Reactive Extensions. I discovered the default buffer size of Flowable is set to 128; unlikely to be a coincidence.

While trying to understand what is happening, I ran into the following documentation on Flowable.subscribeOn.

If there is a create(FlowableOnSubscribe, BackpressureStrategy) type source up in the chain, it is recommended to have requestOn false to avoid same-pool deadlock because requests may pile up behind an eager/blocking emitter.

Although I do not quite understand what a same-pool deadlock is in this situation, it looks like something similar is happening to my stream.

1. What is a same-pool deadlock in Reactive Extensions? What would be a minimal code sample to recreate it (on Android)?

Currently at a loss, I tried applying .subscribeOn( Schedulers.io(), false ) before .subscribe, without really understanding what this does, but my stream still locks up after 128 items have been emitted.

2. How could I go about debugging this issue, and how/where can it be resolved?


回答1:


  1. What is a same-pool deadlock in Reactive Extensions?

RxJava uses single threaded executors in the standard schedulers. When a blocking or eager source is emitting items, it occupies this single thread and even though the downstream requests more, subscribeOn will schedule those requests behind the currently running/blocking code that then never gets notified about the new opportunities.

What would be a minimal code sample to recreate it (on Android)?

Why would you want code that deadlocks?

I tried applying .subscribeOn( Schedulers.io(), false )

What is your actual flow? You likely applied subscribeOn too far from the source and thus it has no effect. The most reliable is to put it right next to create.

How could I go about debugging this issue, and how/where can it be resolved?

Putting doOnNext and doOnRequest at various places and see where signals disappear.



来源:https://stackoverflow.com/questions/54116679/avoiding-same-pool-deadlocks-when-using-flowable-in-reactive-extensions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!