Distributed processing, particularly in conjunction with data access and mutation operations, is a very effective and efficient use of clustered computing resources. This is along the same lines as MapReduce.
A naively conceived query returning potentially hundreds of thousands, or even millions of rows of data in a result set back to the application that queried and requested the data can be very costly, especially under load. Therefore, it is typically more efficient to move the processing and computations on the predicated data set to where the data resides, perform the required computations, summarize the results and then send the reduced data set back to the client.
Additionally, when the computations are handled in parallel, across the cluster of computing resources, the operation can be performed much faster. This typically involves intelligently organizing the data using various partitioning (a.k.a. sharding) strategies to uniformly balance the data set across the cluster.
Well, both Apache Geode and Pivotal GemFire address this very important application concern in its Function Execution framework.
Spring Data for Apache Geode/Pivotal GemFire builds on this Function Execution framework by enabling developers to implement and execute GemFire/Geode Functions using a very simple POJO-based, annotation configuration model.
![]() | Tip |
---|---|
See here for the difference between Function implementation & executions. |
Taking this 1 step further, Spring Boot for Apache Geode/Pivotal GemFire auto-configures and enables both Function implementation and execution out-of-the-box. Therefore, you can immediately begin writing Functions and invoking them without having to worry about all the necessary plumbing to begin with. You can rest assured that it will just work as expected.
Earlier, when we talked about caching, we described a FinancialLoanApplicationService
class
that could process eligibility when a Person
applied for a financial loan.
This can be a very resource intensive & expensive operation since it might involve collecting credit and employment history, gathering information on existing, outstanding/unpaid loans, and so on and so forth. We applied caching in order to not have to recompute, or redetermine eligibility every time a loan office may want to review the decision with the customer.
But what about the process of computing eligibility in the first place?
Currently the application’s FinancialLoanApplicationService
class seems to be designed to fetch the data and perform
the eligibility determination in place. However, it might be far better to distribute the processing and even
determine eligibility for a larger group of people all at once, especially when multiple, related people are involved
in a single decision, as is typically the case.
We implement an EligibilityDeterminationFunction
class using SDG very simply as:
Function implementation.
@Component class EligibilityDeterminationFunction { @GemfireFunction(HA = true, hasResult = true, optimizeForWrite=true) public EligibilityDecision determineEligibility(FunctionContext functionContext, Person person, Timespan timespan) { ... } }
Using the SDG @GemfireFunction
annotation, it is easy to implement our Function as a POJO method. SDG handles registering this POJO method
as a proper Function with GemFire/Geode appropriately.
If we now want to call this Function from our Spring Boot, ClientCache
application, then we simply define
a Function Execution interface with a method name matching the Function name, and targeting the execution
on the "EligibilityDecisions" Region:
Function execution.
@OnRegion("EligibilityDecisions") interface EligibilityDeterminationExecution { EligibilityDecision determineEligibility(Person person, Timespan timespan); }
We can then inject the EligibilityDeterminationExecution
into our FinancialLoanApplicationService
like any other
object/Spring bean:
Function use.
@Service class FinancialLoanApplicationService { private final EligibilityDeterminationExecution execution; public LoanApplicationService(EligibilityDeterminationExecution execution) { this.execution = execution; } @Cacheable("EligibilityDecisions", ...) EligibilityDecision processEligility(Person person, Timespan timespan) { return this.execution.determineEligibility(person, timespan); } }
Just like caching, no addition configuration is required to enable and find your application Function implementations and executions. Simply build and run. Spring Boot for Apache Geode/Pivotal GemFire handles the rest.
![]() | Tip |
---|---|
It is common to implement and register your application Functions on the server and execute them from the client. |