Link to the Information Technology Laboratory Website Link to the Information Access Division Website Link to the NIST Website NIST, IAD Banner

Chapter 5. How to create applications

In this section, we present the three main classes needed to use of the framework. The Smartflow class is the API entry point. This object is used to initialize connection with the server and create flows. The Flow class is used to handle flows, which represent a stream of data blocks. A data block is then manipulated using a Buffer object.

The Smartflow class

This class is used as an "entry point" for all the other classes in the library, and most of the other classes are created directly or indirectly by methods of a Smartflow object, and never directly by instantiating the subordinate objects.

Connecting to the NDFS-II network

The Smartflow object is used to connect or disconnect to the NDFS-II network, to create or destroy flows and to declare the user-defined exit method, which is invoked when a client node quits. In order to use the Smartflow object, you need to include this header in your source code.

#include "Smartflow.h" 

The very first step is to declare and instantiate a Smartflow object:

Smartflow *sf = new Smartflow(); 

After the object has been created, you must call the init method:

bool init( int &argc,char** &argv,
          bool keepSFOptions = false, 
          const std::string application=DEFAULT_APPLICATION_NAME);

This method initializes the various managers required by NDFS-II. It uses the argc and argv parameters from the main function. The third parameter keepSFOptions is used to indicate if you want to keep the specific options concerning the NDFS-II in the argv variable. By default these parameters will be removed and leave the remaining parameters for further parsing in the user’s code. The fourth parameter is used to give an application name. This parameter is presently reserved but will be useful for future development. Most of the time you just need to invoke the init() method as follows:

sf->init(argc, argv);

Then you need to invoke the method bool readyToRun() to check that the Smartflow object is ready to connect to the server:

if ( !sf->readyToRun() ) { 
   //Using the standard output to display the error message. 
   cout << sf->strError() << endl;
   ... 
   return 1; 
} 

Most of the objects in NDFS-II use the Error Manager to let you know if something went wrong. When a method fails and returns false, you can invoke the std::string strError(void) method. This method returns a string giving more details about what went wrong.

At this point, you are ready to connect to the data flow server using

bool connectToApplicationServer(const std::string clientname=DEFAULT_EMPTY,
                                  const std::string clientgroup=DEFAULT_CLIENT_GROUP);

You can specify the name of your client name and its group. The clientgroup argument is not presently used, but is reserved for future development. You can here specify a name for your client. If you don't, the name of the executable, i.e. argv[0] will be used. An example method call is as follows:

if ( !sf->connectToApplicationServer() ) { 
   //using the log macro to display the error message 
   ACE_DEBUG( (USER_PREFIX ACE_TEXT("Error message: %s\n"), sf->strError()) ); 
   ... 
   return 1; 
} 

Setting up an exit strategy for your client node

At this point, your client node is connected to the data flow server and is ready to create flows. Most client nodes work with streams of data and therefore run a loop to produce or consume the data. The user can define in his code an exit function for the client node to exit cleanly. That method is then automatically invoked by the system when the client node receives the kill or abort signal. After defining the method, the user needs to declare which method to invoke. You can do so by invoking:

bool setUserExitFunction(void (*user_exit_function_) (), 
                           bool controlC = true);

or

bool setUserExitFunction(void (*user_exit_function_) (void*userarg), 
                           void *arg, 
                           bool controlC = true);

You should use the first method if your exit method has no parameters, otherwise use the second one. The first parameter is a pointer to the exit method, the second one a pointer to the parameter list of your exit method, and the last one defines whether this method should be called when using "Control+c" or closing the console window. This is the default behavior if not specified otherwise.

Examples showing how to use these methods are located in the folders

src/clients/example_provider_with_complex_exit_func and

src/clients/example_provider_with_simple_exit_func

Setting an exit method is not required but strongly advised. At this point, you are ready to create flows. Flows are created using the Smartflow object.

Created on 2008-06-18 by Antoine Fillinger - Last updated on 2008-11-23 by Antoine Fillinger