Как предотвратить параллельные запросы токенов обновления при использовании аутентификатора Retrofit/OkHttp?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как предотвратить параллельные запросы токенов обновления при использовании аутентификатора Retrofit/OkHttp?

Сообщение Anonymous »


Я только что наткнулся на проблему, когда я начал отправлять слишком параллельные запросы токенов обновления на встроенный сервер, который я построил, что вызвало проблемы с параллелизмом, когда возникает состояние гонки, в котором все эти параллельные запросы запрашивают и обновляют разные токены обновления на в то же время.

Единственное решение, которое я придумал, — это использовать StateFlow, Channel и сопрограмму ввода-вывода с незаданной областью для наблюдения за состоянием обновления, чтобы только первый запрос токена обновления был успешным, а пока он обновляется, другие параллельные запросы блокируются при наблюдении. пока они не получат сигнал от первого запроса токена обновления на использование нового токена.

Это работает, но я новичок в Kotlin и его API-интерфейсах сопрограмм, и это выглядит хаотично, я не могу с этим поделать, но думаю, что определенно есть более разумный способ подойти к этому.

класс MyAuthenticator @Inject конструктор( частный вал обновитьTokenUseCase: RefreshTokenUseCase, частный вал SharedPrefs: SharedPreferences ) : Аутентификатор { частный val isRefreshingToken = MutableStateFlow (false) частный вал newRequest = Channel() переопределить забаву аутентификации (маршрут: Маршрут?, ответ: Ответ): Запрос? { // логика для обработки блокировки параллельных запросов токена обновления, чтобы дождаться первого запроса токена обновления, чтобы использовать его вместо бесполезных вызовов API: если (isRefreshingToken.value) { CoroutineScope(Dispatchers.IO).launch { isRefreshingToken.collect { isRefreshingToken -> если (!isRefreshingToken) { val newToken =sharedPrefs.getToken().orEmpty() val req = response.request.newBuilder() .header("Авторизация", "Носитель $newToken") .строить() newRequest.send(требуется) } } } return runBlocking(Dispatcher.IO) { новыйRequest.receive() } } isRefreshingToken.value = true // логика для обработки обновления токена runBlocking(Dispatchers.IO) { обновитьTokenUseCase() // внутренне вызывает API токена обновления, а затем сохраняет токен в общих настройках }.let { результат -> isRefreshingToken.value = ложь вернуть, если (result.isSuccess) { val newToken =sharedPrefs.getToken().orEmpty() ответ.запрос.newBuilder() .header("Авторизация", "Носитель $newToken") .строить() } еще { // логика обработки сбоя (выход из системы и т. д.) нулевой } } } } Я обыскал весь стек и нашел много предложенных решений, но ни одно из них на самом деле не сработало, половина из которых предлагала использовать синхронизацию, чтобы заставить параллель запускаться упорядоченным образом, что по-прежнему расточительно вызывает API для обновлять токен слишком много раз.
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»