使用RxJava构建“任务队列”的最佳方法

时间:2018-04-21 22:31:14

标签: kotlin queue rx-java reactive-programming rx-java2

目前我正在研究许多与网络相关的功能。目前,我正在处理一个允许我一次发送1条单个信息的网络通道,在发送下一条信息之前,我必须等待它被确认。我用1..n个连接的客户端代表服务器。

其中一些消息,我必须以块的形式发送,这对于RxJava来说相当容易。目前我的“写作”方法看起来像这样:

fun write(bytes: ByteArray, ignoreMtu: Boolean) = 
    server.deviceList()
            .first(emptyList())
            .flatMapObservable { devices ->
                Single.fromCallable {
                    if (ignoreMtu) {
                        bytes.size
                    } else {
                        devices.minBy { device -> device.mtu }?.mtu ?: DEFAULT_MTU
                    }
                }
                        .flatMapObservable { minMtu ->
                            Observable.fromIterable(bytes.asIterable())
                                    .buffer(minMtu)
                        }
                        .map { it.toByteArray() }
                        .doOnNext { server.currentData = bytes }
                        .map { devices }
                        // part i've left out: waiting for each device acknowledging the message, timeouts, etc.
            }

这里缺少的是我只允许同时发送one条信息的部分。另外,我要求的是,如果我在队列中添加消息,我必须能够仅观察此消息的状态(已完成,错误)。

我已经考虑过实现这一目标的最优雅方式。我提出的解决方案包括例如PublishSubject<ByteArray>我在其中推送消息(类似队列),添加订阅者并观察它 - 但如果上一条消息,这将引发例如onError失败。

我想到的另一种方式是在创建/排队时给每个消息一个数字,并且有一个全局的“消息计数器”Observable,我将链接到链的开头filtercurrently sent message == MY_MESSAGE_ID。但这感觉有点脆弱。我可以在订阅终止时递增计数器,但我确信必须有更好的方法来实现我的目标。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

供将来参考:我发现最直接的方法是添加一个在单个线程上工作的调度程序,从而按顺序处理每个任务。