У меня есть проблема с сопрограммой/потоком, которую я пытаюсь решить
У меня есть метод 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)
Я не знаю, как обрабатывать состояние гонки, вызывающее исключение, если во всех регионах не удалось подключиться или после 30-секундного тайм-аута
Кроме того, я новичок в Kotlin Flow и Coroutines, поэтому не знаю, действительно ли здесь необходимо создание потока
У меня есть проблема с сопрограммой/потоком, которую я пытаюсь решить У меня есть метод getClosesRegion, который должен делать следующее: [list] [*]Попытка подключения к каждому региону [*]Первый регион для подключения (я использую запуск, чтобы попытаться подключиться) всем одновременно), должен быть возвращен, а остальные запросы региона должны быть отменено [*]Если во всех регионах не удалось подключиться ИЛИ после 30-секундного тайм-аута, выдать исключение [/list] Это то, что у меня есть на данный момент: [code]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") } [/code] Проблемы с текущим кодом: [list] [*]Если 1 регион был успешно подключен, я ожидаю, что запросы будут отменено (с помощьюscope.cancel()), но на самом деле другие регионы, которые успешно подключились ПОСЛЕ первого, также передают значение в поток ([code]scope.isActive[/code] возвращает true) Я не знаю, как обрабатывать состояние гонки, вызывающее исключение, если во всех регионах не удалось подключиться или после 30-секундного тайм-аута [/list] Кроме того, я новичок в Kotlin Flow и Coroutines, поэтому не знаю, действительно ли здесь необходимо создание потока