vertx中的同步调用

时间:2018-05-03 08:31:57

标签: vert.x

我们尝试将项目从servlet重构为vertx3.x。我们希望重用负责查询数据的DAO层:

interace Adapter {
    List<Feature> query(String layer);
}

class DataBaseAdapter implements Adapter {

}

class FileAdapter implements Adapter {

}

class HttpVertx extends AbstractVertx {
    void start() {
        HttpServer server = vertx.createHttpServer();
        Router router = Router.router(vertx);
        router.route().handler((h->{
            List<Feature> r=new ArrayList();
            String[] layers=getLayerFromRequest(h.request());
            layers.forEach(l->{
                h.vertx().executeBlocking(future->{
                    future.complete(getAdapter(l).query(l));
                },false,res->{
                    List<Feature> data=res.result();
                    r.addAll(data);
                    //now how can I know that the loop have ended, and I can send the `r` to the client?
                });
            });

        }));
        server.requestHandler(router::accept).listen(8080);
    }

    Adapter getAdapter(String layer){
        //return database or file adapter accordingly
        return null;
    }
}

如图所示,原始adapter查询都是块操作,一旦我在循环中执行它们,我不知道它们何时完成。

此外,我不确定是否有必要使用DatabaseAdapter重构vertx-jdbc?如果是,我将不得不将Adapter接口的方法签名更改为同步,但FileAdapter不支持。{/ p>

什么是正确的重构解决方案?

2 个答案:

答案 0 :(得分:1)

  1. 尝试将循环逻辑移动到executeBlocking块并将处理程序类型更改为Handler<List<Feature>>

  2. 不,这并非绝对必要,因为在executeBlocking中包装这些调用已经在与Verticle的工作池进行数据库交互的昂贵工作。

答案 1 :(得分:0)

首先,不要使用executeBlocking() 。它打破了Vert.x的整个想法 其次,我建议重写你的DAO以返回Future。这将需要一些工作,但工作将非常简单。

在高层次上,它看起来应该是这样的:

// Use map(), as it returns value
List<Future> futures = layers.map((l) -> {
   return getAdapter(l).query(l);
});

CompositeFuture.all(futures).setHandler((r) -> {
   if (r.succeeded()) {
    // Continue here
   }
});