AEs that are both local and remote

For a simple local-only AE that does not use shapers, a direct initialize call can be used to get a data handle, such as the C API nzaeInitialize for a function AE and nzaeAggInitialize for an aggregate AE. However, if either shapers or remote AEs are being supported, the AE application must be able to determine how it is invoked.

All-In-One Approach

This example shows the general process for making a data connection. The language adapters have functionality to partially automate this procedure.

if (isLocal)
{

    dataConn = getLocalApi
    // dataConn is the data connection
    switch (dataConn.apiType)
    {
        case FUNCTION: // Table or Scalar Function
            run(dataConn.function)
            close(dataConn.function)
            break
        case AGGREAGATE: // Aggregate Function
            run(dataConn.aggregate)
            close(dataConn.aggregate)
            break
        case SHAPER: // Table Shaper or Scalar Sizer
            run(dataConn.shaper)
            close(dataConn.shaper)
            break
    } 
}
else
{
    // Remote AE
    connPoint = createConnectionPoint
    listener = createListener(connPoint)
    // listener is the notification connection 
    for (;;)
    {
        dataConn = acceptRemoteApi(listener) 
        switch (dataConn.apiType)
        {
            case FUNCTION: // Table or Scalar Function
                run(dataConn.function)
                close(dataConn.function)
                break
            case AGGREGATE: // Aggregate Function
                run(dataConn.aggregate)
                close(dataConn.aggregate)
                break
            case SHAPER: // Table Shaper or Scalar Sizer
                run(dataConn.shaper)
                close(dataConn.shaper)
                break
        }
    }
    // the following code may not be reached
    close(listener)
    close(connPoint) 
}

Forking Approach

When using a programming language such as Java, which has solid thread support, a threaded approach is recommended. For languages without thread support or with limited thread support, the forking approach works well.

For a programming language that can support both threading and forking approaches, such as C and C++, the requirements of the application or support libraries determine the approach.

When using the forking approach, a data connection can be made under the remote AE. Instead of accepting an API, an AE environment can be accepted. An AE environment is not a data connection but can be used in an initialize call to create a data connection. To fork and use a data connection is not valid; however, to fork and use an AE environment is valid. An AE environment can be first serialized to bytes, then unserialized, and then be used to create a data connection. This example uses an AE environment with fork to run a data request in a new process:

for (;;)
 {
    aeEnv = acceptRemoteEnvironment(listener)
    fork

    if(parent)
    {
        // in parent process
        close(aeEnv)
        continue loop
    }

    // in child process 
    freeResources(listener)
    close(connPoint)
    switch (aeEnv.apiType)
    {
        case FUNCTION: // Table or Scalar Function
            conn = initializeFunctionAE(aeEnv)
            run(conn)
            close(conn)
            exit
        case AGGREGATE: // Aggregate Function
            conn = initializeAggregateAE(aeEnv)
            run(conn)
            close(conn)
            close(env)
            exit
        case SHAPER: // Table Shaper or Scalar Sizer
            conn = initializeShaperAE(aeEnv)
            run(conn)
            close(conn)
            exit
    }
  }
}

When using Linux fork, avoid creating "zombie" Linux processes by either ignoring signal SIGCHLD or handling the signal and waiting on the child processes. Waiting on the child processes outside the signal handler is not recommended since the parent could become blocked and not handle subsequent AE notifications. When possible, ignoring the signal is the better approach. If the SIGCHLD signal is handled, care must be taken so that no child processes are missed and the parent does not become blocked.