Fazer outra chamada de Retrofit na emissão de Assunto
Eu tenho uma classe a seguir:
public class SessionStore {
Subject<Session, Session> subject;
public SessionStore() {
subject = new SerializedSubject<>(BehaviorSubject.create(new Session());
}
public void set(Session session) {
subject.onNext(session);
}
public Observable<UserSession> observe() {
return subject.distinctUntilChanged();
}
}
Na atividade, observo a sessão e realizo a operação de rede em cada alteração:
private Subscription init() {
return sessionStore
.observe()
.flatMap(new Func1<Session, Observable<Object>>() {
@Override
public Observable<Object> call(Session session) {
return (session.isValid()
? retrofitService.getThingForValid()
: retrofitService.getThingForInalid())
.subscribeOn(Schedulers.io());
}
})
.subscribe(...);
}
Agora eu tenho um interceptador de solicitação Okhttp, no qual defino a instância da sessão de válida para inválida quando a resposta da rede não for um código 200.
Isto é o que acontece:
Na assinatura inicial para armazenar a sessão, ogetThingForValid()
é executado e falha.OkHttp intercepta a falha e define nova sessão.O armazenamento de sessões emite uma nova sessão agora inválida.A nova emissão executa umgetThingForInvalid()
método.O que é importante saber é que essa execução ocorre no meio da chamada de Retrofit anterior. Isso ocorre porque o cliente OkHttp é encapsulado pelo Retrofit e todos os interceptores são executados antes do retorno do Retrofit.
Tendo isso em mente, você percebe que a segunda chamada já está sendo executada e processada pelo Retrofit, enquanto a primeira ainda não foi concluída.
Quando a primeira chamada termina, ele lança HttpException porque a resposta era diferente do código 200.O xception mata o fluxo rx e com ele a segunda chamada.Tentei ignorar essa exceção no fluxo, mas a segunda chamada é cancelada pelo Retrofit de qualquer maneira.
Você tem alguma idéia de como fazer meu conceito funcionar, por favor?