[programmer/prog-setup.tex] \label{prog_setup} \section{Parameter class} \label{prog_setup_parameter} Configuration and status information of objects can be represented by the \class{Parameter} class. Any object derived from \class{WorkingProcessor} class (e.~g.~ \class{Application}, \class{Device}, \class{Module}, and \class{Port}) can have a list of parameters assigned to it. There are a number of \class{WorkingProcessor} methods to create parameter objects of different kinds and access their values. These are shown in the following table: \begin{tabular}{|l|l|lll|} \hline Type & Class & Create & Getter & Setter \\ \hline string & StrParameter & CreateParStr() & GetParStr() & SetParStr () \\ double & DoubleParameter & CreateParDouble() & GetParDouble() & SetParDouble() \\ int & IntParameter & CreateParInt() & GetParInt() & SetParInt() \\ bool & StrParameter & CreateParBool() & GetParBool() & SetParBool() \\ \hline \end{tabular} The \func{CreatePar...()} methods will internally create a new \class{Parameter} of the specified name if it does not exist before. For any type of parameter the \func{GetParStr()} and \func{SetParStr()} methods can be used which will deliver the parameter value as text string expression. As one can see, to represent a boolean value a string parameter is used. If text of string is "true" (in lower case), the boolean value is recognized as \keyw{true}, otherwise as \keyw{false}. It is recommended to use these \class{WorkingProcessor} methods to create parameters and access their values; but one can also use \func{FindPar()} method to find any parameter object and use its methods directly. \section{Use parameter for control} \label{prog_setup_parametercontrol} One advantage of the \dabc~ parameter objects is that parameter values can be observed and changed by a control system. When a parameter value is changed in the program by a \func{SetPar...} method, the control system is informed and represents such change in an appropriate GUI element. On the other hand, if the user modifies a parameter value in the GUI, the value of the parameter object will be changed and the corresponding parent object (\class{Module}, \class{Device}) gets a callback via virtual method \func{ParameterChanged()}. By implementing a suitable reaction in this call, one could reconfigure or adjust the running program on the fly. A parameter object may be "fixed" via \func{Parameter::SetFixed()} method. This disables possibility to change the parameter value, both from the program and the control/configuration system side. Only when the "fixed" flag is reset to \keyw{false}, the parameter can be modified again. Not all parameters objects should be visible to the control system. Each parameter has a \strong{visibility flag} which is assigned to the parameter instance when it is created. Only when \func{Parameter::IsVisible()} returns \keyw{true}, parameter will be known (visible) to the control system. Even if parameter is seen from control system, it only can be changed \strong{from} control system when flag \func{Parameter::IsChangable()} returns \keyw{true}. Default flags values for newly created parameters can be set in \func{WorkingProcessor::SetParDflts()} function. For visibility user should specify level, which is compared with global visibility level for parameters (aka debug level). This global level can be changed by \func{WorkingProcessor::SetGlobalParsVisibility()} static function or in configuration file (value "Context/Run/parslevel"). Normally module parameters has visibility level 1, module items (port, pool handle) parameters - 3, configuration parameters - 5. Thus, to see all parameters in control system, one should set "parslevel = 5". \section{Example of parameters usage} \label{prog_setup_parameterexample} Let's consider an example of a module which uses parameters: \begin{verbatim} class UserModule : public dabc::ModuleAsync { public: UserModule(const char* name, dabc::Command* cmd = 0) : dabc::ModuleAsync(name, cmd) { CreateParBool("Output", true); CreateParInt("Counter", 0); CreateTimer("Timer", 1.0, false); } virtual void ProcessTimerEvent(dabc::Timer*) { SetParInt("Counter", GetParInt("Counter")+1); if (GetParBool("Output")) DOUT1(("Counter = %d", GetParInt("Counter"))); } }; \end{verbatim} In the module constructor two parameters are created - boolean and integer, and a timer with $1\mbox{~s}$ period. When the module is started, the value of integer parameter "Counter" will be changed every second. If boolean parameter "Output" is set to \keyw{true}, the counter value will be displayed on debug output. Using a control system, the value of the boolean parameter can be changed. To detect and react on such change, one should implement following method: \begin{verbatim} virtual void ParameterChanged(dabc::Parameter* par) { if (par->IsName("Output")) DOUT1(("Output flag changed to %s", DBOOL(GetParBool("Output"))); } \end{verbatim} For performance reasons one should avoid to use parameter getter/setter methods (like \func{GetParBool()} or \func{SetParInt()}) inside a loop being executed many times. The main purpose of a parameter object is to provide a connection to the control and configuration system. In other situations simple class members should be used. \section{Configuration parameters} \label{prog_setup_configurationparameter} Another use case of parameters consists in the object configuration. When one creates an object, like a module or a device, it is often necessary to deliver one or several configuration values to the constructor, e.~g.~ the required number of input ports, or a server socket port number. For such situation configuration parameter are defined. These parameters should be created and set in the object constructor with following methods only: \bdes \item[GetCfgStr] string \item[GetCfgDouble] double \item[GetCfgInt] integer \item[GetCfgBool] boolean \edes All these methods have following arguments: the parameter name, a default value [optional], and a pointer to a \class{Command} object [optional]. Let's add one configuration parameter to our module constructor: \begin{small} \begin{verbatim} UserModule(const char* name, dabc::Command* cmd = 0) : dabc::ModuleAsync(name, cmd) { CreateParBool("Output", true); CreateParInt("Counter", 0); double period = GetCfgDouble("Period", 1.0, cmd); CreateTimer("Timer", period, false); } \end{verbatim} \end{small} Here the period of the timer is set via configuration parameter "Period". How will its value be defined? First of all, it will be checked if a parameter of that name exists in command \func{cmd}. If not, the appropriate entry will be searched in the \dabc\ setup file, as discussed in Section \paref{user-setup} of the \dabc\ user manual. If the configuration file also does not contain such parameter, the specified default value $1.0$ will be used. % \section{Configuration file example} % \label{prog_setup_configfile} % The configuration file is an XML file in a \dabc-specific format, % which contains values for some or all configuration parameters of the system. % % Let's consider this simple but functional configuration file: % % \begin{small} % \begin{verbatim} % % % % % % % % % % % % % % % % \end{verbatim} % \end{small} % % This is an example XML file for an MBS generator, which produces % MBS events and provides them to an {\em MBS transport} server. % To run that example, just "run.sh test.xml" should be executed in a shell. % Other applications % (\dabc~ or {\em Go4}) can connect to that server and read generated mbs events. % % % \section{Basic syntax} % \label{prog_setup_configfile_syntax} % A \dabc~ configuration file should always contain as root node. % Inside the node one or several nodes should exists. % Each node represents the {\em application context} which runs as % independent executable. % Optionally the node can have and nodes, % which are described further in the following sections \ref{prog_setup_configfile_variables} % and \ref{prog_setup_configfile_defaults} % % % \section{Context} % \label{prog_setup_configfile_context} % A node can have two optional attributes: % \bdes % \item["host"] host name, where executable should run, default is "localhost" % \item["name"] application (manager), default is the host name. % \edes % % Inside a node configuration parameters for modules, devices, memory pools are % contained. % In the example file one sees several parameters for the output port of % the generator module. % % % \section{Run arguments} % \label{prog_setup_configfile_run} % Usually a node has a subnode, where the user may define different parameters, relevant for running the \dabc~ executable: % % \bdes % \item[lib] name of a library which should be loaded. Several libraries can be specified. % \item[func] name of a function which should be called to create modules. % This is an alternative to instantiating a subclass of \class{dabc::Application} % (compare section \ref{prog_plugin_applicaton}) % \item[runfunc] function name to run some sequence of operations (start, stop, reconfigure) over application. Useful % for batch mode % \item[port] ssh port number of remote host % \item[user] account name to be used for ssh (login without password should be possible) % \item[init] init script, which should be called before dabc application starts % \item[test] test script, which is called when test sequence is run by run.sh script % \item[timeout] ssh timeout % \item[debugger] argument to run with a debugger. Value should be like "gdb -x run.txt --args", where file run.txt should contain commands "r bt q". % \item[workdir] directory where \dabc~ executable should start % \item[debuglevel] level of debug output on console, default 1 % \item[logfile] filename for log output, default none % \item[loglevel] level of log output to file, default 2 % \item[DIM\_DNS\_NODE] node name of DIM dns server, used by DIM controls implementation % \item[DIM\_DNS\_PORT] port number of DIM dns server, used by DIM controls implementation % \item[cpuinfo] instantiate \class{dabc::CpuInfoModule} to show CPU and memory usage information. % Value must be >= 0. If 0, only two parameters are created, if 15 - several ratemeters will be created. % \item[parslevel] level of pars visibility for control system, default 1 % \edes % % % \section{Variables} % \label{prog_setup_configfile_variables} % In the root node one can insert a node which may contain % definitions of one or several variables. Once defined, % such variables can be used in any place of the configuration file to set parameter values. % In this case the syntax to set a parameter is: % % \begin{small} % \begin{verbatim} % % \end{verbatim} % \end{small} % % It is allowed to define a variable as a combination of text with another variable, % but neither arithmetic nor string operations are supported. % % Using variables, one can modify the example in the following way: % % \begin{small} % \begin{verbatim} % % % % % % % % % % % % % % % % % % % % % % \end{verbatim} % \end{small} % % Here context name and module name are set via {\tt myname} variable, % and mbs server socket port is set via {\tt myport} variable. % % There are several variables which are predefined by the configuration system: % % \bbul % \item DABCSYS - top directory of \dabc~ installation % \item DABCUSERDIR - user-specified directory % \item DABCWORKDIR - current working directory % \item DABCNUMNODES - number of nodes in configuration files % \item DABCNODEID - sequence number of current node in configuration file % \ebul % % Any shell environment variable % is also available as variable in the configuration file to set parameter values. % % % \section{Default values} % \label{prog_setup_configfile_defaults} % There are situations when one needs to set the same value to several similar parameters, % for instance the same queue length for all output ports in the module. % One possible way is to use syntax as described above. % The disadvantage of such approach is that one must expand the XML file % to set each queue length explicitely from the appropriate variable; % so in case of a big number of ports the file will be very long and % confusing to the user. % % Another possibility to set several parameters at once % consists in \strong{wildcard rules} using "*" or "?" symbols. % These can be defined in a node: % % \begin{small} % \begin{verbatim} % % % % % % % % % % % % % % % % % % % % % % % % % % % % \end{verbatim} % \end{small} % % In this example for all ports which names begin with the string "Output", % and which belong to any module, the output queue length will be 5. % A wildcard rule of this form will be applied for % all contexts of the configuration file, % i.~e.~ by such rule we set the output queue length for all modules on all nodes. % This allows to configure a big multi-node cluster with % a compact XML file. % % Another possibility to set default value for some parameters - create % parameter with the same name in parent object. Here word \strong{create} % is crutial - one should use \func{CreateParInt()} method in module constructor - % it is not enough just put additional tag in xml file. For instance, one can % create parameter "MbsServerPort" in generator module and than % MBS server transport, created for output port, will use that value for % as default server port number. \section{Usage of commands for configuration} \label{prog_setup_configuration_commands} Let's consider the possibility to configure a module by means of the \class{Command} class. Here the use case is that an object (like a module) should be created with fixed parameters, ignoring the values specified in the configuration file. In our example one can modify \func{InitMbsGenerator()} function in the following way: \begin{small} \begin{verbatim} extern "C" void InitMbsGenerator() { dabc::Command* cmd = new dabc::CmdCreateModule("mbs::GeneratorModule", "Generator"); cmd->SetInt("SubeventSize", 128); if (!dabc::mgr()->Execute(cmd)) { EOUT(("Cannot create generator module")); exit(1); } ... } \end{verbatim} \end{small} Here one adds an additional parameter of name "SubeventSize" to the \class{CmdCreateModule} object, which will set the MBS subevent size to 128. The generator module constructor will get the parameter value via method \func{GetCfgInt()}, as described in section \ref{prog_setup_configurationparameter}. Since the parameters of the passed \func{cmd} object will override all other settings here, the value of the corresponding entry in the configuration file has no effect.