ROOT  6.06/09
Reference Guide
TProofMonSenderML.cxx
Go to the documentation of this file.
1 // @(#)root/proofplayer:$Id$
2 // Author: G.Ganis July 2011
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
13 //////////////////////////////////////////////////////////////////////////
14 // //
15 // TProofMonSenderML //
16 // //
17 // TProofMonSender implementation for the ML writer. //
18 // //
19 //////////////////////////////////////////////////////////////////////////
20 
21 #include "TProofMonSenderML.h"
22 
23 #include "TDSet.h"
24 #include "TFileInfo.h"
25 #include "THashList.h"
26 #include "TList.h"
27 #include "TParameter.h"
28 #include "TPluginManager.h"
29 #include "TProofDebug.h"
30 #include "TROOT.h"
31 #include "TSystem.h"
32 #include "TVirtualMonitoring.h"
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// Main constructor
36 
37 TProofMonSenderML::TProofMonSenderML(const char *serv, const char *tag,
38  const char *id, const char *subid,
39  const char *opt)
40  : TProofMonSender(serv, "ProofMonSenderML")
41 {
42  fWriter = 0;
43  // Init the sender instance using the plugin manager
44  TPluginHandler *h = 0;
45  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualMonitoringWriter", "MonaLisa"))) {
46  if (h->LoadPlugin() != -1) {
47  fWriter = (TVirtualMonitoringWriter *) h->ExecPlugin(5, serv, tag, id, subid, opt);
49  }
50  }
51  // Flag this instance as valid if the writer initialization succeeded
53 
54  // Set default send control options
58  fSummaryVrs = 1;
59  fDataSetInfoVrs = 1;
60  fFileInfoVrs = 1;
61 
62  // Transfer verbosity requirements
63  PDB(kMonitoring,1) if (fWriter) fWriter->Verbose(kTRUE);
64 }
65 
66 ////////////////////////////////////////////////////////////////////////////////
67 /// Destructor
68 
70 {
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// Send summary record
76 ///
77 /// There are three versions of this record, corresponding the evolution
78 /// in time of the monitoring requirements.
79 ///
80 /// The default version 2 contains the following information
81 ///
82 /// user XRD_STRING
83 /// proofgroup XRD_STRING
84 /// begin XRD_STRING
85 /// end XRD_STRING
86 /// walltime XRD_REAL64
87 /// cputime XRD_REAL64
88 /// bytesread XRD_REAL64
89 /// events XRD_REAL64
90 /// totevents XRD_REAL64
91 /// workers XRD_REAL64
92 /// vmemmxw XRD_REAL64
93 /// rmemmxw XRD_REAL64
94 /// vmemmxm XRD_REAL64
95 /// rmemmxm XRD_REAL64
96 /// numfiles XRD_REAL64
97 /// missfiles XRD_REAL64
98 /// status XRD_REAL64
99 /// rootver XRD_STRING
100 ///
101 /// Version 1 contains the following information
102 /// (no 'status', 'missfiles', 'rootver'; 'dataset' field with name(s) of
103 /// processed dataset(s))
104 ///
105 /// user XRD_STRING
106 /// proofgroup XRD_STRING
107 /// begin XRD_STRING
108 /// end XRD_STRING
109 /// walltime XRD_REAL64
110 /// cputime XRD_REAL64
111 /// bytesread XRD_REAL64
112 /// events XRD_REAL64
113 /// totevents XRD_REAL64
114 /// workers XRD_REAL64
115 /// vmemmxw XRD_REAL64
116 /// rmemmxw XRD_REAL64
117 /// vmemmxm XRD_REAL64
118 /// rmemmxm XRD_REAL64
119 /// numfiles XRD_REAL64
120 /// dataset XRD_STRING
121 ///
122 /// Version 0 contains the following information
123 /// ('group' instead of 'proofgroup'; no 'vmemmxw',
124 /// 'rmemmxw', 'vmemmxm', 'rmemmxm', 'numfiles', 'dataset')
125 ///
126 /// user XRD_STRING
127 /// group XRD_STRING
128 /// begin XRD_STRING
129 /// end XRD_STRING
130 /// walltime XRD_REAL64
131 /// cputime XRD_REAL64
132 /// bytesread XRD_REAL64
133 /// events XRD_REAL64
134 /// totevents XRD_REAL64
135 /// workers XRD_REAL64
136 ///
137 /// Return 0 on success, -1 on any failure.
138 
140 {
141  if (!IsValid()) {
142  Error("SendSummary", "invalid instance: do nothing!");
143  return -1;
144  }
145 
146  // Are we requested to send this info?
147  if (!TestBit(TProofMonSender::kSendSummary)) return 0;
148 
149  // Make sure we have something to send
150  if (!recs || (recs && recs->GetSize() <= 0)) {
151  Error("SendSummary", "records list undefined or empty!");
152  return -1;
153  }
154  TList *xrecs = recs;
155 
156  PDB(kMonitoring,1) Info("SendSummary", "preparing (qid: '%s')", id);
157 
158  // Do not send duplicated information
159  TObject *qtag = recs->FindObject("querytag");
160  if (qtag) recs->Remove(qtag);
161 
162  TObject *dsn = 0;
163  // We may need to correct some variable names first
164  if (fSummaryVrs == 0) {
165  if ((dsn = recs->FindObject("dataset"))) recs->Remove(dsn);
166  } else if (fSummaryVrs == 0) {
167  // Only the first records
168  xrecs = new TList;
169  xrecs->SetOwner(kFALSE);
170  TIter nxr(recs);
171  TObject *o = 0;
172  while ((o = nxr())) {
173  if (!strcmp(o->GetName(), "vmemmxw")) break;
174  xrecs->Add(o);
175  }
176  }
177 
178  PDB(kMonitoring,1)
179  Info("SendSummary", "sending (%d entries)", xrecs->GetSize());
180 
181  // Now we are ready to send
182  Bool_t rc = fWriter->SendParameters(xrecs, id);
183 
184  // Restore the "dataset" entry in the list
185  if (fSummaryVrs > 1 && dsn && xrecs == recs) {
186  TObject *num = recs->FindObject("numfiles");
187  if (num)
188  recs->AddBefore(num, dsn);
189  else
190  recs->Add(dsn);
191  }
192  // Restore the "querytag" entry in the list
193  if (qtag) {
194  TObject *wrks = recs->FindObject("workers");
195  if (wrks)
196  recs->AddAfter(wrks, qtag);
197  else
198  recs->Add(qtag);
199  }
200  if (xrecs != recs) SafeDelete(xrecs);
201 
202  // Done
203  return (rc ? 0 : -1);
204 }
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 /// Post information about the processed dataset(s). The information is taken
208 /// from the TDSet object 'dset' and integrated with the missing files
209 /// information in the list 'missing'. The string 'qid' is the uninque
210 /// ID of the query; 'begin' the starting time.
211 ///
212 /// The records sent by this call will appear with ids 'dataset_<dataset_name_hash>'
213 ///
214 /// There are two versions of this record, with or without the starting time.
215 /// The starting time could be looked up from the summary record, if available.
216 ///
217 /// The default version 1 contains the following information:
218 ///
219 /// dsn XRD_STRING
220 /// querytag XRD_STRING
221 /// querybegin XRD_STRING
222 /// numfiles XRD_REAL64
223 /// missfiles XRD_REAL64
224 ///
225 /// Version 0 contains the following information:
226 /// (no 'querybegin')
227 ///
228 /// dsn XRD_STRING
229 /// querytag XRD_STRING
230 /// numfiles XRD_REAL64
231 /// missfiles XRD_REAL64
232 ///
233 /// The information is posted with a bulk insert.
234 ///
235 /// Returns 0 on success, -1 on failure.
236 
238  const char *begin, const char *qid)
239 {
240  if (!IsValid()) {
241  Error("SendDataSetInfo", "invalid instance: do nothing!");
242  return -1;
243  }
244 
245  // Are we requested to send this info?
247 
248  // The query id (tag) must be given
249  if (!qid || (qid && strlen(qid) <= 0)) {
250  Error("SendDataSetInfo", "query id (tag) undefined!");
251  return -1;
252  }
253  // The dataset must be given
254  if (!dset) {
255  Error("SendDataSetInfo", "TDSet object undefined! (qid: '%s')", qid);
256  return -1;
257  }
258 
259  PDB(kMonitoring,1)
260  Info("SendDataSetInfo", "preparing (qid: '%s')", qid);
261 
262  TList plets;
263  // Extract the information and save it into the relevant multiplets
264  TString dss(dset->GetName()), ds;
265  Ssiz_t from = 0;
266  while ((dss.Tokenize(ds, from , "[,| ]"))) {
267  // Create a new TDSetPlet and add it to the list
268  plets.Add(new TDSetPlet(ds.Data()));
269  }
270  // Now try to count the files
271  TDSetPlet *plet = 0;
272  TIter nxpl(&plets);
273  TObject *o = 0;
274  TDSetElement *e = 0, *ee = 0;
275  TDSet *dsete = 0;
276  TIter nxe(dset->GetListOfElements());
277  TString dse;
278  while ((o = nxe())) {
279  if ((e = dynamic_cast<TDSetElement *>(o))) {
280  dse = e->GetDataSet();
281  if (!dse.IsNull()) {
282  nxpl.Reset();
283  while ((plet = (TDSetPlet *) nxpl())) {
284  if (dse == plet->GetName()) {
285  plet->fFiles += 1;
286  break;
287  }
288  }
289  }
290  } else if ((dsete = dynamic_cast<TDSet *>(o))) {
291  PDB(kMonitoring,1)
292  Info("SendDataSetInfo", "dset '%s' (%d files)",
293  o->GetName(), dsete->GetListOfElements()->GetSize());
294  TIter nxee(dsete->GetListOfElements());
295  while ((ee = (TDSetElement *) nxee())) {
296  dse = ee->GetDataSet();
297  if (!dse.IsNull()) {
298  nxpl.Reset();
299  while ((plet = (TDSetPlet *) nxpl())) {
300  if (dse == plet->GetName()) {
301  plet->fFiles += 1;
302  plet->fDSet = dsete;
303  break;
304  }
305  }
306  }
307  }
308  } else {
309  Warning("SendDataSetInfo", "ignoring unknown element type: '%s'", o->ClassName());
310  }
311  }
312 
313  // Now try to include the missing files info
314  if (missing) {
315  TFileInfo *fi = 0;
316  TIter nxm(missing);
317  TString dsfi, fn;
318  while ((fi = (TFileInfo *) nxm())) {
319  dsfi = fi->GetTitle();
320  if (!dsfi.IsNull() && dsfi != "TFileInfo") {
321  nxpl.Reset();
322  while ((plet = (TDSetPlet *) nxpl())) {
323  if (dsfi == plet->GetName()) {
324  fn = fi->GetCurrentUrl()->GetUrl();
325  if (plet->fDSet && plet->fDSet->GetListOfElements() &&
326  !(plet->fDSet->GetListOfElements()->FindObject(fn))) plet->fFiles += 1;
327  plet->fMissing += 1;
328  break;
329  }
330  }
331  }
332  }
333  }
334 
335  // Prepare objects to be sent
336  TList values;
337  TNamed *nm_dsn = new TNamed("dsn", "");
338  values.Add(nm_dsn);
339  TNamed *nm_querytag = new TNamed("querytag", qid);
340  values.Add(nm_querytag);
341  TNamed *nm_begin = 0;
342  if (fDataSetInfoVrs > 0) {
343  nm_begin = new TNamed("begin", begin);
344  values.Add(nm_begin);
345  }
346  TParameter<Int_t> *pi_numfiles = new TParameter<Int_t>("numfiles", -1);
347  values.Add(pi_numfiles);
348  TParameter<Int_t> *pi_missfiles = new TParameter<Int_t>("missfiles", -1);
349  values.Add(pi_missfiles);
350 
351  PDB(kMonitoring,1)
352  Info("SendDataSetInfo", "sending (%d entries)", plets.GetSize());
353 
354  Bool_t rc = kTRUE;
355  TString dsnh;
356  nxpl.Reset();
357  while ((plet = (TDSetPlet *) nxpl())) {
358  nm_dsn->SetTitle(plet->GetName());
359  pi_numfiles->SetVal(plet->fFiles);
360  pi_missfiles->SetVal(plet->fMissing);
361  dsnh.Form("dataset_%x", TString(plet->GetName()).Hash());
362  if (!(rc = fWriter->SendParameters(&values, dsnh.Data()))) break;
363  }
364 
365  // Done
366  return (rc ? 0 : -1);
367 }
368 
369 ////////////////////////////////////////////////////////////////////////////////
370 /// Post information about the requested files. The information is taken
371 /// from the TDSet object 'dset' and integrated with the missing files
372 /// information in the list 'missing'. The string 'qid' is the unique
373 /// ID of the query; 'begin' the starting time.
374 ///
375 /// The records sent by this call will appear with ids 'file_<file_name_hash>'
376 ///
377 /// There are two versions of this record, with or without the starting time.
378 /// The starting time could be looked up from the summary record, if available.
379 ///
380 /// The default version 1 contains the following information:
381 ///
382 /// lfn XRD_STRING
383 /// path XRD_STRING
384 /// querytag XRD_STRING
385 /// querybegin XRD_STRING
386 /// status XRD_REAL64
387 ///
388 /// Version 0 contains the following information:
389 /// (no 'querybegin')
390 ///
391 /// lfn XRD_STRING
392 /// path XRD_STRING
393 /// querytag XRD_STRING
394 /// status XRD_REAL64
395 ///
396 /// The information is posted with a bulk insert.
397 ///
398 /// Returns 0 on success, -1 on failure.
399 
401  const char *begin, const char *qid)
402 {
403  if (!IsValid()) {
404  Error("SendFileInfo", "invalid instance: do nothing!");
405  return -1;
406  }
407 
408  // Are we requested to send this info?
409  if (!TestBit(TProofMonSender::kSendFileInfo)) return 0;
410 
411  // The query id (tag) must be given
412  if (!qid || (qid && strlen(qid) <= 0)) {
413  Error("SendFileInfo", "query id (tag) undefined!");
414  return -1;
415  }
416  // The dataset must be given
417  if (!dset) {
418  Error("SendFileInfo", "TDSet object undefined! (qid: '%s')", qid);
419  return -1;
420  }
421 
422  PDB(kMonitoring,1) Info("SendFileInfo", "preparing (qid: '%s')", qid);
423 
424  THashList hmiss;
425  if (missing) {
426  TIter nxfm(missing);
427  TFileInfo *fi = 0;
428  while ((fi = (TFileInfo *)nxfm())) {
429  hmiss.Add(new TObjString(fi->GetCurrentUrl()->GetUrl()));
430  }
431  hmiss.Print();
432  }
433 
434  // Prepare objects to be sent
435  TList values;
436  TNamed *nm_lnf = new TNamed("lnf", "");
437  values.Add(nm_lnf);
438  TNamed *nm_path = new TNamed("path", "");
439  values.Add(nm_path);
440  TNamed *nm_querytag = new TNamed("querytag", qid);
441  values.Add(nm_querytag);
442  TNamed *nm_begin = 0;
443  if (fFileInfoVrs > 0) {
444  nm_begin = new TNamed("begin", begin);
445  values.Add(nm_begin);
446  }
447  TParameter<Int_t> *pi_status = new TParameter<Int_t>("status", -1);
448  values.Add(pi_status);
449 
450  PDB(kMonitoring,1)
451  Info("SendFileInfo", "sending (%d entries)",
452  dset->GetListOfElements()->GetSize());
453 
454  // Loop over files
455  Bool_t rc = kTRUE;
456  TObject *o = 0;
457  TDSetElement *e = 0, *ee = 0;
458  TDSet *dsete = 0;
459  TIter nxe(dset->GetListOfElements());
460  TString fne, fneh;
461  Int_t status = -1;
462  while ((o = nxe())) {
463  if ((e = dynamic_cast<TDSetElement *>(o))) {
464  fne = e->GetName();
465  // Try to determine the status
466  status = 1;
467  if (hmiss.FindObject(fne)) status = 0;
468  // Prepare the parameters list
469  nm_lnf->SetTitle(gSystem->BaseName(fne));
470  nm_path->SetTitle(gSystem->DirName(fne));
471  pi_status->SetVal(status);
472  fneh.Form("file_%x", TString(TUrl(fne.Data()).GetFile()).Hash());
473  if (!(rc = fWriter->SendParameters(&values, fneh.Data()))) break;
474  } else if ((dsete = dynamic_cast<TDSet *>(o))) {
475  PDB(kMonitoring,1)
476  Info("SendFileInfo", "dset '%s' (%d files)",
477  o->GetName(), dsete->GetListOfElements()->GetSize());
478  TIter nxee(dsete->GetListOfElements());
479  while ((ee = (TDSetElement *) nxee())) {
480  fne = ee->GetName();
481  // Try to determine the status
482  status = 1;
483  if (hmiss.FindObject(fne)) status = 0;
484  // Prepare the parameters list
485  nm_lnf->SetTitle(gSystem->BaseName(fne));
486  nm_path->SetTitle(gSystem->DirName(fne));
487  pi_status->SetVal(status);
488  fneh.Form("file_%x", TString(TUrl(fne.Data()).GetFile()).Hash());
489  if (!(rc = fWriter->SendParameters(&values, fneh.Data()))) break;
490  }
491  } else {
492  Warning("SendFileInfo", "ignoring unknown element type: '%s'", o->ClassName());
493  }
494  }
495 
496  // Done
497  return (rc ? 0 : -1);
498 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual void Verbose(Bool_t)
Collectable string class.
Definition: TObjString.h:32
virtual ULong_t Hash() const
Return hash value for this object.
Definition: TNamed.h:53
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:212
TVirtualMonitoringWriter * fWriter
Int_t SendFileInfo(TDSet *, TList *, const char *, const char *)
Post information about the requested files.
This class represents a WWW compatible URL.
Definition: TUrl.h:41
Definition: TDSet.h:153
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TH1 * h
Definition: legend2.C:5
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
#define gROOT
Definition: TROOT.h:340
void SetVal(const AParamType &val)
Definition: TParameter.h:79
Int_t LoadPlugin()
Load the plugin library for this handler.
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
Int_t SendDataSetInfo(TDSet *, TList *, const char *, const char *)
Post information about the processed dataset(s).
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:996
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:496
Long_t ExecPlugin(int nargs, const T &...params)
void Reset()
Definition: TCollection.h:161
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
const char * Data() const
Definition: TString.h:349
#define SafeDelete(p)
Definition: RConfig.h:436
#define PDB(mask, level)
Definition: TProofDebug.h:58
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
TList * GetListOfElements() const
Definition: TDSet.h:231
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
A doubly linked list.
Definition: TList.h:47
Named parameter, streamable and storable.
Definition: TParameter.h:49
Bool_t IsValid() const
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:674
Int_t SendSummary(TList *, const char *)
Send summary record.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
virtual Bool_t SendParameters(TList *, const char *=0)
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
Bool_t IsNull() const
Definition: TString.h:387
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: TList.cxx:172
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
const char * GetDataSet() const
Definition: TDSet.h:124
int Ssiz_t
Definition: RtypesCore.h:63
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
TNamed()
Definition: TNamed.h:40
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:220
Mother of all ROOT objects.
Definition: TObject.h:58
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:246
virtual void Add(TObject *obj)
Definition: TList.h:81
TProofMonSenderML(const char *serv, const char *tag, const char *id=0, const char *subid=0, const char *opt="")
Main constructor.
virtual ~TProofMonSenderML()
Destructor.
Class describing a generic file including meta information.
Definition: TFileInfo.h:50
void ResetBit(UInt_t f)
Definition: TObject.h:172
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904