---
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%>](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 an example of function execution in `../examples/dotnet/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 example uses a built-in result collector (`IResultCollector.getResults()`) to retrieve the function results.

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

The .NET example creates a cache, then uses it to create a connection pool.

```csharp
   var cacheFactory = new CacheFactory()
       .Set("log-level", "none");
   var cache = cacheFactory.Create();

   var poolFactory = cache.GetPoolFactory()
       .AddLocator("localhost", 10334);
   var pool = poolFactory.Create("pool");
```

The example uses the connection pool to create a region, with the same characteristics and name as the server-side region (`partition_region`).

```csharp
   var regionFactory = cache.CreateRegionFactory(RegionShortcut.PROXY)
       .SetPoolName("pool");
   var region = regionFactory.Create<object, object>("partition_region");
```

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

```csharp
   string rtimmonsKey = "rtimmons";
   string rtimmonsValue = "Robert Timmons";
   string scharlesKey = "scharles";
   string scharlesValue = "Sylvia Charles";
   region.Put(rtimmonsKey, rtimmonsValue, null);
   region.Put(scharlesKey, scharlesValue, null);
```

To confirm that the data has been stored, the 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.

```csharp
   var user1 = region.Get(rtimmonsKey, null);
   var user2 = region.Get(scharlesKey, null);

   Console.WriteLine(rtimmonsKey + " = " + user1);
   Console.WriteLine(scharlesKey + " = " + user2);
```

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.

```csharp
   ArrayList keyArgs = new ArrayList();
   keyArgs.Add(rtimmonsKey);
   keyArgs.Add(scharlesKey);
```

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

```csharp
   var exc = Client.FunctionService<object>.OnRegion<object, object>(region);
```

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

```csharp
   Client.IResultCollector<object> rc = exc.WithArgs<object>(keyArgs).Execute("ExampleMultiGetFunction");
```

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

```csharp
   ICollection<object> res = rc.GetResult();

   Console.WriteLine("Function Execution Results:");
   Console.WriteLine("   Count = {0}", res.Count);

   foreach (List<object> item in res)
   {
     foreach (object item2 in item)
     {
       Console.WriteLine("   value = {0}", item2.ToString());
     }
   }
```

