Сначала давайте определим, как обновляется токен:
1) Если запроса на обновление токена еще нет, запустите новый
2) Если что-то уже происходит, просто подождите.
В Котлине это можно было бы записать как:
var retrieveToken : Deferred<String>? = null
suspend fun getToken(refresh: Boolean = false): String {
if(retrieveToken == null || refresh && !retrieveToken.isActive)
retrieveToken = async { API.getToken() }
return retrieveToken.await()
}
Теперь повторить попытку API становится довольно просто:
suspend fun requestAPIAndRetry(api: String) {
try {
val token = getToken()
val result = API.call(api, token)
} catch(error) {
// verifiy if it is 401
val token = getToken(refresh = true)
var result = API.call(api, token)
}
}
Теперь, если запросы начинают терпеть неудачу, происходит следующее:
1) Первый вызов getToken(refresh = true) запустит запрос к API и вернет его.
2) Все последующие вызовы будут иметь такой же отложенный вызов, как и первый вызов, поэтому все запросы просто ждут обновления одного токена.
3) Если токен есть, отложенное разрешение разрешится, и все API будут повторять попытку (возможно, даже параллельно).
person
Jonas Wilms
schedule
16.04.2019
job.onJoinв оператореselect. - person Marko Topolnik   schedule 17.04.2019