Belle II Software development
HistoServer2 Class Reference

Public Types

enum  { c_maxBufSize = 160000000 }
 
enum  { c_mergeIntervall = 5000 }
 interval to invoke histogram merge (in msec*2) More...
 

Public Member Functions

 HistoServer2 (int port, const std::string &mapfile)
 
int init ()
 
int server ()
 

Private Member Functions

bool recv_root_message (std::vector< TObject * > &objlist, std::vector< std::string > &strlist, int &fd)
 
void handle_objects (std::vector< TObject * > &objlist, std::vector< std::string > &strlist, int fd, bool &updated)
 
void write_state (void)
 Write connection state to a file.
 

Private Attributes

EvtSocketRecv * m_sock
 
EvtSocketManager * m_man
 
int m_port
 
int m_force_exit
 
TServerSocket * m_root_server_sock = nullptr
 ROOT TSocket receiver.
 
TSocket * m_root_socket = nullptr
 
std::string m_filename
 
HistoManager2 * m_hman
 
std::map< std::string, std::pair< int, bool > > m_units_connected
 connection IP, state and last update time
 
std::map< std::string, time_t > m_unit_last_conn_time
 
std::map< std::string, time_t > m_unit_last_packet_time
 
std::map< std::string, time_t > m_unit_last_content_time
 
time_t m_last_merge_time {}
 

Detailed Description

Definition at line 30 of file HistoServer2.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum

Definition at line 32 of file HistoServer2.h.

32{c_maxBufSize = 160000000 };

◆ anonymous enum

anonymous enum

interval to invoke histogram merge (in msec*2)

Definition at line 34 of file HistoServer2.h.

34{ c_mergeIntervall = 5000 };

Constructor & Destructor Documentation

◆ HistoServer2()

HistoServer2 ( int port,
const std::string & mapfile )

Definition at line 21 of file HistoServer2.cc.

22{
23 TMessage::EnableSchemaEvolutionForAll(kTRUE);
24 m_port = port;
25 m_force_exit = 0;
26 m_filename = filename;
27}

◆ ~HistoServer2()

Definition at line 29 of file HistoServer2.cc.

30{
31 if (m_root_socket) {
32 m_root_socket->Close();
33 delete m_root_socket;
34 m_root_socket = nullptr;
35 }
36
38 m_root_server_sock->Close();
39 delete m_root_server_sock;
40 m_root_server_sock = nullptr;
41 }
42
43 delete m_sock;
44}
TServerSocket * m_root_server_sock
ROOT TSocket receiver.

Member Function Documentation

◆ handle_objects()

void handle_objects ( std::vector< TObject * > & objlist,
std::vector< std::string > & strlist,
int fd,
bool & updated )
private

Definition at line 371 of file HistoServer2.cc.

376{
377 string subdir = "";
378
379 int nobjs = objlist.size();
380
381 for (int i = 0; i < nobjs; i++) {
382 string objname = strlist.at(i);
383
384 if (objname == "DQMRC:CLEAR") {
385 m_hman->clear();
386 m_hman->merge();
387 updated = false;
388 m_last_merge_time = time(0);
389 continue;
390 }
391
392 if (objname == "DQMRC:MERGE") {
393 m_hman->merge();
394 updated = false;
395 m_last_merge_time = time(0);
396 continue;
397 }
398
399 auto lpos = objname.find("DQMRC:SAVE:");
400
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());
405 continue;
406 }
407
408 lpos = objname.find("SUBDIR:");
409
410 if (lpos != string::npos) {
411 subdir = objname.substr(7);
412 if (subdir == "EXIT")
413 subdir = "";
414 continue;
415 }
416
417 if (objname == "COMMAND:EXIT") {
418 subdir = "";
419 continue;
420 }
421
422 TH1* histo = dynamic_cast<TH1*>(objlist.at(i));
423
424 if (histo != nullptr) {
425 m_hman->update(subdir, objname, fd, histo);
426 objlist.at(i) = nullptr;
427 } else {
428 printf("HistoServer2: invalid object '%s', class=%s\n",
429 objname.c_str(), objlist.at(i)->ClassName());
430 continue;
431 }
432
433 updated = true;
434 }
435}

◆ init()

int init ( )

Definition at line 48 of file HistoServer2.cc.

49{
50 m_sock = new EvtSocketRecv(m_port, false);
51 m_man = new EvtSocketManager(m_sock);
52 m_hman = new HistoManager2(m_filename);
53
54 // ROOT socket
55 int rootPort = m_port + 1;
56 m_root_server_sock = new TServerSocket(rootPort, kTRUE);
57 printf("before ROOT socket connection\n");
58 if (!m_root_server_sock->IsValid()) {
59 return -1;
60 }
61 m_root_server_sock->SetOption(kNoBlock, 1);
62 printf("ROOT socket connected\n");
63
64 return 0;
65
66}

