gpt4 book ai didi

java - 使用 RXJava 处理缓存

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:54:08 27 4
gpt4 key购买 nike

我正在尝试使用 rxJava 实现此工作流,但我确定我是否误用或做错了什么。

  • 用户要求登录
  • 如果 loginResult 在缓存中可用,则“发出”缓存的 LoginResult
  • 否则实际执行对 web 服务的请求,如果一切成功则缓存结果
  • 如果发生错误,最多重试 3 次,如果发生第 4 次,则清除缓存。

这是我的完整代码 fragment 。

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"));
}
}
}
});
}
}
}

因为我找不到任何类似的例子,而且我在 1 天前才开始“玩”rxjava,所以我不确定我的实现。

感谢您的宝贵时间。

最佳答案

我认为这段代码没问题,干得好:)

您在 LoginTask 中使用 Observable.create 是正确的,否则调用的结果可能会在内部缓存,然后 retry 将不会帮助很大...

我认为这对于 CachedLoginResultObservable 来说是不必要的。在这里,您可以使用 Observable.justObservable.error 实用方法来简化代码,例如:

public Observable<LoginResult> getObservable() {
if (hasCache()) {
return Observable.just(lr);
} else {
return Observable.error(new RuntimeException("No cache"));
}
}

注意:只是 存储您告诉它在内部发出的值,因此重新订阅将始终产生该值。这就是我在上面暗示的,例如,您不应该执行 Observable.just(performRequest()).retry(3),因为 performRequest 只会被调用一次。

关于java - 使用 RXJava 处理缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29924337/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com