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]> * > >
