GH-752 Add support to stop caching functions in FunctionCatalog

Resolves #752
This commit is contained in:
Oleg Zhurakousky
2021-10-07 15:02:06 +02:00
parent ad6cc60ea6
commit 150f140196
2 changed files with 52 additions and 7 deletions

View File

@@ -194,7 +194,6 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
<T> T doLookup(Class<?> type, String functionDefinition, String[] expectedOutputMimeTypes) { <T> T doLookup(Class<?> type, String functionDefinition, String[] expectedOutputMimeTypes) {
FunctionInvocationWrapper function = this.wrappedFunctionDefinitions.get(functionDefinition); FunctionInvocationWrapper function = this.wrappedFunctionDefinitions.get(functionDefinition);
if (function == null) { if (function == null) {
function = this.compose(type, functionDefinition); function = this.compose(type, functionDefinition);
} }
@@ -269,10 +268,18 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
.filter(fr -> fr.getNames().contains(functionName)) .filter(fr -> fr.getNames().contains(functionName))
.findFirst() .findFirst()
.orElseGet(() -> null); .orElseGet(() -> null);
return functionRegistration != null FunctionInvocationWrapper function = functionRegistration != null
? this.invocationWrapperInstance(functionName, functionRegistration.getTarget(), functionRegistration.getType().getType()) ? this.invocationWrapperInstance(functionName, functionRegistration.getTarget(), functionRegistration.getType().getType())
: null; : null;
if (functionRegistration != null && functionRegistration.getProperties().containsKey("singleton")) {
try {
function.isSingleton = Boolean.parseBoolean(functionRegistration.getProperties().get("singleton"));
}
catch (Exception e) {
// ignore
}
}
return function;
} }
/* /*
@@ -297,7 +304,9 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
composedFunction = (FunctionInvocationWrapper) composedFunction.andThen((Function<Object, Object>) andThenFunction); composedFunction = (FunctionInvocationWrapper) composedFunction.andThen((Function<Object, Object>) andThenFunction);
} }
composedFunction = this.enrichInputIfNecessary(composedFunction); composedFunction = this.enrichInputIfNecessary(composedFunction);
this.wrappedFunctionDefinitions.put(composedFunction.functionDefinition, composedFunction); if (composedFunction.isSingleton) {
this.wrappedFunctionDefinitions.put(composedFunction.functionDefinition, composedFunction);
}
} }
} }
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
@@ -370,6 +379,8 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
private boolean skipOutputConversion; private boolean skipOutputConversion;
private boolean isSingleton = true;
/* /*
* This is primarily to support Stream's ability to access * This is primarily to support Stream's ability to access
* un-converted payload (e.g., to evaluate expression on some attribute of a payload) * un-converted payload (e.g., to evaluate expression on some attribute of a payload)
@@ -389,9 +400,6 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
} }
FunctionInvocationWrapper(String functionDefinition, Object target, Type inputType, Type outputType) { FunctionInvocationWrapper(String functionDefinition, Object target, Type inputType, Type outputType) {
// if (functionAroundWrapper != null) {
// this.setSkipOutputConversion(true);
// }
this.target = target; this.target = target;
this.inputType = this.normalizeType(inputType); this.inputType = this.normalizeType(inputType);
this.outputType = this.normalizeType(outputType); this.outputType = this.normalizeType(outputType);
@@ -399,6 +407,10 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
this.message = this.inputType != null && FunctionTypeUtils.isMessage(this.inputType); this.message = this.inputType != null && FunctionTypeUtils.isMessage(this.inputType);
} }
public boolean isPrototype() {
return this.isPrototype();
}
public void setSkipInputConversion(boolean skipInputConversion) { public void setSkipInputConversion(boolean skipInputConversion) {
if (logger.isDebugEnabled() && skipInputConversion) { if (logger.isDebugEnabled() && skipInputConversion) {
logger.debug("'skipInputConversion' was explicitely set to true. No input conversion will be attempted"); logger.debug("'skipInputConversion' was explicitely set to true. No input conversion will be attempted");

View File

@@ -86,6 +86,39 @@ public class SimpleFunctionRegistryTests {
this.conversionService = new DefaultConversionService(); this.conversionService = new DefaultConversionService();
} }
@Test
public void testCachingOfFunction() {
Echo function = new Echo();
FunctionRegistration<Echo> registration = new FunctionRegistration<>(
function, "echo").type(FunctionType.of(Echo.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter,
new JacksonMapper(new ObjectMapper()));
catalog.register(registration);
FunctionInvocationWrapper instanceA = catalog.lookup("echo", "application/json");
FunctionInvocationWrapper instanceb = catalog.lookup("echo", "text/plain");
FunctionInvocationWrapper instanceC = catalog.lookup("echo", "foo/bar");
assertThat(instanceA).isSameAs(instanceb).isSameAs(instanceC);
}
@Test
public void testNoCachingOfFunction() {
Echo function = new Echo();
FunctionRegistration<Echo> registration = new FunctionRegistration<>(
function, "echo").type(FunctionType.of(Echo.class));
registration.getProperties().put("singleton", "false");
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter,
new JacksonMapper(new ObjectMapper()));
catalog.register(registration);
FunctionInvocationWrapper instanceA = catalog.lookup("echo", "application/json");
FunctionInvocationWrapper instanceb = catalog.lookup("echo", "text/plain");
FunctionInvocationWrapper instanceC = catalog.lookup("echo", "foo/bar");
assertThat(instanceA).isNotSameAs(instanceb).isNotSameAs(instanceC);
}
@Test @Test
public void testSCF640() { public void testSCF640() {
Echo function = new Echo(); Echo function = new Echo();