我想用rxJava來實現這個工作流程,但是我確定如果我濫用或做錯了什麼東西。用RXJava處理緩存
- 用戶要求登錄
- 如果loginResult在高速緩存中可用,那麼「發出」緩衝LoginResult
- 否則實際執行請求的web服務和緩存結果,如果一切全成
- 如果最多發生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'實際上是有意義的。也看看Akarnokd的答案;) –