重建嵌套的Observable

时间:2015-12-09 14:15:41

标签: system.reactive reactive-programming rx-java

这是一个初学者的问题。我将几个进程的输出流回到客户端,我想将每个流存储到一个单独的文件中。

所以我想要的是(大写字母表示嵌套流的结束)

S: -a-a-a-b-b-a-A-c-b-B-c-c-...-d--C...D-e--...-z-E-z--z--...

R:  a-a-a-----a-A (complete)
          b-b-------b-B (complete)
                  c-----c-c--------C (complete)
                                d------D (complete)
                                         e--------E (complete)

                     .
                     .
                     . 
       (end many more nested streams coming)
                     .

所以我想要像Observables的动态工厂。与using()类似,但据我所知using()创建的Observable与原始Observable一样长,而我想在每次嵌套流完成时完成并关闭文件。

重要 - 我不想在内存中缓冲,因为它们是非常长的流(长时间运行的进程的输出)。所以我想避免buffer()groupBy()

1 个答案:

答案 0 :(得分:1)

如果你可以从一个值中确定它是否是特定字母的最终结果,你可以在内部组中使用takeUntilsource .groupBy(v -> v.type) .flatMap(g -> Observable.using( () -> createOutput(g.getKey()), f -> g.takeUntil(v -> v.isEnd).doOnNext(v -> f.write(v))), f -> f.close() ) ) .subscribe(...) (你可能需要在lambdas中进行一些尝试捕获):

TakeUntil

groupBy确保groupBy只保留子流,只要我们期望它的值(如果源是正确排序的,groupBy不会重新创建群组)。

如果你真的想避免Observable.using( HashMap::new, map -> source .doOnNext(v -> { Output o = map.get(v.type); if (o == null) { o = new Output(v.type); map.put(v.type, o); } o.write(v); if (v.isEnd) { o.close(); map.remove(v.type); } }), map -> map.values().forEach(e -> e.close()) ) .subscribe(...); ,你必须手动跟踪每个打开的文件并在适当的时候关闭它们:

SELECT t.* , g.game_name , p.* 
FROM transaction_tbl t 
INNER JOIN game_tbl g ON g.game_id = t.game_id 
INNER JOIN payment_tbl p ON p.payment_id = t.payment_id 
WHERE t.customer_id = 1;