Я пытаюсь реализовать этот рабочий процесс с помощью rxJava, но я уверен, что если я злоупотребляю или делаю неправильно.Обработка кэша с помощью RXJava
- Пользователь просит войти
- Если loginResult доступна в кэше, то «выбрасывают», сохраненную в кэше LoginResult
- Else фактически выполняет запрос к веб-сервиса и кэшировать результат, если все успешна
- Если ошибка повторяет попытку не более 3 раз, и если есть 4-й раз, то очистите кеш.
Вот мой полный фрагмент кода.
public class LoginTask extends BaseBackground<LoginResult> {
private static CachedLoginResult cachedLoginResult = new CachedLoginResult();
private XMLRPCClient xmlrpcClient;
private UserCredentialsHolder userCredentialsHolder;
@Inject
public LoginTask(XMLRPCClient client, UserCredentialsHolder userCredentialsHolder) {
this.xmlrpcClient = client;
this.userCredentialsHolder = userCredentialsHolder;
}
@Override
public LoginResult performRequest() throws Exception {
return UserApi.login(
xmlrpcClient,
userCredentialsHolder.getUserName(),
userCredentialsHolder.getPlainPassword());
}
@Override
public Observable<LoginResult> getObservable() {
return cachedLoginResult.getObservable()
.onErrorResumeNext(
Observable.create(
((Observable.OnSubscribe<LoginResult>) subscriber -> {
try {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(performRequest()); // actually performRequest
}
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
})
)
.doOnNext(cachedLoginResult::setLoginResult)
.retry((attempts, t) -> attempts < 3)
.doOnError(throwable -> cachedLoginResult.purgeCache())
);
}
private static class CachedLoginResult {
private LoginResult lr = null;
private long when = 0;
private CachedLoginResult() {
}
public boolean hasCache() {
return lr != null && when + TimeUnit.MILLISECONDS.convert(30, TimeUnit.MINUTES) > System.currentTimeMillis();
}
public void setLoginResult(LoginResult lr) {
if (lr != null) {
this.lr = lr;
this.when = System.currentTimeMillis();
}
}
public void purgeCache() {
this.lr = null;
this.when = 0;
}
public Observable<LoginResult> getObservable() {
return Observable.create(new Observable.OnSubscribe<LoginResult>() {
@Override
public void call(Subscriber<? super LoginResult> subscriber) {
if (!subscriber.isUnsubscribed()) {
if (hasCache()) {
subscriber.onNext(lr);
subscriber.onCompleted();
} else {
subscriber.onError(new RuntimeException("No cache"));
}
}
}
});
}
}
}
Поскольку я wan't смог найти подобные примеры и я начал «играть» с rxjava только 1 день назад я не уверен в моей реализации.
Спасибо за ваше время.
Здравствуй Саймон, правильно, если «м неправильно, но с помощью Анжелеса и .error заставит значение испускаются при наблюдаемом создании. Что произойдет, если я создам основное наблюдаемое и использую его после истечения срока действия кэша? Думаю, он просто вернет мне 30-минутный кеш, который должен быть истек уже сейчас? –
Вы правы, просто захватите значение кеша в тот момент, когда вы вызываете getObservable(), поэтому «Observable.create» или «Observable.defer» будет иметь смысл. Также посмотрите на ответ Акарнокда;) –