There are several important changes, which require modifications of user's code and existing databases. Read carefully release notes and apply a conversion script (see release download page for details).
The old schema file online/schema/online.schema.xml was renamed to dal/schema/core.schema.xml and their has been changed. There are several views available with release installation:
Software Repository description classes ${TDAQ_INST_PATH}/share/doc/dal/views/ SoftwareRepository.view.ps Classes using Parameter class ${TDAQ_INST_PATH}/share/doc/dal/views/Parameter.view.ps Hardware description classes ${TDAQ_INST_PATH}/share/doc/dal/views/Hardware.view.ps Control classes ${TDAQ_INST_PATH}/share/doc/dal/views/Control.view.ps
Below there is a list of changes:
Run-time process environment is not taken anymore into account in order to parameterize database information via dal converters as it was in the past. The only way to parameterize database is the usage of variables associated with partition object in the database. There is no way to provide user custom variables via ~/.onlinerc file. Each time when a parameter needs to be changed, it is necessary to modify the database.
A variable is described by new Variable class allowing to define name and string value. A group of variables can be combined together into a set-of-variables described by the VariableSet class. Both, a variable or a variable set objects can be associated with partition, segment, computer program or application object (see for details the parameter view mentioned above).
To define an environment variable to be passed to the application one has to create or find an existent variable object and link it with either partition / segment object containing the application, to the computer object or to the application itself using ProcessEnvironment relationship. The same is relevant to set-of-variables object.
To define a variable to be used for substitution of string attributes values one has to create or to find an existent variable object and link it with either partition or it's segment objects using Parameters relationship. The same is relevant to set-of-variables object. If a variable FOO with value BAR is linked with configuration, then the daq::core::SubstituteVariables converter object substitutes all string values containing "${FOO}" by the "BAR". Note, value of a variable can be defined using other variables (the depth of such inclusion is limited to 20 to avoid infinite recursion in case of a circular dependency).
Several TDAQ infrastructure global environment variables and parameters are automatically defined for all applications, as it is described in next section.
Five new attributes have been defined in the partition class. They are used to describe common TDAQ parameters in a way, which is clear and comfortable for any database user:
DBPath describes path to the database repositories. The algorithm dal::Application::get_parameters() creates variable TDAQ_DB_PATH and sets it's value to the value of this attribute. If the value is set to $(TDAQ_DB_PATH ), then the attribute's value is equal to the value of TDAQ_DB_PATH variable defined in the user's environment.
DBName describes name of the database. It works in the way similar to described above, where variable name is TDAQ_DB_DATA.
IPCRef defines IPC reference. It works in the way similar to described above, where variable name is TDAQ_IPC_INIT_REF.
LoogRoot defines default root directory used for logs.
WorkingDir defines default working directory for all applications.
The value of the Name attribute automatically defines TDAQ_PARTITION environment variable and parameter.
Above mentioned environment variable and parameter objects should not be created or linked with configuration anymore. They are defined only and only by the attributes of partition object.
Note, some variables are external to the database, e.g. DBPath and DBName define the database location and the IPCRef is used to find the database server, so the setup or the play_daq program can not read them from the database itself, since they do not know which database to use. The setup or play_daq needs to use a different way to define them (i.e. to set via environment).
Three attributes OutputDevice, ErrorDevice and StartIn are replaced by two new Partition.s attributes LogRoot and WorkingDir and knowledges, how standard output and error files are created relative to the log root.
The existing attributes RestartIfDies and RestartIfFails, which were booleans are renamed to IfDies and IfFails and have enumeration type with range Ignore,Restart,Error.
The algorithm Application::get_host() has new additional parameter ::Configuration&. If application's host and partition's default hosts are not defined, it is assumed the application has to be started on the host, where the algorithm is executed. The name of the host is taken using gethostname() function.
Add new attribute ShortActionTimeout.
The timeout values in the database are local timeouts, i.e. to indicate the maximum amount of time that application can take to perform its own transition. If the application is a controller with controlled items, the real transition timeout shall be calculated as: ActionTimeout = my Action-Timeout in DB + max(controlled items ActionTimeouts in DB).
Add attribute IfError which allows values: Ignore, Restart, Handle, ErrorIgnore, Restart, Handle, Error. This attribute is used by the parent controller to know how to react in case that this controlled application goes in Error state or sends a FATAL error.
The structure of the database directories and names of files were changed. It happened because of TDAQ internal reorganisation and a decision to separate release-specific and site-dependent configuration files. The TDAQ_DB_PATH is set by the release setup script and points to two areas: release-dependent area and site-specific area, e.g.:
TDAQ_DB_PATH=${TDAQ_INST_PATH}/share/data:${TDAQ_INST_PATH}/databases
The files from the former area must not be modified by any way except release patches. The latter token from the path points to site-specific area.
Now the release-dependent files (e.g. the schema files, generated description of the release software repository, templates, examples) belong to the packages, which define or generate them during release build. If database file x.xml is defined by package A, it has to be installed as ${TDAQ_INST_PATH}/share/data/A/x.xml. For example, new schema/core.schema.xml file is defined by the package dal and it is installed as ${TDAQ_INST_PATH}/share/data/dal/schema/core.schema.xml.
The site-specific area contains description of hardware objects, segments and partitions.
The conversion script makes required changes of database file names. Run it from the root directory of database repository.
The C++ DAL namespace was changed from dal to the daq::core.
The conversion script makes such change in the code. Run it from the root directory of C++ package using DAL.
The mechanism for user-defined attribute values modifications was changed (see changes in config package). The dal::SubstituteVariables::from_environment() and dal::SubstituteVariables::from_db() substitution functions defined in the dal package are replaced by new daq::core::SubstituteVariables object.
Originally the mechanism allowing attribute values changes was designed for
substitution of variables from the user's process environment. Later the
substitution took into account db objects of the Environment class. By
design it should see only environment objects associated with
partition/segment/application objects. In practice it took into account ALL
defined environment variables, since there was no way to pass to the old
converter function an additional parameter. Such approach can not be used with
latest proposal on database schema changes, since it says: "the only
parameters taking into account are those, which are linked with partition object".
The old method does not work, if a database contains more then one partition
object, which need to be parameterized differently. The original converter was
implemented as a function knowing only type of attribute and nothing also. Now
the function is replaced by the converter object, which gives more flexibility.
In particular, it's constructor uses reference on partition object.
If your code is using a database converter function (i.e. calls the ::Configuration::register_convert_function()
method), then you need to do the modification. To make a substitution you need
to get a partition object first. If it is unknown, you can not make a
substitution of variables using the dal . The recommended code is shown below:
// database initialization as before
::Configuration db(...);
// check database status
if(!db.loaded()) {std::cerr << "Can not load database: " << db_name << std::endl; return ...}
// find partition; stop, if there is no partition object
const daq::core::Partition * partition = daq::core::get_partition(db, partition_name); if(!partition) {return ...;}
// register variables converter
db.register_converter(new daq::core::SubstituteVariables(db, *partition));
// remove any previously used conversions functions, which do not exist anymore
/***
db->register_convert_function(dal::SubstituteVariables::from_environment);
db->register_convert_function(dal::SubstituteVariables::from_db);
***/
When you reload configuration, you may need to reset the variables substitution, since the partition object or parameters can be different. In this case you need to keep the pointer on the substitution object and call reset() methods with the same arguments, which are used in the object's constructor, e.g.:
// initialize database and find partition object
::Configuration db(...);
const daq::core::Partition * partition1 = daq::core::get_partition(db, partition_name1);
// create and register variable converter object
daq::core::SubstituteVariables * sv_obj = new daq::core::SubstituteVariables(db, *partition1);
db.register_converter(sv_obj);
...
...
// unload configuration and read updated or different one
db.unload(); db.load(...);
// find partition object
const daq::core::Partition * partition2 = daq::core::get_partition(db, partition_name2);
// create and register variable converter object
sv_obj->reset(db, *partition2);
Note several important rules: