Vertx / RxJava / Retrofit阻止

时间:2019-05-10 22:18:37

标签: kotlin server retrofit vert.x

我正在使用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)

,响应太大。有什么想法可以避免阻塞吗?

1 个答案:

答案 0 :(得分:0)

我看到两种解决您的问题的方法:

  1. 使用异步http客户端获取 getLocationByCityName 。我不是在使用改造,而是在研究以下内容:https://futurestud.io/tutorials/retrofit-synchronous-and-asynchronous-requests它具有开箱即用的支持。
  2. 始终可以通过调用 vertx.executeblocking 在专用工作线程上执行阻止代码。可以在这里阅读:https://vertx.io/docs/vertx-core/java/#blocking_code

我建议使用选项1,因为它更干净。