8#include <daq/dqm/HistoServer2.h>
10#include <framework/pcore/MsgHandler.h>
21HistoServer2::HistoServer2(
int port,
const string& filename)
23 TMessage::EnableSchemaEvolutionForAll(kTRUE);
26 m_filename = filename;
29HistoServer2::~HistoServer2()
32 m_root_socket->Close();
34 m_root_socket =
nullptr;
48int HistoServer2::init()
50 m_sock =
new EvtSocketRecv(m_port,
false);
51 m_man =
new EvtSocketManager(m_sock);
52 m_hman =
new HistoManager2(m_filename);
55 int rootPort = m_port + 1;
57 printf(
"before ROOT socket connection\n");
62 printf(
"ROOT socket connected\n");
69int HistoServer2::server()
75 char* buffer =
new char[c_maxBufSize];
80 while (m_force_exit == 0) {
83 vector<TObject*> objlist;
84 vector<string> strlist;
86 if (recv_root_message(objlist, strlist, root_fd)) {
87 printf(
"HistoServer2: ROOT received nobjs=%zu\n", objlist.size());
88 handle_objects(objlist, strlist, root_fd, updated);
91 for (
auto* obj : objlist) {
95 int exam_stat = m_man->examine();
97 }
else if (exam_stat == 1) {
99 vector<int>& recvsock = m_man->connected_socket_list();
100 for (vector<int>::iterator it = recvsock.begin();
101 it != recvsock.end(); ++it) {
103 if (m_man->connected(fd)) {
104 struct sockaddr_in isa;
105 socklen_t isize =
sizeof(isa);
106 getpeername(fd, (
struct sockaddr*)&isa, &isize);
107 char address[INET_ADDRSTRLEN];
108 strcpy(address, inet_ntoa(isa.sin_addr));
109 char* ptr = strrchr(address,
'.');
115 m_unit_last_conn_time[address] = now;
117 int is = sio.get(fd, buffer, c_maxBufSize);
120 strftime(mbstr,
sizeof(mbstr),
"%F %T", localtime(&now));
121 printf(
"[%s] HistoServer2: fd %d / %s disconnected\n", mbstr, fd, address);
129 EvtMessage* hmsg =
new EvtMessage(buffer);
130 vector<TObject*> objlist;
131 vector<string> strlist;
132 msghdl.decode_msg(hmsg, objlist, strlist);
133 int nobjs = (hmsg->
header())->reserved[1];
137 strftime(mbstr,
sizeof(mbstr),
"%F %T", localtime(&now));
138 m_unit_last_packet_time[address] = now;
139 printf(
"[%s] HistoServer2 : received nobjs = %d from %s\n", mbstr, nobjs, address);
140 if (nobjs > 0) m_unit_last_content_time[address] = now;
141 for (
int i = 0; i < nobjs; i++) {
144 string objname = strlist.at(i);
145 auto lpos = objname.find(
"SUBDIR:");
146 if (lpos != string::npos) {
147 subdir = objname.substr(7);
148 if (subdir ==
"EXIT") subdir =
"";
152 m_hman->update(subdir, strlist.at(i), fd, (TH1*)objlist.at(i));
161 if (loop_counter % c_mergeIntervall == 0) {
163 m_last_merge_time = time(0);
164 strftime(mbstr,
sizeof(mbstr),
"%F %T", localtime(&m_last_merge_time));
165 printf(
"[%s] HistoServer2: merging histograms\n", mbstr);
180 std::string name =
"/tmp/dqm_hserver_state_" + m_filename;
181 FILE* fh = fopen(name.c_str(),
"wt+");
183 time_t now = time(0);
184 strftime(mbstr,
sizeof(mbstr),
"%F %T", localtime(&now));
185 strftime(mbstr2,
sizeof(mbstr2),
"%F %T", localtime(&m_last_merge_time));
186 fprintf(fh,
"%s,%s,%s\n", m_filename.c_str(), mbstr, mbstr2);
189 int nr = it.second.first;
190 int con = it.second.second;
191 strftime(mbstr,
sizeof(mbstr),
"%F %T", localtime(&m_unit_last_conn_time[it.first]));
192 strftime(mbstr2,
sizeof(mbstr2),
"%F %T", localtime(&m_unit_last_packet_time[it.first]));
193 strftime(mbstr3,
sizeof(mbstr3),
"%F %T", localtime(&m_unit_last_content_time[it.first]));
194 if (it.first ==
"127.0.0.1") {
195 fprintf(fh,
"RUNCONTROL,");
197 if (nr >= 0 and nr < 20) {
198 fprintf(fh,
"HLT%d,", nr);
199 }
else if (nr > 100 and nr < 110) {
200 fprintf(fh,
"ERECO%d,", nr - 100);
202 fprintf(fh,
"UNKNOWN,");
205 fprintf(fh,
"%s,%d,%s,%s,%s\n", it.first.c_str(), con, mbstr, mbstr2, mbstr3);
211bool HistoServer2::recv_root_message(
212 vector<TObject*>& objlist,
213 vector<string>& strlist,
221 if (!m_root_socket) {
225 if (!sock || sock ==
reinterpret_cast<TSocket*
>(-1)) {
229 if (!sock->IsValid()) {
234 m_root_socket = sock;
236 printf(
"HistoServer2: ROOT client connected fd=%d\n",
237 m_root_socket->GetDescriptor());
239 time_t now = time(0);
242 m_unit_last_conn_time[
"127.0.0.1"] = now;
247 int ready = m_root_socket->Select(TSocket::kRead, 0);
254 printf(
"HistoServer2: ROOT Select failed fd=%d ready=%d\n",
255 m_root_socket->GetDescriptor(), ready);
257 m_root_socket->Close();
258 delete m_root_socket;
259 m_root_socket =
nullptr;
264 TMessage* msg =
nullptr;
266 int recv_size = m_root_socket->Recv(msg);
268 printf(
"HistoServer2: ROOT Recv fd=%d ret=%d msg=%p\n",
269 m_root_socket->GetDescriptor(),
271 static_cast<void*
>(msg));
273 if (recv_size <= 0 || !msg) {
275 printf(
"HistoServer2: ROOT client disconnected/error fd=%d ret=%d\n",
276 m_root_socket->GetDescriptor(),
283 m_root_socket->Close();
284 delete m_root_socket;
285 m_root_socket =
nullptr;
290 time_t now = time(0);
291 m_unit_last_packet_time[
"127.0.0.1"] = now;
293 printf(
"HistoServer2: ROOT message fd=%d what=%d len=%d\n",
294 m_root_socket->GetDescriptor(),
298 if (msg->What() != kMESS_OBJECT) {
300 printf(
"HistoServer2: unexpected ROOT message type %d\n",
307 TObject* received = msg->ReadObject(msg->GetClass());
309 TList* list =
dynamic_cast<TList*
>(received);
314 printf(
"HistoServer2: expected TList, got %s\n",
315 received->ClassName());
330 TObject* obj =
nullptr;
332 while ((obj = next())) {
334 TObject* copy = obj->Clone();
338 if (
auto* hist =
dynamic_cast<TH1*
>(copy); hist !=
nullptr) {
340 hist->SetDirectory(
nullptr);
342 objlist.push_back(hist);
343 strlist.push_back(hist->GetName());
345 }
else if (
auto* text =
dynamic_cast<TText*
>(copy); text !=
nullptr) {
347 objlist.push_back(text);
348 strlist.push_back(text->GetTitle());
352 objlist.push_back(copy);
353 strlist.push_back(copy->GetName());
359 m_unit_last_packet_time[
"127.0.0.1"] = now;
361 if (!objlist.empty()) {
362 m_unit_last_content_time[
"127.0.0.1"] = now;
368 return !objlist.empty();
371void HistoServer2::handle_objects(
372 vector<TObject*>& objlist,
373 vector<string>& strlist,
379 int nobjs = objlist.size();
381 for (
int i = 0; i < nobjs; i++) {
382 string objname = strlist.at(i);
384 if (objname ==
"DQMRC:CLEAR") {
388 m_last_merge_time = time(0);
392 if (objname ==
"DQMRC:MERGE") {
395 m_last_merge_time = time(0);
399 auto lpos = objname.find(
"DQMRC:SAVE:");
401 if (lpos != string::npos) {
402 auto filename = objname.substr(11);
403 m_hman->filedump(filename);
404 printf(
"DQMRC:SAVE? %s\n", filename.c_str());
408 lpos = objname.find(
"SUBDIR:");
410 if (lpos != string::npos) {
411 subdir = objname.substr(7);
412 if (subdir ==
"EXIT")
417 if (objname ==
"COMMAND:EXIT") {
422 TH1* histo =
dynamic_cast<TH1*
>(objlist.at(i));
424 if (histo !=
nullptr) {
425 m_hman->update(subdir, objname, fd, histo);
426 objlist.at(i) =
nullptr;
428 printf(
"HistoServer2: invalid object '%s', class=%s\n",
429 objname.c_str(), objlist.at(i)->ClassName());
EvtHeader * header()
Get pointer to EvtHeader.
TServerSocket * m_root_server_sock
ROOT TSocket receiver.
std::map< std::string, std::pair< int, bool > > m_units_connected
connection IP, state and last update time
void write_state(void)
Write connection state to a file.
Abstract base class for different kinds of events.