You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/02/18 09:55:58 UTC
[isis] branch master updated: ISIS-2158: simplify QueryResultCache
usage
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 8040ab2 ISIS-2158: simplify QueryResultCache usage
8040ab2 is described below
commit 8040ab2d3c32e388151ce631001aaa363508b704
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Feb 18 10:55:45 2020 +0100
ISIS-2158: simplify QueryResultCache usage
---
.../queryresultscache/QueryResultsCache.java | 37 ++++++-
.../QueryResultsCacheDefault.java | 114 ++++++++++++++++-----
.../isis/applib/services/wrapper/AsyncWrap.java | 84 ++++-----------
.../core/commons/handler/MethodReferences.java | 95 +++++++++++++++++
.../runtimeservices/wrapper/AsyncWrapDefault.java | 16 +--
5 files changed, 248 insertions(+), 98 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java b/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java
index 33018f2..a3a6b4d 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java
@@ -21,6 +21,15 @@ package org.apache.isis.applib.services.queryresultscache;
import java.util.Arrays;
import java.util.concurrent.Callable;
+import org.apache.isis.core.commons.handler.MethodReferences.Call0;
+import org.apache.isis.core.commons.handler.MethodReferences.Call1;
+import org.apache.isis.core.commons.handler.MethodReferences.Call2;
+import org.apache.isis.core.commons.handler.MethodReferences.Call3;
+import org.apache.isis.core.commons.handler.MethodReferences.Call4;
+import org.apache.isis.core.commons.handler.MethodReferences.Call5;
+
+
+
/**
* This service (API and implementation) provides a mechanism by which idempotent query results can be cached for the duration of an interaction.
* Most commonly this allows otherwise "naive" - eg that makes a repository call many times within a loop - to
@@ -33,6 +42,30 @@ import java.util.concurrent.Callable;
*/
public interface QueryResultsCache {
+ // -- INTERFACE
+
+ public <T> T execute(Callable<T> callable, Class<?> callingClass, String methodName, Object... keys);
+
+ <R> R execute(Call0<? extends R> action, Class<?> callingClass, String methodName);
+
+ <R, A0> R execute(Call1<? extends R, A0> action, Class<?> callingClass, String methodName,
+ A0 arg0);
+
+ <R, A0, A1> R execute(Call2<? extends R, A0, A1> action, Class<?> callingClass, String methodName,
+ A0 arg0, A1 arg1);
+
+ <R, A0, A1, A2> R execute(Call3<? extends R, A0, A1, A2> action, Class<?> callingClass, String methodName,
+ A0 arg0, A1 arg1, A2 arg2);
+
+ <R, A0, A1, A2, A3> R execute(Call4<? extends R, A0, A1, A2, A3> action, Class<?> callingClass, String methodName,
+ A0 arg0, A1 arg1, A2 arg2, A3 arg3);
+
+ <R, A0, A1, A2, A3, A4> R execute(Call5<? extends R, A0, A1, A2, A3, A4> action, Class<?> callingClass, String methodName,
+ A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4);
+
+ public void resetForNextTransaction();
+
+
// -- KEY
public static class Key {
@@ -116,10 +149,6 @@ public interface QueryResultsCache {
}
}
- // -- INTERFACE
-
- public <T> T execute(Callable<T> callable, Class<?> callingClass, String methodName, Object... keys);
- public void resetForNextTransaction();
}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheDefault.java b/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheDefault.java
index 6f3e79c..5ddf15c 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheDefault.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheDefault.java
@@ -32,6 +32,12 @@ import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.services.WithTransactionScope;
+import org.apache.isis.core.commons.handler.MethodReferences.Call0;
+import org.apache.isis.core.commons.handler.MethodReferences.Call1;
+import org.apache.isis.core.commons.handler.MethodReferences.Call2;
+import org.apache.isis.core.commons.handler.MethodReferences.Call3;
+import org.apache.isis.core.commons.handler.MethodReferences.Call4;
+import org.apache.isis.core.commons.handler.MethodReferences.Call5;
import org.apache.isis.core.commons.internal.base._Casts;
import org.apache.isis.core.commons.internal.base._NullSafe;
import org.apache.isis.core.commons.internal.collections._Maps;
@@ -58,6 +64,64 @@ import lombok.extern.log4j.Log4j2;
public class QueryResultsCacheDefault implements QueryResultsCache, WithTransactionScope {
private final Map<Key, Value<?>> cache = _Maps.newHashMap();
+
+ @Override
+ public <R> R execute(Call0<? extends R> action, Class<?> callingClass, String methodName) {
+ if(isIgnoreCache()) {
+ return action.call();
+ }
+ final Key cacheKey = new Key(callingClass, methodName);
+ return executeWithCaching(()->action.call(), cacheKey);
+ }
+
+ @Override
+ public <R, A0> R execute(Call1<? extends R, A0> action, Class<?> callingClass, String methodName, A0 arg0) {
+ if(isIgnoreCache()) {
+ return action.call(arg0);
+ }
+ final Key cacheKey = new Key(callingClass, methodName, arg0);
+ return executeWithCaching(()->action.call(arg0), cacheKey);
+ }
+
+ @Override
+ public <R, A0, A1> R execute(Call2<? extends R, A0, A1> action, Class<?> callingClass, String methodName, A0 arg0,
+ A1 arg1) {
+ if(isIgnoreCache()) {
+ return action.call(arg0, arg1);
+ }
+ final Key cacheKey = new Key(callingClass, methodName, arg0, arg1);
+ return executeWithCaching(()->action.call(arg0, arg1), cacheKey);
+ }
+
+ @Override
+ public <R, A0, A1, A2> R execute(Call3<? extends R, A0, A1, A2> action, Class<?> callingClass, String methodName,
+ A0 arg0, A1 arg1, A2 arg2) {
+ if(isIgnoreCache()) {
+ return action.call(arg0, arg1, arg2);
+ }
+ final Key cacheKey = new Key(callingClass, methodName, arg0, arg1, arg2);
+ return executeWithCaching(()->action.call(arg0, arg1, arg2), cacheKey);
+ }
+
+ @Override
+ public <R, A0, A1, A2, A3> R execute(Call4<? extends R, A0, A1, A2, A3> action, Class<?> callingClass,
+ String methodName, A0 arg0, A1 arg1, A2 arg2, A3 arg3) {
+ if(isIgnoreCache()) {
+ return action.call(arg0, arg1, arg2, arg3);
+ }
+ final Key cacheKey = new Key(callingClass, methodName, arg0, arg1, arg2, arg3);
+ return executeWithCaching(()->action.call(arg0, arg1, arg2, arg3), cacheKey);
+ }
+
+ @Override
+ public <R, A0, A1, A2, A3, A4> R execute(Call5<? extends R, A0, A1, A2, A3, A4> action, Class<?> callingClass,
+ String methodName, A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
+ if(isIgnoreCache()) {
+ return action.call(arg0, arg1, arg2, arg3, arg4);
+ }
+ final Key cacheKey = new Key(callingClass, methodName, arg0, arg1, arg2, arg3, arg4);
+ return executeWithCaching(()->action.call(arg0, arg1, arg2, arg3, arg4), cacheKey);
+ }
@Override
public <T> T execute(
@@ -76,18 +140,6 @@ public class QueryResultsCacheDefault implements QueryResultsCache, WithTransact
return executeWithCaching(callable, cacheKey);
}
-//XXX not used
-// private <T> T execute(final Callable<T> callable, final Key cacheKey) {
-// if(isIgnoreCache()) {
-// try {
-// return callable.call();
-// } catch (Exception e) {
-// throw new RuntimeException(e);
-// }
-// }
-// return executeWithCaching(callable, cacheKey);
-// }
-
private <T> T executeWithCaching(final Callable<T> callable, final Key cacheKey) {
try {
final Value<?> cacheValue = cache.get(cacheKey);
@@ -113,18 +165,6 @@ public class QueryResultsCacheDefault implements QueryResultsCache, WithTransact
}
}
-//XXX not used
-// private <T> Value<T> get(final Class<?> callingClass, final String methodName, final Object... keys) {
-// return get(new Key(callingClass, methodName, keys));
-// }
-//
-// @SuppressWarnings("unchecked")
-// private <T> Value<T> get(final Key cacheKey) {
-// Value<T> value = (Value<T>) cache.get(cacheKey);
-// logHitOrMiss(cacheKey, value);
-// return value;
-// }
-
private <T> void put(final Key cacheKey, final T result) {
log.debug("PUT: {}", cacheKey);
cache.put(cacheKey, new Value<T>(result));
@@ -159,5 +199,31 @@ public class QueryResultsCacheDefault implements QueryResultsCache, WithTransact
return _NullSafe.stream(cacheControl)
.anyMatch(c->c.isIgnoreCache());
}
+
+ // -- REMOVED
+
+ //XXX not used
+// private <T> Value<T> get(final Class<?> callingClass, final String methodName, final Object... keys) {
+// return get(new Key(callingClass, methodName, keys));
+// }
+//
+// @SuppressWarnings("unchecked")
+// private <T> Value<T> get(final Key cacheKey) {
+// Value<T> value = (Value<T>) cache.get(cacheKey);
+// logHitOrMiss(cacheKey, value);
+// return value;
+// }
+
+ //XXX not used
+// private <T> T execute(final Callable<T> callable, final Key cacheKey) {
+// if(isIgnoreCache()) {
+// try {
+// return callable.call();
+// } catch (Exception e) {
+// throw new RuntimeException(e);
+// }
+// }
+// return executeWithCaching(callable, cacheKey);
+// }
}
\ No newline at end of file
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/AsyncWrap.java b/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/AsyncWrap.java
index 9b4bdd3..f042d97 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/AsyncWrap.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/AsyncWrap.java
@@ -24,6 +24,16 @@ import java.util.function.Consumer;
import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
import org.apache.isis.core.commons.collections.ImmutableEnumSet;
+import org.apache.isis.core.commons.handler.MethodReferences.Call1;
+import org.apache.isis.core.commons.handler.MethodReferences.Call2;
+import org.apache.isis.core.commons.handler.MethodReferences.Call3;
+import org.apache.isis.core.commons.handler.MethodReferences.Call4;
+import org.apache.isis.core.commons.handler.MethodReferences.Call5;
+import org.apache.isis.core.commons.handler.MethodReferences.Run1;
+import org.apache.isis.core.commons.handler.MethodReferences.Run2;
+import org.apache.isis.core.commons.handler.MethodReferences.Run3;
+import org.apache.isis.core.commons.handler.MethodReferences.Run4;
+import org.apache.isis.core.commons.handler.MethodReferences.Run5;
/**
* Binds to a domain object, to prepare for type-safe asynchronous action invocation.
@@ -35,60 +45,6 @@ import org.apache.isis.core.commons.collections.ImmutableEnumSet;
*/
public interface AsyncWrap<T> {
- // -- METHOD REFERENCE MATCHERS (WITHOUT RETURN VALUE)
-
- @FunctionalInterface
- public static interface Run0<T> {
- void run(T obj);
- }
-
- @FunctionalInterface
- public static interface Run1<T, A1> {
- void run(T obj, A1 arg1);
- }
-
- @FunctionalInterface
- public static interface Run2<T, A1, A2> {
- void run(T obj, A1 arg1, A2 arg2);
- }
-
- @FunctionalInterface
- public static interface Run3<T, A1, A2, A3> {
- void run(T obj, A1 arg1, A2 arg2, A3 arg3);
- }
-
- @FunctionalInterface
- public static interface Run4<T, A1, A2, A3, A4> {
- void run(T obj, A1 arg1, A2 arg2, A3 arg3, A4 arg4);
- }
-
- // -- METHOD REFERENCE MATCHERS (WITH RETURN VALUE)
-
- @FunctionalInterface
- public static interface Call0<T, R> {
- R call(T obj);
- }
-
- @FunctionalInterface
- public static interface Call1<T, R, A1> {
- R call(T obj, A1 arg1);
- }
-
- @FunctionalInterface
- public static interface Call2<T, R, A1, A2> {
- R call(T obj, A1 arg1, A2 arg2);
- }
-
- @FunctionalInterface
- public static interface Call3<T, R, A1, A2, A3> {
- R call(T obj, A1 arg1, A2 arg2, A3 arg3);
- }
-
- @FunctionalInterface
- public static interface Call4<T, R, A1, A2, A3, A4> {
- R call(T obj, A1 arg1, A2 arg2, A3 arg3, A4 arg4);
- }
-
// -- CONFIGURATION
ExecutorService getExecutor();
@@ -101,30 +57,30 @@ public interface AsyncWrap<T> {
// -- INVOCATION (WITH RETURN VALUE)
- <R> Future<R> call(Call0<? super T, ? extends R> action);
+ <R> Future<R> call(Call1<? extends R, ? super T> action);
- <R, A1> Future<R> call(Call1<? super T, ? extends R, A1> action,
+ <R, A1> Future<R> call(Call2<? extends R, ? super T, A1> action,
A1 arg1);
- <R, A1, A2> Future<R> call(Call2<? super T, ? extends R, A1, A2> action,
+ <R, A1, A2> Future<R> call(Call3<? extends R, ? super T, A1, A2> action,
A1 arg1, A2 arg2);
- <R, A1, A2, A3> Future<R> call(Call3<? super T, ? extends R, A1, A2, A3> action,
+ <R, A1, A2, A3> Future<R> call(Call4<? extends R, ? super T, A1, A2, A3> action,
A1 arg1, A2 arg2, A3 arg3);
- <R, A1, A2, A3, A4> Future<R> call(Call4<? super T, ? extends R, A1, A2, A3, A4> action,
+ <R, A1, A2, A3, A4> Future<R> call(Call5<? extends R, ? super T, A1, A2, A3, A4> action,
A1 arg1, A2 arg2, A3 arg3, A4 arg4);
// -- INVOCATION (WITHOUT RETURN VALUE)
- default Future<Void> run(Run0<? super T> action) {
+ default Future<Void> run(Run1<? super T> action) {
return call(obj->{
action.run(obj);
return null;
});
}
- default <A1> Future<Void> run(Run1<? super T, A1> action,
+ default <A1> Future<Void> run(Run2<? super T, A1> action,
A1 arg1) {
return call(obj->{
@@ -133,7 +89,7 @@ public interface AsyncWrap<T> {
});
}
- default <A1, A2> Future<Void> run(Run2<? super T, A1, A2> action,
+ default <A1, A2> Future<Void> run(Run3<? super T, A1, A2> action,
A1 arg1, A2 arg2) {
return call(obj->{
@@ -142,7 +98,7 @@ public interface AsyncWrap<T> {
});
}
- default <A1, A2, A3> Future<Void> run(Run3<? super T, A1, A2, A3> action,
+ default <A1, A2, A3> Future<Void> run(Run4<? super T, A1, A2, A3> action,
A1 arg1, A2 arg2, A3 arg3) {
return call(obj->{
@@ -151,7 +107,7 @@ public interface AsyncWrap<T> {
});
}
- default <A1, A2, A3, A4> Future<Void> run(Run4<? super T, A1, A2, A3, A4> action,
+ default <A1, A2, A3, A4> Future<Void> run(Run5<? super T, A1, A2, A3, A4> action,
A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
return call(obj->{
diff --git a/core/commons/src/main/java/org/apache/isis/core/commons/handler/MethodReferences.java b/core/commons/src/main/java/org/apache/isis/core/commons/handler/MethodReferences.java
new file mode 100644
index 0000000..2fa4266
--- /dev/null
+++ b/core/commons/src/main/java/org/apache/isis/core/commons/handler/MethodReferences.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.core.commons.handler;
+
+import lombok.experimental.UtilityClass;
+
+/**
+ *
+ * @since 2.0
+ *
+ */
+@UtilityClass
+public class MethodReferences {
+
+ // -- METHOD REFERENCE MATCHERS (WITHOUT RETURN VALUE)
+
+ @FunctionalInterface
+ public static interface Run0 {
+ void run();
+ }
+
+ @FunctionalInterface
+ public static interface Run1<A0> {
+ void run(A0 arg0);
+ }
+
+ @FunctionalInterface
+ public static interface Run2<A0, A1> {
+ void run(A0 arg0, A1 arg1);
+ }
+
+ @FunctionalInterface
+ public static interface Run3<A0, A1, A2> {
+ void run(A0 arg0, A1 arg1, A2 arg2);
+ }
+
+ @FunctionalInterface
+ public static interface Run4<A0, A1, A2, A3> {
+ void run(A0 arg0, A1 arg1, A2 arg2, A3 arg3);
+ }
+
+ @FunctionalInterface
+ public static interface Run5<A0, A1, A2, A3, A4> {
+ void run(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4);
+ }
+
+ // -- METHOD REFERENCE MATCHERS (WITH RETURN VALUE)
+
+ @FunctionalInterface
+ public static interface Call0<R> {
+ R call();
+ }
+
+ @FunctionalInterface
+ public static interface Call1<R, A0> {
+ R call(A0 arg0);
+ }
+
+ @FunctionalInterface
+ public static interface Call2<R, A0, A1> {
+ R call(A0 arg0, A1 arg1);
+ }
+
+ @FunctionalInterface
+ public static interface Call3<R, A0, A1, A2> {
+ R call(A0 arg0, A1 arg1, A2 arg2);
+ }
+
+ @FunctionalInterface
+ public static interface Call4<R, A0, A1, A2, A3> {
+ R call(A0 arg0, A1 arg1, A2 arg2, A3 arg3);
+ }
+
+ @FunctionalInterface
+ public static interface Call5<R, A0, A1, A2, A3, A4> {
+ R call(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4);
+ }
+
+}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/AsyncWrapDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/AsyncWrapDefault.java
index d660782..b441369 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/AsyncWrapDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/AsyncWrapDefault.java
@@ -30,6 +30,11 @@ import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.core.commons.collections.ImmutableEnumSet;
+import org.apache.isis.core.commons.handler.MethodReferences.Call1;
+import org.apache.isis.core.commons.handler.MethodReferences.Call2;
+import org.apache.isis.core.commons.handler.MethodReferences.Call3;
+import org.apache.isis.core.commons.handler.MethodReferences.Call4;
+import org.apache.isis.core.commons.handler.MethodReferences.Call5;
import org.apache.isis.core.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.runtime.context.IsisContext;
import org.apache.isis.core.runtime.session.IsisSessionFactory;
@@ -41,7 +46,6 @@ import lombok.NonNull;
import lombok.With;
import lombok.val;
import lombok.extern.log4j.Log4j2;
-
/**
*
* @since 2.0
@@ -83,7 +87,7 @@ class AsyncWrapDefault<T> implements AsyncWrap<T> {
// -- METHOD REFERENCE MATCHERS (WITH RETURN VALUE)
@Override
- public <R> Future<R> call(Call0<? super T, ? extends R> action) {
+ public <R> Future<R> call(Call1<? extends R, ? super T> action) {
if(shouldValidate()) {
// do validation synchronous (with the calling thread)
@@ -103,7 +107,7 @@ class AsyncWrapDefault<T> implements AsyncWrap<T> {
@Override
- public <R, A1> Future<R> call(Call1<? super T, ? extends R, A1> action, A1 arg1) {
+ public <R, A1> Future<R> call(Call2<? extends R, ? super T, A1> action, A1 arg1) {
if(shouldValidate()) {
// do validation synchronous (with the calling thread)
@@ -122,7 +126,7 @@ class AsyncWrapDefault<T> implements AsyncWrap<T> {
}
@Override
- public <R, A1, A2> Future<R> call(Call2<? super T, ? extends R, A1, A2> action, A1 arg1, A2 arg2) {
+ public <R, A1, A2> Future<R> call(Call3<? extends R, ? super T, A1, A2> action, A1 arg1, A2 arg2) {
if(shouldValidate()) {
// do validation synchronous (with the calling thread)
@@ -142,7 +146,7 @@ class AsyncWrapDefault<T> implements AsyncWrap<T> {
@Override
- public <R, A1, A2, A3> Future<R> call(Call3<? super T, ? extends R, A1, A2, A3> action,
+ public <R, A1, A2, A3> Future<R> call(Call4<? extends R, ? super T, A1, A2, A3> action,
A1 arg1, A2 arg2, A3 arg3) {
if(shouldValidate()) {
@@ -163,7 +167,7 @@ class AsyncWrapDefault<T> implements AsyncWrap<T> {
@Override
- public <R, A1, A2, A3, A4> Future<R> call(Call4<? super T, ? extends R, A1, A2, A3, A4> action,
+ public <R, A1, A2, A3, A4> Future<R> call(Call5<? extends R, ? super T, A1, A2, A3, A4> action,
A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
if(shouldValidate()) {