我希望在api帖子之前实现批处理机制,以进行一些简单的事件收集和日志记录。 由于这是Android设备,因此我也想处理该服务是否停止的生命周期事件,因此,如果该服务已停止但尚未达到计数或时间,那么手动刷新缓冲窗口的方法是什么。
例如,我有一个PublishSubject(主题),创建一个flowable并对其执行窗口操作,如下所示:
subject.toFlowable(BackpressureStrategy.BUFFER)
.window(30,
TimeUnit.SECONDS,
20,
true)
.flatMapSingle { it.toList() }
.subscribe (this::send)
如果我的服务/应用被暂停或终止,我只想发送缓冲区中的内容。
答案 0 :(得分:0)
您面临的问题是在必要时停止观察并刷新窗口中的当前项目。 Flowable.window()
运算符的文档说:
当源发布者完成或遇到错误时,结果发布者将发出当前窗口并传播来自源发布者的通知。
因此,您需要使Subject
发出错误或完成。在大多数情况下,这不是与主题打交道的正确方法。让我们将Subject
替换为易于完成的内容:
private val stopObserver = BehaviorSubject.create<Unit>() // (1)
private fun emitStop() { // (2)
stopObserver.onNext(Unit)
}
private fun sourceSubject(): Flowable<Long> { // (3)
return Flowable.interval(1, TimeUnit.SECONDS)
.takeUntil(stopObserver.toFlowable(BackpressureStrategy.BUFFER)) // (4)
}
private fun runObservation() { // (5)
sourceSubject()
.window(10)
.flatMapSingle { it.toList() }
.doOnNext { Log.d("onNext", "${it.count()} items") }
.subscribe()
}
重要部分的说明:
Subject
,它在您意识到应用停止或暂停时发出。onNext
向Subject
发出emitStop()
事件sourceSubject()
函数模仿您的来源Subject
。这个每秒发射一次物品。takeUntil()
运算符在传递的Publisher
(stopObserver
)发出项时完成流。这样可以确保我们的总体source Publisher
(sourceSubject
)完成。window()
运算符的简单版本,但是对于源发布者,它们都使用相同的原理。可能的输出:
2019-11-30 10:48:54.527 D/onNext: 10 items
2019-11-30 10:49:04.524 D/onNext: 10 items
2019-11-30 10:49:14.525 D/onNext: 10 items
2019-11-30 10:49:19.056 D/onNext: 4 items