kotlin - Vertx/RxJava/Retrofit 阻塞
问题描述
我正在使用 Kotlin/Vertx/RxJava/Retrofit 服务器,但是当调用需要太长时间的外部 API 时,一些调用会阻塞 Vertx。
原始处理程序进行调用:
val response = weatherService.getWeatherSummaryByCity(countryCode = queryParams[0], adminCode = queryParams[1], cityName = queryParams[2])
这反过来执行外部调用:
fun getWeatherSummaryByCity(countryCode: String, adminCode: String, cityName: String): WeatherSummary? {
val citiesList = externalAPI.getLocationByCityName(countryCode = countryCode, adminCode = adminCode, cityName = cityName)
var weatherSummary : WeatherSummary? = null
citiesList
.doOnError { error -> print(error) }
.filter { cityList -> !cityList.isEmpty() }
.map { cityList -> cityList[0] }
.filter { city -> city.Key != null && !city.Key.isEmpty() }
.subscribe( { city: City -> weatherSummary = createWeatherSummary(city) } )
return weatherSummary
}
这是Retrofit使用的界面
interface ExternalAPI {
@GET("/locations/{version}/cities/{countryCode}/{adminCode}/search.json")
fun getLocationByCityName(
@Path("version") version: String = "v1",
@Path("countryCode") countryCode: String,
@Path("adminCode") adminCode: String,
@Query("q") cityName: String,
@Query("apikey") apiKey: String = key,
@Query("details") details: String = "true",
@Query("language") language: String = "en-US"): Observable<List<City>>
}
代码按原样工作,但如果 externalAPI 花费的时间太长,它会阻止 Vertx。当我尝试这个时也会发生同样的情况:
Json.encodePrettily(response)
而且反应太大了。有什么想法可以避免阻塞吗?
解决方案
我看到两种方法来处理你的问题:
- 使用异步 http 客户端来获取getLocationByCityName。我没有使用改造,而是看这个:https ://futurestud.io/tutorials/retrofit-synchronous-and-asynchronous-requests它有开箱即用的支持。
- 阻塞代码总是可以通过调用vertx.executeblocking在专用工作线程上执行。这可以在这里阅读:https ://vertx.io/docs/vertx-core/java/#blocking_code
我会建议选项 1,因为它更干净。
推荐阅读
- python - 在 PDF 中搜索信息
- webrtc - WebRTC 媒体聊天中网络更改后的无效对等连接
- python-3.x - 如何使用 TLS 连接与服务器通信?
- kotlin - 如何在 Kotlin 中打乱可变列表的元素?
- c++ - pybind11(嵌入)导入到根命名空间
- javascript - .eslintrc 中的“插件”属性有什么作用?
- firebase - 如果文档 ID 包含字符串,则 Firebase Firestore 安全规则允许
- python - 在 Python 中使用“adb shell”
- python - 通过 python 运行 vba 宏,但你可以在 python 中添加进度条来测量 vba 进程吗?
- python - 如何将数据从表单保存到 django 模型?