Skip to content

Commit

Permalink
Merge pull request #124 from anilibria/feature/configuration-update
Browse files Browse the repository at this point in the history
feat: always update config on start
  • Loading branch information
RadiationX authored Oct 31, 2023
2 parents d8affc2 + 6156c8c commit 4d40716
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ConfiguringAnalytics(
}


// больше не используется, но на всякий случай пусть будет
fun checkLast(
addressTag: String,
timeInMillis: Long,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package ru.radiationx.data.datasource.remote.api

import com.squareup.moshi.Moshi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEmpty
import kotlinx.coroutines.withTimeout
import ru.radiationx.data.ApiClient
import ru.radiationx.data.MainClient
import ru.radiationx.data.datasource.remote.Api
import ru.radiationx.data.datasource.remote.IClient
import ru.radiationx.data.datasource.remote.address.ApiConfig
import ru.radiationx.data.datasource.remote.fetchApiResponse
Expand All @@ -13,25 +18,16 @@ import ru.radiationx.data.entity.response.config.ApiConfigResponse
import javax.inject.Inject

class ConfigurationApi @Inject constructor(
@ApiClient private val client: IClient,
@MainClient private val mainClient: IClient,
private val apiConfig: ApiConfig,
private val moshi: Moshi
private val moshi: Moshi,
) {

suspend fun checkAvailable(apiUrl: String): Boolean {
return withTimeout(15_000) {
check(mainClient, apiUrl)
}
}

suspend fun checkApiAvailable(apiUrl: String): Boolean {
return withTimeout(15_000) {
try {
check(client, apiUrl)
} catch (ex: Throwable) {
false
}
mainClient
.postFull(apiUrl, mapOf("query" to "empty"))
.let { true }
}
}

Expand All @@ -43,12 +39,6 @@ class ConfigurationApi @Inject constructor(
}
}

private suspend fun check(client: IClient, apiUrl: String): Boolean {
return client
.postFull(apiUrl, mapOf("query" to "empty"))
.let { true }
}

private suspend fun getMergeConfig(): ApiConfigResponse {
val apiFlow = flow {
emit(getConfigFromApi())
Expand All @@ -71,7 +61,7 @@ class ConfigurationApi @Inject constructor(
"query" to "config"
)
val response = withTimeout(10_000) {
client.post(apiConfig.apiUrl, args)
mainClient.post(Api.DEFAULT_ADDRESS.api, args)
}
return response
.fetchApiResponse(moshi)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import ru.radiationx.data.datasource.remote.address.ApiAddress
import ru.radiationx.data.datasource.remote.address.ApiConfig
import ru.radiationx.data.entity.common.ConfigScreenState
import ru.radiationx.data.repository.ConfigurationRepository
import ru.radiationx.data.system.WrongHostException
import timber.log.Timber
import java.io.IOException
import java.util.concurrent.TimeoutException
import javax.inject.Inject
import javax.net.ssl.*

Expand All @@ -22,9 +19,11 @@ class ConfiguringInteractor @Inject constructor(
private val analytics: ConfiguringAnalytics,
) {

private val initialState = State.LOAD_CONFIG

private val screenState = MutableStateFlow(ConfigScreenState())

private var currentState = State.CHECK_LAST
private var currentState = initialState

private val scope = CoroutineScope(Dispatchers.Main.immediate + SupervisorJob())

Expand All @@ -38,8 +37,7 @@ class ConfiguringInteractor @Inject constructor(
fun initCheck() {
startAddressTag = apiConfig.tag
fullTimeCounter.start()
currentState = State.CHECK_LAST
updateState(currentState)
updateState(initialState)
doByState()
}

Expand All @@ -50,7 +48,7 @@ class ConfiguringInteractor @Inject constructor(

fun nextCheck() {
analytics.onNextStepClick(currentState.toAnalyticsState())
val nextState = getNextState() ?: State.CHECK_LAST
val nextState = getNextState() ?: initialState
doByState(nextState)
}

Expand Down Expand Up @@ -82,82 +80,21 @@ class ConfiguringInteractor @Inject constructor(
}

private fun doByState(anchor: State = currentState) = when (anchor) {
State.CHECK_LAST -> checkLast()
State.LOAD_CONFIG -> loadConfig()
State.CHECK_AVAIL -> checkAvail()
State.CHECK_PROXIES -> checkProxies()
}

private fun getNextState(anchor: State = currentState): State? = when (anchor) {
State.CHECK_LAST -> State.LOAD_CONFIG
State.LOAD_CONFIG -> State.CHECK_AVAIL
State.CHECK_AVAIL -> State.CHECK_PROXIES
State.CHECK_PROXIES -> null
}

private fun getTitleByState(state: State?): String? = when (state) {
State.CHECK_LAST -> "Проверка текущих адресов"
State.LOAD_CONFIG -> "Загрузка новых адресов"
State.CHECK_AVAIL -> "Проверка новых адресов"
State.CHECK_PROXIES -> "Проверка прокси-серверов"
else -> null
}

private fun checkLast() {
updateState(State.CHECK_LAST)
val timeCounter = TimeCounter()


scope.launch {
timeCounter.start()
screenState.update {
it.copy(
status = "Проверка доступности сервера",
needRefresh = false
)
}
runCatching {
zipLastCheck()
}.onSuccess { result ->
analytics.checkLast(apiConfig.tag, timeCounter.elapsed(), result, null)
if (result) {
isFullSuccess = true
screenState.update {
it.copy(status = "Сервер доступен")
}

apiConfig.updateNeedConfig(false)
} else {
loadConfig()
}
}.onFailure { error ->
analytics.checkLast(apiConfig.tag, timeCounter.elapsed(), false, error)
Timber.e(error)
when (error) {
is WrongHostException,
is TimeoutException,
is TimeoutCancellationException,
is IOException,
-> loadConfig()

else -> {
screenState.update {
it.copy(
status = "Ошибка проверки доступности сервера: ${error.message}",
needRefresh = true
)
}
}
}
}
}
}

private fun loadConfig() {
updateState(State.LOAD_CONFIG)
val timeCounter = TimeCounter()


scope.launch {
timeCounter.start()
screenState.update {
Expand Down Expand Up @@ -208,7 +145,7 @@ class ConfiguringInteractor @Inject constructor(
isFullSuccess = true
analytics.checkAvail(activeAddress.tag, timeCounter.elapsed(), true, null)
screenState.update {
it.copy(status = "Найдет доступный адрес")
it.copy(status = "Найден доступный адрес")
}
apiConfig.updateActiveAddress(activeAddress)
apiConfig.updateNeedConfig(false)
Expand Down Expand Up @@ -319,23 +256,13 @@ class ConfiguringInteractor @Inject constructor(
.first()
}

private suspend fun zipLastCheck(): Boolean {
val flowMain = flow { emit(configurationRepository.checkAvailable(apiConfig.apiUrl)) }
val flowApi = flow { emit(configurationRepository.checkApiAvailable(apiConfig.apiUrl)) }
return combine(flowMain, flowApi) { mainRes, apiRes ->
mainRes && apiRes
}.first()
}

private fun State.toAnalyticsState(): AnalyticsConfigState = when (this) {
State.CHECK_LAST -> AnalyticsConfigState.CHECK_LAST
State.LOAD_CONFIG -> AnalyticsConfigState.LOAD_CONFIG
State.CHECK_AVAIL -> AnalyticsConfigState.CHECK_AVAIL
State.CHECK_PROXIES -> AnalyticsConfigState.CHECK_PROXIES
}

private enum class State {
CHECK_LAST,
LOAD_CONFIG,
CHECK_AVAIL,
CHECK_PROXIES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ class ConfigurationRepository @Inject constructor(
.checkAvailable(apiUrl)
}

suspend fun checkApiAvailable(apiUrl: String): Boolean = withContext(Dispatchers.IO) {
configurationApi
.checkApiAvailable(apiUrl)
}

suspend fun getConfiguration(): ApiConfigData = withContext(Dispatchers.IO) {
configurationApi
.getConfiguration()
Expand Down

0 comments on commit 4d40716

Please sign in to comment.