Student
Ну не очень, если честно. У меня при обновление токена с помощью Authenticator идет куча запросов
Сергій
Сергій
знакомый кейс
Student
Student
и чакер показывает, что реаольно много запросов уходит на update токена
Mike
это что-то про чакры?
Student
и httpclient в logcat тоже срёт запросов 20, хотя все они завершаются успешно - 200
Anonymous
Почему при клике на кнопку ничего не происходит?
Mike
Сергей
да, он серый же
Student
https://gist.github.com/Denchabaev/e1a564448ff9784863381ee410b285dd
Сергій
да. она прописана в методе authenticate
кейс такой
1. уходит паралельно несколько запросов
2. кто-то первый фейлится с 401 и летит в аутентификатор
3. начинается обновление токена
4. другие запросы тоже начинают падать на 401
5. прилетают в аутентификатор тоже
6. первый запрос обновил токен и ты его закешировал например
7. другие запросы в аутентификаторе берут уже “валидный” токен и пытаются его заново обновить и снова падают
Student
такой вот код)
Сергій
у нас как-то так было
Student
Сергій
Student
и аннотация @synchronized тоже не помогает
Сергій
надо строить очередь
Сергій
пока кто-то обновляет токен, другие просто ждут
Student
надо строить очередь
очередь запросов строить на уровне презентеров или на уровне ретрофита/http клиента?
Сергій
реализация уже up to you
Mike
неужели нет готового?
Сергій
rx, lock… что хочешь
Muzaffar
Александр спасибо
Student
так так, спасибо большое за ответы
Student
нужно подумать, как это правильнее сделать
Student
все методы для хождения в сеть у меня реактивные.
Student
ну я так понимаю, что это я должен каким-то образом okhttp клиенту задать свойство блокировки или ретрофиту
Сергій
ты можешь сделать отдельную сущность которая занимается обновлением токена, а все будут просто к ней подключатся в аутентикаторе и слушать или запускать обновление
Сергій
или быстрый фикс, сделать okhttp однопоточным 😁
Сергій
тогда все запросы будут последовательными
.
чет что Максус что Денис по 4 дня над одной задачей бтются
.
странно ето
Mike
Сергій
главное процесс 😉
Denis
.
я так рофлю
Student
собственно, у меня так оно и есть. есть класс class AuthKeycloakRepository(private val authApi: AuthApi)
Его мы передаем такому интерактору: AuthKeycloakInteractor(
private val authKeycloakRepository: AuthKeycloakRepository,
private val accountManager: AccountManager
)
и есть AuthenticatorForOkHttpClient(
private val authKeycloakInteractor:AuthKeycloakInteractor,
private val accountManager: AccountManager,
private val router: Router
)
куда di передает репозиторий и api.
так же у меня два okhttpclient, один main - для лазания в сеть, ему я и навешиваю AuthenticatorForOkHttpClient, а другой OkHttpClient для AuthKeycloakInteractor. Как-то так я попытался разнести
.
ну все правильно. а колл адаптер есть?
.
код провайда ретрофита и окхттп из модуля покаж
Student
код провайда ретрофита и окхттп из модуля покаж
это для авторизации:
//region Authenticator
single(named("AuthenticatorClient")) {
with(OkHttpClient.Builder()) {
connectTimeout(30, TimeUnit.SECONDS)
readTimeout(30, TimeUnit.SECONDS)
addInterceptor(ErrorResponseInterceptor())
if (BuildConfig.DEBUG) {
addNetworkInterceptor(
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
)
addInterceptor(ChuckerInterceptor(get()))
}
build()
}
}
factory(named("AuthenticatorApi")) {
Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(get()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(get(named(name = "AuthenticatorClient")))
.baseUrl(getProperty(PROPERTY_SERVER_URL) as String)
.build()
.create(AuthApi::class.java)
}
//endregion
Student
а это основной:
//region Main
single(named("MainClient")) {
with(OkHttpClient.Builder()) {
connectTimeout(30, TimeUnit.SECONDS)
readTimeout(30, TimeUnit.SECONDS)
addInterceptor(ErrorResponseInterceptor())
authenticator(AuthenticatorForOkHttpClient(get(), get(), get()))
addInterceptor(AuthHeaderInterceptor(get()))
if (BuildConfig.DEBUG) {
addNetworkInterceptor(
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
)
addInterceptor(ChuckerInterceptor(get()))
}
build()
}
}
factory(named("MainApi")) {
Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(get()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(get(named(name = "MainClient")))
.baseUrl(getProperty(PROPERTY_SERVER_URL) as String)
.build()
.create(MainApi::class.java)
}
//endregion
.
ну заебашь через коладаптер
Student
а это authenticator для main client: https://gist.github.com/Denchabaev/e1a564448ff9784863381ee410b285dd
Student
.
дык унаследуй
.
и расширь
.
можно в один поток но имхо костыль и быстрофикс
.
тогда в зипах не будет смысла)
Сергій
Student
спасибо
Aleksey
Кто какую техническую аналитику использует?
Fabric Answers уже не хватает
Yakov
Yakov
Он и так сюда зайдёт если прилетит 401
Student
Yakov
Хм?
В аутинтификато попадают только запросы с 401, тебе точно не надо смотреть что это 401
Yakov
Хм?
Делаешь просто запрос на получения нового токен по рефреш токен
Yakov
Далее строишь из сфейленых запросов новые запросы с новым токеном
Yakov
val refreshResponse =
authApi.refreshTokenBlocking(RefreshTokenRequest(storage.refreshToken)).execute()
val accessToken = refreshResponse.body()?.accessToken
val refreshToken = refreshResponse.body()?.refreshToken
if (accessToken != null && refreshToken != null) {
storage.authToken = accessToken
storage.refreshToken = refreshToken
return response.request().newBuilder()
.addHeader("Authorization", accessToken)
.build()
}
Yakov
что типа этого
Yakov
а ну return null
Student
👍 спасибо. Попробую
Кирилл
Alexander
ребя подскажите, после перехода на androidx setNavigationItemSelectedListener подсвечивается красным
Line'R
Есть где почитать как реализовать такое кастомное вью с анимацией?
Line'R
Что то внятного не могу найти.
Сергей
Ну, без анимации я бы рисовал по канве, через DrawPath
Line'R
Надо анимировать. Что бы линия рисовалась постепенно
Сергей
с анимацией можно ей же, рисуя линию по точкам, но это гемор будет
Line'R
На канве и я могу просто нарисовать, но так оно статическое выходит
Сергей
надо сделать перехват onDraw, брать от текущего времени скажем 1/10 секунды и рисовать ее по 1/20 ширины.
Сергій
Path + PathDashPathEffect
Сергій
А пики можно с помощью Bezier curve
Сергей
тогда она за 2 секунды дорисуется до конца. Или сколько там надо. Потом стереть и заново