У меня есть метод getClosesRegion, который должен делать следующее:
- Попытка подключения к каждому региону
- Первый регион для подключения (я использую запуск, чтобы попытаться подключиться) всем одновременно), должен быть возвращен, а остальные запросы региона должны быть отменено
- Если во всех регионах не удалось подключиться ИЛИ после 30-секундного тайм-аута, выдать исключение
Код: Выделить всё
override suspend fun getClosestRegion(): Region {
val regions = regionsRepository.getRegions()
val firstSuccessResult = MutableSharedFlow(replay = 1)
val scope = CoroutineScope(Dispatchers.IO)
// Attempts to connect to every region until the first success
scope.launch {
regions.forEach { region ->
launch {
val retrofitClient = buildRetrofitClient(region.backendUrl)
val regionAuthenticationAPI = retrofitClient.create(AuthenticationAPI::class.java)
val response = regionAuthenticationAPI.canConnect()
if (response.isSuccessful && scope.isActive) {
scope.cancel()
firstSuccessResult.emit(region)
}
}
}
}
val result = withTimeoutOrNull(TimeUnit.SECONDS.toMillis(30)) { firstSuccessResult.first() }
if (result != null)
return result
throw Exception("Failed to connect to any region")
}
- Если 1 регион был успешно подключен, я ожидаю, что запросы будут отменено (с помощьюscope.cancel()), но на самом деле другие регионы, которые успешно подключились ПОСЛЕ первого, также передают значение в поток (возвращает true)
Код: Выделить всё
scope.isActive
Я не знаю, как обрабатывать состояние гонки, вызывающее исключение, если во всех регионах не удалось подключиться или после 30-секундного тайм-аута
Подробнее здесь: https://stackoverflow.com/questions/724 ... -in-kotlin