Python example (multiple simultaneous connections)

To create a remote mode program that can handle multiple simultaneous connections, each connection must be handled independently to avoid blocking. The Python AE framework performs this task. By default, the Python AE framework uses threads to handle each request. It is possible to override this functionality and have the framework either run single-threaded or use forking to handle multiple simultaneous requests.

When run() is called on the class, the class calls getRequestHandlingStyle(). By default it looks at the class variable, DEFAULT_REQUEST_HANDLING_STYLE. There are two ways to override the way an AE runs: the function getRequestHandlingStyle() can be overloaded when more intricate behavior is desired, or the class variable DEFAULT_REQUEST_HANDLING_STYLE can be overridden. The example shown uses the simple method to force the framework to fork and show that the internal handler is not being run in the same process as the running remote AE by returning the current and the parent process Ids.

This example uses the following file name:

fork.py

Code

import nzae

class ForkAe(nzae.Ae):
 
    DEFAULT_REQUEST_HANDLING_STYLE = nzae.Ae.REQUEST_HANDLING_STYLE__FORK
 
    def _getFunctionResult(self, row):
        return [parentProcessId, os.getpid()]

parentProcessId = os.getpid()

ForkAe.run()

Deployment

Deploy the script:

$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language python64 \
     --template deploy ./fork.py --version 3

Registration

Register both the forking AE and the launcher AE:

$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language python64 --version 3 \
     --template udtf --exe fork.py --sig "remote_fork(int4)" \
     --return "table(parent_id int4, child_id int4)" --remote \
     --rname forkRemote

$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language python64 --version 3 \
     --template udtf --exe fork.py --sig "launch_remote_fork(int4)" \
     --return "table(aeresult varchar(255))" --remote --launch \
     --rname forkRemote

Running

Run the remote AE server:

SELECT * FROM TABLE WITH FINAL(launch_remote_fork(0));
                         AERESULT
-----------------------------------------------------------------------
 tran: 8592 session: 16283 DATA slc: 0 hardware: 0 machine: TT4-R045 process:
32082 thread: 32082
(1 row)

Now run the forking AE:

SELECT * FROM TABLE WITH FINAL(remote_fork(0));
 PARENT_ID | CHILD_ID
-----------+----------
     32082 |    32154
(1 row)

The Python framework is performing the forking. If the DEFAULT_REQUEST_HANDLING_STYLE variable were not overridden, the numbers would match, as no new process was created to handle the request.

Although in these examples the /nz/export path is hard-coded, when creating AEs for release, this path should be retrieved through the command nzenv using the variable NZ_EXPORT_DIR.