8#include "daq/expreco/ERecoMasterCallback.h"
10#include "daq/expreco/ERecoRunControlCallback.h"
12#include "daq/rfarm/manager/RFCommand.h"
13#include "daq/rfarm/manager/RfNodeInfo.h"
14#include "daq/rfarm/manager/RfUnitInfo.h"
16#include <daq/slc/nsm/NSMCommunicator.h>
17#include <daq/slc/runcontrol/RCCommand.h>
18#include <daq/slc/runcontrol/RCHandlerException.h>
19#include <daq/slc/system/Time.h>
21#include <daq/slc/base/StringUtil.h>
22#include <daq/slc/base/TimeoutException.h>
26ERecoMasterCallback::ERecoMasterCallback(
ConfigFile& config) : m_callback(NULL)
28 reg(RFCommand::CONFIGURE);
29 reg(RFCommand::UNCONFIGURE);
30 reg(RFCommand::START);
32 reg(RFCommand::RESUME);
33 reg(RFCommand::PAUSE);
34 reg(RFCommand::RESTART);
35 reg(RFCommand::STATUS);
37 m_rcnode =
NSMNode(config.get(
"ereco.rcnode"));
38 LogFile::debug(
"ERecoMaster started: Bridge Node = %s", m_rcnode.getName().c_str());
41void ERecoMasterCallback::initialize(
const DBObject& obj)
46void ERecoMasterCallback::configure(
const DBObject& obj)
48 m_nodes = NSMNodeList();
49 m_dataname = StringList();
50 const std::string format = obj(
"system").getText(
"nsmdata");
52 if (obj.hasObject(
"dqmserver")) {
53 m_nodes.push_back(
NSMNode(obj(
"dqmserver").getText(
"nodename")));
56 std::string nodename = obj(
"distributor").getText(
"nodename");
57 m_nodes.push_back(
NSMNode(nodename));
58 addData(nodename, format);
60 const DBObject& processor(obj(
"processor"));
61 int maxnodes = processor.getInt(
"nnodes");
62 int idbase = processor.getInt(
"idbase");
63 std::string hostbase = processor.getText(
"nodebase");
64 std::string badlist = processor.getText(
"badlist");
66 for (
int i = 0; i < maxnodes; i++) {
67 sprintf(idname,
"%2.2d", idbase + i);
68 if (badlist.size() == 0 || StringUtil::find(badlist, idname)) {
69 nodename = StringUtil::form(
"evp_%s%2.2d", hostbase.c_str(), idbase + i);
70 m_nodes.push_back(
NSMNode(nodename));
71 addData(nodename, format);
75 nodename = obj(
"eventsampler").getText(
"nodename");
76 m_nodes.push_back(
NSMNode(nodename));
80 std::string rcconf = obj.getName();
81 if (StringUtil::find(rcconf,
"@")) {
82 rcconf = StringUtil::split(rcconf,
'@')[1];
84 for (NSMNodeList::iterator it = m_nodes.begin();
85 it != m_nodes.end(); ++it) {
88 std::string vname = StringUtil::form(
"node[%d]", i++);
89 add(
new NSMVHandlerText(vname +
".rcstate",
true,
false, s.getLabel()));
92 StringUtil::tolower(node.getName())));
93 vname = StringUtil::tolower(node.getName());
94 add(
new NSMVHandlerText(vname +
".rcstate",
true,
false, s.getLabel()));
99void ERecoMasterCallback::setState(
NSMNode& node,
const RCState& state)
101 node.setState(state);
103 for (NSMNodeList::iterator it = m_nodes.begin();
104 it != m_nodes.end(); ++it) {
106 if (StringUtil::toupper(rnode.getName()) == StringUtil::toupper(node.getName())) {
107 std::string vname = StringUtil::form(
"node[%d].rcstate", i);
108 set(vname, state.getLabel());
113 std::string vname = StringUtil::tolower(node.getName()) +
".rcstate";
114 set(vname, state.getLabel());
117void ERecoMasterCallback::monitor()
119 if (!m_callback->getData().isAvailable())
return;
121 unitinfo->nnodes = m_dataname.size();
122 unitinfo->updatetime =
Time().get();
123 unitinfo->rcstate = getNode().getState().getId();
125 for (StringList::iterator it = m_dataname.begin();
126 it != m_dataname.end(); ++it) {
129 if (data.isAvailable()) {
132 memcpy(nodeinfo_o, nodeinfo_i,
sizeof(
RfNodeInfo));
137 static unsigned long long count = 0;
138 for (NSMNodeList::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) {
140 if (count % 60 == 59 || node.getState() == RCState::UNKNOWN) {
141 if (NSMCommunicator::send(
NSMMessage(node, RFCommand::STATUS))) {
143 setState(node, RCState::UNKNOWN);
150void ERecoMasterCallback::ok(
const char* nodename,
const char* data)
152 for (NSMNodeList::iterator it = m_nodes.begin();
153 it != m_nodes.end(); ++it) {
155 if (node.getName() == nodename) {
156 if (strcmp(data,
"Configured") == 0) {
157 setState(node, RCState::READY_S);
158 }
else if (strcmp(data,
"Unconfigured") == 0) {
159 setState(node, RCState::NOTREADY_S);
160 }
else if (strcmp(data,
"Stopped") == 0) {
161 setState(node, RCState::READY_S);
162 }
else if (strcmp(data,
"Running") == 0) {
163 setState(node, RCState::RUNNING_S);
164 }
else if (strcmp(data,
"Idle") == 0) {
165 setState(node, RCState::PAUSED_S);
167 LogFile::debug(
"OK << %s (%s)", nodename, data);
171 LogFile::warning(
"OK from unknown node %s (%s)", nodename, data);
174void ERecoMasterCallback::error(
const char* nodename,
const char* data)
176 for (NSMNodeList::iterator it = m_nodes.begin();
177 it != m_nodes.end(); ++it) {
179 if (node.getName() == nodename) {
180 LogFile::error(
"ERROR << %s (%s)", nodename, data);
181 setState(node, RCState::NOTREADY_S);
185 LogFile::warning(
"Error from unknwon node %s : %s)", nodename, data);
188void ERecoMasterCallback::load(
const DBObject& ,
const std::string& )
190 for (NSMNodeList::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) {
192 printf(
"Loading : %s\n", node.getName().c_str());
193 if (node.getName().find(
"EVP") == std::string::npos) {
195 bool configured =
true;
196 for (NSMNodeList::iterator it2 = m_nodes.begin();
198 if (it2->getState() != RCState::READY_S)
201 if (configured)
break;
203 perform(NSMCommunicator::select(30));
207 if (node.getState() != RCState::READY_S) {
208 printf(
"ERecoMasterCallback::load : loading %s\n", (node.getName()).c_str());
209 if (NSMCommunicator::send(
NSMMessage(node, RCCommand::LOAD))) {
210 setState(node, RCState::LOADING_TS);
211 LogFile::debug(
"%s >> LOADING", node.getName().c_str());
216 LogFile::debug(
"%s is READY", node.getName().c_str());
220 bool configured =
true;
221 for (NSMNodeList::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) {
222 if (it->getState() != RCState::READY_S) configured =
false;
224 if (configured)
break;
226 perform(NSMCommunicator::select(30));
229 if (m_callback != NULL)
230 m_callback->setState(RCState::READY_S);
231 RCCallback::setState(RCState::READY_S);
234void ERecoMasterCallback::abort()
236 for (NSMNodeList::reverse_iterator it = m_nodes.rbegin();
237 it != m_nodes.rend(); ++it) {
239 if (node.getName().find(
"EVP") == std::string::npos) {
241 bool unconfigured =
true;
242 for (NSMNodeList::reverse_iterator it2 = m_nodes.rbegin();
244 if (it2->getState() != RCState::NOTREADY_S)
245 unconfigured =
false;
247 if (unconfigured)
break;
249 perform(NSMCommunicator::select(30));
253 if (node.getState() != RCState::NOTREADY_S) {
254 if (NSMCommunicator::send(
NSMMessage(node, RCCommand::ABORT))) {
255 setState(node, RCState::ABORTING_RS);
256 LogFile::debug(
"%s >> ABORTING", node.getName().c_str());
261 LogFile::debug(
"%s is NOTREADY", node.getName().c_str());
265 bool unconfigured =
true;
266 for (NSMNodeList::reverse_iterator it = m_nodes.rbegin(); it != m_nodes.rend(); ++it) {
267 if (it->getState() != RCState::NOTREADY_S) unconfigured =
false;
269 if (unconfigured)
break;
271 perform(NSMCommunicator::select(30));
274 if (m_callback != NULL)
275 m_callback->setState(RCState::NOTREADY_S);
276 RCCallback::setState(RCState::NOTREADY_S);
279void ERecoMasterCallback::start(
int expno,
int runno)
281 int pars[] = {expno, runno};
283 if (getNode().
getName().find(
"_") != std::string::npos) {
284 get(
"hlt.script", script);
287 LogFile::debug(
"asking database : node = %s", m_rcnode.getName().c_str());
288 get(m_rcnode,
"RUNCONTROL@hlt.script", script);
291 script =
"run_" + script +
".py";
292 printf(
"ERECO script = %s\n", script.c_str());
294 for (NSMNodeList::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) {
296 if (node.getName().find(
"EVP") == std::string::npos) {
298 bool configured =
true;
299 for (NSMNodeList::iterator it2 = m_nodes.begin();
301 if (it2->getState() != RCState::RUNNING_S)
304 if (configured)
break;
306 perform(NSMCommunicator::select(30));
310 if (node.getState() != RCState::RUNNING_S) {
311 if (NSMCommunicator::send(
NSMMessage(node, RCCommand::START, 2, pars, script))) {
312 setState(node, RCState::STARTING_TS);
313 LogFile::debug(
"%s >> STARTING (script=%s)", node.getName().c_str(), script.c_str());
318 LogFile::debug(
"%s is RUNNING", node.getName().c_str());
322 bool configured =
true;
323 for (NSMNodeList::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) {
324 if (it->getState() != RCState::RUNNING_S) configured =
false;
326 if (configured)
break;
328 perform(NSMCommunicator::select(30));
331 char cmdline[] =
"hsendcommand DQMRC:CLEAR erctl 9991";
333 printf(
"ERecoMaster : DQM TMemFile cleared\n");
335 if (m_callback != NULL)
336 m_callback->setState(RCState::RUNNING_S);
337 RCCallback::setState(RCState::RUNNING_S);
340void ERecoMasterCallback::stop()
342 for (NSMNodeList::reverse_iterator it = m_nodes.rbegin();
343 it != m_nodes.rend(); ++it) {
345 if (node.getName().find(
"EVP") == std::string::npos) {
347 bool unconfigured =
true;
348 for (NSMNodeList::reverse_iterator it2 = m_nodes.rbegin();
350 if (it2->getState() != RCState::READY_S)
351 unconfigured =
false;
353 if (unconfigured)
break;
355 perform(NSMCommunicator::select(30));
359 if (node.getState() != RCState::READY_S) {
360 if (NSMCommunicator::send(
NSMMessage(node, RCCommand::STOP))) {
361 setState(node, RCState::STOPPING_TS);
362 LogFile::debug(
"%s >> STOPPING", node.getName().c_str());
367 LogFile::debug(
"%s is READY", node.getName().c_str());
371 bool unconfigured =
true;
372 for (NSMNodeList::reverse_iterator it = m_nodes.rbegin(); it != m_nodes.rend(); ++it) {
373 if (it->getState() != RCState::READY_S) unconfigured =
false;
375 if (unconfigured)
break;
377 perform(NSMCommunicator::select(30));
380 if (m_callback != NULL)
381 m_callback->setState(RCState::READY_S);
382 RCCallback::setState(RCState::READY_S);
385bool ERecoMasterCallback::pause()
390bool ERecoMasterCallback::resume(
int )
395void ERecoMasterCallback::recover(
const DBObject& obj,
const std::string& runtype)
401void ERecoMasterCallback::addData(
const std::string& dataname,
const std::string& format)
403 openData(dataname, format);
404 int i = (int)m_dataname.size();
405 std::string vname = StringUtil::form(
"data[%d].name", i);
406 add(
new NSMVHandlerText(vname,
true,
false, StringUtil::tolower(dataname)));
407 vname = StringUtil::form(
"data[%d].format", i);
409 m_dataname.push_back(dataname);
415 if (RCCallback::perform(com)) {
418 const RFCommand cmd = msg.getRequestName();
420 if (cmd == RFCommand::CONFIGURE) {
421 load(getDBObject(),
"");
423 }
else if (cmd == RFCommand::UNCONFIGURE) {
426 }
else if (cmd == RFCommand::START) {
428 }
else if (cmd == RFCommand::STOP) {
430 }
else if (cmd == RFCommand::RESTART) {
432 }
else if (cmd == RFCommand::PAUSE) {
434 }
else if (cmd == RFCommand::RESUME) {
436 }
else if (cmd == RFCommand::STATUS) {
440 std::string emsg = StringUtil::form(
"%s. aborting", e.what());
441 LogFile::error(emsg);
444 RCCallback::setState(RCState::ABORTING_RS);
446 RCCallback::setState(RCState::NOTREADY_S);
448 std::string exmsg = StringUtil::form(
"Failed to abort : %s", ex.what());
449 LogFile::fatal(exmsg);
451 }
catch (
const std::exception& e) {
452 LogFile::fatal(
"Unknown exception: %s. terminating process", e.what());
TString getName(const TObject *obj)
human-readable name (e.g.
Abstract base class for different kinds of events.