1 #include "daq/slc/runcontrol/RCCallback.h"
3 #include <daq/slc/database/DBHandlerException.h>
4 #include <daq/slc/database/DBInterface.h>
5 #include <daq/slc/database/DBObjectLoader.h>
7 #include <daq/slc/runcontrol/RCCommand.h>
8 #include <daq/slc/runcontrol/RCHandlerException.h>
9 #include <daq/slc/runcontrol/RCHandlerFatalException.h>
11 #include <daq/slc/system/LogFile.h>
12 #include <daq/slc/system/TCPSocket.h>
13 #include <daq/slc/system/TCPSocketReader.h>
14 #include <daq/slc/system/TCPSocketWriter.h>
16 #include <daq/slc/nsm/NSMCommunicator.h>
32 const std::string& name,
const std::string& val)
34 bool handleGetText(std::string& val)
36 const DBObject& obj(m_callback.getDBObject());
40 bool handleSetText(
const std::string& val)
42 RCState state(m_callback.getNode().getState());
43 RCState tstate(RCCommand::CONFIGURE.nextTState());
44 m_callback.setState(tstate);
47 m_callback.dbload(val.size(), val.c_str());
51 DBObject& obj(m_callback.getDBObject());
53 m_callback.configure(obj);
54 m_callback.setState(state);
66 RCCallback::RCCallback(
int timeout)
69 reg(RCCommand::CONFIGURE);
72 reg(RCCommand::START);
74 reg(RCCommand::RECOVER);
75 reg(RCCommand::RESUME);
76 reg(RCCommand::PAUSE);
77 reg(RCCommand::ABORT);
78 reg(RCCommand::STATUS);
79 reg(NSMCommand::FATAL);
83 m_expno = m_runno = 0;
88 LogFile::debug(
"init");
93 LogFile::fatal(
"Failed to initialize. %s. terminating process (84)",
e.what());
97 LogFile::debug(
"init done");
98 setState(RCState::NOTREADY_S);
99 tabort =
Date().get();
105 const RCCommand cmd = msg.getRequestName();
106 const RCState state_org(getNode().getState());
107 RCState state(getNode().getState());
108 if (NSMCallback::perform(com))
return true;
109 if (cmd.isAvailable(state) == NSMCommand::DISABLED) {
112 addNode(
NSMNode(msg.getNodeName()));
114 set(
"rcrequest", msg.getRequestName());
115 }
catch (
const std::exception& e) {
116 LogFile::error(
e.what());
118 RCState tstate(cmd.nextTState());
120 if (tstate != Enum::UNKNOWN) {
121 log(LogFile::DEBUG,
"RC request %s from %s", msg.getRequestName(), msg.getNodeName());
123 std::string nodename = getNode().getName();
124 bool ismaster = nodename ==
"RUNCONTROL" ||
125 (StringUtil::find(nodename,
"RC_") && !StringUtil::find(nodename,
"HLT"));
126 if (cmd == RCCommand::CONFIGURE) {
127 m_runcontrol.setName(msg.getNodeName());
128 configure_raw(msg.getLength(), msg.getData());
129 }
else if (cmd == RCCommand::BOOT) {
130 m_runcontrol.setName(msg.getNodeName());
132 std::string opt = msg.getLength() > 0 ? msg.getData() :
"";
134 }
else if (cmd == RCCommand::LOAD) {
137 m_runcontrol.setName(msg.getNodeName());
138 std::string runtype = (msg.getLength() > 0 ? msg.getData() :
"");
139 if (runtype.size() == 0) {
140 get(
"runtype", runtype);
141 }
else if (runtype.size() > 0) {
142 set(
"runtype", runtype);
145 load(m_obj, runtype);
146 }
else if (cmd == RCCommand::START) {
147 m_runcontrol.setName(msg.getNodeName());
148 m_expno = (msg.getNParams() > 0) ? msg.getParam(0) : 0;
149 m_runno = (msg.getNParams() > 1) ? msg.getParam(1) : 0;
151 log(LogFile::NOTICE,
"Run start by %s (exp=%05d, run=%06d)",
152 msg.getNodeName(), m_runno, m_expno);
154 start(m_expno, m_runno);
155 }
else if (cmd == RCCommand::STOP) {
157 log(LogFile::NOTICE,
"Run stop by %s (exp=%05d, run=%06d)",
158 msg.getNodeName(), m_runno, m_expno);
161 }
else if (cmd == RCCommand::RESUME) {
163 log(LogFile::NOTICE,
"Run resume by %s (exp=%05d, run=%06d)",
164 msg.getNodeName(), m_runno, m_expno);
166 if (!resume(msg.getParam(0))) {
167 setState(RCState::NOTREADY_S);
170 }
else if (cmd == RCCommand::PAUSE) {
172 log(LogFile::NOTICE,
"Run pause by %s (exp=%05d, run=%06d)",
173 msg.getNodeName(), m_runno, m_expno);
176 setState(RCState::NOTREADY_S);
181 if (cmd == RCCommand::ABORT) {
182 double t =
Date().get();
183 if (t - tabort > 3) {
185 log(LogFile::NOTICE,
"Run abort by %s (exp=%05d, run=%06d)",
186 msg.getNodeName(), m_runno, m_expno);
188 m_runcontrol.setName(msg.getNodeName());
192 }
else if (cmd == RCCommand::RECOVER) {
194 get(
"runtype", runtype);
195 recover(m_obj, runtype);
198 log(LogFile::FATAL,
"Failed to recover/abort : %s",
e.what());
201 RCState state = cmd.nextState();
202 if (getNode().getState() == tstate &&
203 state != Enum::UNKNOWN && m_auto) {
206 state = getNode().getState();
207 if (state != Enum::UNKNOWN) {
208 if ((cmd == RCCommand::START &&
209 (state == RCState::RUNNING_S || state == RCState::STARTING_TS)) ||
210 ((cmd == RCCommand::STOP || cmd == RCCommand::ABORT)
211 && state_org == RCState::RUNNING_S)) {
213 dump(cmd == RCCommand::START);
215 LogFile::error(
e.what());
220 log(LogFile::FATAL,
e.what());
222 log(LogFile::ERROR,
e.what());
223 setState(RCState::ERROR_ES);
224 }
catch (
const std::exception& e) {
225 log(LogFile::FATAL,
"Unknown exception: %s. terminating process (193)",
e.what());
230 void RCCallback::dump(
bool isstart)
233 get(
"runtype", runtype);
234 std::string rcconfig = getNode().getName() +
"@RC:"
235 + (isstart ?
"start:" :
"end:") + runtype
236 + StringUtil::form(
":%05d:%04d", m_expno, m_runno);
237 std::stringstream ss;
238 ss << dbdump() << std::endl;
239 ss <<
"config : " << rcconfig << std::endl;
240 LogFile::debug(ss.str());
242 DBObject obj = DBObjectLoader::load(file);
244 std::string table = m_table +
"record";
248 DBObjectLoader::createDB(db, table, obj);
252 }
else if (m_provider_host.size() > 0 && m_provider_port > 0) {
253 TCPSocket socket(m_provider_host, m_provider_port);
258 writer.writeString(table);
259 writer.writeObject(obj);
273 LogFile::fatal(
e.what());
274 setState(RCState::ERROR_ES);
277 LogFile::error(
e.what());
278 setState(RCState::ERROR_ES);
280 }
catch (
const std::exception& e) {
281 LogFile::fatal(
"Unknown exception: %s. terminating process (249)",
e.what());
285 std::string RCCallback::dbdump()
287 std::stringstream ss;
288 StringList& hnames(getHandlerNames());
289 NSMVHandlerList& handlers(getHandlers());
290 for (StringList::iterator it = hnames.begin();
291 it != hnames.end(); it++) {
292 std::string hname = *it;
294 std::string vname = StringUtil::replace(hname,
"@",
"");
295 if (!handler.useGet()) {
298 if (!handler.isDumped()) {
301 if (vname.c_str()[0] ==
'.') {
305 handler.handleGet(var);
306 switch (var.getType()) {
308 ss << vname <<
" : int(" << var.getInt() <<
")" << std::endl;
311 ss << vname <<
" : float(" << var.getFloat() <<
")" << std::endl;
314 ss << vname <<
" : \"" << var.getText() <<
"\"" << std::endl;
320 ss << getDBObject().sprint(
true) << std::endl;
321 ss <<
"nodename : " << std::endl;
325 void RCCallback::setState(
const RCState& state)
327 RCState state_org = getNode().getState();
328 if (state_org != state) {
329 LogFile::debug(
"state transit : %s >> %s",
330 state_org.getLabel(), state.getLabel());
332 getNode().setState(state);
333 set(
"rcstate", state.getLabel());
334 }
catch (
const std::exception& e) {
335 LogFile::error(
e.what());
340 DBObject RCCallback::dbload(
const std::string& path)
343 std::string pathin, table, config;
344 LogFile::debug(path);
345 if (path.find(
"db://") != std::string::npos) {
346 pathin = StringUtil::replace(path,
"db://",
"");
347 StringList s = StringUtil::split(pathin,
'/');
355 }
else if (path.find(
"file://") != std::string::npos) {
356 pathin = StringUtil::replace(path,
"file:/",
"");
359 if (table.size() > 0 && config.size() > 0) {
363 obj = DBObjectLoader::load(db, table, config,
false);
364 if (obj.getName().size() > 0) {
365 config = obj.getName();
372 }
else if (m_provider_host.size() > 0 && m_provider_port > 0) {
373 TCPSocket socket(m_provider_host, m_provider_port);
378 writer.writeString(table +
"/" + config);
380 obj.readObject(reader);
382 if (obj.getName().size() > 0) {
383 config = obj.getName();
387 throw (
IOException(
"Socket connection error : %s ",
e.what()));
394 void RCCallback::configure_raw(
int length,
const char* data)
397 dbload(length, data);
404 void RCCallback::dbload(
int ,
const char* )
407 m_rcconfig = node.getName() +
"@RC:" + m_rcconfig_org;
408 LogFile::debug(
"Loading '%s'", m_rcconfig.c_str());
409 if (m_file.size() > 0) {
410 StringList
files = StringUtil::split(m_file,
',');
412 for (
size_t i = 0; i <
files.size(); i++) {
415 m_obj = DBObjectLoader::load(conf);
416 m_obj.print(m_showall);
417 }
else if (getDB()) {
419 std::string rcconfig =
"";
421 if (m_runtype_record.size()) {
422 rcconfig = node.getName() +
"@RC:start:" + m_runtype_record +
":";
423 obj1 = DBObjectLoader::load(db, m_table +
"record", rcconfig, m_showall);
425 obj2 = DBObjectLoader::load(db, m_table, m_rcconfig, m_showall);
426 if (obj1.getDate() < obj2.getDate()) {
430 m_rcconfig = rcconfig;
433 m_obj.print(m_showall);
434 }
else if (m_provider_host.size() > 0 && m_provider_port > 0) {
435 TCPSocket socket(m_provider_host, m_provider_port);
438 std::string rcconfig =
"";
439 if (m_runtype_record.size() > 0) {
440 rcconfig = node.getName() +
"@RC:start:" + m_runtype_record +
":";
444 writer.writeString(m_table +
"record/" + rcconfig);
446 obj1.readObject(reader);
452 writer.writeString(m_table +
"/" + m_rcconfig);
454 obj2.readObject(reader);
455 if (obj1.getDate() < obj2.getDate()) {
459 m_rcconfig = rcconfig;
461 m_obj.print(m_showall);
464 throw (
IOException(
"Socket connection error : %s ",
e.what()));
470 add(
new NSMVHandlerText(
"dbtable",
true,
false, m_table),
false,
true);
471 add(
new NSMVHandlerText(
"rcstate",
true,
false, RCState::NOTREADY_S.getLabel()),
false,
true);