◆ recv_root_message()

bool recv_root_message ( std::vector< TObject * > & objlist,
std::vector< std::string > & strlist,
int & fd )
private

Definition at line 211 of file HistoServer2.cc.

215{
216 fd = -1;
217
218 // No ROOT client connected yet.
219 // Try to accept one.
220
221 if (!m_root_socket) {
222
223 TSocket* sock = m_root_server_sock->Accept();
224
225 if (!sock || sock == reinterpret_cast<TSocket*>(-1)) {
226 return false;
227 }
228
229 if (!sock->IsValid()) {
230 delete sock;
231 return false;
232 }
233
234 m_root_socket = sock;
235
236 printf("HistoServer2: ROOT client connected fd=%d\n",
237 m_root_socket->GetDescriptor());
238
239 time_t now = time(0);
240
241 m_units_connected["127.0.0.1"] = std::pair(0, true);
242 m_unit_last_conn_time["127.0.0.1"] = now;
243
244 return false;
245 }
246
247 int ready = m_root_socket->Select(TSocket::kRead, 0);
248
249 if (ready == 0) {
250 return false;
251 }
252
253 if (ready < 0) {
254 printf("HistoServer2: ROOT Select failed fd=%d ready=%d\n",
255 m_root_socket->GetDescriptor(), ready);
256
257 m_root_socket->Close();
258 delete m_root_socket;
259 m_root_socket = nullptr;
260
261 return false;
262 }
263
264 TMessage* msg = nullptr;
265
266 int recv_size = m_root_socket->Recv(msg);
267
268 printf("HistoServer2: ROOT Recv fd=%d ret=%d msg=%p\n",
269 m_root_socket->GetDescriptor(),
270 recv_size,
271 static_cast<void*>(msg));
272
273 if (recv_size <= 0 || !msg) {
274
275 printf("HistoServer2: ROOT client disconnected/error fd=%d ret=%d\n",
276 m_root_socket->GetDescriptor(),
277 recv_size);
278
279 m_units_connected["127.0.0.1"] = std::pair(0, false);
280
281 delete msg;
282
283 m_root_socket->Close();
284 delete m_root_socket;
285 m_root_socket = nullptr;
286
287 return false;
288 }
289
290 time_t now = time(0);
291 m_unit_last_packet_time["127.0.0.1"] = now;
292
293 printf("HistoServer2: ROOT message fd=%d what=%d len=%d\n",
294 m_root_socket->GetDescriptor(),
295 msg->What(),
296 msg->Length());
297
298 if (msg->What() != kMESS_OBJECT) {
299
300 printf("HistoServer2: unexpected ROOT message type %d\n",
301 msg->What());
302
303 delete msg;
304 return false;
305 }
306
307 TObject* received = msg->ReadObject(msg->GetClass());
308
309 TList* list = dynamic_cast<TList*>(received);
310
311 if (!list) {
312
313 if (received) {
314 printf("HistoServer2: expected TList, got %s\n",
315 received->ClassName());
316 }
317
318 delete received;
319 delete msg;
320
321 return false;
322 }
323
324 // Convert TList into the same form as decode_msg():
325 //
326 // vector<TObject*>
327 // vector<string>
328
329 TIter next(list);
330 TObject* obj = nullptr;
331
332 while ((obj = next())) {
333
334 TObject* copy = obj->Clone();
335
336 if (!copy) continue;
337
338 if (auto* hist = dynamic_cast<TH1*>(copy); hist != nullptr) {
339
340 hist->SetDirectory(nullptr);
341
342 objlist.push_back(hist);
343 strlist.push_back(hist->GetName());
344
345 } else if (auto* text = dynamic_cast<TText*>(copy); text != nullptr) {
346
347 objlist.push_back(text);
348 strlist.push_back(text->GetTitle());
349
350 } else {
351
352 objlist.push_back(copy);
353 strlist.push_back(copy->GetName());
354 }
355 }
356
357 now = time(0);
358
359 m_unit_last_packet_time["127.0.0.1"] = now;
360
361 if (!objlist.empty()) {
362 m_unit_last_content_time["127.0.0.1"] = now;
363 }
364
365 delete list;
366 delete msg;
367
368 return !objlist.empty();
369}
std::map< std::string, std::pair< int, bool > > m_units_connected
connection IP, state and last update time

◆ server()

int server ( )

Definition at line 69 of file HistoServer2.cc.

