Project

General

Profile

Introduction to using the Run Control Receiver

13-May-2010, KAB

The basic idea behind the Run Control Receiver class is that you can specify callbacks that get invoked when Run Control messages arrive. The receiving of the messages, the sending of any replies, and the management of the objects that do those things is handled for you.

The following are some sample steps for making use of a RunControlReceiver in your application:
  • create a RunControlReceiver instance early in your application's lifecycle and store a handle to that instance for later use
    • the two arguments to the RunControlReceiver constructor are the name of your application and a list of "RMS broadcast" targets that you want to listen to
    • all of these strings should match the ones that are used to send messages to your application
    • the application name is the RMS "target" that Run Control will use to send messages directly to your application (e.g. "dcm000" or "bufferNodeEVB000") If you are uncertain about what names should be used, we should discuss them as a group.
    • "RMS broadcast" targets are strings that Run Control may use to send messages to groups of applications. For example, an "allDCMs" target name could be used to send messages to all DCMs in a partition.
  • add a listener to the RunControlReceiver instance to handle the message from Run Control that tells your application which partition it belongs to
    • obviously, this also should be done early in your application's life cycle
    • the signatures of the addListener methods are the following:
      • RunControlReceiver::addListener<MSGTYPE, LSTNR, REPLYTYPE>(int partitionNumber, LSNTR* listener);
      • RunControlReceiver::addListener<MSGTYPE, LSTNR, REPLYTYPE>(int partitionNumber, boost::shared_ptr<LSNTR> listener);
    • you can use either method, or both, for specifying your callback routines. The first is probably most useful if you want to specify "this" as the listener pointer. (That is, the class that adds a callback to the RunControlReceiver could specify itself as the listener. Of course, in that case, that class would need to implement the appropriate callback method.) The second signature can be used if you want to create separate classes (and objects) to handle the message processing.
    • currently, I believe that runcontrolmessages::EstablishPartitionRequest should be used as the message type (MSGTYPE) for receiving a partition assignment and runcontrolmessages::EstablishPartitionResponse should be used for the reply type (REPLYTYPE) to respond to a partition assignment
    • the "null partition" (partition number -1) should be used for the partition number in this case. Please use the gov::fnal::cd::rms::base::RmsDestination::NULL_PARTITION constant for the null partition number, when possible.
  • when an EstablishPartitionRequest is received, do whatever processing is appropriate to your application (of course), and also add listeners to the RunControlReceiver using the partition number that you have been assigned
  • when a ReleaseFromPartitionRequest message is received, do whatever processing is appropriate and also tell the RunControlReceiver to disconnect from the partition
Notes:
  • each of your listeners must have a method with a signature like the following:
    • boost::shared_ptr<REPLYTYPE> handleMessage(boost::shared_ptr<MSGTYPE> message);
  • if your callback returns a non-empty shared pointer (to a response message), then that message will be automatically sent back to Run Control for you by the RunControlReceiver
  • you should add the following line to the bottom of your SRT GNUmakefile to include the needed headers and libraries for using the RunControlReceiver:
    • include SoftRelTools/arch_spec_rcclient.mk
Example code:
  • see attached SampleDCM.h/cpp files (latest and greatest versions are available from here).
  • only sample callbacks are provided in the SampleDCM code. Your application will probably want to listen for every Run Control message.
Command-line utility for sending Run Control messages:
  • the source code is in the NovaRunControlClient/cxx/test area (see sendRunControlMessage.cc)
  • to run the application, simply type 'sendRunControlMessage <arguments>' (type 'sendRunControlMessage' with no arguments to see the usage hints)
Sample steps to see the sendRunControlMessage application in action:
  • create a personal ospl.xml file as described here, if needed
  • in one shell window,
    • source /nova/novadaq/setup/setup_novadaq_nt1.sh -r development (or current)
    • export OSPL_URI=file://<yourWorkArea>/ospl.xml
    • ospl start
    • SampleDCMMain dcm000
  • in a second shell window,
    • source /nova/novadaq/setup/setup_novadaq_nt1.sh -r development (or current)
    • export OSPL_URI=file://<yourWorkArea>/ospl.xml
    • sendRunControlMessage -1 establishpartition 0 (the first argument is a negative one, not a dash-el)
    • sendRunControlMessage 0 beginrun 100
    • sendRunControlMessage 0 stoprun
    • sendRunControlMessage 0 releasefrompartition
  • back in the first shell window,
    • ctrl-c (to stop the SampleDCMMain)
    • ospl stop (to stop the DDS daemon)
Run Control messages:
  • to see the full list of Run Control messages that have been defined, see the RunControlMessages.idl file in CVS
  • the sendRunControlMessage application may not have all of the official messages included. Invoke it without any arguments to see which ones are included. And feel free to add any new ones that you're anxious to see included!
See also: