Runcontrol: Difference between revisions
Jump to navigation
Jump to search
(17 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
Lets use 'tokenInterval' as example. It reside in database, and can be changed by runcontrol. Following steps were made to implement 'tokenInterval' functionality: | Lets use 'tokenInterval' as example. It reside in database, and can be changed by runcontrol. Following steps were made to implement 'tokenInterval' functionality: | ||
'''server side''' | |||
* rcServer/Components.s/daqRun.h: object must have a type 'daqData' to use reloaded operations etc: | * rcServer/Components.s/daqRun.h: object must have a type 'daqData' to use reloaded operations etc: | ||
#include <rcsTokenIntervalWriter.h> | |||
/* token interval value: writeUpdate == 1 means write to database */ | |||
void tokenInterval (int val, int writeUpdate = 1); | |||
int tokenInterval (void) const; | |||
/* update token interval number */ | |||
void updateTokenInterval (int interval); | |||
daqData* tokenInterval_; /* variable */ | daqData* tokenInterval_; /* variable */ | ||
Line 17: | Line 27: | ||
tokenIWriter_ = new rcsTokenIntervalWriter (this); /* create database writer */ | tokenIWriter_ = new rcsTokenIntervalWriter (this); /* create database writer */ | ||
tokenInterval_->writer (tokenIWriter_); /* register database writer */ | tokenInterval_->writer (tokenIWriter_); /* register database writer */ | ||
*tokenInterval_ = 0; /* reset when needed */ | |||
* rcServer/Components.s/daqRun.cc: two methods dealing with database: | |||
/* called from dbaseReader::parseOptions() when reading '_option' table during 'Configure' transition; | |||
in line '*tokenInterval_ = itval' operator '=' overloaded in daqData class, calling 'notifychannels' and 'write' | |||
methods; 'write' method calls rcsTokenIntervalWriter::write() registered above | |||
*/ | |||
void | |||
daqRun::tokenInterval (int itval, int writeUpdate) | |||
{ | |||
/* if not write to database, disable the write */ | |||
if (!writeUpdate) tokenInterval_->disableWrite (); | |||
*tokenInterval_ = itval; /*overloaded '=' here ! */ | |||
if (!writeUpdate) tokenInterval_->enableWrite (); | |||
} | |||
/* writer for 'tokenInterval_', called from rcServer/Components.s/rcsTokenIntervalWriter.cc registered above */ | |||
void | |||
daqRun::updateTokenInterval (int itval) | |||
{ | |||
dbreader_->putTokenInterval (itval); /* put new value into database */ | |||
} | |||
* rcServer/Components.s/rcsTokenIntervalWriter.cc: writer to database: | |||
void | |||
rcsTokenIntervalWriter::write (daqData* data) | |||
{ | |||
run_->updateTokenInterval ((int)(*data)); | |||
} | |||
* rcServer/Components.s/dbaseReader.cc: reading/writing value to database: | |||
/* called from 'daqRun::updateTokenInterval(int itval)', record value to database */ | |||
void | |||
dbaseReader::putTokenInterval(int itval) | |||
{ | |||
..... | |||
::sprintf (qstring, "update %s_option set value = '%d' where name = '%s'",run_.runtype (), itval, DBASE_TOKEN_INTERVAL); | |||
..... | |||
} | |||
/* read _option table, get tokenInterval value and calls daqRun::tokenInterval(int itval, int writeUpdate) disabling 'write' | |||
to avoid writing back to the database we just read it from */ | |||
int | |||
dbaseReader::parseOptions (char* runtype) | |||
{ | |||
..... | |||
else if (::strcmp (row[0], DBASE_TOKEN_INTERVAL) == 0) /* DBASE_TOKEN_INTERVAL="tokenInterval" */ | |||
{ | |||
int titval; | |||
if (::sscanf (row[1], "%d", &titval) >= 1) | |||
{ | |||
run_.tokenInterval (titval, 0); | |||
reporter->cmsglog (CMSGLOG_INFO1,"Token interval %d \n", titval); | |||
} | |||
} | |||
..... | |||
} | |||
'''client side''' | |||
* rcClient/src.s/rcClient.h: | |||
daqData* tokenInterval_; | |||
* rcClient/src.s/rcClient.cc: same as on server side, but use 'rccDaqData' instead of 'rcsDaqData': | |||
tokenInterval_ = new rccDaqData (exptname_, "tokenInterval", 0); | |||
tokenInterval_->connect (dataManager_); | |||
tokenInterval_->enableWrite (); | |||
* Xui/src.s/rcClientHandler.cc: | |||
/* connect to database, setting callbacks (called when database changed ?)*/ | |||
int | |||
rcClientHandler::connect (char* database, char* exptname, char* msqld) | |||
{ | |||
..... | |||
if (handler_.monitorOnCallback (exptname, "tokenInterval", | |||
(rcCallback)&(rcClientHandler::tokenIntervalCallback), | |||
(void *)this) != CODA_SUCCESS) | |||
fprintf (stderr, "Cannot monitor on %s tolenInterval\n", exptname); | |||
..... | |||
} | |||
void | |||
rcClientHandler::tokenIntervalCallback (int status, void* arg, daqNetData* data) | |||
{ | |||
rcClientHandler* obj = (rcClientHandler *)arg; | |||
if (status == CODA_SUCCESS) | |||
{ | |||
obj->tokenIVal_ = (int)(*data); | |||
obj->setTokenInterval (obj->tokenIVal_); | |||
} | |||
} | |||
/* token interval changed, update all panels */ | |||
void | |||
rcClientHandler::setTokenInterval (int interval) | |||
{ | |||
codaSlistIterator ite (panels_); | |||
rcPanel* panel = 0; | |||
for (ite.init(); !ite; ++ite) | |||
{ | |||
panel = (rcPanel *) ite (); | |||
panel-> configTokenInterval (interval); | |||
} | |||
} | |||
/* return token interval value */ | |||
int | |||
rcClientHandler::tokenInterval (void) const | |||
{ | |||
return tokenIVal_; | |||
} | |||
* Xui/src.s/rcTokenIButton.cc: set token interval: | |||
void | |||
rcTokenIButton::sendTokenInterval (int newval) | |||
{ | |||
/* get client handler */ | |||
rcClient& client=netHandler_.clientHandler(); | |||
daqData data (client.exptname (), "tokenInterval", newval); | |||
if (client.setValueCallback (data, | |||
(rcCallback)&(rcTokenIButton::setTICallback), | |||
(void *)this) != CODA_SUCCESS) | |||
{ | |||
reportErrorMsg ("Cannot send new token interval value to the server !"); | |||
return; | |||
} | |||
} | |||
void | |||
rcTokenIButton::setTICallback (int status, void* arg, daqNetData* ) | |||
{ | |||
rcTokenIButton* obj = (rcTokenIButton *)arg; | |||
if (status != CODA_SUCCESS) | |||
{ | |||
obj->reportErrorMsg ("Setting new token interval to the server failed !"); | |||
return; | |||
} | |||
} |
Latest revision as of 09:24, 6 October 2015
This page describes run control part of Coda DAQ system. It reside in $CODA/src/rc/ directory.
Communication between rcServer and runcontrol
Lets use 'tokenInterval' as example. It reside in database, and can be changed by runcontrol. Following steps were made to implement 'tokenInterval' functionality:
server side
- rcServer/Components.s/daqRun.h: object must have a type 'daqData' to use reloaded operations etc:
#include <rcsTokenIntervalWriter.h>
/* token interval value: writeUpdate == 1 means write to database */ void tokenInterval (int val, int writeUpdate = 1); int tokenInterval (void) const; /* update token interval number */ void updateTokenInterval (int interval);
daqData* tokenInterval_; /* variable */ daqDataWriter* tokenIWriter_; /* database writer */
- rcServer/Components.s/daqRun.cc: create object, connect it to manager, and enable writing:
tokenInterval_ = new rcsDaqData (exptname_, "tokenInterval", 0); /* create variable */ tokenInterval_->connect (dataManager_); /* register to data manager (class daqDataUpdater) */ tokenInterval_->enableWrite (); /* enable writing to database */ tokenIWriter_ = new rcsTokenIntervalWriter (this); /* create database writer */ tokenInterval_->writer (tokenIWriter_); /* register database writer */ *tokenInterval_ = 0; /* reset when needed */
- rcServer/Components.s/daqRun.cc: two methods dealing with database:
/* called from dbaseReader::parseOptions() when reading '_option' table during 'Configure' transition; in line '*tokenInterval_ = itval' operator '=' overloaded in daqData class, calling 'notifychannels' and 'write' methods; 'write' method calls rcsTokenIntervalWriter::write() registered above */ void daqRun::tokenInterval (int itval, int writeUpdate) { /* if not write to database, disable the write */ if (!writeUpdate) tokenInterval_->disableWrite (); *tokenInterval_ = itval; /*overloaded '=' here ! */ if (!writeUpdate) tokenInterval_->enableWrite (); }
/* writer for 'tokenInterval_', called from rcServer/Components.s/rcsTokenIntervalWriter.cc registered above */ void daqRun::updateTokenInterval (int itval) { dbreader_->putTokenInterval (itval); /* put new value into database */ }
- rcServer/Components.s/rcsTokenIntervalWriter.cc: writer to database:
void rcsTokenIntervalWriter::write (daqData* data) { run_->updateTokenInterval ((int)(*data)); }
- rcServer/Components.s/dbaseReader.cc: reading/writing value to database:
/* called from 'daqRun::updateTokenInterval(int itval)', record value to database */ void dbaseReader::putTokenInterval(int itval) { ..... ::sprintf (qstring, "update %s_option set value = '%d' where name = '%s'",run_.runtype (), itval, DBASE_TOKEN_INTERVAL); ..... }
/* read _option table, get tokenInterval value and calls daqRun::tokenInterval(int itval, int writeUpdate) disabling 'write' to avoid writing back to the database we just read it from */ int dbaseReader::parseOptions (char* runtype) { ..... else if (::strcmp (row[0], DBASE_TOKEN_INTERVAL) == 0) /* DBASE_TOKEN_INTERVAL="tokenInterval" */ { int titval; if (::sscanf (row[1], "%d", &titval) >= 1) { run_.tokenInterval (titval, 0); reporter->cmsglog (CMSGLOG_INFO1,"Token interval %d \n", titval); } } ..... }
client side
- rcClient/src.s/rcClient.h:
daqData* tokenInterval_;
- rcClient/src.s/rcClient.cc: same as on server side, but use 'rccDaqData' instead of 'rcsDaqData':
tokenInterval_ = new rccDaqData (exptname_, "tokenInterval", 0); tokenInterval_->connect (dataManager_); tokenInterval_->enableWrite ();
- Xui/src.s/rcClientHandler.cc:
/* connect to database, setting callbacks (called when database changed ?)*/ int rcClientHandler::connect (char* database, char* exptname, char* msqld) { ..... if (handler_.monitorOnCallback (exptname, "tokenInterval", (rcCallback)&(rcClientHandler::tokenIntervalCallback), (void *)this) != CODA_SUCCESS) fprintf (stderr, "Cannot monitor on %s tolenInterval\n", exptname); ..... }
void rcClientHandler::tokenIntervalCallback (int status, void* arg, daqNetData* data) { rcClientHandler* obj = (rcClientHandler *)arg; if (status == CODA_SUCCESS) { obj->tokenIVal_ = (int)(*data); obj->setTokenInterval (obj->tokenIVal_); } }
/* token interval changed, update all panels */ void rcClientHandler::setTokenInterval (int interval) { codaSlistIterator ite (panels_); rcPanel* panel = 0; for (ite.init(); !ite; ++ite) { panel = (rcPanel *) ite (); panel-> configTokenInterval (interval); } }
/* return token interval value */ int rcClientHandler::tokenInterval (void) const { return tokenIVal_; }
- Xui/src.s/rcTokenIButton.cc: set token interval:
void rcTokenIButton::sendTokenInterval (int newval) { /* get client handler */ rcClient& client=netHandler_.clientHandler(); daqData data (client.exptname (), "tokenInterval", newval); if (client.setValueCallback (data, (rcCallback)&(rcTokenIButton::setTICallback), (void *)this) != CODA_SUCCESS) { reportErrorMsg ("Cannot send new token interval value to the server !"); return; } }
void rcTokenIButton::setTICallback (int status, void* arg, daqNetData* ) { rcTokenIButton* obj = (rcTokenIButton *)arg; if (status != CODA_SUCCESS) { obj->reportErrorMsg ("Setting new token interval to the server failed !"); return; } }