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")
<T> T doLookup(Class<?> type, String functionDefinition, String[] expectedOutputMimeTypes) {
FunctionInvocationWrapper function = this.wrappedFunctionDefinitions.get(functionDefinition);
if (function == null) {
function = this.compose(type, functionDefinition);
}
@@ -269,10 +268,18 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
.filter(fr -> fr.getNames().contains(functionName))
.findFirst()
.orElseGet(() -> null);
return functionRegistration != null
FunctionInvocationWrapper function = functionRegistration != null
? this.invocationWrapperInstance(functionName, functionRegistration.getTarget(), functionRegistration.getType().getType())
: 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 = this.enrichInputIfNecessary(composedFunction);
this.wrappedFunctionDefinitions.put(composedFunction.functionDefinition, composedFunction);
if (composedFunction.isSingleton) {
this.wrappedFunctionDefinitions.put(composedFunction.functionDefinition, composedFunction);
}
}
}
if (logger.isDebugEnabled()) {
@@ -370,6 +379,8 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
private boolean skipOutputConversion;
private boolean isSingleton = true;
/*
* This is primarily to support Stream's ability to access
* 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) {
// if (functionAroundWrapper != null) {
// this.setSkipOutputConversion(true);
// }
this.target = target;
this.inputType = this.normalizeType(inputType);
this.outputType = this.normalizeType(outputType);
@@ -399,6 +407,10 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
this.message = this.inputType != null && FunctionTypeUtils.isMessage(this.inputType);
}
public boolean isPrototype() {
return this.isPrototype();
}
public void setSkipInputConversion(boolean skipInputConversion) {
if (logger.isDebugEnabled() && skipInputConversion) {
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();
}
@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
public void testSCF640() {
Echo function = new Echo();