next up previous contents
Next: Minos Event Display (sub) Up: The MINOS Off-line Software Previous: Database Maintenance   Contents

Subsections


Dispatcher

Last significant change: 2002/06/25


Introduction

The purpose of the dispatcher is to handle the distribution of data from the online systems (DAQ and DCS) to the near-online client applications which need access to that data.

The dispatcher client applications may be local or remote to the dispatcher server. Examples of local clients are the online monitoring and database update systems. Remote clients may use the dispatcher to access the latest data produced at the detector site.

Figure 19.1: MINOS data flow diagram illustrates the role of the dispatcher in the flow of data from the online data generators to the dispatcher's near-online client applications.
\includegraphics[width=6in]{dds_dataflow.eps}

The dispatcher package provides server side and client side code as is illustrated in Figure 19.1. On the server side, the package provides a parent server (ddsparentserver) which is intended to be run continuously in the background at the detector source site. When the ddsparentserver receives a request for data from a new client, it forks and executes a child server (ddschildserver) to actually handle the data transfer with the client.

On the client side, the package provides a DDSClient class which acts as the interface by which the client may connect to and receive data from the dispatcher server. The client may either interact ``directly'' with the dispatcher through the DDSClient class, or indirectly within the offline framework via the IoModules package.


Installing the Dispatcher Parent Server

The typical client of the dispatcher will not need to worry about installing the ddsparentserver, but instead will be able to use the ddsparentserver already installed and maintained at the detector site. For those that do need to worry about installing the ddsparentserver, detailed installation instructions are provided here.

If the dispatcher server will be serving open data files from a disk mounted on a pc different from the one on which the server is run, the dispatcher will need access to the files via the ROOT provided server daemon rootd. This is because rootd was determined to be more reliable at serving open files to the dispatcher server than NFS. The following installation steps should be carried out only if rootd useage is required:

If, on the other hand, the ddsparentserver will be serving either closed files from a disk on either its own or the data source pc, or open files from a disk on its own pc, the rootd server need not be used. In this case, the environment variable DDS_DAQ_DATA_DIR should be set to point to the data source directory path visible to the ddsparentserver through a file sharing system, e.g.

         setenv DDS_DAQ_DATA_DIR  /mnt/data
Setting the DAQ_DATA_DIR environment variable is not necessary.

After the appropriate environment variable(s) have been defined, the ddsparentserver can be started. For example,

       ddsparentserver -l Verbose >&! ddsparentserver.log &
