我正在使用带有Kotlin语言的Vertx web和Verticle编写一个Web服务项目。当我尝试切换到Vertx Sync以停止进入回调地狱时,我的代码的某些部分在没有理由的情况下运行了不止一次。使用旧的回调结构时,没有这样的问题。这是一些示例代码:
router.post("/layers").handler(fiberHandler { routingContext ->
val request = routingContext.request()
val response = request.response()
response.putHeader("content-type", "application/json")
val layer = gson.fromJson<Layer>(routingContext.bodyAsString, Layer::class.java)
val layerResult = awaitResult<Message<UUID>> { vert.eventBus().send("PersistLayer", layer, it) }
val viewResult = awaitResult<Message<Long>> { vert.eventBus().send("CreateView", layerResult.body(), it) }
response.isChunked = true
response.write(gson.toJson(viewResult.body()))
response.statusCode = 201
})
一旦我把#34; PersisLayer&#34;行下一行多次运行。省略此行时,下一行运行一次。
这是PersistLayer代码:
vert.eventBus().consumer<Layer>("PersistLayer").handler {
val layer = it.body()
layer.sid = Generators.timeBasedGenerator().generate()
entityManager.apply {
transaction.begin()
persist(layer)
transaction.commit()
}
it.reply(layer.sid)
}
答案 0 :(得分:1)
我想我设法重现并解决了你的问题 不知道为什么你没有从Quasar那里得到很多例外。应该警告某些东西没有检测。
问题出在这一行:
router.post("/layers").handler(fiberHandler { routingContext -> ...
fiberHandler
实际上会收到一个处理程序,您可以隐式地在此处实现。
// That's what you actually do
class SomeHandler : Handler<RoutingContext> {
override fun handle(event: RoutingContext?) {
}
}
但该类在@Suspendable
方法上缺少handle
注释。
因此,不是指定一个块,而是创建一个单独的类,最好是在一个单独的文件中,看起来像这样:
class MyHandler(private val vertx: Vertx) : Handler<RoutingContext> {
@Suspendable
override fun handle(req: RoutingContext?) {
val result = Sync.awaitResult<Message<String>>({
vertx.eventBus().send("someAddress", "Hi", it)
})
println("Got response")
val result2 = Sync.awaitResult<Message<String>>({
vertx.eventBus().send("someAddress", "Hi", it)
})
println("Got second response")
req?.response()?.end(result.body() + result2.body())
}
}
不如原版那么好,但这不应该混淆Quasar。