如何将vert.x ReactiveReadStream <document>转换为ReactiveWriteStream <buffer>

时间:2017-11-07 16:29:04

标签: spring vert.x reactive

我有一个简单的用例。这是进行休息调用,查询mongo然后将任意大量的数据流返回给客户端,所有这些都使用反应流类型进行背压管理。

使用Spring WebFlux和Reactor很容易实现。我现在正尝试使用vert.x实现相同的目标,作为实现简易性的比较。

发现vert.x mongo客户端缺乏管理背压的支持,我现在尝试使用WebFlux mongo客户端,然后通过vert.x HttpResponse将数据泵回,如下面的代码所示:

public class MyMongoVerticle extends AbstractVerticle {

ReactiveMongoOperations operations;

public void start() throws Exception {

final Router router = Router.router(vertx);

router.route().handler(BodyHandler.create());

    router.get("/myUrl").handler(ctx -> {

      // WebFlux mongo operations returns a ReactiveStreams compatible entity
      Flux<Document> mongoStream = operations.findAll(Document.class, "myCollection");

      ReactiveReadStream rrs = ReactiveReadStream.readStream();
      // rrs is ReactiveStream streams subscriber
      mongoStream.subscribe(rrs);

      // Pump pumps the rrs (ReactiveReadStream) to the HttpServerResponse (ReactiveWriteStream)
      Pump pump = Pump.pump(rrs, ctx.response());
      pump.start();

    });

    vertx.createHttpServer().requestHandler(router::accept).listen(8777);
 }
}    

我遇到的问题是HttpServerResponse实现了ReactiveWriteStream&lt; Buffer&gt;所以期待缓冲而不是文档流。结果是ClassCaseException。

我的问题是如何将此文档流转换为ReactiveWriteStream&lt; Buffer&gt;?可能有另一种更好的方法可以做到这一点,所以我对其他如何实现这一点的建议持开放态度。

1 个答案:

答案 0 :(得分:0)

Pump不会为你工作,因为它目前不支持转换。你必须自己实施泵。幸运的是,这不应该太难:

       Flux<Document> mongoStream = operations.findAll(Document.class, "myCollection");

        ReactiveReadStream<Document> rrs = ReactiveReadStream.readStream();
        mongoStream.subscribe(rrs);

        HttpServerResponse outStream = ctx.response();
        // Changes start here
        rrs.handler(d -> {                
            if (outStream.writeQueueFull()) {
                outStream.drainHandler((s) -> {
                    rrs.resume();
                });
                rrs.pause();
            }
            else {
                outStream.write(d.toJson());
            }
        }).endHandler(h -> {
            outStream.end();
        });

请注意,我不希望这比#34; native&#34;更有效。 WebFlux实施。

此外,此示例中的JSON将被破坏,因为我没有将其包装在适当的JSON数组中