Late key generation for consistent evaluation of unless expressions

Includes removal of evict step on pipeline exception, retaining a previous cache value and avoiding an incomplete key (for consistency with non-reactive caching).

Closes gh-31626
This commit is contained in:
Juergen Hoeller
2023-11-22 00:27:32 +01:00
parent 1410c466b7
commit 5a3ad6b7c9
2 changed files with 36 additions and 36 deletions

View File

@@ -652,9 +652,8 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
@Nullable Object result, Collection<CachePutRequest> putRequests) {
for (CacheOperationContext context : contexts) {
if (isConditionPassing(context, result) && context.canPutToCache(result)) {
Object key = generateKey(context, result);
putRequests.add(new CachePutRequest(context, key));
if (isConditionPassing(context, result)) {
putRequests.add(new CachePutRequest(context));
}
}
}
@@ -943,22 +942,16 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
private final CacheOperationContext context;
private final Object key;
public CachePutRequest(CacheOperationContext context, Object key) {
public CachePutRequest(CacheOperationContext context) {
this.context = context;
this.key = key;
}
@Nullable
public Object apply(@Nullable Object result) {
if (result instanceof CompletableFuture<?> future) {
return future.whenComplete((value, ex) -> {
if (ex != null) {
performEvict(ex);
}
else {
performPut(value);
if (ex == null) {
performCachePut(value);
}
});
}
@@ -968,27 +961,20 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return returnValue;
}
}
performPut(result);
performCachePut(result);
return null;
}
void performPut(@Nullable Object value) {
if (logger.isTraceEnabled()) {
logger.trace("Creating cache entry for key '" + this.key + "' in cache(s) " +
this.context.getCacheNames());
}
for (Cache cache : this.context.getCaches()) {
doPut(cache, this.key, value);
}
}
void performEvict(Throwable cause) {
if (logger.isTraceEnabled()) {
logger.trace("Removing cache entry for key '" + this.key + "' from cache(s) " +
this.context.getCacheNames() + " due to exception: " + cause);
}
for (Cache cache : this.context.getCaches()) {
doEvict(cache, this.key, false);
public void performCachePut(@Nullable Object value) {
if (this.context.canPutToCache(value)) {
Object key = generateKey(this.context, value);
if (logger.isTraceEnabled()) {
logger.trace("Creating cache entry for key '" + key + "' in cache(s) " +
this.context.getCacheNames());
}
for (Cache cache : this.context.getCaches()) {
doPut(cache, key, value);
}
}
}
}
@@ -1017,11 +1003,10 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
@Override
public void onError(Throwable t) {
this.request.performEvict(t);
}
@Override
public void onComplete() {
this.request.performPut(this.cacheValue);
this.request.performCachePut(this.cacheValue);
}
}
@@ -1107,7 +1092,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
else {
return adapter.fromPublisher(Mono.from(adapter.toPublisher(result))
.doOnSuccess(request::performPut).doOnError(request::performEvict));
.doOnSuccess(request::performCachePut));
}
}
return NOT_HANDLED;