Creating an Operator
To register an operator, call v2_operator_create from init :
extern "C" V2_EXPORT void init( v2_context_t ctx ) { v2_operator_t op = v2_operator_create( ctx, // the context passed by the engine to init "demo.strlen", // operator ID; must be globally unique "Strlen Demo", // user-friendly operator name init_strlen // initialization handler (see below) ); // Add an input port so the operator can receive and process data: v2_operator_add_input( op, // pointer returned by v2_operator_create "inString", // port name; must be unique within this operator "string" // port type ); // Add an output port so the operator can send data: v2_operator_add_output( op, "outLength", "int64" ); }
The subengine does not impose any special format for port names, but we recommended prefixing them with in or out. The prefixing makes it easier to identify them apart when their names appear in the logs.
const char* init_strlen( v2_process_t proc ) { v2_process_set_port_handler( proc, // the process, created by the engine "inString", // which port this handler is associated with strlen_on_input // the actual handler (below) ); return NULL; // no error } const char* strlen_on_input( v2_process_t proc, v2_datum_t datum ) { // Extract the string contained in `datum` const char* str = v2_datum_get_string( datum ); size_t len = strlen( str ); // Create the output datum containing the length // of the input string v2_datum_t out = v2_datum_from_int64( (int64_t)len ); // Write it to the output port v2_process_output( proc, "outLength", out ); // Release the `out` handle (see explanation below) v2_datum_release( out ); return NULL; // no error }
Result
You have created a basic operator. The initialization and termination, configuration properties, and timed handlers (timers) are described in the subsequent chapters of this guide.
Compiling an Operator Library
Compile the code to create an operator into a dynamic library (shared object), so that it can be consumed by the C++ subengine executable.# Compile C/C++ sources into position-independent object files (.o) $ gcc -c -fPIC <sources> # Link the object files together into a shared object $ gcc -shared -o <output-name>.so <object-files>
After compiling, you can place the <output-name>.so file in the lib/ directory of the subengine and call run.sh -j. This call helps generate the JSON descriptions for your new operator.
Standard and External Libraries
The C++ subengine runs in a Docker container with Debian 9.2. This operating system provides libstdc++.so.6 that the C++ subengine executable requires to consume the operators.- Compile with -static-libstdc++; or
- Write a custom Dockerfile based on Debian 9.2 in which your desired Standard Library
version or vendor is installed and available.
Next, associate your operator with the docker image by adding a tag using the v2_operator_add_tag function in your operator library.
The same concept applies to all external libraries on which the operators may depend. You can either link to them statically or include them in a custom Dockerfile.