Description
boglesby opened DATAGEODE-295 and commented
This issue occurs with SBDG 1.2.1.RELEASE and also 1.2.2.RELEASE.
When my boot client executes an OnServers
function, I see it executing on all of my servers, but the result the caller gets back contains only 1 server's result instead of the expected collection.
I saw this behavior with the default ResultCollector
. If I add a custom ResultCollector
, I see addResult being invoked for each server's result. In my custom ResultCollector
, the addResult method does a put into a ConcurrentHashMap
.
The initial implementation of getResult was returning the ConcurrentHashMap
of results, but that failed with a ClassCastException
:
java.lang.ClassCastException: java.util.concurrent.ConcurrentHashMap cannot be cast to java.lang.Iterable
at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.execute(AbstractFunctionExecution.java:140) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.execute(AbstractFunctionExecution.java:95) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.AbstractFunctionExecution.executeAndExtract(AbstractFunctionExecution.java:158) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate.executeAndExtract(AbstractFunctionTemplate.java:79) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate.executeAndExtract(AbstractFunctionTemplate.java:57) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.GemfireOnServersFunctionTemplate.executeAndExtract(GemfireOnServersFunctionTemplate.java:45) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean.invokeFunction(GemfireFunctionProxyFactoryBean.java:102) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean.invoke(GemfireFunctionProxyFactoryBean.java:96) ~[spring-data-geode-2.2.1.RELEASE.jar:2.2.1.RELEASE]
ResultCollector.getResult
is not required to return an Iterable
in general.
AbstractFunctionExecution.executeAndExtract
gets the next element in the Iterable
and returns it:
<T> T executeAndExtract() {
Iterable<T> results = this.execute();
if (results != null && results.iterator().hasNext()) {
-> Object result = results.iterator().next();
if (result instanceof Throwable) {
throw new FunctionException(String.format("Execution of Function %s failed", this.function != null ? this.function.getClass().getName() : String.format("with ID [%s]", this.functionId)), (Throwable)result);
} else {
return result;
}
} else {
return null;
}
}
Any other elements in the Iterable
are lost. Is it expecting an Iterable
with one element which is the actual result?
If I change getResult in my custom ResultCollector
to return a SingletonSet
containing the actual result like this, it works:
return Collections.singleton(this.results);
No further details from DATAGEODE-295