Vertx / RxJava / Блокировка дооснащения - PullRequest
1 голос
/ 11 мая 2019

Я работаю на сервере Kotlin / Vertx / RxJava / Retrofit, но некоторые вызовы блокируют Vertx при вызове внешнего API, который занимает слишком много времени.

Исходный обработчик выполняет вызов:

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 голосов
/ 12 мая 2019

Я вижу два способа решения вашей проблемы:

  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, поскольку он более чистый.

...