Student
Ну не очень, если честно. У меня при обновление токена с помощью Authenticator идет куча запросов
Сергій
знакомый кейс
Student
Student
и чакер показывает, что реаольно много запросов уходит на update токена
Mike
это что-то про чакры?
Student
и httpclient в logcat тоже срёт запросов 20, хотя все они завершаются успешно - 200
Anonymous
Почему при клике на кнопку ничего не происходит?
Mike
Почему при клике на кнопку ничего не происходит?
а почему должно? Кто вызовет метод onClick?
Сергей
да, он серый же
Student
https://gist.github.com/Denchabaev/e1a564448ff9784863381ee410b285dd
Сергій
да. она прописана в методе authenticate
кейс такой 1. уходит паралельно несколько запросов 2. кто-то первый фейлится с 401 и летит в аутентификатор 3. начинается обновление токена 4. другие запросы тоже начинают падать на 401 5. прилетают в аутентификатор тоже 6. первый запрос обновил токен и ты его закешировал например 7. другие запросы в аутентификаторе берут уже “валидный” токен и пытаются его заново обновить и снова падают
Student
такой вот код)
Сергій
у нас как-то так было
Student
и аннотация @synchronized тоже не помогает
Сергій
надо строить очередь
Сергій
пока кто-то обновляет токен, другие просто ждут
Student
надо строить очередь
очередь запросов строить на уровне презентеров или на уровне ретрофита/http клиента?
Сергій
реализация уже up to you
Mike
неужели нет готового?
Сергій
rx, lock… что хочешь
Mike
rx, lock… что хочешь
я про аутентификатор, который приостанавливает запросы
Сергій
я про аутентификатор, который приостанавливает запросы
он вызывается на потоке запроса, у окхттп есть свой пул потоков
Muzaffar
Александр спасибо
Student
так так, спасибо большое за ответы
Student
нужно подумать, как это правильнее сделать
Student
все методы для хождения в сеть у меня реактивные.
Student
ну я так понимаю, что это я должен каким-то образом okhttp клиенту задать свойство блокировки или ретрофиту
Сергій
ты можешь сделать отдельную сущность которая занимается обновлением токена, а все будут просто к ней подключатся в аутентикаторе и слушать или запускать обновление
Сергій
или быстрый фикс, сделать okhttp однопоточным 😁
Сергій
тогда все запросы будут последовательными
.
чет что Максус что Денис по 4 дня над одной задачей бтются
.
странно ето
Сергій
главное процесс 😉
.
я так рофлю
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
чет что Максус что Денис по 4 дня над одной задачей бтются
ну что-то тяжко идёт. сервер переделали с basic authentication на authentication с двумя токенами. и вроде бы задача проста, но что-то туго идёт)
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
ну заебашь через коладаптер
думаешь что OLD standard call adapter лучше rx?
Student
или быстрый фикс, сделать okhttp однопоточным 😁
можно подсказку, как это сделать)
.
дык унаследуй
.
и расширь
Сергій
можно подсказку, как это сделать)
в билдере OkHttp можно указать Dispatcher
.
можно в один поток но имхо костыль и быстрофикс
.
тогда в зипах не будет смысла)
Сергій
Student
спасибо
Aleksey
Кто какую техническую аналитику использует? Fabric Answers уже не хватает
Yakov
https://gist.github.com/Denchabaev/e1a564448ff9784863381ee410b285dd
Чувак перечитай про него
Yakov
Он и так сюда зайдёт если прилетит 401
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 секунды дорисуется до конца. Или сколько там надо. Потом стереть и заново