Java 番石榴的条件记忆法
我知道怎么做。然而,我只想在满足某些条件的情况下回忆。我调用的服务有时会返回一个不成功的响应。如果服务的响应成功,我只想回忆一下Java 番石榴的条件记忆法,java,caching,guava,memoization,Java,Caching,Guava,Memoization,我知道怎么做。然而,我只想在满足某些条件的情况下回忆。我调用的服务有时会返回一个不成功的响应。如果服务的响应成功,我只想回忆一下 MyResponse myResponse = myService.call() boolean success = myResponse.isSuccessful(); 我的缓存是这样创建的: 私有供应商缓存 private void createCache() { this.cache = Suppliers .memoizeWithEx
MyResponse myResponse = myService.call()
boolean success = myResponse.isSuccessful();
我的缓存是这样创建的:
私有供应商缓存代码>
private void createCache() {
this.cache = Suppliers
.memoizeWithExpiration(myService::call, timeout,
TimeUnit.MINUTES);
}
问题:只有在响应成功时,才可以使用传递给memoizeWiftation
方法的供应商,以某种方式缓存响应吗?
我发现的唯一解决方法是,在检索值时,首先调用cache.get()
,检查缓存中存储的对象是否成功,如果不成功,再次调用createCache()
清除它,然后再次获取值。这样,如果后续服务调用返回一个有效的对象,它将被存储,如果不是,每个后续调用都将清除缓存并再次调用该服务
public MyResponse getResponse() {
MyResponse myResponse = cache.get();
if (myResponse.isSuccess()) {
return myResponse;
} else {
createCache();
return cache.get();
}
}
然而,在这个解决方案中,如果缓存是空的,并且服务返回不成功的响应,它将立即被再次调用 您可以在服务类中或任何其他合适的位置创建一个方法Calluntilsucces
(这里我假设它在您的服务中)。您还可以在此方法中定义最大尝试次数,之后它将返回null,这样您就可以避免无限期地调用您的服务(下面提供的代码中没有实现此建议,但这样做非常容易)。正如Guava方法所期望的那样,您甚至可以使用此逻辑创建lambda,并将其直接传递给memoizewifthexpatition
方法
public MyResponse callUntilSuccess() {
MyResponse response = myService.call();
while (!response.isSuccessful()) {
response = myService.call();
}
return response;
}
然后以这种方式进行记录:
private void createCache() {
this.cache = Suppliers
.memoizeWithExpiration(myService::callUntilSuccess, timeout,
TimeUnit.MINUTES);
}
这就是你要找的吗
private void createCache() {
this.cache = Suppliers.memoizeWithExpiration(
Suppliers.compose(
response -> (response.isSuccess() ? response : null),
myService::call
),
timeout,
TimeUnit.MINUTES
);
}
在这里,它将缓存响应或null,这取决于它是否成功
MyResponse myResponse = myService.call()
boolean success = myResponse.isSuccessful();
有关compose
的更多信息,请点击此处
编辑:
如果您需要在成功时缓存该值,并在失败时将缓存留空,同时返回失败的请求,那么您自己就差不多做到了,只需在getResponse
中稍微更改返回逻辑,如下所示:
public MyResponse getResponse() {
final MyResponse myResponse = cache.get();
if (!myResponse.isSuccess()) {
this.createCache(); // clear cache
}
return myResponse; // don't call .get() again!
}
您在IMO中查看的位置不正确。您需要更改getResponse()
中的逻辑,以便在所有情况下都不使用cache.get()
,因为如果您成功地不进行有条件的缓存,则无法返回结果。也就是说,在else
分支中调用myService::call
,然后有条件地创建缓存。未缓存?->呼叫服务,成功吗?->缓存,否则返回错误,不缓存。你是对的,但我不知道是否可以调用服务,然后选择缓存响应而不再次调用服务-这就是我在这里要问的。memoizewexpatition
方法的全部要点是服务调用隐藏在缓存的get
方法下。因此,我将值放入缓存的唯一方法是调用调用下面的服务的get
方法。如果你知道如何使用番石榴来实现这一点,请写一个答案,我很乐意接受。在这一点上,你偏离了番石榴的假设。备忘录代码很简单,因此您可以复制它并使用其他用例进行扩展。是的,就是这样,非常简单!。另一个人先回答,所以我接受他的回答,但我也喜欢撰写的想法。非常感谢。