24 dabc::ModuleAsync(name, cmd)
103 .
AddArg(
"oninit",
"int",
false,
"0");
120 auto iter1 = items.begin();
121 auto iter2 = nodes.begin();
122 while (iter1 != items.end()) {
124 items.insert(iter1, item);
125 nodes.insert(iter2, node);
132 items.emplace_back(item);
133 nodes.emplace_back(node);
143 FILE* f = fopen(
"lastcalibr.txt", do_write ?
"w" :
"r");
145 EOUT(
"FAIL to open file lastcalibr.txt for %s", do_write ?
"writing" :
"reading");
151 fprintf(f,
"%lu\n", (
long unsigned) tm.
AsJSDate());
152 fprintf(f,
"%f\n", quality);
153 fprintf(f,
"%u\n", runid);
155 long unsigned tm_js = 0;
156 if (fscanf(f,
"%lu", &tm_js) != 1)
EOUT(
"Fail to get time from lastcalibr.txt");
158 if (fscanf(f,
"%lf", &quality) != 1)
EOUT(
"Fail to get quality from lastcalibr.txt");
159 if (fscanf(f,
"%u", &runid) != 1)
EOUT(
"Fail to get runid from lastcalibr.txt");
161 if (!do_write) fCalibrRunId = runid;
167 DOUT0(
"CALIBR INFO %s", info.c_str());
178 if (cmd.
IsName(dabc::CmdGetNamesList::CmdName())) {
182 std::vector<std::string> binp, bbuild, nodes_inp, nodes_build;
183 while (iter.
next()) {
189 std::size_t pos = producer.find_last_of(
"/");
190 if (pos != std::string::npos) producer.resize(pos);
192 if (kind ==
"sender") AddItem(binp, nodes_inp, item.
ItemName(), producer);
193 if (kind ==
"receiver") AddItem(bbuild, nodes_build, item.
ItemName(), producer);
198 if ((fLastBuilders.size()>0) && (fLastBuilders == bbuild)) {
200 if (!fInitRunCmd.null() && (fSameBuildersCnt > cmd.
GetInt(
"oninit"))) {
201 DOUT0(
"DETECTED SAME BUILDERS %d", fSameBuildersCnt);
203 fInitRunCmd.SetBool(
"#verified",
true);
204 int res = ExecuteCommand(fInitRunCmd);
206 fInitRunCmd.Reply(res);
208 fInitRunCmd.Release();
212 fSameBuildersCnt = 0;
215 fLastBuilders = bbuild;
217 fWorkerHierarchy.GetHChild(
"Inputs").SetField(
"value", binp);
218 fWorkerHierarchy.GetHChild(
"Inputs").SetField(
"nodes", nodes_inp);
219 fWorkerHierarchy.GetHChild(
"Builders").SetField(
"value", bbuild);
220 fWorkerHierarchy.GetHChild(
"Builders").SetField(
"nodes", nodes_build);
223 if (!fCtrlTm.Expired())
return true;
224 if (fCtrlCnt > 0) { fCtrlError =
true;
EOUT(
"Fail to get %d control records", fCtrlCnt); }
237 fCtrlStateQuality = 1;
242 fCtrlInpNodesCnt = 0;
243 fCtrlInpNodesExpect = 0;
244 fCtrlBldNodesCnt = 0;
245 fCtrlBldNodesExpect = 0;
250 fCurrentLost = fCurrentEvents = fCurrentData = 0;
254 for (
unsigned n=0;n<bbuild.size();++n) {
256 subcmd.
SetInt(
"#bnet_ctrl_id", fCtrlId);
258 publ.
Submit(Assign(subcmd));
262 for (
unsigned n=0;n<binp.size();++n) {
264 subcmd.
SetInt(
"#bnet_ctrl_id", fCtrlId);
266 publ.
Submit(Assign(subcmd));
271 fCtrlStateQuality = 0.;
272 fCtrlStateName =
"NoNodes";
273 }
else if (binp.size()==0) {
274 fCtrlStateQuality = 0.;
275 fCtrlStateName =
"NoInputs";
276 }
else if (bbuild.size() == 0) {
277 fCtrlStateQuality = 0.;
278 fCtrlStateName =
"NoBuilders";
279 }
else if (fCtrlErrorCnt > 5) {
280 fCtrlStateQuality = 0.1;
281 fCtrlStateName =
"LostControl";
284 if (!fCtrlStateName.empty()) {
285 SetParValue(
"State",
"NoNodes");
286 SetParValue(
"Quality", fCtrlStateQuality);
291 }
else if (cmd.
HasField(
"#bnet_cnt")) {
294 DOUT0(
"Get %s reply id:%d expecting:%d replies:%d cmd:%s", cmd.
GetName(), cmd.
GetInt(
"#bnet_cnt"), fCmdCnt, fCmdReplies, fCurrentFileCmd.GetName());
296 if (!fCurrentFileCmd.null() && (cmd.
GetInt(
"#bnet_cnt") == fCmdCnt)) {
298 bool stop_calibr = fCurrentFileCmd.IsName(
"StopRun") && fCurrentFileCmd.GetBool(
"#calibr_run");
300 if (stop_calibr && cmd.
HasField(
"quality"))
301 if (cmd.
GetDouble(
"quality") < fCmdQuality)
304 if (--fCmdReplies <= 0) {
306 fCalibrRunId = fCurrentFileCmd.GetUInt(
"#calibr_runid");
310 fWorkerHierarchy.GetHChild(
"RunningCmd").SetField(
"value",
"");
312 if (stop_calibr) PreserveLastCalibr(
true, fCmdQuality, fCalibrRunId);
316 }
else if (cmd.
HasField(
"#refresh_cnt")) {
318 if (!fCurrentRefreshCmd.null() && (cmd.
GetInt(
"#refresh_cnt") == fRefreshCnt)) {
320 q0 = fCurrentRefreshCmd.GetDouble(
"quality", 1.);
323 fCurrentRefreshCmd.SetDouble(
"quality", q0);
326 if (--fRefreshReplies <= 0) {
328 PreserveLastCalibr(
true, q0, fCalibrRunId);
334 }
else if (cmd.
GetInt(
"#bnet_ctrl_id") == fCtrlId) {
344 bool is_builder =
false;
346 while (iter.
next()) {
356 if (item.
GetField(
"_bnet").
AsStr() ==
"receiver") is_builder =
true;
358 if (is_builder) fCtrlBldNodesCnt++;
359 else fCtrlInpNodesCnt++;
364 if (fCtrlStateName.empty() || (quality < fCtrlStateQuality)) {
365 fCtrlStateQuality = quality;
366 fCtrlStateName = state;
374 if (!fTotalData)
DOUT0(
"FIRST TIME GET DATA %d %lu", fCtrlCnt, item.
GetField(
"build_data").
AsUInt());
377 if (fNewRunTm.Expired() && (fCtrlSzLimit > 0) && (fMaxRunSize > 0) && (item.
GetField(
"runsize").
AsUInt() > fMaxRunSize*1e6))
384 if (runid && !runprefix.empty()) {
387 fCtrlRunPrefix = runprefix;
388 }
else if ((fCtrlRunId != runid) || (fCtrlRunPrefix != runprefix)) {
389 if ((fCtrlStateQuality > 0) && fNewRunTm.Expired()) {
390 fCtrlStateName =
"RunMismatch";
391 fCtrlStateQuality = 0;
397 if (fCtrlInpNodesExpect == 0) fCtrlInpNodesExpect = ninputs;
399 if ((fCtrlInpNodesExpect != ninputs) && (fCtrlStateQuality > 0)) {
400 fCtrlStateName =
"InputsMismatch";
401 fCtrlStateQuality = 0;
406 if (fCtrlBldNodesExpect==0) fCtrlBldNodesExpect = nbuilders;
407 if ((fCtrlBldNodesExpect != nbuilders) && (fCtrlStateQuality > 0)) {
408 fCtrlStateName =
"BuildersMismatch";
409 fCtrlStateQuality = 0;
417 if (fCtrlStateName.empty()) {
418 fCtrlStateName =
"Ready";
419 fCtrlStateQuality = 1.;
421 if ((fCtrlInpNodesCnt == 0) && (fCtrlStateQuality > 0)) {
422 fCtrlStateName =
"NoInputs";
423 fCtrlStateQuality = 0;
426 if ((fCtrlInpNodesExpect != fCtrlInpNodesCnt) && (fCtrlStateQuality > 0)) {
427 fCtrlStateName =
"InputsMismatch";
428 fCtrlStateQuality = 0;
431 if ((fCtrlBldNodesCnt == 0) && (fCtrlStateQuality > 0)) {
432 fCtrlStateName =
"NoBuilders";
433 fCtrlStateQuality = 0;
435 if ((fCtrlBldNodesExpect != fCtrlBldNodesCnt) && (fCtrlStateQuality > 0)) {
436 fCtrlStateName =
"BuildersMismatch";
437 fCtrlStateQuality = 0;
440 SetParValue(
"State", fCtrlStateName);
441 SetParValue(
"Quality", fCtrlStateQuality);
442 SetParValue(
"RunId", fCtrlRunId);
444 SetParValue(
"RunPrefix", fCtrlRunPrefix);
446 fWorkerHierarchy.GetHChild(
"LastPrefix").SetField(
"value", fCtrlRunPrefix);
448 DOUT3(
"BNET control sequence ready state %s overlimit %s", fCtrlStateName.c_str(),
DBOOL(fCtrlSzLimit>1));
450 bool do_set = (fTotalEvents || fTotalLost) && (fCurrentLost >= fTotalLost) && (fCurrentEvents >= fTotalEvents) && (fCurrentData >= fTotalData);
453 double spent = fLastRateTm.SpentTillNow();
454 spent = (spent > 1e-3) ? 1./spent : 0.;
456 fCtrlLost = (fCurrentLost-fTotalLost)*spent;
457 fCtrlEvents = (fCurrentEvents-fTotalEvents)*spent;
458 fCtrlData = (fCurrentData-fTotalData)*spent/1024./1024.;
460 if ((fCtrlEvents > 1e9) || (fCtrlLost > 1e9) || (fCtrlData > 1e9)) do_set =
false;
463 fTotalLost = fCurrentLost;
464 fTotalEvents = fCurrentEvents;
465 fTotalData = fCurrentData;
466 fLastRateTm.GetNow();
469 Par(
"DataRate").SetValue(fCtrlData);
470 Par(
"EventsRate").SetValue(fCtrlEvents);
471 Par(
"LostRate").SetValue(fCtrlLost);
474 SetParValue(
"TotalEvents", fTotalEvents);
475 SetParValue(
"TotalLost", fTotalLost);
477 if (fControl && (fCtrlSzLimit > 1) && fCurrentFileCmd.null()) {
502 if (!fCurrentFileCmd.null() && fCurrentFileCmd.IsTimedout()) {
503 EOUT(
"Abort RUN command %s", fCurrentFileCmd.GetName());
505 fWorkerHierarchy.GetHChild(
"RunningCmd").SetField(
"value",
"");
508 if (!fInitRunCmd.null() && fInitRunCmd.IsTimedout())
516 if (!fCurrentFileCmd.null()) {
517 EOUT(
"Ignore run command - previous %s not completed", fCurrentFileCmd.GetName());
521 bool isstart = cmd.
IsName(
"StartRun");
525 if (isstart && (cmd.
GetInt(
"oninit")>0) && !cmd.
GetBool(
"#verified")) {
526 DOUT0(
"Detect START RUN with oninit flag!!!!");
532 fSameBuildersCnt = 0;
537 std::vector<std::string> builders = fWorkerHierarchy.GetHChild(
"Builders").GetField(
"value").AsStrVect();
543 fCurrentFileCmd = cmd;
559 std::string query, prefix;
561 unsigned lastrunid = fWorkerHierarchy.GetHChild(
"MasterRunId").GetField(
"value").AsUInt();
562 std::string lastprefix = fWorkerHierarchy.GetHChild(
"LastPrefix").GetField(
"value").AsStr();
564 prefix = cmd.
GetStr(
"prefix");
565 if (prefix ==
"NO_FILE" || prefix ==
"--" || (prefix.empty() && (lastprefix ==
"--" || lastprefix.empty())))
573 if (!prefix.empty()) {
574 query.append(
"&prefix=");
575 query.append(prefix);
577 DOUT0(
"Starting new run %s", query.c_str());
583 fWorkerHierarchy.GetHChild(
"RunningCmd").SetField(
"value",
dabc::format(
"Start %s %u", prefix.c_str(), runid));
585 fWorkerHierarchy.GetHChild(
"RunningCmd").SetField(
"value",
dabc::format(
"Stop %s %u", lastprefix.c_str(), lastrunid));
587 fWorkerHierarchy.GetHChild(
"MasterRunId").SetField(
"value", runid);
589 if (isstart && !prefix.empty())
590 fWorkerHierarchy.GetHChild(
"LastPrefix").SetField(
"value", prefix);
592 DOUT0(
"MASTER cmd:%s doing:%s query:%s prefix:%s lastprefix:%s lastrunid:%u cmdcnt:%d", cmd.
GetName(), (isstart ?
"START" :
"STOP"), query.c_str(), prefix.c_str(), lastprefix.c_str(), lastrunid, fCmdCnt);
594 for (
unsigned n=0; n<builders.size(); ++n) {
596 subcmd.
SetInt(
"#bnet_cnt", fCmdCnt);
599 publ.
Submit(Assign(subcmd));
604 if (isstart && (prefix ==
"tc") && lastprefix.empty()) {
606 }
else if (!isstart && (lastprefix ==
"tc")) {
610 if (!query.empty()) {
611 fCurrentFileCmd.SetBool(
"#calibr_run",
true);
612 fCurrentFileCmd.SetUInt(
"#calibr_runid", lastrunid);
615 std::vector<std::string> inputs = fWorkerHierarchy.GetHChild(
"Inputs").GetField(
"value").AsStrVect();
617 for (
unsigned n=0; n<inputs.size(); ++n) {
619 subcmd.
SetInt(
"#bnet_cnt", fCmdCnt);
622 publ.
Submit(Assign(subcmd));
629 }
else if (cmd.
IsName(
"RefreshRun")) {
631 if (!fCurrentRefreshCmd.null()) {
632 EOUT(
"Ignore run command - previous %s not completed", fCurrentRefreshCmd.GetName());
639 fCurrentRefreshCmd = cmd;
643 fCurrentRefreshCmd.
SetDouble(
"quality", 1.0);
646 std::vector<std::string> inputs = fWorkerHierarchy.GetHChild(
"Inputs").GetField(
"value").AsStrVect();
648 for (
unsigned n = 0; n < inputs.size(); ++n) {
650 subcmd.
SetInt(
"#refresh_cnt", fRefreshCnt);
653 publ.
Submit(Assign(subcmd));
657 }
else if (cmd.
IsName(
"ResetDAQ")) {
658 std::vector<std::string> builders = fWorkerHierarchy.GetHChild(
"Builders").GetField(
"value").AsStrVect();
659 std::vector<std::string> inputs = fWorkerHierarchy.GetHChild(
"Inputs").GetField(
"value").AsStrVect();
664 for (
unsigned n=0; n<inputs.size(); ++n) {
669 for (
unsigned n=0; n<builders.size(); ++n) {
Command used to produce custom binary data for published in hierarchy entries.
Command to request names list.
static Hierarchy GetResNamesList(dabc::Command &cmd)
CommandDefinition & AddArg(const std::string &name, const std::string &kind="string", bool required=true, const RecordField &dflt=RecordField())
Represents command with its arguments.
double TimeTillTimeout(double extra=0.) const
Returns time which remains until command should be timed out.
unsigned GetUInt(const std::string &name, unsigned dflt=0) const
double GetDouble(const std::string &name, double dflt=0.) const
bool SetInt(const std::string &name, int v)
std::string GetStr(const std::string &name, const std::string &dflt="") const
Command & SetTimeout(double tm)
Set maximum time which can be used for command execution.
bool IsTimeoutSet() const
Return true if timeout was specified.
bool GetBool(const std::string &name, bool dflt=false) const
bool SetDouble(const std::string &name, double v)
bool IsTimedout() const
Returns true if command timeout is expired.
int GetInt(const std::string &name, int dflt=0) const
Class for holding GMT time with precision of nanoseconds.
std::string AsJSString(int ndecimal=3) const
convert string into sec.frac format, can be interpret directly in JavaScript ISO 8601 standard is use...
void SetJSDate(uint64_t jsdate)
Set value in form of JS date - milliseconds since 1.1.1970.
uint64_t AsJSDate() const
Return date and time in JS format - number of millisecond since 1.1.1970.
std::string AsString(int ndecimal=0, bool localtime=false) const
convert string into human-readable format, cannot be interpret directly in JavaScript
Represents objects hierarchy of remote (or local) DABC process.
Hierarchy CreateHChild(const std::string &name, bool allowslahes=false, bool sortorder=false)
Create child item in hierarchy with specified name If allowslahes enabled, instead of subfolders item...
std::string ItemName() const
Name which is used as item name in hierarchy.
Hierarchy GetHChild(const std::string &name, bool allowslahes=false, bool force=false, bool sortorder=false)
Return child, if necessary creates with full subfolder If force specified, missing childs and folders...
void Create(const std::string &name, bool withmutex=false)
Create top-level object with specified name.
Iterator over objects hierarchy
Object * next(bool goinside=true)
virtual Parameter CreatePar(const std::string &name, const std::string &kind="")
virtual bool ReplyCommand(Command cmd)
Reimplement this method to react on command reply Return true if command can be destroyed by framewor...
unsigned CreateTimer(const std::string &name, double period_sec=-1., bool synchron=false)
bool SetValue(const RecordField &v)
Set parameter value.
Parameter & SetFld(const std::string &name, const RecordField &v)
Parameter & SetUnits(const std::string &unit)
Set units field of parameter.
uint64_t AsUInt(uint64_t dflt=0) const
bool AsBool(bool dflt=false) const
std::string AsStr(const std::string &dflt="") const
int64_t AsInt(int64_t dflt=0) const
double AsDouble(double dflt=0.) const
RecordField GetField(const std::string &name) const
bool HasField(const std::string &name) const
bool SetField(const std::string &name, const RecordField &v)
const char * GetName() const
Return name of referenced object, if object not assigned, returns "---".
bool IsName(const char *name) const
Returns true if object name is the same as specified one.
bool null() const
Returns true if reference contains nullptr.
Reference on dabc::Worker
CommandDefinition CreateCmdDef(const std::string &name)
Hierarchy fWorkerHierarchy
place for publishing of worker parameters
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration field of specified name Configuration value of specified name searched in follo...
virtual bool PublishPars(const std::string &path)
void PreserveLastCalibr(bool do_write=false, double quality=1., unsigned runid=0)
virtual int ExecuteCommand(dabc::Command cmd)
Main method where commands are executed.
dabc::TimeStamp fLastRateTm
last time ratemeter was updated
dabc::TimeStamp fNewRunTm
time when last control count was send
int fRefreshCnt
currently running refresh command
int fCtrlCnt
how many control replies are awaited
int fCmdReplies
number of replies for current command
double fCmdQuality
current command quality, used when creating calibration
virtual bool ReplyCommand(dabc::Command cmd)
Reimplement this method to react on command reply Return true if command can be destroyed by framewor...
uint64_t fCurrentData
current value
uint64_t fTotalData
last value
unsigned fMaxRunSize
maximal run size in MB
uint64_t fTotalLost
last value
uint64_t fTotalEvents
last value
uint64_t fCurrentLost
current value
BnetMasterModule(const std::string &name, dabc::Command cmd=nullptr)
uint64_t fCurrentEvents
current value
virtual void BeforeModuleStart()
int fCtrlErrorCnt
number of consequent control errors
int fCtrlSzLimit
0 - do nothing, 1 - start checking (after start run), 2 - exced
virtual void ProcessTimerEvent(unsigned timer)
Method called by framework when timer event is produced.
int fCtrlId
counter for control requests
int fSameBuildersCnt
how many time same number of inputs was detected
bool fCtrlError
if there are error during current communication loop
dabc::TimeStamp fCtrlTm
time when last control count was send
bool fControl
when true, master actively controls BNET nodes and switches to new RUNs
int fRefreshReplies
number of replies for current command
void AddItem(std::vector< std::string > &items, std::vector< std::string > &nodes, const std::string &item, const std::string &node)
int fCmdCnt
just counter to avoid mismatch
std::string format(const char *fmt,...)
std::string FormatFilename(uint32_t runid, uint16_t ebid=0)
void GetNow()
Method to acquire current time stamp.