FunctionService.onRegion is preferable to onPool or onServer if you
actually want to work with data in a region. The key is that within the
function, you want to make sure you actually use the data set for that
function context like this:

Region localData = PartitionRegionHelper.getLocalDataForContext(context)

Do not use PartitionRegionHelper.getLocalData(Region). The function service
divides up the buckets between different members and that information is
contained in the context. If you don't use the context like above, you may
end up covering the same buckets multiple times.

Another good option to consider is Spring Data Gemfire's function support.
SDG lets you annotate plain java methods and use them as functions. That
would help if you have a method that you want to execute as a geode
function and directly from some other java code, because you don't need to
worry about constructing a function context.
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/#function-annotations

-Dan

On Fri, Apr 15, 2016 at 1:36 PM, Matt Ross <[email protected]> wrote:

> Hi all,
>
> I'm involved in a sizable GemFire Project right now that is requiring me
> to execute Functions in a number of ways, and I wanted to poll the
> community for some best practices.  So initially I would execute all
> functions like this.
>
> ResultCollector<?, ?> rc = FunctionService.onRegion(region)
>     .withArgs(arguments).execute("my-awesome-function");
>
> And this worked reliably for quite some time, until I started mixing up 
> functions that were executing on partition redundant data and replicated 
> data.  I initially started having problems with this method when I had this 
> setup.
>
> 1 locator, 2 servers,  and executing functions that would run queries on 
> partition redundant and replicated regions.  I started getting this problem 
> where the function would execute on both servers, and the result collector 
> would indeterminately chose a server to return results from.  According to 
> logging statements placed within my function I was able to confirm that the 
> function was being executed twice, on both servers.  We were able to fix this 
> problem by switching from executing on region, to executing on Pool.  The 
> initial logic being since there was replicated data on both servers, the 
> function would execute on both servers(Hyptothesis).
>
> Another issue was executing functions from within a function without a 
> function context.  Let's say I have one function that I execute with on Pool, 
> there for it is passed a Function Context.  But when I'm actually in the 
> function I need to execute other functions, some needing a 
> RegionFunctionContext and some just needing a FunctionContext.  Initially I 
> was able to just use a Result Collector and FunctionService.onRegion to get a 
> region context, and then pass my current function context to an instance of a 
> new function
>
> MyAwesomeFunction myAwesomeFunction= MyAwesomeFunction();
>
> myAweSomeFunction.execute(functionContext);
>
> This worked for a time but complexity started rising and more problems came 
> up.
>
> So in short I wanted to throw out the blanket question of best practices on 
> using (onRegion/onPool/onServer), calling other functions from within 
> functions, what type of functions should be used on what type of regions, and 
> general design patterns when executing functions.  Thanks!
>
> *Matthew Ross | Data Engineer | Pivotal*
> *625 Avenue of the Americas NY, NY 10011*
> *516-941-7535 <516-941-7535> | [email protected] <[email protected]> *
>
>

Reply via email to