70{
71 SocketIO sio;
72 MsgHandler msghdl(0);
73 char mbstr[100];
74 time_t now = time(0);
75 char* buffer = new char[c_maxBufSize];
76 // vector<int> recvsock;
77 int loop_counter = 0;
78 bool updated = false;
80 while (m_force_exit == 0) {
81 fflush(stdout);
82 {
83 vector<TObject*> objlist;
84 vector<string> strlist;
85 int root_fd = -1;
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);
89 }
90 // Objects were cloned in recvRootMessage().
91 for (auto* obj : objlist) {
92 delete obj;
93 }
94 }
95 int exam_stat = m_man->examine();
96 if (exam_stat == 0) {
97 } else if (exam_stat == 1) { //
98 // printf ( "Histo data ready on socket\n" );
99 vector<int>& recvsock = m_man->connected_socket_list();
100 for (vector<int>::iterator it = recvsock.begin();
101 it != recvsock.end(); ++it) {
102 int fd = *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, '.');
110 int nr = -1;
111 if (ptr) {
112 nr = atoi(ptr + 1);
113 }
114 now = time(0);
115 m_unit_last_conn_time[address] = now;
116
117 int is = sio.get(fd, buffer, c_maxBufSize);
118 if (is <= 0) {
119 now = time(0);
120 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
121 printf("[%s] HistoServer2: fd %d / %s disconnected\n", mbstr, fd, address);
122 m_man->remove(fd);
123 m_units_connected[address] = std::pair(nr, false);
124 break;
125 }
126 m_units_connected[address] = std::pair(nr, true);
127 // printf ( "EvtMessage received : size = %d from fd=%d\n", is, fd );
128
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];
134 // string subdir = "ROOT";
135 string subdir = "";
136 now = time(0);
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++) {
142 // printf ( "Object : %s received, class = %s\n", (strlist.at(i)).c_str(),
143 // (objlist.at(i))->ClassName() );
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 = "";
149 // printf("HistoServer2 : subdirectory set to %s (%s)\n", subdir.c_str(), objname.c_str());
150 // no update to histograms ...
151 } else {
152 m_hman->update(subdir, strlist.at(i), fd, (TH1*)objlist.at(i));
153 updated = true; // histograms have been updated
154 }
155 }
156 }
157 }
158 }
159 usleep(1000);
160 loop_counter++;
161 if (loop_counter % c_mergeIntervall == 0) {
162 if (updated) {
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);
166 m_hman->merge();
167 updated = false; // have merged, thus reset updated
168 }
169 write_state();
170 }
171 }
172 return 0;
173}
EvtHeader * header()
Get pointer to EvtHeader.
void write_state(void)
Write connection state to a file.

◆ write_state()

void write_state ( void )
private

Write connection state to a file.

Definition at line 175 of file HistoServer2.cc.

176{
177 char mbstr[100];
178 char mbstr2[100];
179 char mbstr3[100];
180 std::string name = "/tmp/dqm_hserver_state_" + m_filename;
181 FILE* fh = fopen(name.c_str(), "wt+");
182 if (fh) {
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);
187
188 for (auto& it : m_units_connected) {
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,");
196 } else {
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);
201 } else {
202 fprintf(fh, "UNKNOWN,");
203 }
204 }
205 fprintf(fh, "%s,%d,%s,%s,%s\n", it.first.c_str(), con, mbstr, mbstr2, mbstr3);
206 }
207 fclose(fh);
208 }
209}

Member Data Documentation

◆ m_filename

std::string m_filename
private

Definition at line 64 of file HistoServer2.h.

◆ m_force_exit

int m_force_exit
private

Definition at line 48 of file HistoServer2.h.

◆ m_hman

HistoManager2* m_hman
private

Definition at line 65 of file HistoServer2.h.

◆ m_last_merge_time

time_t m_last_merge_time {}
private

Definition at line 72 of file HistoServer2.h.

72{};

◆ m_man

EvtSocketManager* m_man
private

Definition at line 46 of file HistoServer2.h.

◆ m_port

int m_port
private

Definition at line 47 of file HistoServer2.h.

◆ m_root_server_sock

TServerSocket* m_root_server_sock = nullptr
private

ROOT TSocket receiver.

Definition at line 51 of file HistoServer2.h.

◆ m_root_socket

TSocket* m_root_socket = nullptr
private

Definition at line 52 of file HistoServer2.h.

◆ m_sock

EvtSocketRecv* m_sock
private

Definition at line 45 of file HistoServer2.h.

◆ m_unit_last_conn_time

std::map<std::string, time_t> m_unit_last_conn_time
private

Definition at line 69 of file HistoServer2.h.

◆ m_unit_last_content_time

std::map<std::string, time_t> m_unit_last_content_time
private

Definition at line 71 of file HistoServer2.h.

◆ m_unit_last_packet_time

std::map<std::string, time_t> m_unit_last_packet_time
private

Definition at line 70 of file HistoServer2.h.

◆ m_units_connected

std::map<std::string, std::pair<int, bool> > m_units_connected
private

connection IP, state and last update time

Definition at line 68 of file HistoServer2.h.


The documentation for this class was generated from the following files: