---
title:  Function Execution
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

A client can invoke a server-resident function, with parameters, and can collect and operate on the returned results.

## <a id="nc-fe-server_side_requirements"></a>Server-side Requirements

To be callable from your client, a function must be 

- resident on the server, and
- registered as available for client access.

See [Executing a Function in <%=vars.product_name_long%>](<%=vars.serverman%>/developing/function_exec/function_execution.html) 
in the <%=vars.product_name%> User Guide for details on how to write and register server-resident functions.

## <a id="nc-fe-client_side_requirements"></a>Client-side Requirements

The client must connect to the server through a connection pool in order to invoke a server-side function.

## <a id="nc-fe-how_functions_execute"></a>How Functions Execute

1.  The calling client application runs the `execute` method on the `Execution` object. The function must already be registered on the servers.
2.  The function is invoked on the servers where it needs to run. The servers are determined by the `FunctionService on*` 
method calls, region configuration, and any filters.
3.  If the function has results, the result is returned in a `ResultCollector` object.
4.  The client collects results using the `ResultCollector.getResult()` method.

In every client where you want to execute the function and process the results:

- Use one of the `FunctionService on*` methods to create an `Execution` object. The `on*` methods,
`onRegion`, `onServer` and `onServers`, define the highest level where the function is run.
- If you use `onRegion` you can further narrow your run scope by setting key filters.
- A function run using `onRegion` is a *data dependent* function – others are *data-independent* functions.
- You can run a data dependent function against partitioned and colocated partitioned regions. From the client, provide the appropriate key
 sets to the function call.

-  The `Execution` object allows you to customize the invocation by:
    -   Providing a set of data keys to `withFilter` to narrow the execution scope. This works only for `onRegion` Execution objects (data-dependent functions).
    -   Providing function arguments to `withArgs`.
    -   Defining a custom `ResultCollector` for `withCollector`.

-  Call the `Execution.execute()` method to run the function.

## <a id="nc-fe-processing_function_results"></a>Processing Function Results

To get the results from the function in the client app, use the result collector returned from the function execution.
The `getResult` methods of the default result collector block until all results are received, then return the full result set.

The client can use the default result collector. If the client needs special results handling, code a custom `ResultsCollector` implementation to replace the default.
Use the `Execution::withCollector` method to specify the custom collector.
To handle the results in a custom manner:

1.  Write a class that implements the `ResultCollector` interface to handle the results in a custom manner. The methods are of two types: one handles data and information from <%=vars.product_name%> and populates the results set, while the other returns the compiled results to the calling application:
    -  `addResult` is called when results arrive from the `Function` methods. Use `addResult` to add a single result to the ResultCollector.
    -  `endResults` is called to signal the end of all results from the function execution.
    -  `getResult` is available to your executing application (the one that calls `Execution.execute`) to retrieve the results. This may block until all results are available.
    -  `clearResults` is called to clear partial results from the results collector. This is used only for highly available `onRegion` functions where the calling application waits for the results. If the call fails, before <%=vars.product_name%> retries the execution, it calls `clearResults` to ready the instance for a clean set of results.
2.  Use the `Execution` object in your executing member to call `withCollector`, passing your custom collector.

## <a id="nc-fe-examples"></a>Function Execution Example

The native client release contains examples of function execution in `../examples/cpp/functionexecution`.

- The example begins with a server-side script that runs `gfsh` commands to create a region, simply called "partition_region".
- The function is preloaded with a JAR file containing the server-side Java function code. 
- The function, called "ExampleMultiGetFunction", is defined in the
`examples/utilities` directory of your distribution. As its input parameter, the function takes an array of keys,
then performs a `get` on each key and returns an array containing the results.
- The function does not load values into the data store. That is a separate operation, performed in these examples by
the client, and does not involve the server-side function.

As prerequisites, the client code must be aware of the connection to the server, the name of the function, and the expected type/format 
of the input parameter and return value.

The client:

- creates an execution object
- provides the execution object with a populated input parameter array
- invokes the object's execute method to invoke the server-side function

If the client expects results, it must create a result object.
The .NET Framework example uses a built-in result collector (`IResultCollector.getResults()`) to retrieve the function results.

The example creates a result variable to hold the results from the collector.

### <a id="nc-fe-cpp_example"></a>C++ Example
This section contains code snippets showing highlights of the C++ function execution example. They are not intended for cut-and-paste execution.
For the complete source, see the example source directory.

The C++ example creates a cache.

```cpp
Cache setupCache() {
  return CacheFactory()
      .set("log-level", "none")
      .create();
}
```

The example client uses the cache to create a connection pool, 

```cpp
void createPool(const Cache& cache) {
  auto pool = cache.getPoolManager()
      .createFactory()
      .addServer("localhost", EXAMPLE_SERVER_PORT)
      .create("pool");
}
```

Then, using that pool, the client creates a region with the same characteristics and name as the server-side region (`partition_region`).

```cpp
std::shared_ptr<Region> createRegion(Cache& cache) {
  auto regionFactory = cache.createRegionFactory(RegionShortcut::PROXY);
  auto region = regionFactory.setPoolName("pool").create("partition_region");

  return region;
}
```

The sample client populates the server's datastore with values, using the API and some sample key-value pairs.

```cpp
void populateRegion(const std::shared_ptr<Region>& region) {
  for (int i = 0; i < keys.size(); i++) {
    region->put(keys[i], values[i]);
  }
}
```

As confirmation that the data has been stored, the sample client uses the API to retrieve the values and write them to the console.
This is done without reference to the server-side example function.

```cpp
std::shared_ptr<CacheableVector> populateArguments() {
  auto arguments = CacheableVector::create();
  for (int i = 0; i < keys.size(); i++) {
    arguments->push_back(CacheableKey::create(keys[i]));
  }
  return arguments;
}
```

Next, the client retrieves those same values using the server-side example function.
The client code creates the input parameter, an array of keys whose values are to be retrieved.

```cpp
std::vector<std::string> executeFunctionOnServer(const std::shared_ptr<Region> region,
    const std::shared_ptr<CacheableVector> arguments) {
  std::vector<std::string> resultList;
```

The client creates an execution object using `Client.FunctionService.OnRegion` and specifying the region.

```cpp
  auto functionService = FunctionService::onServer(region->getRegionService());
```

The client then calls the server side function with its input arguments and stores the results in a vector.

```cpp
  if(auto executeFunctionResult = functionService.withArgs(arguments).execute(getFuncIName)->getResult()) {
    for (auto &arrayList: *executeFunctionResult) {
      for (auto &cachedString: *std::dynamic_pointer_cast<CacheableArrayList>(arrayList)) {
        resultList.push_back(std::dynamic_pointer_cast<CacheableString>(cachedString)->value());
      }
    }
  } else {
    std::cout << "get executeFunctionResult is NULL\n";
  }

  return resultList;
}
```

It then loops through the results vector and prints the retrieved values.

```cpp
void printResults(const std::vector<std::string>& resultList) {
  std::cout << "Result count = " << resultList.size() << std::endl << std::endl;
  int i = 0;
  for (auto &cachedString: resultList) {
    std::cout << "\tResult[" << i << "]=" << cachedString << std::endl;
    ++i;
  }
```