will start the ddsparentserver running in the background (on csh). Both ddsparentserver and ddschildserver log messages will be sent to the log file ddsparenterver.log. The option -l can be used to specify the level at which log messages are written to the ddsparentserver.log file. A full list of options that the ddsparentserver supports can be obtained by specifying the option -h, for example:
       ddsparentserver -h

       Currently, the options supported are: 

       useage: ddsparentserver -p[port#] -m[max no. clients] -l[loglevel]
        -p: port number to listen on (default=9090)
        -m: maximum number of concurrent clients (default = 10)
        -l: loglevel at which to print messages (default=Info).
            valid arguments are: Verbose, Debug, Info, Warning, Error, Fatal
        -h: print this message

To shutdown the ddsparentserver, run the binary ddscomm provided by the Dispatcher package, with the '-s' option, e.g.

  ddscomm -s
This will by default connect to the ddsparentserver running on the ddscomm host pc and listening on port 9090 to shut it down. A list of options supported by ddscomm can be obtained with the -h option, for example :
  ddscomm -h

Running a Dispatcher Client

There are two methods of connecting to the dispatcher as a client: Although the syntax of the two approaches are different, the basic steps that the client must take to receive data from the dispatcher is the same, and is summarized here.

First, the client must connect to the ddsparentserver. For this it must know the server host ip address, and possibly port number on which the ddsparentserver has been set up to listen if this is different than the default of 9090.

Second, the client must submit a subscription to specify the type of data they would like to receive and the mode in which they wish to receive it. Based on the client's subscription, the dispatcher will apply server-side cuts to the data before shipping the data to the client to ensure that the client's subscription is met. As part of this subscription, the client can specify:

The client may change its subscription at any time during its session with the dispatcher server by resubmitting a new subscription.

Finally, after connecting to the dispatcher and submitting a subscription, the client is ready to receive data from the dispatcher. This is done by requesting the Next record set satisfying the clients subscription. Optionally, the client can request to advance by more than 1 record set as an argument to the Next method. The client can also adjust a waittime before the dispatcher server will give up trying to locate a record set satisfying the client's subscription and return with a timeout message. By default this is set to 120 seconds.

The client can also jump to the file of interest by using either the GoToFile or GoToNext file methods as illustrated in the examples.

An Example Use of DDSClient Interface

This example illustrates how to write a driver program that makes use of the DDSClient class to receive data from the dispatcher. See Dispatcher/test/DemoClient.cc for more examples of useage and additional comments.

#include "TIterator.h"
#include "RawData/RawRecord.h"
#include "MinosObjectMap/MomNavigator.h"
#include "Dispatcher/DDSClient.h"
#include "Dispatcher/DDSSubscription.h"

int main() {

  // Create a new DDSClient object connected to the server running on
  // daqdds.minos-soudan.org 
  DDSClient* ddsclient = new DDSClient("daqdds.minos-soudan.org");

  // Check validity of connected socket before using it
  if ( !ddsclient -> IsValid() ) {
    cout << "Error in creation of socket connected to server." << endl;
    delete ddsclient; ddsclient = 0;
    return 1;  // end of session
  }

  // Configure Subscription and send it to Server.
  ddsclient->GetSubscription()->SetKeepUpMode(DDS::kAll);
  ddsclient->GetSubscription()->SetStreams("DaqSnarl,DaqMonitor");
  ddsclient->GetSubscription()->SetSelection("DaqSnarl",
            "((RawDaqSnarlHeader*)fHeader)->GetSnarl() % 10 == 0 
          && ((RawDaqSnarlHeader*)fHeader)->GetTrigSrc()==4");


  DDS::EMessageType msgrc = ddsclient->Subscribe();
  if (msgrc != DDS::kOk) {
    cout  << "An error message " << DDS::AsString(msgrc) 
          << " was received from DDS::Subscribe." << endl;    
    return 1;
  }

  // Begin receiving record sets from server.  This loop is set up to
  // continue receiving record sets until an error condition occurs, e.g.
  // a timeout.
  Int_t nentry = 0;
  msgrc = DDS::kOk;
  while (msgrc == DDS::kOk) {
    MomNavigator* mom = 0;
    UInt_t waittime = 120;
    Int_t advanceby = 1;
    msgrc = ddsclient -> Next(mom,waittime,advanceby); 
    if (msgrc == DDS::kOk) {
      nentry++;
      if ( mom ) {
        TIter fiter = mom -> FragmentIter();
        RawRecord* rawrecord;
        while ( (rawrecord = dynamic_cast<RawRecord*>(fiter.Next())) ) {
          // Process the record
        }
        delete mom; mom = 0; // deleting mom record also deletes all records
      } 
    }
  }

  // See Dispatcher/DDS.h for a list of DDS::EMessageType's that may be
  // returned by DDSClient methods.
  cout << "\nAfter "<<nentry<< " total entries retrieved, an error message:\n" 
       << DDS::AsString(msgrc)
       << " was returned from DDSClient::Next.\n" << endl;

  ddsclient -> Shutdown();
  delete ddsclient; ddsclient = 0;

  return 0;

}

An Example Use of JobC Interface

This example shows how to use the JobC Interface to the dispatcher. The subscription is identical to the one in the DDSClient interface example. See Demo/dispatcher.C for additional options.

// usage: loon -bq dispatcher.C
{

  JobC j;

  j.Input.Set("Format=DDS");
  j.Input.Set("DDSServer=daqdds.minos-soudan.org"); 
  j.Input.Set("Streams=DaqSnarl,DaqMonitor"); 
  j.Input.Set("DDSKeepUpMode=All");  // default is FileKeepUp
  j.Input.Set("DDSTimeOut=120");      // (seconds) waittime
  j.Input.Select("DaqSnarl",
            "((RawDaqSnarlHeader*)fHeader)->GetSnarl() % 10 == 0 
          && ((RawDaqSnarlHeader*)fHeader)->GetTrigSrc()==4");

  j.Path.Create("Demo","EventDump::Ana");
  j.Path("Demo").Mod("EventDump").Cmd("Dump Fragments");
  j.Path("Demo").Run();  // Runs until an error occurs (e.g.timeout)

}


next up previous contents
Next: Minos Event Display (sub) Up: The MINOS Off-line Software Previous: Database Maintenance   Contents
MINOS Software 2017-11-20