...
However, the common case is that the user wants to send a single result, so we should provide a simpler function interface for this case that has a single return value.
Function code must exist on the client
The function service API provides a way to invoke functions by id, for example
Code Block |
---|
FunctionService.onServer().execute("MY_FUNCTION_ID") |
However, internally, we look up the function object itself from the function service in order to read the isHA, optimizeForWrite, and hasResult properties of the function. That means the code must exist on the client and must be registered with the FunctionService.
This is also an opportunity for the user to see an exception if the class on the client does not match the class on the server for these properties.
Lambdas and functions
Lambdas cannot be used for Geode functions, because there are multiple non abstract methods on function like hasResult, isHA, etc.
It would be nice to able to write short functions as lambda expressions, For example
Code Block |
---|
FunctionService.onMembers().execute( () -> System.out.println() ); |
However, that is not possible currently because Function has several non default methods.
We can also get rid of FunctionAdapter in favor of using default methods on Function.
Suggested API changes
Instead of a single Function interface, there should be multiple interfaces for different types of functions. TODO - Do we really need VoidFunction (equivalent to hasResult() == false)
Code Block |
---|
interface RegionFunction<T> {
public T execute(RegionFunctionContext context)
}
interface Function<T> {
public T execute(FunctionContext context)
} |
RegionFunctionContext should have a method to the local data for the context
Code Block |
---|
RegionFunctionContext {
public Region getLocalData();
} |
isHA, optimizeForWrite, and hasResult should be removed from Function and should be added to Execution instead
ResultCollector should have an addException method
Code Block |
---|
public interface ResultCollector<T,S> {
public void addException(DistributedMember member, Throwable t);
...
} |
Example of the improved API
Code Block |
---|
FunctionService functionService = cache.getFunctionService();
//RegionFunction with a single result
ResultCollector<String, Collection<String>> rc = functionService.onRegion(region)
.execute(ctx -> ctx.getLocalData().get("key"))
Collection<String> values = rc.getResult()
//RegionFunction without a result, that is optimized for write, but is not HA
functionService.onRegion(region)
.optimizeForWrite(true)
.isHA(true)
.hasResult(false)
.execute(ctx -> ctx.getLocalData().put("key", "value))
|