ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TProof.cxx
Go to the documentation of this file.
1 // @(#)root/proof:$Id: a2a50e759072c37ccbc65ecbcce735a76de86e95 $
2 // Author: Fons Rademakers 13/02/97
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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  \defgroup proof PROOF
13 
14  Classes defining the Parallel ROOT Facility, PROOF, a framework for parallel analysis of ROOT TTrees.
15 
16 */
17 
18 /**
19  \defgroup proofkernel PROOF kernel Libraries
20  \ingroup proof
21 
22  The PROOF kernel libraries (libProof, libProofPlayer, libProofDraw) contain the classes defining
23  the kernel of the PROOF facility, i.e. the protocol and the utilities to steer data processing
24  and handling of results.
25 
26 */
27 
28 /** \class TProof
29 \ingroup proofkernel
30 
31 This class controls a Parallel ROOT Facility, PROOF, cluster.
32 It fires the worker servers, it keeps track of how many workers are
33 running, it keeps track of the workers running status, it broadcasts
34 messages to all workers, it collects results, etc.
35 
36 */
37 
38 #include <stdlib.h>
39 #include <fcntl.h>
40 #include <errno.h>
41 #ifdef WIN32
42 # include <io.h>
43 # include <sys/stat.h>
44 # include <sys/types.h>
45 # include "snprintf.h"
46 #else
47 # include <unistd.h>
48 #endif
49 #include <vector>
50 
51 #include "RConfigure.h"
52 #include "Riostream.h"
53 #include "Getline.h"
54 #include "TBrowser.h"
55 #include "TChain.h"
56 #include "TCondor.h"
57 #include "TDSet.h"
58 #include "TError.h"
59 #include "TEnv.h"
60 #include "TEntryList.h"
61 #include "TEventList.h"
62 #include "TFile.h"
63 #include "TFileInfo.h"
64 #include "TFunction.h"
65 #include "TFTP.h"
66 #include "THashList.h"
67 #include "TInterpreter.h"
68 #include "TKey.h"
69 #include "TMap.h"
70 #include "TMath.h"
71 #include "TMessage.h"
72 #include "TMethodArg.h"
73 #include "TMethodCall.h"
74 #include "TMonitor.h"
75 #include "TObjArray.h"
76 #include "TObjString.h"
77 #include "TParameter.h"
78 #include "TProof.h"
79 #include "TProofNodeInfo.h"
80 #include "TProofOutputFile.h"
81 #include "TVirtualProofPlayer.h"
82 #include "TVirtualPacketizer.h"
83 #include "TProofServ.h"
84 #include "TPluginManager.h"
85 #include "TQueryResult.h"
86 #include "TRandom.h"
87 #include "TRegexp.h"
88 #include "TROOT.h"
89 #include "TSlave.h"
90 #include "TSocket.h"
91 #include "TSortedList.h"
92 #include "TSystem.h"
93 #include "TTree.h"
94 #include "TUrl.h"
95 #include "TFileCollection.h"
96 #include "TDataSetManager.h"
97 #include "TDataSetManagerFile.h"
98 #include "TMacro.h"
99 #include "TSelector.h"
100 #include "TPRegexp.h"
101 
102 #include <mutex>
103 
104 TProof *gProof = 0;
105 
106 // Rotating indicator
107 char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
108 
109 TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
110 TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
111 
113 
114 //----- PROOF Interrupt signal handler -----------------------------------------
115 ////////////////////////////////////////////////////////////////////////////////
116 /// TProof interrupt handler.
117 
119 {
120  if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
121 
122  // Cannot ask the user : abort any remote processing
123  fProof->StopProcess(kTRUE);
124 
125  } else {
126  // Real stop or request to switch to asynchronous?
127  const char *a = 0;
128  if (fProof->GetRemoteProtocol() < 22) {
129  a = Getline("\nSwitch to asynchronous mode not supported remotely:"
130  "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
131  } else {
132  a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
133  " any other key to continue: ");
134  }
135  if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
136 
137  Info("Notify","Processing interrupt signal ... %c", a[0]);
138 
139  // Stop or abort any remote processing
140  Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
141  fProof->StopProcess(abort);
142 
143  } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
144  // Stop any remote processing
145  fProof->GoAsynchronous();
146  }
147  }
148 
149  return kTRUE;
150 }
151 
152 //----- Input handler for messages from TProofServ -----------------------------
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Constructor
155 
157  : TFileHandler(s->GetDescriptor(),1),
158  fSocket(s), fProof(p)
159 {
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// Handle input
164 
166 {
168  return kTRUE;
169 }
170 
171 
172 //------------------------------------------------------------------------------
173 
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// Used to sort slaveinfos by ordinal.
178 
179 Int_t TSlaveInfo::Compare(const TObject *obj) const
180 {
181  if (!obj) return 1;
182 
183  const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
184 
185  if (!si) return fOrdinal.CompareTo(obj->GetName());
186 
187  const char *myord = GetOrdinal();
188  const char *otherord = si->GetOrdinal();
189  while (myord && otherord) {
190  Int_t myval = atoi(myord);
191  Int_t otherval = atoi(otherord);
192  if (myval < otherval) return 1;
193  if (myval > otherval) return -1;
194  myord = strchr(myord, '.');
195  if (myord) myord++;
196  otherord = strchr(otherord, '.');
197  if (otherord) otherord++;
198  }
199  if (myord) return -1;
200  if (otherord) return 1;
201  return 0;
202 }
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// Used to compare slaveinfos by ordinal.
206 
208 {
209  if (!obj) return kFALSE;
210  const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
211  if (!si) return kFALSE;
212  return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Print slave info. If opt = "active" print only the active
217 /// slaves, if opt="notactive" print only the not active slaves,
218 /// if opt = "bad" print only the bad slaves, else
219 /// print all slaves.
220 
221 void TSlaveInfo::Print(Option_t *opt) const
222 {
223  TString stat = fStatus == kActive ? "active" :
224  fStatus == kBad ? "bad" :
225  "not active";
226 
227  Bool_t newfmt = kFALSE;
228  TString oo(opt);
229  if (oo.Contains("N")) {
230  newfmt = kTRUE;
231  oo.ReplaceAll("N","");
232  }
233  if (oo == "active" && fStatus != kActive) return;
234  if (oo == "notactive" && fStatus != kNotActive) return;
235  if (oo == "bad" && fStatus != kBad) return;
236 
237  if (newfmt) {
238  TString msd, si, datadir;
239  if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
240  if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
241  if (fSysInfo.fCpus > 0) {
242  si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
244  } else {
245  si.Form("| %s", fHostName.Data());
246  }
247  Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
248 
249  } else {
250  TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
251 
252  std::cout << "Slave: " << fOrdinal
253  << " hostname: " << fHostName
254  << " msd: " << msd
255  << " perf index: " << fPerfIndex
256  << " " << stat
257  << std::endl;
258  }
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// Setter for fSysInfo
263 
265 {
266  fSysInfo.fOS = si.fOS; // OS
267  fSysInfo.fModel = si.fModel; // computer model
268  fSysInfo.fCpuType = si.fCpuType; // type of cpu
269  fSysInfo.fCpus = si.fCpus; // number of cpus
270  fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
271  fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
272  fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
273  fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
274 }
275 
277 
278 //------------------------------------------------------------------------------
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Destructor
282 
283 TMergerInfo::~TMergerInfo()
284 {
285  // Just delete the list, the objects are owned by other list
286  if (fWorkers) {
287  fWorkers->SetOwner(kFALSE);
288  SafeDelete(fWorkers);
289  }
290 }
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Increase number of already merged workers by 1
293 
295 {
296  if (AreAllWorkersMerged())
297  Error("SetMergedWorker", "all workers have been already merged before!");
298  else
299  fMergedWorkers++;
300 }
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 /// Add new worker to the list of workers to be merged by this merger
304 
306 {
307  if (!fWorkers)
308  fWorkers = new TList();
309  if (fWorkersToMerge == fWorkers->GetSize()) {
310  Error("AddWorker", "all workers have been already assigned to this merger");
311  return;
312  }
313  fWorkers->Add(sl);
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// Return if merger has already merged all workers, i.e. if it has finished its merging job
318 
320 {
321  return (fWorkersToMerge == fMergedWorkers);
322 }
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Return if the determined number of workers has been already assigned to this merger
326 
328 {
329  if (!fWorkers)
330  return kFALSE;
331 
332  return (fWorkers->GetSize() == fWorkersToMerge);
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// This a private API function.
337 /// It checks whether the connection string contains a PoD cluster protocol.
338 /// If it does, then the connection string will be changed to reflect
339 /// a real PROOF connection string for a PROOF cluster managed by PoD.
340 /// PoD: http://pod.gsi.de .
341 /// Return -1 if the PoD request failed; return 0 otherwise.
342 
343 static Int_t PoDCheckUrl(TString *_cluster)
344 {
345  if ( !_cluster )
346  return 0;
347 
348  // trim spaces from both sides of the string
349  *_cluster = _cluster->Strip( TString::kBoth );
350  // PoD protocol string
351  const TString pod_prot("pod");
352 
353  // URL test
354  // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
355  TUrl url( _cluster->Data() );
356  if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
357  return 0;
358 
359  // PoD cluster is used
360  // call pod-info in a batch mode (-b).
361  // pod-info will find either a local PoD cluster or
362  // a remote one, manged by pod-remote.
363  *_cluster = gSystem->GetFromPipe("pod-info -c -b");
364  if( 0 == _cluster->Length() ) {
365  Error("PoDCheckUrl", "PoD server is not running");
366  return -1;
367  }
368  return 0;
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Create a PROOF environment. Starting PROOF involves either connecting
373 /// to a master server, which in turn will start a set of slave servers, or
374 /// directly starting as master server (if master = ""). Masterurl is of
375 /// the form: [proof[s]://]host[:port]. Conffile is the name of the config
376 /// file describing the remote PROOF cluster (this argument alows you to
377 /// describe different cluster configurations).
378 /// The default is proof.conf. Confdir is the directory where the config
379 /// file and other PROOF related files are (like motd and noproof files).
380 /// Loglevel is the log level (default = 1). User specified custom config
381 /// files will be first looked for in $HOME/.conffile.
382 
383 TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
384  Int_t loglevel, const char *alias, TProofMgr *mgr)
385  : fUrl(masterurl)
386 {
387  // Default initializations
388  InitMembers();
389 
390  // This may be needed during init
391  fManager = mgr;
392 
393  // Default server type
395 
396  // Default query mode
397  fQueryMode = kSync;
398 
399  // Parse the main URL, adjusting the missing fields and setting the relevant
400  // bits
403 
404  // Protocol and Host
405  if (!masterurl || strlen(masterurl) <= 0) {
406  fUrl.SetProtocol("proof");
407  fUrl.SetHost("__master__");
408  } else if (!(strstr(masterurl, "://"))) {
409  fUrl.SetProtocol("proof");
410  }
411  // Port
412  if (fUrl.GetPort() == TUrl(" ").GetPort())
413  fUrl.SetPort(TUrl("proof:// ").GetPort());
414 
415  // Make sure to store the FQDN, so to get a solid reference for subsequent checks
416  if (!strcmp(fUrl.GetHost(), "__master__"))
417  fMaster = fUrl.GetHost();
418  else if (!strlen(fUrl.GetHost()))
419  fMaster = gSystem->GetHostByName(gSystem->HostName()).GetHostName();
420  else
421  fMaster = gSystem->GetHostByName(fUrl.GetHost()).GetHostName();
422 
423  // Server type
424  if (strlen(fUrl.GetOptions()) > 0) {
425  TString opts(fUrl.GetOptions());
426  if (!(strncmp(fUrl.GetOptions(),"std",3))) {
428  opts.Remove(0,3);
429  fUrl.SetOptions(opts.Data());
430  } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
432  opts.Remove(0,4);
433  fUrl.SetOptions(opts.Data());
434  }
435  }
436 
437  // Instance type
441  if (fMaster == "__master__") {
442  fMasterServ = kTRUE;
445  } else if (fMaster == "prooflite") {
446  // Client and master are merged
447  fMasterServ = kTRUE;
449  }
450  // Flag that we are a client
452  if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
453 
454  Init(masterurl, conffile, confdir, loglevel, alias);
455 
456  // If the user was not set, get it from the master
457  if (strlen(fUrl.GetUser()) <= 0) {
458  TString usr, emsg;
459  if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
460  TObjString *os = fMacroLog.GetLineWith("const char");
461  if (os) {
462  Ssiz_t fst = os->GetString().First('\"');
463  Ssiz_t lst = os->GetString().Last('\"');
464  usr = os->GetString()(fst+1, lst-fst-1);
465  } else {
466  emsg = "could not find 'const char *' string in macro log";
467  }
468  } else {
469  emsg = "could not retrieve user info";
470  }
471  if (!emsg.IsNull()) {
472  // Get user logon name
474  if (pw) {
475  usr = pw->fUser;
476  delete pw;
477  }
478  Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
479  }
480  // Set the user name in the main URL
481  fUrl.SetUser(usr.Data());
482  }
483 
484  // If called by a manager, make sure it stays in last position
485  // for cleaning
486  if (mgr) {
488  gROOT->GetListOfSockets()->Remove(mgr);
489  gROOT->GetListOfSockets()->Add(mgr);
490  }
491 
492  // Old-style server type: we add this to the list and set the global pointer
494  if (!gROOT->GetListOfProofs()->FindObject(this))
495  gROOT->GetListOfProofs()->Add(this);
496 
497  // Still needed by the packetizers: needs to be changed
498  gProof = this;
499 }
500 
501 ////////////////////////////////////////////////////////////////////////////////
502 /// Protected constructor to be used by classes deriving from TProof
503 /// (they have to call Init themselves and override StartSlaves
504 /// appropriately).
505 ///
506 /// This constructor simply closes any previous gProof and sets gProof
507 /// to this instance.
508 
509 TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
510 {
511  // Default initializations
512  InitMembers();
513 
514  if (!gROOT->GetListOfProofs()->FindObject(this))
515  gROOT->GetListOfProofs()->Add(this);
516 
517  gProof = this;
518 }
519 
520 ////////////////////////////////////////////////////////////////////////////////
521 /// Default initializations
522 
524 {
525  fValid = kFALSE;
526  fTty = kFALSE;
527  fRecvMessages = 0;
528  fSlaveInfo = 0;
532  fLastPollWorkers_s = -1;
533  fActiveSlaves = 0;
534  fInactiveSlaves = 0;
535  fUniqueSlaves = 0;
536  fAllUniqueSlaves = 0;
537  fNonUniqueMasters = 0;
538  fActiveMonitor = 0;
539  fUniqueMonitor = 0;
540  fAllUniqueMonitor = 0;
541  fCurrentMonitor = 0;
542  fBytesRead = 0;
543  fRealTime = 0;
544  fCpuTime = 0;
545  fIntHandler = 0;
546  fProgressDialog = 0;
549  fPlayer = 0;
550  fFeedback = 0;
551  fChains = 0;
552  fDSet = 0;
553  fNotIdle = 0;
554  fSync = kTRUE;
556  fIsWaiting = kFALSE;
557  fRedirLog = kFALSE;
558  fLogFileW = 0;
559  fLogFileR = 0;
562  fMacroLog.SetName("ProofLogMacro");
563 
564  fWaitingSlaves = 0;
565  fQueries = 0;
566  fOtherQueries = 0;
567  fDrawQueries = 0;
568  fMaxDrawQueries = 1;
569  fSeqNum = 0;
570 
571  fSessionID = -1;
572  fEndMaster = kFALSE;
573 
575  fPackageLock = 0;
578 
579  fInputData = 0;
580 
581  fPrintProgress = 0;
582 
583  fLoadedMacros = 0;
584 
585  fProtocol = -1;
586  fSlaves = 0;
588  fBadSlaves = 0;
589  fAllMonitor = 0;
590  fDataReady = kFALSE;
591  fBytesReady = 0;
592  fTotalBytes = 0;
593  fAvailablePackages = 0;
594  fEnabledPackages = 0;
595  fRunningDSets = 0;
596 
597  fCollectTimeout = -1;
598 
599  fManager = 0;
600  fQueryMode = kSync;
602 
605  fMergers = 0;
606  fMergersCount = -1;
608  fWorkersToMerge = 0;
610 
611  fPerfTree = "";
612 
613  fWrksOutputReady = 0;
614 
615  fSelector = 0;
616 
617  fPrepTime = 0.;
618 
619  // Check if the user defined a list of environment variables to send over:
620  // include them into the dedicated list
621  if (gSystem->Getenv("PROOF_ENVVARS")) {
622  TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
623  Int_t from = 0;
624  while (envs.Tokenize(env, from, ",")) {
625  if (!env.IsNull()) {
626  if (!gSystem->Getenv(env)) {
627  Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
628  } else {
629  if (!envsfound.IsNull()) envsfound += ",";
630  envsfound += env;
631  TProof::DelEnvVar(env);
632  TProof::AddEnvVar(env, gSystem->Getenv(env));
633  }
634  }
635  }
636  if (envsfound.IsNull()) {
637  Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
638  } else {
639  Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
640  }
641  }
642 
643  // Done
644  return;
645 }
646 
647 ////////////////////////////////////////////////////////////////////////////////
648 /// Clean up PROOF environment.
649 
651 {
652  if (fChains) {
653  while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
654  // remove "chain" from list
655  chain->SetProof(0);
657  }
658  }
659 
660  // remove links to packages enabled on the client
661  if (TestBit(TProof::kIsClient)) {
662  // iterate over all packages
663  TIter nextpackage(fEnabledPackagesOnClient);
664  while (TObjString *package = dynamic_cast<TObjString*>(nextpackage())) {
665  FileStat_t stat;
666  if (gSystem->GetPathInfo(package->String(), stat) == 0) {
667  // check if symlink, if so unlink
668  // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
669  // existing file or to a directory, but if fIsLink is true the symlink exists
670  if (stat.fIsLink)
671  gSystem->Unlink(package->String());
672  }
673  }
674  }
675 
676  Close();
704  if (fWrksOutputReady) {
706  delete fWrksOutputReady;
707  }
708 
709  // remove file with redirected logs
710  if (TestBit(TProof::kIsClient)) {
711  if (fLogFileR)
712  fclose(fLogFileR);
713  if (fLogFileW)
714  fclose(fLogFileW);
715  if (fLogFileName.Length() > 0)
717  }
718 
719  // Remove for the global list
720  gROOT->GetListOfProofs()->Remove(this);
721  // ... and from the manager list
722  if (fManager && fManager->IsValid())
723  fManager->DiscardSession(this);
724 
725  if (gProof && gProof == this) {
726  // Set previous as default
727  TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
728  while ((gProof = (TProof *)pvp())) {
729  if (gProof->InheritsFrom(TProof::Class()))
730  break;
731  }
732  }
733 
734  // For those interested in our destruction ...
735  Emit("~TProof()");
736  Emit("CloseWindow()");
737 }
738 
739 ////////////////////////////////////////////////////////////////////////////////
740 /// Start the PROOF environment. Starting PROOF involves either connecting
741 /// to a master server, which in turn will start a set of slave servers, or
742 /// directly starting as master server (if master = ""). For a description
743 /// of the arguments see the TProof ctor. Returns the number of started
744 /// master or slave servers, returns 0 in case of error, in which case
745 /// fValid remains false.
746 
747 Int_t TProof::Init(const char *, const char *conffile,
748  const char *confdir, Int_t loglevel, const char *alias)
749 {
751 
752  fValid = kFALSE;
753 
754  // Connected to terminal?
755  fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
756 
757  // If in attach mode, options is filled with additional info
758  Bool_t attach = kFALSE;
759  if (strlen(fUrl.GetOptions()) > 0) {
760  attach = kTRUE;
761  // A flag from the GUI
762  TString opts = fUrl.GetOptions();
763  if (opts.Contains("GUI")) {
765  opts.Remove(opts.Index("GUI"));
766  fUrl.SetOptions(opts);
767  }
768  }
769 
770  if (TestBit(TProof::kIsMaster)) {
771  // Fill default conf file and conf dir
772  if (!conffile || !conffile[0])
774  if (!confdir || !confdir[0])
776  // The group; the client receives it in the kPROOF_SESSIONTAG message
778  } else {
779  fConfDir = confdir;
780  fConfFile = conffile;
781  }
782 
783  // Analysise the conffile field
784  if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
786 
788  fLogLevel = loglevel;
791  fImage = fMasterServ ? "" : "<local>";
792  fIntHandler = 0;
793  fStatus = 0;
794  fRecvMessages = new TList;
796  fSlaveInfo = 0;
797  fChains = new TList;
798  fAvailablePackages = 0;
799  fEnabledPackages = 0;
800  fRunningDSets = 0;
802  fInputData = 0;
804  fPrintProgress = 0;
805 
808 
809  // Timeout for some collect actions
810  fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
811 
812  // Should the workers be started dynamically; default: no
813  fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
814 
815  // Default entry point for the data pool is the master
817  fDataPoolUrl.Form("root://%s", fMaster.Data());
818  else
819  fDataPoolUrl = "";
820 
821  fProgressDialog = 0;
823 
824  // Default alias is the master name
825  TString al = (alias) ? alias : fMaster.Data();
826  SetAlias(al);
827 
828  // Client logging of messages from the master and slaves
829  fRedirLog = kFALSE;
830  if (TestBit(TProof::kIsClient)) {
831  fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
832  if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
833  Error("Init", "could not create temporary logfile");
834  if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
835  Error("Init", "could not open temp logfile for reading");
836  }
838 
839  // Status of cluster
840  fNotIdle = 0;
841  // Query type
842  fSync = (attach) ? kFALSE : kTRUE;
843  // Not enqueued
844  fIsWaiting = kFALSE;
845 
846  // Counters
847  fBytesRead = 0;
848  fRealTime = 0;
849  fCpuTime = 0;
850 
851  // List of queries
852  fQueries = 0;
853  fOtherQueries = 0;
854  fDrawQueries = 0;
855  fMaxDrawQueries = 1;
856  fSeqNum = 0;
857 
858  // Remote ID of the session
859  fSessionID = -1;
860 
861  // Part of active query
862  fWaitingSlaves = 0;
863 
864  // Make remote PROOF player
865  fPlayer = 0;
866  MakePlayer();
867 
868  fFeedback = new TList;
869  fFeedback->SetOwner();
870  fFeedback->SetName("FeedbackList");
872 
873  // sort slaves by descending performance index
875  fActiveSlaves = new TList;
876  fInactiveSlaves = new TList;
877  fUniqueSlaves = new TList;
878  fAllUniqueSlaves = new TList;
879  fNonUniqueMasters = new TList;
880  fBadSlaves = new TList;
881  fAllMonitor = new TMonitor;
882  fActiveMonitor = new TMonitor;
883  fUniqueMonitor = new TMonitor;
885  fCurrentMonitor = 0;
886 
889 
890  fPackageLock = 0;
892  fLoadedMacros = 0;
894 
895  // Enable optimized sending of streamer infos to use embedded backward/forward
896  // compatibility support between different ROOT versions and different versions of
897  // users classes
898  Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
899  if (enableSchemaEvolution) {
901  } else {
902  Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
903  }
904 
905  if (IsMaster()) {
906  // to make UploadPackage() method work on the master as well.
908  } else {
909 
910  TString sandbox;
911  if (GetSandbox(sandbox, kTRUE) != 0) {
912  Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
913  return 0;
914  }
915 
916  // Package Dir
917  fPackageDir = gEnv->GetValue("Proof.PackageDir", "");
918  if (fPackageDir.IsNull())
919  fPackageDir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
920  if (AssertPath(fPackageDir, kTRUE) != 0) {
921  Error("Init", "failure asserting directory %s", fPackageDir.Data());
922  return 0;
923  }
924  }
925 
926  if (!IsMaster()) {
927  // List of directories where to look for global packages
928  TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
929  if (globpack.Length() > 0) {
930  Int_t ng = 0;
931  Int_t from = 0;
932  TString ldir;
933  while (globpack.Tokenize(ldir, from, ":")) {
935  if (gSystem->AccessPathName(ldir, kReadPermission)) {
936  Warning("Init", "directory for global packages %s does not"
937  " exist or is not readable", ldir.Data());
938  } else {
939  // Add to the list, key will be "G<ng>", i.e. "G0", "G1", ...
940  TString key = TString::Format("G%d", ng++);
941  if (!fGlobalPackageDirList) {
944  }
945  fGlobalPackageDirList->Add(new TNamed(key,ldir));
946  }
947  }
948  }
949 
950  TString lockpath(fPackageDir);
951  lockpath.ReplaceAll("/", "%");
952  lockpath.Insert(0, TString::Format("%s/%s",
954  fPackageLock = new TProofLockPath(lockpath.Data());
955 
957  fEnabledPackagesOnClient->SetOwner();
958  }
959 
960  // Master may want dynamic startup
961  if (fDynamicStartup) {
962  if (!IsMaster()) {
963  // If on client - start the master
964  if (!StartSlaves(attach))
965  return 0;
966  }
967  } else {
968 
969  // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
970  // result retrieving, ...)
971  Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
972  if (!IsMaster() || !masterOnly) {
973  // Start slaves (the old, static, per-session way)
974  if (!StartSlaves(attach))
975  return 0;
976  // Client: Is Master in dynamic startup mode?
977  if (!IsMaster()) {
978  Int_t dyn = 0;
979  GetRC("Proof.DynamicStartup", dyn);
980  if (dyn != 0) fDynamicStartup = kTRUE;
981  }
982  }
983  }
984  // we are now properly initialized
985  fValid = kTRUE;
986 
987  // De-activate monitor (will be activated in Collect)
989 
990  // By default go into parallel mode
991  Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
992  TNamed *n = 0;
993  if (TProof::GetEnvVars() &&
994  (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
995  TString s(n->GetTitle());
996  if (s.IsDigit()) nwrk = s.Atoi();
997  }
998  GoParallel(nwrk, attach);
999 
1000  // Send relevant initial state to slaves
1001  if (!attach)
1002  SendInitialState();
1003  else if (!IsIdle())
1004  // redirect log
1005  fRedirLog = kTRUE;
1006 
1007  // Done at this point, the alias will be communicated to the coordinator, if any
1009  SetAlias(al);
1010 
1011  SetActive(kFALSE);
1012 
1013  if (IsValid()) {
1014 
1015  // Activate input handler
1017 
1019  gROOT->GetListOfSockets()->Add(this);
1020  }
1021 
1022  AskParallel();
1023 
1024  return fActiveSlaves->GetSize();
1025 }
1026 
1027 ////////////////////////////////////////////////////////////////////////////////
1028 /// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1029 /// Use the existing setting or the default if nothing is found.
1030 /// If 'assert' is kTRUE, make also sure that the path exists.
1031 /// Return 0 on success, -1 on failure
1032 
1034 {
1035  // Get it from 'rc', if defined
1036  if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1037  // Or use the default 'rc'
1038  if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1039  // If nothing found , use the default
1040  if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1041  // Expand special settings
1042  if (sb == ".") {
1043  sb = gSystem->pwd();
1044  } else if (sb == "..") {
1045  sb = gSystem->DirName(gSystem->pwd());
1046  }
1047  gSystem->ExpandPathName(sb);
1048 
1049  // Assert the path, if required
1050  if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1051  // Done
1052  return 0;
1053 }
1054 
1055 ////////////////////////////////////////////////////////////////////////////////
1056 /// The config file field may contain special instructions which need to be
1057 /// parsed at the beginning, e.g. for debug runs with valgrind.
1058 /// Several options can be given separated by a ','
1059 
1060 void TProof::ParseConfigField(const char *config)
1061 {
1062  TString sconf(config), opt;
1063  Ssiz_t from = 0;
1064  Bool_t cpuPin = kFALSE;
1065 
1066  // Analysise the field
1067  const char *cq = (IsLite()) ? "\"" : "";
1068  while (sconf.Tokenize(opt, from, ",")) {
1069  if (opt.IsNull()) continue;
1070 
1071  if (opt.BeginsWith("valgrind")) {
1072  // Any existing valgrind setting? User can give full settings, which we fully respect,
1073  // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1074  // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1075  // will add option "--time-stamp --leak-check=full" to our default options
1076  TString mst, top, sub, wrk, all;
1077  TList *envs = fgProofEnvList;
1078  TNamed *n = 0;
1079  if (envs) {
1080  if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1081  all = n->GetTitle();
1082  if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1083  mst = n->GetTitle();
1084  if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1085  top = n->GetTitle();
1086  if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1087  sub = n->GetTitle();
1088  if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1089  wrk = n->GetTitle();
1090  }
1091  if (all != "" && mst == "") mst = all;
1092  if (all != "" && top == "") top = all;
1093  if (all != "" && sub == "") sub = all;
1094  if (all != "" && wrk == "") wrk = all;
1095  if (all != "" && all.BeginsWith("valgrind_opts:")) {
1096  // The field is used to add an option Reset the setting
1097  Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1098  " must be set again for next run , if any");
1099  TProof::DelEnvVar("PROOF_WRAPPERCMD");
1100  }
1101  TString var, cmd;
1102  cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1103  TString mstlab("NO"), wrklab("NO");
1104  Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1105  !opt.Contains("topmaster") && !opt.Contains("submaster")))
1106  ? kTRUE : kFALSE;
1107  if (doMaster) {
1108  if (!IsLite()) {
1109  // Check if we have to add a var
1110  if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1111  mst.ReplaceAll("valgrind_opts:","");
1112  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1113  TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1114  mstlab = "YES";
1115  } else if (mst != "") {
1116  mstlab = "YES";
1117  }
1118  } else {
1119  if (opt.Contains("master")) {
1120  Warning("ParseConfigField",
1121  "master valgrinding does not make sense for PROOF-Lite: ignoring");
1122  opt.ReplaceAll("master", "");
1123  if (!opt.Contains("workers")) return;
1124  }
1125  if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1126  }
1127  }
1128  if (opt.Contains("topmaster")) {
1129  // Check if we have to add a var
1130  if (top == "" || top.BeginsWith("valgrind_opts:")) {
1131  top.ReplaceAll("valgrind_opts:","");
1132  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1133  TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1134  mstlab = "YES";
1135  } else if (top != "") {
1136  mstlab = "YES";
1137  }
1138  }
1139  if (opt.Contains("submaster")) {
1140  // Check if we have to add a var
1141  if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1142  sub.ReplaceAll("valgrind_opts:","");
1143  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1144  TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1145  mstlab = "YES";
1146  } else if (sub != "") {
1147  mstlab = "YES";
1148  }
1149  }
1150  if (opt.Contains("=workers") || opt.Contains("+workers")) {
1151  // Check if we have to add a var
1152  if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1153  wrk.ReplaceAll("valgrind_opts:","");
1154  var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1155  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1156  TString nwrks("2");
1157  Int_t inw = opt.Index('#');
1158  if (inw != kNPOS) {
1159  nwrks = opt(inw+1, opt.Length());
1160  if (!nwrks.IsDigit()) nwrks = "2";
1161  }
1162  // Set the relevant variables
1163  if (!IsLite()) {
1164  TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1165  } else {
1166  gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1167  }
1168  wrklab = nwrks;
1169  // Register the additional worker log in the session file
1170  // (for the master this is done automatically)
1171  TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1172  } else if (wrk != "") {
1173  wrklab = "ALL";
1174  }
1175  }
1176  // Increase the relevant timeouts
1177  if (!IsLite()) {
1178  TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1179  gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1180  } else {
1181  gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1182  }
1183  // Warn for slowness
1184  Printf(" ");
1185  if (!IsLite()) {
1186  Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1187  } else {
1188  Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1189  }
1190  Printf(" ---> Please be patient: startup may be VERY slow ...");
1191  Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1192  Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1193  Printf(" ");
1194 
1195  } else if (opt.BeginsWith("igprof-pp")) {
1196 
1197  // IgProf profiling on master and worker. PROOF does not set the
1198  // environment for you: proper environment variables (like PATH and
1199  // LD_LIBRARY_PATH) should be set externally
1200 
1201  Printf("*** Requested IgProf performance profiling ***");
1202  TString addLogExt = "__igprof.pp__.log";
1203  TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1204  TString tmp;
1205 
1206  if (IsLite()) {
1207  addLogFmt.Append("\"");
1208  addLogFmt.Prepend("\"");
1209  }
1210 
1211  tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1212  TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1213 
1214  tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1215  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1216 
1217  TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1218 
1219  } else if (opt.BeginsWith("cpupin=")) {
1220  // Enable CPU pinning. Takes as argument the list of processor IDs
1221  // that will be used in order. Processor IDs are numbered from 0,
1222  // use likwid to see how they are organized. A possible parameter
1223  // format would be:
1224  //
1225  // cpupin=3+4+0+9+10+22+7
1226  //
1227  // Only the specified processor IDs will be used in a round-robin
1228  // fashion, dealing with the fact that you can request more workers
1229  // than the number of processor IDs you have specified.
1230  //
1231  // To use all available processors in their order:
1232  //
1233  // cpupin=*
1234 
1235  opt.Remove(0, 7);
1236 
1237  // Remove any char which is neither a number nor a plus '+'
1238  for (Ssiz_t i=0; i<opt.Length(); i++) {
1239  Char_t c = opt[i];
1240  if ((c != '+') && ((c < '0') || (c > '9')))
1241  opt[i] = '_';
1242  }
1243  opt.ReplaceAll("_", "");
1244  TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1245  cpuPin = kTRUE;
1246  } else if (opt.BeginsWith("workers=")) {
1247 
1248  // Request for a given number of workers (within the max) or worker
1249  // startup combination:
1250  // workers=5 start max 5 workers (or less, if less are assigned)
1251  // workers=2x start max 2 workers per node (or less, if less are assigned)
1252  opt.ReplaceAll("workers=","");
1253  TProof::AddEnvVar("PROOF_NWORKERS", opt);
1254  }
1255  }
1256 
1257  // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1258  #ifdef R__LINUX
1259  if (IsLite() && cpuPin) {
1260  Printf("*** Requested CPU pinning ***");
1261  const TList *ev = GetEnvVars();
1262  const char *pinCmd = "taskset -c <cpupin>";
1263  TString val;
1264  TNamed *p;
1265  if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1266  val = p->GetTitle();
1267  val.Insert(val.Length()-1, " ");
1268  val.Insert(val.Length()-1, pinCmd);
1269  }
1270  else {
1271  val.Form("\"%s\"", pinCmd);
1272  }
1273  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1274  }
1275  #endif
1276 }
1277 
1278 ////////////////////////////////////////////////////////////////////////////////
1279 /// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1280 /// that the path is writable
1281 
1282 Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1283 {
1284  if (!inpath || strlen(inpath) <= 0) {
1285  Error("AssertPath", "undefined input path");
1286  return -1;
1287  }
1288 
1289  TString path(inpath);
1290  gSystem->ExpandPathName(path);
1291 
1292  if (gSystem->AccessPathName(path, kFileExists)) {
1293  if (gSystem->mkdir(path, kTRUE) != 0) {
1294  Error("AssertPath", "could not create path %s", path.Data());
1295  return -1;
1296  }
1297  }
1298  // It must be writable
1299  if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1300  if (gSystem->Chmod(path, 0666) != 0) {
1301  Error("AssertPath", "could not make path %s writable", path.Data());
1302  return -1;
1303  }
1304  }
1305 
1306  // Done
1307  return 0;
1308 }
1309 
1310 ////////////////////////////////////////////////////////////////////////////////
1311 /// Set manager and schedule its destruction after this for clean
1312 /// operations.
1313 
1315 {
1316  fManager = mgr;
1317 
1318  if (mgr) {
1320  gROOT->GetListOfSockets()->Remove(mgr);
1321  gROOT->GetListOfSockets()->Add(mgr);
1322  }
1323 }
1324 
1325 ////////////////////////////////////////////////////////////////////////////////
1326 /// Works on the master node only.
1327 /// It starts workers on the machines in workerList and sets the paths,
1328 /// packages and macros as on the master.
1329 /// It is a subbstitute for StartSlaves(...)
1330 /// The code is mostly the master part of StartSlaves,
1331 /// with the parallel startup removed.
1332 
1334 {
1335  if (!IsMaster()) {
1336  Error("AddWorkers", "AddWorkers can only be called on the master!");
1337  return -1;
1338  }
1339 
1340  if (!workerList || !(workerList->GetSize())) {
1341  Error("AddWorkers", "empty list of workers!");
1342  return -2;
1343  }
1344 
1345  // Code taken from master part of StartSlaves with the parllel part removed
1346 
1347  fImage = gProofServ->GetImage();
1348  if (fImage.IsNull())
1349  fImage.Form("%s:%s", TUrl(gSystem->HostName()).GetHostFQDN(), gProofServ->GetWorkDir());
1350 
1351  // Get all workers
1352  UInt_t nSlaves = workerList->GetSize();
1353  UInt_t nSlavesDone = 0;
1354  Int_t ord = 0;
1355 
1356  // Loop over all new workers and start them (if we had already workers it means we are
1357  // increasing parallelism or that is not the first time we are called)
1358  Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1359 
1360  // A list of TSlave objects for workers that are being added
1361  TList *addedWorkers = new TList();
1362  if (!addedWorkers) {
1363  // This is needed to silence Coverity ...
1364  Error("AddWorkers", "cannot create new list for the workers to be added");
1365  return -2;
1366  }
1367  addedWorkers->SetOwner(kFALSE);
1368  TListIter next(workerList);
1369  TObject *to;
1370  TProofNodeInfo *worker;
1371  TSlaveInfo *dummysi = new TSlaveInfo();
1372  while ((to = next())) {
1373  // Get the next worker from the list
1374  worker = (TProofNodeInfo *)to;
1375 
1376  // Read back worker node info
1377  const Char_t *image = worker->GetImage().Data();
1378  const Char_t *workdir = worker->GetWorkDir().Data();
1379  Int_t perfidx = worker->GetPerfIndex();
1380  Int_t sport = worker->GetPort();
1381  if (sport == -1)
1382  sport = fUrl.GetPort();
1383 
1384  // Create worker server
1385  TString fullord;
1386  if (worker->GetOrdinal().Length() > 0) {
1387  fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1388  } else {
1389  fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1390  }
1391 
1392  // Remove worker from the list of workers terminated gracefully
1393  dummysi->SetOrdinal(fullord);
1394  TSlaveInfo *rmsi = (TSlaveInfo *)fTerminatedSlaveInfos->Remove(dummysi);
1395  if (rmsi) SafeDelete(rmsi);
1396 
1397  // Create worker server
1398  TString wn(worker->GetNodeName());
1399  if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1400  TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1401  // Add group info in the password firdl, if any
1402  if (strlen(gProofServ->GetGroup()) > 0) {
1403  // Set also the user, otherwise the password is not exported
1404  if (strlen(u.GetUser()) <= 0)
1405  u.SetUser(gProofServ->GetUser());
1407  }
1408  TSlave *slave = 0;
1409  if (worker->IsWorker()) {
1410  slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1411  } else {
1412  slave = CreateSubmaster(u.GetUrl(), fullord,
1413  image, worker->GetMsd(), worker->GetNWrks());
1414  }
1415 
1416  // Add to global list (we will add to the monitor list after
1417  // finalizing the server startup)
1418  Bool_t slaveOk = kTRUE;
1419  fSlaves->Add(slave);
1420  if (slave->IsValid()) {
1421  addedWorkers->Add(slave);
1422  } else {
1423  slaveOk = kFALSE;
1424  fBadSlaves->Add(slave);
1425  Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1426  }
1427 
1428  PDB(kGlobal,3)
1429  Info("AddWorkers", "worker on host %s created"
1430  " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1431 
1432  // Notify opening of connection
1433  nSlavesDone++;
1435  m << TString("Opening connections to workers") << nSlaves
1436  << nSlavesDone << slaveOk;
1437  gProofServ->GetSocket()->Send(m);
1438 
1439  ord++;
1440  } //end of the worker loop
1441  SafeDelete(dummysi);
1442 
1443  // Cleanup
1444  SafeDelete(workerList);
1445 
1446  nSlavesDone = 0;
1447 
1448  // Here we finalize the server startup: in this way the bulk
1449  // of remote operations are almost parallelized
1450  TIter nxsl(addedWorkers);
1451  TSlave *sl = 0;
1452  while ((sl = (TSlave *) nxsl())) {
1453 
1454  // Finalize setup of the server
1455  if (sl->IsValid())
1456  sl->SetupServ(TSlave::kSlave, 0);
1457 
1458  // Monitor good slaves
1459  Bool_t slaveOk = kTRUE;
1460  if (sl->IsValid()) {
1461  fAllMonitor->Add(sl->GetSocket());
1462  PDB(kGlobal,3)
1463  Info("AddWorkers", "worker on host %s finalized"
1464  " and added to list", sl->GetOrdinal());
1465  } else {
1466  slaveOk = kFALSE;
1467  fBadSlaves->Add(sl);
1468  }
1469 
1470  // Notify end of startup operations
1471  nSlavesDone++;
1473  m << TString("Setting up worker servers") << nSlaves
1474  << nSlavesDone << slaveOk;
1475  gProofServ->GetSocket()->Send(m);
1476  }
1477 
1478  // Now set new state on the added workers (on all workers for simplicity)
1479  // use fEnabledPackages, fLoadedMacros,
1480  // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1481  // no need to load packages that are only loaded and not enabled (dyn mode)
1482  Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1483  TNamed *n = 0;
1484  if (TProof::GetEnvVars() &&
1485  (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1486  TString s(n->GetTitle());
1487  if (s.IsDigit()) nwrk = s.Atoi();
1488  }
1489 
1490  if (fDynamicStartup && goMoreParallel) {
1491 
1492  PDB(kGlobal, 3)
1493  Info("AddWorkers", "will invoke GoMoreParallel()");
1494  Int_t nw = GoMoreParallel(nwrk);
1495  PDB(kGlobal, 3)
1496  Info("AddWorkers", "GoMoreParallel()=%d", nw);
1497 
1498  }
1499  else {
1500  // Not in Dynamic Workers mode
1501  PDB(kGlobal, 3)
1502  Info("AddWorkers", "will invoke GoParallel()");
1503  GoParallel(nwrk, kFALSE, 0);
1504  }
1505 
1506  // Set worker processing environment
1507  SetupWorkersEnv(addedWorkers, goMoreParallel);
1508 
1509  // Update list of current workers
1510  PDB(kGlobal, 3)
1511  Info("AddWorkers", "will invoke SaveWorkerInfo()");
1512  SaveWorkerInfo();
1513 
1514  // Inform the client that the number of workers has changed
1515  if (fDynamicStartup && gProofServ) {
1516  PDB(kGlobal, 3)
1517  Info("AddWorkers", "will invoke SendParallel()");
1519 
1520  if (goMoreParallel && fPlayer) {
1521  // In case we are adding workers dynamically to an existing process, we
1522  // should invoke a special player's Process() to set only added workers
1523  // to the proper state
1524  PDB(kGlobal, 3)
1525  Info("AddWorkers", "will send the PROCESS message to selected workers");
1526  fPlayer->JoinProcess(addedWorkers);
1527  // Update merger counters (new workers are not yet active)
1528  fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1529  }
1530  }
1531 
1532  // Cleanup
1533  delete addedWorkers;
1534 
1535  return 0;
1536 }
1537 
1538 ////////////////////////////////////////////////////////////////////////////////
1539 /// Set up packages, loaded macros, include and lib paths ...
1540 
1541 void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1542 {
1543  // Packages
1545  if (packs->GetSize() > 0) {
1546  TIter nxp(packs);
1547  TPair *pck = 0;
1548  while ((pck = (TPair *) nxp())) {
1549  // Upload and Enable methods are intelligent and avoid
1550  // re-uploading or re-enabling of a package to a node that has it.
1551  if (fDynamicStartup && increasingWorkers) {
1552  // Upload only on added workers
1553  PDB(kGlobal, 3)
1554  Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1555  if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1556  EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1557  } else {
1558  PDB(kGlobal, 3)
1559  Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1560  if (UploadPackage(pck->GetName()) >= 0)
1561  EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1562  }
1563  }
1564  }
1565 
1566  // Loaded macros
1567  if (fLoadedMacros) {
1568  TIter nxp(fLoadedMacros);
1569  TObjString *os = 0;
1570  while ((os = (TObjString *) nxp())) {
1571  PDB(kGlobal, 3) {
1572  Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1573  Printf("Loading a macro : %s", os->GetName());
1574  }
1575  Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1576  }
1577  }
1578 
1579  // Dynamic path
1580  TString dyn = gSystem->GetDynamicPath();
1581  dyn.ReplaceAll(":", " ");
1582  dyn.ReplaceAll("\"", " ");
1583  PDB(kGlobal, 3)
1584  Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1585  AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1586 
1587  // Include path
1588  TString inc = gSystem->GetIncludePath();
1589  inc.ReplaceAll("-I", " ");
1590  inc.ReplaceAll("\"", " ");
1591  PDB(kGlobal, 3)
1592  Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1593  AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1594 
1595  // Done
1596  return;
1597 }
1598 
1599 ////////////////////////////////////////////////////////////////////////////////
1600 /// Used for shuting down the workres after a query is finished.
1601 /// Sends each of the workers from the workerList, a kPROOF_STOP message.
1602 /// If the workerList == 0, shutdown all the workers.
1603 
1605 {
1606  if (!IsMaster()) {
1607  Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1608  return -1;
1609  }
1610 
1611  fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1612 
1613  if (!workerList) {
1614  // shutdown all the workers
1615  TIter nxsl(fSlaves);
1616  TSlave *sl = 0;
1617  while ((sl = (TSlave *) nxsl())) {
1618  // Shut down the worker assumig that it is not processing
1619  TerminateWorker(sl);
1620  }
1621 
1622  } else {
1623  if (!(workerList->GetSize())) {
1624  Error("RemoveWorkers", "The list of workers should not be empty!");
1625  return -2;
1626  }
1627 
1628  // Loop over all the workers and stop them
1629  TListIter next(workerList);
1630  TObject *to;
1631  TProofNodeInfo *worker;
1632  while ((to = next())) {
1633  TSlave *sl = 0;
1634  if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1635  // Get the next worker from the list
1636  worker = (TProofNodeInfo *)to;
1637  TIter nxsl(fSlaves);
1638  while ((sl = (TSlave *) nxsl())) {
1639  // Shut down the worker assumig that it is not processing
1640  if (sl->GetName() == worker->GetNodeName())
1641  break;
1642  }
1643  } else if (to->InheritsFrom(TSlave::Class())) {
1644  sl = (TSlave *) to;
1645  } else {
1646  Warning("RemoveWorkers","unknown object type: %s - it should be"
1647  " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1648  }
1649  // Shut down the worker assumig that it is not processing
1650  if (sl) {
1651  if (gDebug > 0)
1652  Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1653  TerminateWorker(sl);
1654  }
1655  }
1656  }
1657 
1658  // Update also the master counter
1659  if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1660 
1661  return 0;
1662 }
1663 
1664 ////////////////////////////////////////////////////////////////////////////////
1665 /// Start up PROOF slaves.
1666 
1668 {
1669  // If this is a master server, find the config file and start slave
1670  // servers as specified in the config file
1671  if (TestBit(TProof::kIsMaster)) {
1672 
1673  Int_t pc = 0;
1674  TList *workerList = new TList;
1675  // Get list of workers
1676  if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1677  TString emsg("no resource currently available for this session: please retry later");
1678  if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1679  gProofServ->SendAsynMessage(emsg.Data());
1680  return kFALSE;
1681  }
1682  // Setup the workers
1683  if (AddWorkers(workerList) < 0)
1684  return kFALSE;
1685 
1686  } else {
1687 
1688  // create master server
1689  Printf("Starting master: opening connection ...");
1690  TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1691 
1692  if (slave->IsValid()) {
1693 
1694  // Notify
1695  fprintf(stderr,"Starting master:"
1696  " connection open: setting up server ... \r");
1697  StartupMessage("Connection to master opened", kTRUE, 1, 1);
1698 
1699  if (!attach) {
1700 
1701  // Set worker interrupt handler
1702  slave->SetInterruptHandler(kTRUE);
1703 
1704  // Finalize setup of the server
1706 
1707  if (slave->IsValid()) {
1708 
1709  // Notify
1710  Printf("Starting master: OK ");
1711  StartupMessage("Master started", kTRUE, 1, 1);
1712 
1713  // check protocol compatibility
1714  // protocol 1 is not supported anymore
1715  if (fProtocol == 1) {
1716  Error("StartSlaves",
1717  "client and remote protocols not compatible (%d and %d)",
1719  slave->Close("S");
1720  delete slave;
1721  return kFALSE;
1722  }
1723 
1724  fSlaves->Add(slave);
1725  fAllMonitor->Add(slave->GetSocket());
1726 
1727  // Unset worker interrupt handler
1728  slave->SetInterruptHandler(kFALSE);
1729 
1730  // Set interrupt PROOF handler from now on
1731  fIntHandler = new TProofInterruptHandler(this);
1732 
1733  // Give-up after 5 minutes
1734  Int_t rc = Collect(slave, 300);
1735  Int_t slStatus = slave->GetStatus();
1736  if (slStatus == -99 || slStatus == -98 || rc == 0) {
1737  fSlaves->Remove(slave);
1738  fAllMonitor->Remove(slave->GetSocket());
1739  if (slStatus == -99)
1740  Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1741  else if (slStatus == -98)
1742  Error("StartSlaves", "could not setup output redirection on master");
1743  else
1744  Error("StartSlaves", "setting up master");
1745  slave->Close("S");
1746  delete slave;
1747  return 0;
1748  }
1749 
1750  if (!slave->IsValid()) {
1751  fSlaves->Remove(slave);
1752  fAllMonitor->Remove(slave->GetSocket());
1753  slave->Close("S");
1754  delete slave;
1755  Error("StartSlaves",
1756  "failed to setup connection with PROOF master server");
1757  return kFALSE;
1758  }
1759 
1760  if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1761  if ((fProgressDialog =
1762  gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1763  if (fProgressDialog->LoadPlugin() == -1)
1764  fProgressDialog = 0;
1765  }
1766  } else {
1767  // Notify
1768  Printf("Starting master: failure");
1769  }
1770  } else {
1771 
1772  // Notify
1773  Printf("Starting master: OK ");
1774  StartupMessage("Master attached", kTRUE, 1, 1);
1775 
1776  if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1777  if ((fProgressDialog =
1778  gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1779  if (fProgressDialog->LoadPlugin() == -1)
1780  fProgressDialog = 0;
1781  }
1782 
1783  fSlaves->Add(slave);
1784  fIntHandler = new TProofInterruptHandler(this);
1785  }
1786 
1787  } else {
1788  delete slave;
1789  // Notify only if verbosity is on: most likely the failure has already been notified
1790  if (gDebug > 0)
1791  Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1792  return kFALSE;
1793  }
1794  }
1795 
1796  return kTRUE;
1797 }
1798 
1799 ////////////////////////////////////////////////////////////////////////////////
1800 /// Close all open slave servers.
1801 /// Client can decide to shutdown the remote session by passing option is 'S'
1802 /// or 's'. Default for clients is detach, if supported. Masters always
1803 /// shutdown the remote counterpart.
1804 
1806 {
1807  { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1808 
1809  fValid = kFALSE;
1810  if (fSlaves) {
1811  if (fIntHandler)
1812  fIntHandler->Remove();
1813 
1814  TIter nxs(fSlaves);
1815  TSlave *sl = 0;
1816  while ((sl = (TSlave *)nxs()))
1817  sl->Close(opt);
1818 
1819  fActiveSlaves->Clear("nodelete");
1820  fUniqueSlaves->Clear("nodelete");
1821  fAllUniqueSlaves->Clear("nodelete");
1822  fNonUniqueMasters->Clear("nodelete");
1823  fBadSlaves->Clear("nodelete");
1824  fInactiveSlaves->Clear("nodelete");
1825  fSlaves->Delete();
1826  }
1827  }
1828 
1830  gROOT->GetListOfSockets()->Remove(this);
1831 
1832  if (fChains) {
1833  while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1834  // remove "chain" from list
1835  chain->SetProof(0);
1836  RemoveChain(chain);
1837  }
1838  }
1839 
1840  if (IsProofd()) {
1841 
1842  gROOT->GetListOfProofs()->Remove(this);
1843  if (gProof && gProof == this) {
1844  // Set previous proofd-related as default
1845  TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1846  while ((gProof = (TProof *)pvp())) {
1847  if (gProof->IsProofd())
1848  break;
1849  }
1850  }
1851  }
1852  }
1853 }
1854 
1855 ////////////////////////////////////////////////////////////////////////////////
1856 /// Create a new TSlave of type TSlave::kSlave.
1857 /// Note: creation of TSlave is private with TProof as a friend.
1858 /// Derived classes must use this function to create slaves.
1859 
1860 TSlave *TProof::CreateSlave(const char *url, const char *ord,
1861  Int_t perf, const char *image, const char *workdir)
1862 {
1863  TSlave* sl = TSlave::Create(url, ord, perf, image,
1864  this, TSlave::kSlave, workdir, 0);
1865 
1866  if (sl->IsValid()) {
1867  sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1868  // must set fParallel to 1 for slaves since they do not
1869  // report their fParallel with a LOG_DONE message
1870  sl->fParallel = 1;
1871  }
1872 
1873  return sl;
1874 }
1875 
1876 
1877 ////////////////////////////////////////////////////////////////////////////////
1878 /// Create a new TSlave of type TSlave::kMaster.
1879 /// Note: creation of TSlave is private with TProof as a friend.
1880 /// Derived classes must use this function to create slaves.
1881 
1882 TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1883  const char *image, const char *msd, Int_t nwk)
1884 {
1885  TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1886  TSlave::kMaster, 0, msd, nwk);
1887 
1888  if (sl->IsValid()) {
1889  sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1890  }
1891 
1892  return sl;
1893 }
1894 
1895 ////////////////////////////////////////////////////////////////////////////////
1896 /// Find slave that has TSocket s. Returns 0 in case slave is not found.
1897 
1899 {
1900  TSlave *sl;
1901  TIter next(fSlaves);
1902 
1903  while ((sl = (TSlave *)next())) {
1904  if (sl->IsValid() && sl->GetSocket() == s)
1905  return sl;
1906  }
1907  return 0;
1908 }
1909 
1910 ////////////////////////////////////////////////////////////////////////////////
1911 /// Add to the fUniqueSlave list the active slaves that have a unique
1912 /// (user) file system image. This information is used to transfer files
1913 /// only once to nodes that share a file system (an image). Submasters
1914 /// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1915 /// list. That list is used to trigger the transferring of files to
1916 /// the submaster's unique slaves without the need to transfer the file
1917 /// to the submaster.
1918 
1920 {
1921  fUniqueSlaves->Clear();
1926 
1928 
1929  while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1930  if (fImage == sl->fImage) {
1931  if (sl->GetSlaveType() == TSlave::kMaster) {
1932  fNonUniqueMasters->Add(sl);
1933  fAllUniqueSlaves->Add(sl);
1934  fAllUniqueMonitor->Add(sl->GetSocket());
1935  }
1936  continue;
1937  }
1938 
1939  TIter next2(fUniqueSlaves);
1940  TSlave *replace_slave = 0;
1941  Bool_t add = kTRUE;
1942  while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1943  if (sl->fImage == sl2->fImage) {
1944  add = kFALSE;
1945  if (sl->GetSlaveType() == TSlave::kMaster) {
1946  if (sl2->GetSlaveType() == TSlave::kSlave) {
1947  // give preference to master
1948  replace_slave = sl2;
1949  add = kTRUE;
1950  } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1951  fNonUniqueMasters->Add(sl);
1952  fAllUniqueSlaves->Add(sl);
1953  fAllUniqueMonitor->Add(sl->GetSocket());
1954  } else {
1955  Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1956  R__ASSERT(0);
1957  }
1958  }
1959  break;
1960  }
1961  }
1962 
1963  if (add) {
1964  fUniqueSlaves->Add(sl);
1965  fAllUniqueSlaves->Add(sl);
1966  fUniqueMonitor->Add(sl->GetSocket());
1967  fAllUniqueMonitor->Add(sl->GetSocket());
1968  if (replace_slave) {
1969  fUniqueSlaves->Remove(replace_slave);
1970  fAllUniqueSlaves->Remove(replace_slave);
1971  fUniqueMonitor->Remove(replace_slave->GetSocket());
1972  fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1973  }
1974  }
1975  }
1976 
1977  // will be actiavted in Collect()
1980 }
1981 
1982 ////////////////////////////////////////////////////////////////////////////////
1983 /// Return number of slaves as described in the config file.
1984 
1986 {
1987  return fSlaves->GetSize();
1988 }
1989 
1990 ////////////////////////////////////////////////////////////////////////////////
1991 /// Return number of active slaves, i.e. slaves that are valid and in
1992 /// the current computing group.
1993 
1995 {
1996  return fActiveSlaves->GetSize();
1997 }
1998 
1999 ////////////////////////////////////////////////////////////////////////////////
2000 /// Return number of inactive slaves, i.e. slaves that are valid but not in
2001 /// the current computing group.
2002 
2004 {
2005  return fInactiveSlaves->GetSize();
2006 }
2007 
2008 ////////////////////////////////////////////////////////////////////////////////
2009 /// Return number of unique slaves, i.e. active slaves that have each a
2010 /// unique different user files system.
2011 
2013 {
2014  return fUniqueSlaves->GetSize();
2015 }
2016 
2017 ////////////////////////////////////////////////////////////////////////////////
2018 /// Return number of bad slaves. This are slaves that we in the config
2019 /// file, but refused to startup or that died during the PROOF session.
2020 
2022 {
2023  return fBadSlaves->GetSize();
2024 }
2025 
2026 ////////////////////////////////////////////////////////////////////////////////
2027 /// Ask the for the statistics of the slaves.
2028 
2030 {
2031  if (!IsValid()) return;
2032 
2035 }
2036 
2037 ////////////////////////////////////////////////////////////////////////////////
2038 /// Get statistics about CPU time, real time and bytes read.
2039 /// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2040 /// and GetBytesRead()
2041 
2043 {
2044  if (fProtocol > 27) {
2045  // This returns the correct result
2046  AskStatistics();
2047  } else {
2048  // AskStatistics is buggy: parse the output of Print()
2049  RedirectHandle_t rh;
2050  gSystem->RedirectOutput(fLogFileName, "a", &rh);
2051  Print();
2052  gSystem->RedirectOutput(0, 0, &rh);
2053  TMacro *mp = GetLastLog();
2054  if (mp) {
2055  // Look for global directories
2056  TIter nxl(mp->GetListOfLines());
2057  TObjString *os = 0;
2058  while ((os = (TObjString *) nxl())) {
2059  TString s(os->GetName());
2060  if (s.Contains("Total MB's processed:")) {
2061  s.ReplaceAll("Total MB's processed:", "");
2062  if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2063  } else if (s.Contains("Total real time used (s):")) {
2064  s.ReplaceAll("Total real time used (s):", "");
2065  if (s.IsFloat()) fRealTime = s.Atof();
2066  } else if (s.Contains("Total CPU time used (s):")) {
2067  s.ReplaceAll("Total CPU time used (s):", "");
2068  if (s.IsFloat()) fCpuTime = s.Atof();
2069  }
2070  }
2071  delete mp;
2072  }
2073  }
2074 
2075  if (verbose) {
2076  Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2077  GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2078  }
2079 }
2080 
2081 ////////////////////////////////////////////////////////////////////////////////
2082 /// Ask the for the number of parallel slaves.
2083 
2085 {
2086  if (!IsValid()) return;
2087 
2090 }
2091 
2092 ////////////////////////////////////////////////////////////////////////////////
2093 /// Ask the master for the list of queries.
2094 
2096 {
2097  if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2098 
2099  Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2101  m << all;
2102  Broadcast(m, kActive);
2104 
2105  // This should have been filled by now
2106  return fQueries;
2107 }
2108 
2109 ////////////////////////////////////////////////////////////////////////////////
2110 /// Number of queries processed by this session
2111 
2113 {
2114  if (fQueries)
2115  return fQueries->GetSize() - fOtherQueries;
2116  return 0;
2117 }
2118 
2119 ////////////////////////////////////////////////////////////////////////////////
2120 /// Set max number of draw queries whose results are saved
2121 
2123 {
2124  if (max > 0) {
2125  if (fPlayer)
2126  fPlayer->SetMaxDrawQueries(max);
2127  fMaxDrawQueries = max;
2128  }
2129 }
2130 
2131 ////////////////////////////////////////////////////////////////////////////////
2132 /// Get max number of queries whose full results are kept in the
2133 /// remote sandbox
2134 
2136 {
2138  m << kFALSE;
2139  Broadcast(m, kActive);
2141 }
2142 
2143 ////////////////////////////////////////////////////////////////////////////////
2144 /// Return pointer to the list of query results in the player
2145 
2147 {
2148  return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2149 }
2150 
2151 ////////////////////////////////////////////////////////////////////////////////
2152 /// Return pointer to the full TQueryResult instance owned by the player
2153 /// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2154 
2156 {
2157  return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2158 }
2159 
2160 ////////////////////////////////////////////////////////////////////////////////
2161 /// Ask the master for the list of queries.
2162 /// Options:
2163 /// "A" show information about all the queries known to the
2164 /// server, i.e. even those processed by other sessions
2165 /// "L" show only information about queries locally available
2166 /// i.e. already retrieved. If "L" is specified, "A" is
2167 /// ignored.
2168 /// "F" show all details available about queries
2169 /// "H" print help menu
2170 /// Default ""
2171 
2173 {
2174  Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2175  if (help) {
2176 
2177  // Help
2178 
2179  Printf("+++");
2180  Printf("+++ Options: \"A\" show all queries known to server");
2181  Printf("+++ \"L\" show retrieved queries");
2182  Printf("+++ \"F\" full listing of query info");
2183  Printf("+++ \"H\" print this menu");
2184  Printf("+++");
2185  Printf("+++ (case insensitive)");
2186  Printf("+++");
2187  Printf("+++ Use Retrieve(<#>) to retrieve the full"
2188  " query results from the master");
2189  Printf("+++ e.g. Retrieve(8)");
2190 
2191  Printf("+++");
2192 
2193  return;
2194  }
2195 
2196  if (!IsValid()) return;
2197 
2198  Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2199 
2200  TObject *pq = 0;
2201  if (!local) {
2202  GetListOfQueries(opt);
2203 
2204  if (!fQueries) return;
2205 
2206  TIter nxq(fQueries);
2207 
2208  // Queries processed by other sessions
2209  if (fOtherQueries > 0) {
2210  Printf("+++");
2211  Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2212  Int_t nq = 0;
2213  while (nq++ < fOtherQueries && (pq = nxq()))
2214  pq->Print(opt);
2215  }
2216 
2217  // Queries processed by this session
2218  Printf("+++");
2219  Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2221  while ((pq = nxq()))
2222  pq->Print(opt);
2223 
2224  } else {
2225 
2226  // Queries processed by this session
2227  Printf("+++");
2228  Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2230 
2231  // Queries available locally
2232  TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2233  if (listlocal) {
2234  Printf("+++");
2235  Printf("+++ Queries available locally: %d", listlocal->GetSize());
2236  TIter nxlq(listlocal);
2237  while ((pq = nxlq()))
2238  pq->Print(opt);
2239  }
2240  }
2241  Printf("+++");
2242 }
2243 
2244 ////////////////////////////////////////////////////////////////////////////////
2245 /// See if the data is ready to be analyzed.
2246 
2247 Bool_t TProof::IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
2248 {
2249  if (!IsValid()) return kFALSE;
2250 
2251  TList submasters;
2252  TIter nextSlave(GetListOfActiveSlaves());
2253  while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2254  if (sl->GetSlaveType() == TSlave::kMaster) {
2255  submasters.Add(sl);
2256  }
2257  }
2258 
2259  fDataReady = kTRUE; //see if any submasters set it to false
2260  fBytesReady = 0;
2261  fTotalBytes = 0;
2262  //loop over submasters and see if data is ready
2263  if (submasters.GetSize() > 0) {
2264  Broadcast(kPROOF_DATA_READY, &submasters);
2265  Collect(&submasters);
2266  }
2267 
2268  bytesready = fBytesReady;
2269  totalbytes = fTotalBytes;
2270 
2271  EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2272 
2273  PDB(kGlobal,2)
2274  Info("IsDataReady", "%lld / %lld (%s)",
2275  bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2276 
2277  return fDataReady;
2278 }
2279 
2280 ////////////////////////////////////////////////////////////////////////////////
2281 /// Send interrupt to master or slave servers.
2282 
2284 {
2285  if (!IsValid()) return;
2286 
2287  TList *slaves = 0;
2288  if (list == kAll) slaves = fSlaves;
2289  if (list == kActive) slaves = fActiveSlaves;
2290  if (list == kUnique) slaves = fUniqueSlaves;
2291  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2292 
2293  if (slaves->GetSize() == 0) return;
2294 
2295  TSlave *sl;
2296  TIter next(slaves);
2297 
2298  while ((sl = (TSlave *)next())) {
2299  if (sl->IsValid()) {
2300 
2301  // Ask slave to progate the interrupt request
2302  sl->Interrupt((Int_t)type);
2303  }
2304  }
2305 }
2306 
2307 ////////////////////////////////////////////////////////////////////////////////
2308 /// Returns number of slaves active in parallel mode. Returns 0 in case
2309 /// there are no active slaves. Returns -1 in case of error.
2310 
2312 {
2313  if (!IsValid()) return -1;
2314 
2315  // iterate over active slaves and return total number of slaves
2316  TIter nextSlave(GetListOfActiveSlaves());
2317  Int_t nparallel = 0;
2318  while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2319  if (sl->GetParallel() >= 0)
2320  nparallel += sl->GetParallel();
2321 
2322  return nparallel;
2323 }
2324 
2325 ////////////////////////////////////////////////////////////////////////////////
2326 /// Returns list of TSlaveInfo's. In case of error return 0.
2327 
2329 {
2330  if (!IsValid()) return 0;
2331 
2332  if (fSlaveInfo == 0) {
2334  fSlaveInfo->SetOwner();
2335  } else {
2336  fSlaveInfo->Delete();
2337  }
2338 
2339  TList masters;
2341  TSlave *slave;
2342 
2343  while ((slave = (TSlave *) next()) != 0) {
2344  if (slave->GetSlaveType() == TSlave::kSlave) {
2345  const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2346  TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2347  name,
2348  slave->GetPerfIdx());
2349  fSlaveInfo->Add(slaveinfo);
2350 
2351  TIter nextactive(GetListOfActiveSlaves());
2352  TSlave *activeslave;
2353  while ((activeslave = (TSlave *) nextactive())) {
2354  if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2355  slaveinfo->SetStatus(TSlaveInfo::kActive);
2356  break;
2357  }
2358  }
2359 
2360  TIter nextbad(GetListOfBadSlaves());
2361  TSlave *badslave;
2362  while ((badslave = (TSlave *) nextbad())) {
2363  if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2364  slaveinfo->SetStatus(TSlaveInfo::kBad);
2365  break;
2366  }
2367  }
2368  // Get system info if supported
2369  if (slave->IsValid()) {
2370  if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2371  MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2372  else
2373  masters.Add(slave);
2374  }
2375 
2376  } else if (slave->GetSlaveType() == TSlave::kMaster) {
2377  if (slave->IsValid()) {
2378  if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2379  MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2380  else
2381  masters.Add(slave);
2382  }
2383  } else {
2384  Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2385  R__ASSERT(0);
2386  }
2387  }
2388  if (masters.GetSize() > 0) Collect(&masters);
2389 
2390  return fSlaveInfo;
2391 }
2392 
2393 ////////////////////////////////////////////////////////////////////////////////
2394 /// Activate slave server list.
2395 
2397 {
2399  mon->DeActivateAll();
2400 
2401  slaves = !slaves ? fActiveSlaves : slaves;
2402 
2403  TIter next(slaves);
2404  TSlave *sl;
2405  while ((sl = (TSlave*) next())) {
2406  if (sl->IsValid())
2407  mon->Activate(sl->GetSocket());
2408  }
2409 }
2410 
2411 ////////////////////////////////////////////////////////////////////////////////
2412 /// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2413 /// monitored by 'mon'.
2414 
2416 {
2417  TMonitor *m = (mon) ? mon : fCurrentMonitor;
2418  if (m) {
2419  if (on)
2420  m->ActivateAll();
2421  else
2422  m->DeActivateAll();
2423  }
2424 }
2425 
2426 ////////////////////////////////////////////////////////////////////////////////
2427 /// Broadcast the group priority to all workers in the specified list. Returns
2428 /// the number of workers the message was successfully sent to.
2429 /// Returns -1 in case of error.
2430 
2431 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2432 {
2433  if (!IsValid()) return -1;
2434 
2435  if (workers->GetSize() == 0) return 0;
2436 
2437  int nsent = 0;
2438  TIter next(workers);
2439 
2440  TSlave *wrk;
2441  while ((wrk = (TSlave *)next())) {
2442  if (wrk->IsValid()) {
2443  if (wrk->SendGroupPriority(grp, priority) == -1)
2444  MarkBad(wrk, "could not send group priority");
2445  else
2446  nsent++;
2447  }
2448  }
2449 
2450  return nsent;
2451 }
2452 
2453 ////////////////////////////////////////////////////////////////////////////////
2454 /// Broadcast the group priority to all workers in the specified list. Returns
2455 /// the number of workers the message was successfully sent to.
2456 /// Returns -1 in case of error.
2457 
2458 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2459 {
2460  TList *workers = 0;
2461  if (list == kAll) workers = fSlaves;
2462  if (list == kActive) workers = fActiveSlaves;
2463  if (list == kUnique) workers = fUniqueSlaves;
2464  if (list == kAllUnique) workers = fAllUniqueSlaves;
2465 
2466  return BroadcastGroupPriority(grp, priority, workers);
2467 }
2468 
2469 ////////////////////////////////////////////////////////////////////////////////
2470 /// Reset the merge progress notificator
2471 
2473 {
2475 }
2476 
2477 ////////////////////////////////////////////////////////////////////////////////
2478 /// Broadcast a message to all slaves in the specified list. Returns
2479 /// the number of slaves the message was successfully sent to.
2480 /// Returns -1 in case of error.
2481 
2482 Int_t TProof::Broadcast(const TMessage &mess, TList *slaves)
2483 {
2484  if (!IsValid()) return -1;
2485 
2486  if (!slaves || slaves->GetSize() == 0) return 0;
2487 
2488  int nsent = 0;
2489  TIter next(slaves);
2490 
2491  TSlave *sl;
2492  while ((sl = (TSlave *)next())) {
2493  if (sl->IsValid()) {
2494  if (sl->GetSocket()->Send(mess) == -1)
2495  MarkBad(sl, "could not broadcast request");
2496  else
2497  nsent++;
2498  }
2499  }
2500 
2501  return nsent;
2502 }
2503 
2504 ////////////////////////////////////////////////////////////////////////////////
2505 /// Broadcast a message to all slaves in the specified list (either
2506 /// all slaves or only the active slaves). Returns the number of slaves
2507 /// the message was successfully sent to. Returns -1 in case of error.
2508 
2510 {
2511  TList *slaves = 0;
2512  if (list == kAll) slaves = fSlaves;
2513  if (list == kActive) slaves = fActiveSlaves;
2514  if (list == kUnique) slaves = fUniqueSlaves;
2515  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2516 
2517  return Broadcast(mess, slaves);
2518 }
2519 
2520 ////////////////////////////////////////////////////////////////////////////////
2521 /// Broadcast a character string buffer to all slaves in the specified
2522 /// list. Use kind to set the TMessage what field. Returns the number of
2523 /// slaves the message was sent to. Returns -1 in case of error.
2524 
2525 Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2526 {
2527  TMessage mess(kind);
2528  if (str) mess.WriteString(str);
2529  return Broadcast(mess, slaves);
2530 }
2531 
2532 ////////////////////////////////////////////////////////////////////////////////
2533 /// Broadcast a character string buffer to all slaves in the specified
2534 /// list (either all slaves or only the active slaves). Use kind to
2535 /// set the TMessage what field. Returns the number of slaves the message
2536 /// was sent to. Returns -1 in case of error.
2537 
2538 Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2539 {
2540  TMessage mess(kind);
2541  if (str) mess.WriteString(str);
2542  return Broadcast(mess, list);
2543 }
2544 
2545 ////////////////////////////////////////////////////////////////////////////////
2546 /// Broadcast an object to all slaves in the specified list. Use kind to
2547 /// set the TMEssage what field. Returns the number of slaves the message
2548 /// was sent to. Returns -1 in case of error.
2549 
2551 {
2552  TMessage mess(kind);
2553  mess.WriteObject(obj);
2554  return Broadcast(mess, slaves);
2555 }
2556 
2557 ////////////////////////////////////////////////////////////////////////////////
2558 /// Broadcast an object to all slaves in the specified list. Use kind to
2559 /// set the TMEssage what field. Returns the number of slaves the message
2560 /// was sent to. Returns -1 in case of error.
2561 
2563 {
2564  TMessage mess(kind);
2565  mess.WriteObject(obj);
2566  return Broadcast(mess, list);
2567 }
2568 
2569 ////////////////////////////////////////////////////////////////////////////////
2570 /// Broadcast a raw buffer of specified length to all slaves in the
2571 /// specified list. Returns the number of slaves the buffer was sent to.
2572 /// Returns -1 in case of error.
2573 
2575 {
2576  if (!IsValid()) return -1;
2577 
2578  if (slaves->GetSize() == 0) return 0;
2579 
2580  int nsent = 0;
2581  TIter next(slaves);
2582 
2583  TSlave *sl;
2584  while ((sl = (TSlave *)next())) {
2585  if (sl->IsValid()) {
2586  if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2587  MarkBad(sl, "could not send broadcast-raw request");
2588  else
2589  nsent++;
2590  }
2591  }
2592 
2593  return nsent;
2594 }
2595 
2596 ////////////////////////////////////////////////////////////////////////////////
2597 /// Broadcast a raw buffer of specified length to all slaves in the
2598 /// specified list. Returns the number of slaves the buffer was sent to.
2599 /// Returns -1 in case of error.
2600 
2602 {
2603  TList *slaves = 0;
2604  if (list == kAll) slaves = fSlaves;
2605  if (list == kActive) slaves = fActiveSlaves;
2606  if (list == kUnique) slaves = fUniqueSlaves;
2607  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2608 
2609  return BroadcastRaw(buffer, length, slaves);
2610 }
2611 
2612 ////////////////////////////////////////////////////////////////////////////////
2613 /// Broadcast file to all workers in the specified list. Returns the number of workers
2614 /// the buffer was sent to.
2615 /// Returns -1 in case of error.
2616 
2617 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2618 {
2619  if (!IsValid()) return -1;
2620 
2621  if (wrks->GetSize() == 0) return 0;
2622 
2623  int nsent = 0;
2624  TIter next(wrks);
2625 
2626  TSlave *wrk;
2627  while ((wrk = (TSlave *)next())) {
2628  if (wrk->IsValid()) {
2629  if (SendFile(file, opt, rfile, wrk) < 0)
2630  Error("BroadcastFile",
2631  "problems sending file to worker %s (%s)",
2632  wrk->GetOrdinal(), wrk->GetName());
2633  else
2634  nsent++;
2635  }
2636  }
2637 
2638  return nsent;
2639 }
2640 
2641 ////////////////////////////////////////////////////////////////////////////////
2642 /// Broadcast file to all workers in the specified list. Returns the number of workers
2643 /// the buffer was sent to.
2644 /// Returns -1 in case of error.
2645 
2646 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2647 {
2648  TList *wrks = 0;
2649  if (list == kAll) wrks = fSlaves;
2650  if (list == kActive) wrks = fActiveSlaves;
2651  if (list == kUnique) wrks = fUniqueSlaves;
2652  if (list == kAllUnique) wrks = fAllUniqueSlaves;
2653 
2654  return BroadcastFile(file, opt, rfile, wrks);
2655 }
2656 
2657 ////////////////////////////////////////////////////////////////////////////////
2658 /// Release the used monitor to be used, making sure to delete newly created
2659 /// monitors.
2660 
2662 {
2663  if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2664  && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2665  delete mon;
2666  }
2667 }
2668 
2669 ////////////////////////////////////////////////////////////////////////////////
2670 /// Collect responses from slave sl. Returns the number of slaves that
2671 /// responded (=1).
2672 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2673 /// which means wait forever).
2674 /// If defined (>= 0) endtype is the message that stops this collection.
2675 
2676 Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2677 {
2678  Int_t rc = 0;
2679 
2680  TMonitor *mon = 0;
2681  if (!sl->IsValid()) return 0;
2682 
2683  if (fCurrentMonitor == fAllMonitor) {
2684  mon = new TMonitor;
2685  } else {
2686  mon = fAllMonitor;
2687  mon->DeActivateAll();
2688  }
2689  mon->Activate(sl->GetSocket());
2690 
2691  rc = Collect(mon, timeout, endtype, deactonfail);
2692  ReleaseMonitor(mon);
2693  return rc;
2694 }
2695 
2696 ////////////////////////////////////////////////////////////////////////////////
2697 /// Collect responses from the slave servers. Returns the number of slaves
2698 /// that responded.
2699 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2700 /// which means wait forever).
2701 /// If defined (>= 0) endtype is the message that stops this collection.
2702 
2703 Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2704 {
2705  Int_t rc = 0;
2706 
2707  TMonitor *mon = 0;
2708 
2709  if (fCurrentMonitor == fAllMonitor) {
2710  mon = new TMonitor;
2711  } else {
2712  mon = fAllMonitor;
2713  mon->DeActivateAll();
2714  }
2715  TIter next(slaves);
2716  TSlave *sl;
2717  while ((sl = (TSlave*) next())) {
2718  if (sl->IsValid())
2719  mon->Activate(sl->GetSocket());
2720  }
2721 
2722  rc = Collect(mon, timeout, endtype, deactonfail);
2723  ReleaseMonitor(mon);
2724  return rc;
2725 }
2726 
2727 ////////////////////////////////////////////////////////////////////////////////
2728 /// Collect responses from the slave servers. Returns the number of slaves
2729 /// that responded.
2730 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2731 /// which means wait forever).
2732 /// If defined (>= 0) endtype is the message that stops this collection.
2733 
2734 Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2735 {
2736  Int_t rc = 0;
2737  TMonitor *mon = 0;
2738 
2739  if (list == kAll) mon = fAllMonitor;
2740  if (list == kActive) mon = fActiveMonitor;
2741  if (list == kUnique) mon = fUniqueMonitor;
2742  if (list == kAllUnique) mon = fAllUniqueMonitor;
2743  if (fCurrentMonitor == mon) {
2744  // Get a copy
2745  mon = new TMonitor(*mon);
2746  }
2747  mon->ActivateAll();
2748 
2749  rc = Collect(mon, timeout, endtype, deactonfail);
2750  ReleaseMonitor(mon);
2751  return rc;
2752 }
2753 
2754 ////////////////////////////////////////////////////////////////////////////////
2755 /// Collect responses from the slave servers. Returns the number of messages
2756 /// received. Can be 0 if there are no active slaves.
2757 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2758 /// which means wait forever).
2759 /// If defined (>= 0) endtype is the message that stops this collection.
2760 /// Collect also stops its execution from time to time to check for new
2761 /// workers in Dynamic Startup mode.
2762 
2763 Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2764 {
2765  Int_t collectId = gRandom->Integer(9999);
2766 
2767  PDB(kCollect, 3)
2768  Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2769 
2770  // Reset the status flag and clear the messages in the list, if any
2771  fStatus = 0;
2772  fRecvMessages->Clear();
2773 
2774  Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2775 
2776  if (!mon->GetActive(actto)) return 0;
2777 
2779 
2780  // Used by external code to know what we are monitoring
2781  TMonitor *savedMonitor = 0;
2782  if (fCurrentMonitor) {
2783  savedMonitor = fCurrentMonitor;
2784  fCurrentMonitor = mon;
2785  } else {
2786  fCurrentMonitor = mon;
2787  fBytesRead = 0;
2788  fRealTime = 0.0;
2789  fCpuTime = 0.0;
2790  }
2791 
2792  // We want messages on the main window during synchronous collection,
2793  // but we save the present status to restore it at the end
2794  Bool_t saveRedirLog = fRedirLog;
2795  if (!IsIdle() && !IsSync())
2796  fRedirLog = kFALSE;
2797 
2798  int cnt = 0, rc = 0;
2799 
2800  // Timeout counter
2801  Long_t nto = timeout;
2802  PDB(kCollect, 2)
2803  Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2804 
2805  // On clients, handle Ctrl-C during collection
2806  if (fIntHandler)
2807  fIntHandler->Add();
2808 
2809  // Sockets w/o activity during the last 'sto' millisecs are deactivated
2810  Int_t nact = 0;
2811  Long_t sto = -1;
2812  Int_t nsto = 60;
2813  Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2814  mon->ResetInterrupt();
2815  while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2816 
2817  // Dump last waiting sockets, if in debug mode
2818  PDB(kCollect, 2) {
2819  if (nact < 4) {
2820  TList *al = mon->GetListOfActives();
2821  if (al && al->GetSize() > 0) {
2822  Info("Collect"," %d node(s) still active:", al->GetSize());
2823  TIter nxs(al);
2824  TSocket *xs = 0;
2825  while ((xs = (TSocket *)nxs())) {
2826  TSlave *wrk = FindSlave(xs);
2827  if (wrk)
2828  Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2829  else
2830  Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2831  xs->GetInetAddress().GetPort());
2832  }
2833  }
2834  }
2835  }
2836 
2837  // Preemptive poll for new workers on the master only in Dynamic Mode and only
2838  // during processing (TODO: should work on Top Master only)
2840  ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2843  fLastPollWorkers_s = time(0);
2845  PDB(kCollect, 1)
2846  Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2847  }
2848 
2849  // Wait for a ready socket
2850  PDB(kCollect, 3)
2851  Info("Collect", "Will invoke Select() #%04d", collectId);
2852  TSocket *s = mon->Select(1000);
2853 
2854  if (s && s != (TSocket *)(-1)) {
2855  // Get and analyse the info it did receive
2856  rc = CollectInputFrom(s, endtype, deactonfail);
2857  if (rc == 1 || (rc == 2 && !savedMonitor)) {
2858  // Deactivate it if we are done with it
2859  mon->DeActivate(s);
2860  PDB(kCollect, 2)
2861  Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2862  s, mon->GetActive(),
2863  mon->GetListOfActives()->First());
2864  } else if (rc == 2) {
2865  // This end message was for the saved monitor
2866  // Deactivate it if we are done with it
2867  if (savedMonitor) {
2868  savedMonitor->DeActivate(s);
2869  PDB(kCollect, 2)
2870  Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2871  s, savedMonitor->GetActive(),
2872  savedMonitor->GetListOfActives()->First());
2873  }
2874  }
2875 
2876  // Update counter (if no error occured)
2877  if (rc >= 0)
2878  cnt++;
2879  } else {
2880  // If not timed-out, exit if not stopped or not aborted
2881  // (player exits status is finished in such a case); otherwise,
2882  // we still need to collect the partial output info
2883  if (!s)
2885  mon->DeActivateAll();
2886  // Decrease the timeout counter if requested
2887  if (s == (TSocket *)(-1) && nto > 0)
2888  nto--;
2889  }
2890 
2891  // Check if there are workers with ready output to be sent and ask the first to send it
2892  if (IsMaster() && fWrksOutputReady && fWrksOutputReady->GetSize() > 0) {
2893  // Maximum number of concurrent sendings
2894  Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2895  if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2896  mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2897  TIter nxwr(fWrksOutputReady);
2898  TSlave *wrk = 0;
2899  while (mxws && (wrk = (TSlave *) nxwr())) {
2900  if (!wrk->TestBit(TSlave::kOutputRequested)) {
2901  // Ask worker for output
2902  TMessage sendoutput(kPROOF_SENDOUTPUT);
2903  PDB(kCollect, 2)
2904  Info("Collect", "worker %s was asked to send its output to master",
2905  wrk->GetOrdinal());
2906  if (wrk->GetSocket()->Send(sendoutput) != 1) {
2908  mxws--;
2909  }
2910  } else {
2911  // Count
2912  mxws--;
2913  }
2914  }
2915  }
2916 
2917  // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2918  sto = -1;
2919  if (--nsto <= 0) {
2920  sto = (Long_t) actto;
2921  nsto = 60;
2922  }
2923 
2924  } // end loop over active monitors
2925 
2926  // If timed-out, deactivate the remaining sockets
2927  if (nto == 0) {
2928  TList *al = mon->GetListOfActives();
2929  if (al && al->GetSize() > 0) {
2930  // Notify the name of those which did timeout
2931  Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2932  TIter nxs(al);
2933  TSocket *xs = 0;
2934  while ((xs = (TSocket *)nxs())) {
2935  TSlave *wrk = FindSlave(xs);
2936  if (wrk)
2937  Info("Collect"," %s", wrk->GetName());
2938  else
2939  Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2940  xs->GetInetAddress().GetPort());
2941  }
2942  }
2943  mon->DeActivateAll();
2944  }
2945 
2946  // Deactivate Ctrl-C special handler
2947  if (fIntHandler)
2948  fIntHandler->Remove();
2949 
2950  // make sure group view is up to date
2951  SendGroupView();
2952 
2953  // Restore redirection setting
2954  fRedirLog = saveRedirLog;
2955 
2956  // Restore the monitor
2957  fCurrentMonitor = savedMonitor;
2958 
2960 
2961  PDB(kCollect, 3)
2962  Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2963 
2964  return cnt;
2965 }
2966 
2967 ////////////////////////////////////////////////////////////////////////////////
2968 /// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2969 /// them. Returns the number of new workers found, or <0 on errors.
2970 
2972 {
2973  // Requests for worker updates
2974  Int_t dummy = 0;
2975  TList *reqWorkers = new TList();
2976  reqWorkers->SetOwner(kFALSE);
2977 
2978  if (!TestBit(TProof::kIsMaster)) {
2979  Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2980  return -1;
2981  }
2982  if (!gProofServ) {
2983  Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2984  return -1;
2985  }
2986 
2987  gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2988 
2989  // List of new workers only (TProofNodeInfo)
2990  TList *newWorkers = new TList();
2991  newWorkers->SetOwner(kTRUE);
2992 
2993  TIter next(reqWorkers);
2994  TProofNodeInfo *ni;
2995  TString fullOrd;
2996  while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2997 
2998  // Form the full ordinal
2999  fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
3000 
3001  TIter nextInner(fSlaves);
3002  TSlave *sl;
3003  Bool_t found = kFALSE;
3004  while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
3005  if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
3006  found = kTRUE;
3007  break;
3008  }
3009  }
3010 
3011  if (found) delete ni;
3012  else {
3013  newWorkers->Add(ni);
3014  PDB(kGlobal, 1)
3015  Info("PollForNewWorkers", "New worker found: %s:%s",
3016  ni->GetNodeName().Data(), fullOrd.Data());
3017  }
3018  }
3019 
3020  delete reqWorkers; // not owner
3021 
3022  Int_t nNewWorkers = newWorkers->GetEntries();
3023 
3024  // Add the new workers
3025  if (nNewWorkers > 0) {
3026  PDB(kGlobal, 1)
3027  Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
3028  Int_t rv = AddWorkers(newWorkers);
3029  if (rv < 0) {
3030  Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3031  return -1;
3032  }
3033  // Don't delete newWorkers: AddWorkers() will do that
3034  }
3035  else {
3036  PDB(kGlobal, 2)
3037  Info("PollForNewWorkers", "No new worker found");
3038  delete newWorkers;
3039  }
3040 
3041  return nNewWorkers;
3042 }
3043 
3044 ////////////////////////////////////////////////////////////////////////////////
3045 /// Remove links to objects in list 'ol' from gDirectory
3046 
3048 {
3049  if (ol) {
3050  TIter nxo(ol);
3051  TObject *o = 0;
3052  while ((o = nxo()))
3053  gDirectory->RecursiveRemove(o);
3054  }
3055 }
3056 
3057 ////////////////////////////////////////////////////////////////////////////////
3058 /// Collect and analyze available input from socket s.
3059 /// Returns 0 on success, -1 if any failure occurs.
3060 
3062 {
3063  TMessage *mess;
3064 
3065  Int_t recvrc = 0;
3066  if ((recvrc = s->Recv(mess)) < 0) {
3067  PDB(kCollect,2)
3068  Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3069  Bool_t bad = kTRUE;
3070  if (recvrc == -5) {
3071  // Broken connection: try reconnection
3073  if (s->Reconnect() == 0) {
3075  bad = kFALSE;
3076  }
3077  }
3078  if (bad)
3079  MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3080  // Ignore this wake up
3081  return -1;
3082  }
3083  if (!mess) {
3084  // we get here in case the remote server died
3085  MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3086  return -1;
3087  }
3088  Int_t rc = 0;
3089 
3090  Int_t what = mess->What();
3091  TSlave *sl = FindSlave(s);
3092  rc = HandleInputMessage(sl, mess, deactonfail);
3093  if (rc == 1 && (endtype >= 0) && (what != endtype))
3094  // This message was for the base monitor in recursive case
3095  rc = 2;
3096 
3097  // We are done successfully
3098  return rc;
3099 }
3100 
3101 ////////////////////////////////////////////////////////////////////////////////
3102 /// Analyze the received message.
3103 /// Returns 0 on success (1 if this the last message from this socket), -1 if
3104 /// any failure occurs.
3105 
3107 {
3108  char str[512];
3109  TObject *obj;
3110  Int_t rc = 0;
3111 
3112  if (!mess || !sl) {
3113  Warning("HandleInputMessage", "given an empty message or undefined worker");
3114  return -1;
3115  }
3116  Bool_t delete_mess = kTRUE;
3117  TSocket *s = sl->GetSocket();
3118  if (!s) {
3119  Warning("HandleInputMessage", "worker socket is undefined");
3120  return -1;
3121  }
3122 
3123  // The message type
3124  Int_t what = mess->What();
3125 
3126  PDB(kCollect,3)
3127  Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3128 
3129  switch (what) {
3130 
3131  case kMESS_OK:
3132  // Add the message to the list
3133  fRecvMessages->Add(mess);
3134  delete_mess = kFALSE;
3135  break;
3136 
3137  case kMESS_OBJECT:
3138  if (fPlayer) fPlayer->HandleRecvHisto(mess);
3139  break;
3140 
3141  case kPROOF_FATAL:
3142  { TString msg;
3143  if ((mess->BufferSize() > mess->Length()))
3144  (*mess) >> msg;
3145  if (msg.IsNull()) {
3146  MarkBad(s, "received kPROOF_FATAL");
3147  } else {
3148  MarkBad(s, msg);
3149  }
3150  }
3151  if (fProgressDialogStarted) {
3152  // Finalize the progress dialog
3153  Emit("StopProcess(Bool_t)", kTRUE);
3154  }
3155  break;
3156 
3157  case kPROOF_STOP:
3158  // Stop collection from this worker
3159  Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3160  sl->GetOrdinal());
3161  rc = 1;
3162  break;
3163 
3164  case kPROOF_GETTREEHEADER:
3165  // Add the message to the list
3166  fRecvMessages->Add(mess);
3167  delete_mess = kFALSE;
3168  rc = 1;
3169  break;
3170 
3171  case kPROOF_TOUCH:
3172  // send a request for touching the remote admin file
3173  {
3174  sl->Touch();
3175  }
3176  break;
3177 
3178  case kPROOF_GETOBJECT:
3179  // send slave object it asks for
3180  mess->ReadString(str, sizeof(str));
3181  obj = gDirectory->Get(str);
3182  if (obj)
3183  s->SendObject(obj);
3184  else
3185  s->Send(kMESS_NOTOK);
3186  break;
3187 
3188  case kPROOF_GETPACKET:
3189  {
3190  PDB(kGlobal,2)
3191  Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3192  TDSetElement *elem = 0;
3193  elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3194 
3195  if (elem != (TDSetElement*) -1) {
3196  TMessage answ(kPROOF_GETPACKET);
3197  answ << elem;
3198  s->Send(answ);
3199 
3200  while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3201  TPair *p = (TPair*) fWaitingSlaves->First();
3202  s = (TSocket*) p->Key();
3203  TMessage *m = (TMessage*) p->Value();
3204 
3205  elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3206  if (elem != (TDSetElement*) -1) {
3208  a << elem;
3209  s->Send(a);
3210  // remove has to happen via Links because TPair does not have
3211  // a Compare() function and therefore RemoveFirst() and
3212  // Remove(TObject*) do not work
3214  delete p;
3215  delete m;
3216  } else {
3217  break;
3218  }
3219  }
3220  } else {
3221  if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3222  fWaitingSlaves->Add(new TPair(s, mess));
3223  delete_mess = kFALSE;
3224  }
3225  }
3226  break;
3227 
3228  case kPROOF_LOGFILE:
3229  {
3230  Int_t size;
3231  (*mess) >> size;
3232  PDB(kGlobal,2)
3233  Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3234  RecvLogFile(s, size);
3235  }
3236  break;
3237 
3238  case kPROOF_LOGDONE:
3239  (*mess) >> sl->fStatus >> sl->fParallel;
3240  PDB(kCollect,2)
3241  Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3242  sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3243  if (sl->fStatus != 0) {
3244  // Return last nonzero status
3245  fStatus = sl->fStatus;
3246  // Deactivate the worker, if required
3247  if (deactonfail) DeactivateWorker(sl->fOrdinal);
3248  }
3249  // Remove from the workers-ready list
3252  fWrksOutputReady->Remove(sl);
3253  }
3254  rc = 1;
3255  break;
3256 
3257  case kPROOF_GETSTATS:
3258  {
3259  (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3260  >> sl->fWorkDir >> sl->fProofWorkDir;
3261  PDB(kCollect,2)
3262  Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3263  TString img;
3264  if ((mess->BufferSize() > mess->Length()))
3265  (*mess) >> img;
3266  // Set image
3267  if (img.IsNull()) {
3268  if (sl->fImage.IsNull())
3269  sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3270  sl->fProofWorkDir.Data());
3271  } else {
3272  sl->fImage = img;
3273  }
3274  PDB(kGlobal,2)
3275  Info("HandleInputMessage",
3276  "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3277 
3278  fBytesRead += sl->fBytesRead;
3279  fRealTime += sl->fRealTime;
3280  fCpuTime += sl->fCpuTime;
3281  rc = 1;
3282  }
3283  break;
3284 
3285  case kPROOF_GETPARALLEL:
3286  {
3287  Bool_t async = kFALSE;
3288  (*mess) >> sl->fParallel;
3289  if ((mess->BufferSize() > mess->Length()))
3290  (*mess) >> async;
3291  rc = (async) ? 0 : 1;
3292  }
3293  break;
3294 
3295  case kPROOF_CHECKFILE:
3296  { // New servers (>= 5.22) send the status
3297  if ((mess->BufferSize() > mess->Length())) {
3298  (*mess) >> fCheckFileStatus;
3299  } else {
3300  // Form old servers this meant success (failure was signaled with the
3301  // dangerous kPROOF_FATAL)
3302  fCheckFileStatus = 1;
3303  }
3304  rc = 1;
3305  }
3306  break;
3307 
3308  case kPROOF_SENDFILE:
3309  { // New server: signals ending of sendfile operation
3310  rc = 1;
3311  }
3312  break;
3313 
3314  case kPROOF_PACKAGE_LIST:
3315  {
3316  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3317  Int_t type = 0;
3318  (*mess) >> type;
3319  switch (type) {
3323  if (fEnabledPackages) {
3325  } else {
3326  Error("HandleInputMessage",
3327  "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3328  }
3329  break;
3330  case TProof::kListPackages:
3333  if (fAvailablePackages) {
3335  } else {
3336  Error("HandleInputMessage",
3337  "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3338  }
3339  break;
3340  default:
3341  Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3342  }
3343  }
3344  break;
3345 
3346  case kPROOF_SENDOUTPUT:
3347  {
3348  // We start measuring the merging time
3349  fPlayer->SetMerging();
3350 
3351  // Worker is ready to send output: make sure the relevant bit is reset
3353  PDB(kGlobal,2)
3354  Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3355  // Create the list if not yet done
3356  if (!fWrksOutputReady) {
3357  fWrksOutputReady = new TList;
3359  }
3360  fWrksOutputReady->Add(sl);
3361  }
3362  break;
3363 
3364  case kPROOF_OUTPUTOBJECT:
3365  {
3366  // We start measuring the merging time
3367  fPlayer->SetMerging();
3368 
3369  PDB(kGlobal,2)
3370  Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3371  Int_t type = 0;
3372  const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3374  Info("HandleInputMessage", "finalization on %s started ...", prefix);
3376  }
3377 
3378  while ((mess->BufferSize() > mess->Length())) {
3379  (*mess) >> type;
3380  // If a query result header, add it to the player list
3381  if (fPlayer) {
3382  if (type == 0) {
3383  // Retrieve query result instance (output list not filled)
3384  TQueryResult *pq =
3386  if (pq) {
3387  // Add query to the result list in TProofPlayer
3388  fPlayer->AddQueryResult(pq);
3389  fPlayer->SetCurrentQuery(pq);
3390  // And clear the output list, as we start merging a new set of results
3391  if (fPlayer->GetOutputList())
3392  fPlayer->GetOutputList()->Clear();
3393  // Add the unique query tag as TNamed object to the input list
3394  // so that it is available in TSelectors for monitoring
3395  TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3396  if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3397  fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3398  fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3399  } else {
3400  Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3401  }
3402  } else if (type > 0) {
3403  // Read object
3404  TObject *o = mess->ReadObject(TObject::Class());
3405  // Increment counter on the client side
3407  TString msg;
3408  Bool_t changed = kFALSE;
3409  msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3410  if (gProofServ) {
3412  } else if (IsTty() || changed) {
3413  fprintf(stderr, "%s\r", msg.Data());
3414  }
3415  // Add or merge it
3416  if ((fPlayer->AddOutputObject(o) == 1)) {
3417  // Remove the object if it has been merged
3418  SafeDelete(o);
3419  }
3420  if (type > 1) {
3421  // Update the merger progress info
3423  if (TestBit(TProof::kIsClient) && !IsLite()) {
3424  // In PROOFLite this has to be done once only in TProofLite::Process
3426  if (pq) {
3428  // Add input objects (do not override remote settings, if any)
3429  TObject *xo = 0;
3430  TIter nxin(fPlayer->GetInputList());
3431  // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3432  if (!pq->GetInputList()) pq->SetInputList(new TList());
3433  while ((xo = nxin()))
3434  if (!pq->GetInputList()->FindObject(xo->GetName()))
3435  pq->AddInput(xo->Clone());
3436  // If the last object, notify the GUI that the result arrived
3437  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3438  }
3439  // Processing is over
3440  UpdateDialog();
3441  }
3442  }
3443  }
3444  } else {
3445  Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3446  }
3447  }
3448  }
3449  break;
3450 
3451  case kPROOF_OUTPUTLIST:
3452  {
3453  // We start measuring the merging time
3454  fPlayer->SetMerging();
3455 
3456  PDB(kGlobal,2)
3457  Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3458  TList *out = 0;
3459  if (fPlayer) {
3460  if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3461  out = (TList *) mess->ReadObject(TList::Class());
3462  } else {
3463  TQueryResult *pq =
3465  if (pq) {
3466  // Add query to the result list in TProofPlayer
3467  fPlayer->AddQueryResult(pq);
3468  fPlayer->SetCurrentQuery(pq);
3469  // To avoid accidental cleanups from anywhere else
3470  // remove objects from gDirectory and clone the list
3471  out = pq->GetOutputList();
3472  CleanGDirectory(out);
3473  out = (TList *) out->Clone();
3474  // Notify the GUI that the result arrived
3475  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3476  } else {
3477  PDB(kGlobal,2)
3478  Info("HandleInputMessage",
3479  "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3480  }
3481  }
3482  if (out) {
3483  out->SetOwner();
3484  fPlayer->AddOutput(out); // Incorporate the list
3485  SafeDelete(out);
3486  } else {
3487  PDB(kGlobal,2)
3488  Info("HandleInputMessage",
3489  "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3490  }
3491  } else {
3492  Warning("HandleInputMessage",
3493  "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3494  }
3495  // On clients at this point processing is over
3496  if (TestBit(TProof::kIsClient) && !IsLite())
3497  UpdateDialog();
3498  }
3499  break;
3500 
3501  case kPROOF_QUERYLIST:
3502  {
3503  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3504  (*mess) >> fOtherQueries >> fDrawQueries;
3505  if (fQueries) {
3506  fQueries->Delete();
3507  delete fQueries;
3508  fQueries = 0;
3509  }
3510  fQueries = (TList *) mess->ReadObject(TList::Class());
3511  }
3512  break;
3513 
3514  case kPROOF_RETRIEVE:
3515  {
3516  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3517  TQueryResult *pq =
3519  if (pq && fPlayer) {
3520  fPlayer->AddQueryResult(pq);
3521  // Notify the GUI that the result arrived
3522  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3523  } else {
3524  PDB(kGlobal,2)
3525  Info("HandleInputMessage",
3526  "kPROOF_RETRIEVE: query result missing or player undefined");
3527  }
3528  }
3529  break;
3530 
3531  case kPROOF_MAXQUERIES:
3532  {
3533  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3534  Int_t max = 0;
3535 
3536  (*mess) >> max;
3537  Printf("Number of queries fully kept remotely: %d", max);
3538  }
3539  break;
3540 
3541  case kPROOF_SERVERSTARTED:
3542  {
3543  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3544 
3545  UInt_t tot = 0, done = 0;
3546  TString action;
3547  Bool_t st = kTRUE;
3548 
3549  (*mess) >> action >> tot >> done >> st;
3550 
3551  if (TestBit(TProof::kIsClient)) {
3552  if (tot) {
3553  TString type = (action.Contains("submas")) ? "submasters"
3554  : "workers";
3555  Int_t frac = (Int_t) (done*100.)/tot;
3556  char msg[512] = {0};
3557  if (frac >= 100) {
3558  snprintf(msg, 512, "%s: OK (%d %s) \n",
3559  action.Data(),tot, type.Data());
3560  } else {
3561  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3562  action.Data(), done, tot, frac);
3563  }
3564  if (fSync)
3565  fprintf(stderr,"%s", msg);
3566  else
3567  NotifyLogMsg(msg, 0);
3568  }
3569  // Notify GUIs
3570  StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3571  } else {
3572 
3573  // Just send the message one level up
3575  m << action << tot << done << st;
3576  gProofServ->GetSocket()->Send(m);
3577  }
3578  }
3579  break;
3580 
3581  case kPROOF_DATASET_STATUS:
3582  {
3583  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3584 
3585  UInt_t tot = 0, done = 0;
3586  TString action;
3587  Bool_t st = kTRUE;
3588 
3589  (*mess) >> action >> tot >> done >> st;
3590 
3591  if (TestBit(TProof::kIsClient)) {
3592  if (tot) {
3593  TString type = "files";
3594  Int_t frac = (Int_t) (done*100.)/tot;
3595  char msg[512] = {0};
3596  if (frac >= 100) {
3597  snprintf(msg, 512, "%s: OK (%d %s) \n",
3598  action.Data(),tot, type.Data());
3599  } else {
3600  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3601  action.Data(), done, tot, frac);
3602  }
3603  if (fSync)
3604  fprintf(stderr,"%s", msg);
3605  else
3606  NotifyLogMsg(msg, 0);
3607  }
3608  // Notify GUIs
3609  DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3610  } else {
3611 
3612  // Just send the message one level up
3614  m << action << tot << done << st;
3615  gProofServ->GetSocket()->Send(m);
3616  }
3617  }
3618  break;
3619 
3620  case kPROOF_STARTPROCESS:
3621  {
3622  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3623 
3624  // For Proof-Lite this variable is the number of workers and is set
3625  // by the player
3626  if (!IsLite()) {
3627  fNotIdle = 1;
3628  fIsWaiting = kFALSE;
3629  }
3630 
3631  // Redirect the output, if needed
3632  fRedirLog = (fSync) ? fRedirLog : kTRUE;
3633 
3634  // The signal is used on masters by XrdProofdProtocol to catch
3635  // the start of processing; on clients it allows to update the
3636  // progress dialog
3637  if (!TestBit(TProof::kIsMaster)) {
3638 
3639  // This is the end of preparation
3640  fQuerySTW.Stop();
3642  PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3643 
3644  TString selec;
3645  Int_t dsz = -1;
3646  Long64_t first = -1, nent = -1;
3647  (*mess) >> selec >> dsz >> first >> nent;
3648  // Start or reset the progress dialog
3649  if (!gROOT->IsBatch()) {
3650  if (fProgressDialog &&
3652  if (!fProgressDialogStarted) {
3653  fProgressDialog->ExecPlugin(5, this,
3654  selec.Data(), dsz, first, nent);
3656  } else {
3657  ResetProgressDialog(selec, dsz, first, nent);
3658  }
3659  }
3661  }
3662  }
3663  }
3664  break;
3665 
3666  case kPROOF_ENDINIT:
3667  {
3668  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3669 
3670  if (TestBit(TProof::kIsMaster)) {
3671  if (fPlayer)
3672  fPlayer->SetInitTime();
3673  }
3674  }
3675  break;
3676 
3677  case kPROOF_SETIDLE:
3678  {
3679  PDB(kGlobal,2)
3680  Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3681 
3682  // The session is idle
3683  if (IsLite()) {
3684  if (fNotIdle > 0) {
3685  fNotIdle--;
3686  PDB(kGlobal,2)
3687  Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3688  } else {
3689  Warning("HandleInputMessage",
3690  "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3691  sl->GetOrdinal());
3692  }
3693  } else {
3694  fNotIdle = 0;
3695  // Check if the query has been enqueued
3696  if ((mess->BufferSize() > mess->Length()))
3697  (*mess) >> fIsWaiting;
3698  }
3699  }
3700  break;
3701 
3702  case kPROOF_QUERYSUBMITTED:
3703  {
3704  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3705 
3706  // We have received the sequential number
3707  (*mess) >> fSeqNum;
3708  Bool_t sync = fSync;
3709  if ((mess->BufferSize() > mess->Length()))
3710  (*mess) >> sync;
3711  if (sync != fSync && fSync) {
3712  // The server required to switch to asynchronous mode
3713  Activate();
3714  fSync = kFALSE;
3715  }
3716  DisableGoAsyn();
3717  // Check if the query has been enqueued
3718  fIsWaiting = kTRUE;
3719  // For Proof-Lite this variable is the number of workers and is set by the player
3720  if (!IsLite())
3721  fNotIdle = 1;
3722 
3723  rc = 1;
3724  }
3725  break;
3726 
3727  case kPROOF_SESSIONTAG:
3728  {
3729  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3730 
3731  // We have received the unique tag and save it as name of this object
3732  TString stag;
3733  (*mess) >> stag;
3734  SetName(stag);
3735  // In the TSlave object
3736  sl->SetSessionTag(stag);
3737  // Server may have also sent the group
3738  if ((mess->BufferSize() > mess->Length()))
3739  (*mess) >> fGroup;
3740  // Server may have also sent the user
3741  if ((mess->BufferSize() > mess->Length())) {
3742  TString usr;
3743  (*mess) >> usr;
3744  if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3745  }
3746  }
3747  break;
3748 
3749  case kPROOF_FEEDBACK:
3750  {
3751  PDB(kGlobal,2)
3752  Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3753  TList *out = (TList *) mess->ReadObject(TList::Class());
3754  out->SetOwner();
3755  if (fPlayer)
3756  fPlayer->StoreFeedback(sl, out); // Adopts the list
3757  else
3758  // Not yet ready: stop collect asap
3759  rc = 1;
3760  }
3761  break;
3762 
3763  case kPROOF_AUTOBIN:
3764  {
3765  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3766 
3767  TString name;
3768  Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3769 
3770  (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3771 
3772  if (fPlayer) fPlayer->UpdateAutoBin(name,xmin,xmax,ymin,ymax,zmin,zmax);
3773 
3774  TMessage answ(kPROOF_AUTOBIN);
3775 
3776  answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3777 
3778  s->Send(answ);
3779  }
3780  break;
3781 
3782  case kPROOF_PROGRESS:
3783  {
3784  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3785 
3786  if (GetRemoteProtocol() > 25) {
3787  // New format
3788  TProofProgressInfo *pi = 0;
3789  (*mess) >> pi;
3790  fPlayer->Progress(sl,pi);
3791  } else if (GetRemoteProtocol() > 11) {
3792  Long64_t total, processed, bytesread;
3793  Float_t initTime, procTime, evtrti, mbrti;
3794  (*mess) >> total >> processed >> bytesread
3795  >> initTime >> procTime
3796  >> evtrti >> mbrti;
3797  if (fPlayer)
3798  fPlayer->Progress(sl, total, processed, bytesread,
3799  initTime, procTime, evtrti, mbrti);
3800 
3801  } else {
3802  // Old format
3803  Long64_t total, processed;
3804  (*mess) >> total >> processed;
3805  if (fPlayer)
3806  fPlayer->Progress(sl, total, processed);
3807  }
3808  }
3809  break;
3810 
3811  case kPROOF_STOPPROCESS:
3812  {
3813  // This message is sent from a worker that finished processing.
3814  // We determine whether it was asked to finish by the
3815  // packetizer or stopped during processing a packet
3816  // (by TProof::RemoveWorkers() or by an external signal).
3817  // In the later case call packetizer->MarkBad.
3818  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3819 
3820  Long64_t events = 0;
3821  Bool_t abort = kFALSE;
3823 
3824  if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3825  (*mess) >> status >> abort;
3826  } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3827  (*mess) >> events >> abort;
3828  } else {
3829  (*mess) >> events;
3830  }
3831  if (fPlayer) {
3832  if (fProtocol > 18) {
3833  TList *listOfMissingFiles = 0;
3834  if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3835  listOfMissingFiles = new TList();
3836  listOfMissingFiles->SetName("MissingFiles");
3837  if (fPlayer)
3838  fPlayer->AddOutputObject(listOfMissingFiles);
3839  }
3840  if (fPlayer->GetPacketizer()) {
3841  Int_t ret =
3842  fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3843  if (ret > 0)
3844  fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3845  // This object is now owned by the packetizer
3846  status = 0;
3847  }
3848  if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3849  } else {
3850  fPlayer->AddEventsProcessed(events);
3851  }
3852  }
3853  SafeDelete(status);
3854  if (!TestBit(TProof::kIsMaster))
3855  Emit("StopProcess(Bool_t)", abort);
3856  break;
3857  }
3858 
3859  case kPROOF_SUBMERGER:
3860  {
3861  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3862  HandleSubmerger(mess, sl);
3863  }
3864  break;
3865 
3866  case kPROOF_GETSLAVEINFO:
3867  {
3868  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3869 
3870  Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3871  Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3872  TList* tmpinfo = 0;
3873  (*mess) >> tmpinfo;
3874  if (tmpinfo == 0) {
3875  Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3876  } else {
3877  tmpinfo->SetOwner(kFALSE);
3878  Int_t nentries = tmpinfo->GetSize();
3879  for (Int_t i=0; i<nentries; i++) {
3880  TSlaveInfo* slinfo =
3881  dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3882  if (slinfo) {
3883  // If PROOF-Lite
3884  if (IsLite()) slinfo->fHostName = gSystem->HostName();
3885  // Check if we have already a instance for this worker
3886  TIter nxw(fSlaveInfo);
3887  TSlaveInfo *ourwi = 0;
3888  while ((ourwi = (TSlaveInfo *)nxw())) {
3889  if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3890  ourwi->SetSysInfo(slinfo->GetSysInfo());
3891  ourwi->fHostName = slinfo->GetName();
3892  if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3893  ourwi->fDataDir = slinfo->GetDataDir();
3894  break;
3895  }
3896  }
3897  if (!ourwi) {
3898  fSlaveInfo->Add(slinfo);
3899  } else {
3900  slinfo = ourwi;
3901  }
3902  if (slinfo->fStatus != TSlaveInfo::kBad) {
3903  if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3904  if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3905  }
3906  if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3907  slinfo->fMsd = sl->GetMsd();
3908  }
3909  }
3910  delete tmpinfo;
3911  rc = 1;
3912  }
3913  }
3914  break;
3915 
3916  case kPROOF_VALIDATE_DSET:
3917  {
3918  PDB(kGlobal,2)
3919  Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3920  TDSet* dset = 0;
3921  (*mess) >> dset;
3922  if (!fDSet)
3923  Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3924  else
3925  fDSet->Validate(dset);
3926  delete dset;
3927  }
3928  break;
3929 
3930  case kPROOF_DATA_READY:
3931  {
3932  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3933  Bool_t dataready = kFALSE;
3934  Long64_t totalbytes, bytesready;
3935  (*mess) >> dataready >> totalbytes >> bytesready;
3936  fTotalBytes += totalbytes;
3937  fBytesReady += bytesready;
3938  if (dataready == kFALSE) fDataReady = dataready;
3939  }
3940  break;
3941 
3942  case kPROOF_PING:
3943  // do nothing (ping is already acknowledged)
3944  break;
3945 
3946  case kPROOF_MESSAGE:
3947  {
3948  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3949 
3950  // We have received the unique tag and save it as name of this object
3951  TString msg;
3952  (*mess) >> msg;
3953  Bool_t lfeed = kTRUE;
3954  if ((mess->BufferSize() > mess->Length()))
3955  (*mess) >> lfeed;
3956 
3957  if (TestBit(TProof::kIsClient)) {
3958 
3959  if (fSync) {
3960  // Notify locally
3961  fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3962  } else {
3963  // Notify locally taking care of redirection, windows logs, ...
3964  NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3965  }
3966  } else {
3967 
3968  // The message is logged for debugging purposes.
3969  fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3970  if (gProofServ) {
3971  // We hide it during normal operations
3973 
3974  // And send the message one level up
3975  gProofServ->SendAsynMessage(msg, lfeed);
3976  }
3977  }
3978  }
3979  break;
3980 
3981  case kPROOF_VERSARCHCOMP:
3982  {
3983  TString vac;
3984  (*mess) >> vac;
3985  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3986  Int_t from = 0;
3987  TString vers, archcomp;
3988  if (vac.Tokenize(vers, from, "|"))
3989  vac.Tokenize(archcomp, from, "|");
3990  sl->SetArchCompiler(archcomp);
3991  vers.ReplaceAll(":","|");
3992  sl->SetROOTVersion(vers);
3993  }
3994  break;
3995 
3996  default:
3997  {
3998  Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3999  sl->GetOrdinal(), what);
4000  }
4001  break;
4002  }
4003 
4004  // Cleanup
4005  if (delete_mess)
4006  delete mess;
4007 
4008  // We are done successfully
4009  return rc;
4010 }
4011 
4012 ////////////////////////////////////////////////////////////////////////////////
4013 /// Process a message of type kPROOF_SUBMERGER
4014 
4016 {
4017  // Message sub-type
4018  Int_t type = 0;
4019  (*mess) >> type;
4020  TSocket *s = sl->GetSocket();
4021 
4022  switch (type) {
4023  case kOutputSent:
4024  {
4025  if (IsEndMaster()) {
4026  Int_t merger_id = -1;
4027  (*mess) >> merger_id;
4028 
4029  PDB(kSubmerger, 2)
4030  Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4031  sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4032 
4033  if (!fMergers || fMergers->GetSize() <= merger_id) {
4034  Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4035  break;
4036  }
4037  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4038  mi->SetMergedWorker();
4039  if (mi->AreAllWorkersMerged()) {
4040  mi->Deactivate();
4041  if (GetActiveMergersCount() == 0) {
4042  fMergers->Clear();
4043  delete fMergers;
4044  fMergersSet = kFALSE;
4045  fMergersCount = -1;
4046  fLastAssignedMerger = 0;
4047  PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4048  }
4049  }
4050  } else {
4051  PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4052  }
4053  }
4054  break;
4055 
4056  case kMergerDown:
4057  {
4058  Int_t merger_id = -1;
4059  (*mess) >> merger_id;
4060 
4061  PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4062 
4063  if (!fMergers || fMergers->GetSize() <= merger_id) {
4064  Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4065  break;
4066  }
4067 
4068  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4069  if (!mi->IsActive()) {
4070  break;
4071  } else {
4072  mi->Deactivate();
4073  }
4074 
4075  // Stop the invalid merger in the case it is still listening
4076  TMessage stop(kPROOF_SUBMERGER);
4077  stop << Int_t(kStopMerging);
4078  stop << 0;
4079  s->Send(stop);
4080 
4081  // Ask for results from merger (only original results from this node as worker are returned)
4082  AskForOutput(mi->GetMerger());
4083 
4084  // Ask for results from all workers assigned to this merger
4085  TIter nxo(mi->GetWorkers());
4086  TObject * o = 0;
4087  while ((o = nxo())) {
4088  AskForOutput((TSlave *)o);
4089  }
4090  PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4091  }
4092  break;
4093 
4094  case kOutputSize:
4095  {
4096  if (IsEndMaster()) {
4097  PDB(kSubmerger, 2)
4098  Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4099 
4100  const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4101  if (!fFinalizationRunning) {
4102  Info("HandleSubmerger", "finalization on %s started ...", prefix);
4104  }
4105 
4106  Int_t output_size = 0;
4107  Int_t merging_port = 0;
4108  (*mess) >> output_size >> merging_port;
4109 
4110  PDB(kSubmerger, 2) Info("HandleSubmerger",
4111  "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4112  sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4113  TString msg;
4114  if (!fMergersSet) {
4115 
4117 
4118  // First pass - setting number of mergers according to user or dynamically
4119  fMergersCount = -1; // No mergers used if not set by user
4120  TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4121  if (mc) fMergersCount = mc->GetVal(); // Value set by user
4122  TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4123  if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4124 
4125  // Mergers count specified by user but not valid
4126  if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4127  msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4128  prefix, fMergersCount, activeWorkers);
4129  if (gProofServ)
4131  else
4132  Printf("%s",msg.Data());
4133  fMergersCount = 0;
4134  }
4135  // Mergers count will be set dynamically
4136  if ((fMergersCount == 0) && (!fMergersByHost)) {
4137  if (activeWorkers > 1) {
4138  fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4139  if (activeWorkers / fMergersCount < 2)
4140  fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4141  }
4142  if (fMergersCount > 1)
4143  msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4144  prefix, fMergersCount, activeWorkers);
4145  else {
4146  msg.Form("%s: No mergers will be used for %d workers",
4147  prefix, activeWorkers);
4148  fMergersCount = -1;
4149  }
4150  if (gProofServ)
4152  else
4153  Printf("%s",msg.Data());
4154  } else if (fMergersByHost) {
4155  // We force mergers at host level to minimize network traffic
4156  if (activeWorkers > 1) {
4157  fMergersCount = 0;
4158  THashList hosts;
4159  TIter nxwk(fSlaves);
4160  TObject *wrk = 0;
4161  while ((wrk = nxwk())) {
4162  if (!hosts.FindObject(wrk->GetName())) {
4163  hosts.Add(new TObjString(wrk->GetName()));
4164  fMergersCount++;
4165  }
4166  }
4167  }
4168  if (fMergersCount > 1)
4169  msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4170  prefix, fMergersCount, activeWorkers);
4171  else {
4172  msg.Form("%s: No mergers will be used for %d workers",
4173  prefix, activeWorkers);
4174  fMergersCount = -1;
4175  }
4176  if (gProofServ)
4178  else
4179  Printf("%s",msg.Data());
4180  } else {
4181  msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4182  prefix, fMergersCount, activeWorkers);
4183  if (gProofServ)
4185  else
4186  Printf("%s",msg.Data());
4187  }
4188 
4189  // We started merging; we call it here because fMergersCount is still the original number
4190  // and can be saved internally
4192 
4193  // Update merger counters (new workers are not yet active)
4195 
4196  if (fMergersCount > 0) {
4197 
4198  fMergers = new TList();
4199  fLastAssignedMerger = 0;
4200  // Total number of workers, which will not act as mergers ('pure workers')
4201  fWorkersToMerge = (activeWorkers - fMergersCount);
4202  // Establish the first merger
4203  if (!CreateMerger(sl, merging_port)) {
4204  // Cannot establish first merger
4205  AskForOutput(sl);
4206  fWorkersToMerge--;
4207  fMergersCount--;
4208  }
4210  } else {
4211  AskForOutput(sl);
4212  }
4213  fMergersSet = kTRUE;
4214  } else {
4215  // Multiple pass
4216  if (fMergersCount == -1) {
4217  // No mergers. Workers send their outputs directly to master
4218  AskForOutput(sl);
4219  } else {
4220  if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4221  RedirectWorker(s, sl, output_size);
4222  fRedirectNext--;
4223  } else {
4224  Bool_t newMerger = kTRUE;
4225  if (fMergersByHost) {
4226  TIter nxmg(fMergers);
4227  TMergerInfo *mgi = 0;
4228  while ((mgi = (TMergerInfo *) nxmg())) {
4229  if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4230  newMerger = kFALSE;
4231  break;
4232  }
4233  }
4234  }
4235  if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4236  // Still not enough mergers established
4237  if (!CreateMerger(sl, merging_port)) {
4238  // Cannot establish a merger
4239  AskForOutput(sl);
4240  fWorkersToMerge--;
4241  fMergersCount--;
4242  }
4243  } else
4244  RedirectWorker(s, sl, output_size);
4245  }
4246  }
4247  }
4248  } else {
4249  Error("HandleSubMerger","kOutputSize received not on endmaster!");
4250  }
4251  }
4252  break;
4253  }
4254 }
4255 
4256 ////////////////////////////////////////////////////////////////////////////////
4257 /// Redirect output of worker sl to some merger
4258 
4259 void TProof::RedirectWorker(TSocket *s, TSlave * sl, Int_t output_size)
4260 {
4261  Int_t merger_id = -1;
4262 
4263  if (fMergersByHost) {
4264  for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4265  TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4266  if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4267  merger_id = i;
4268  break;
4269  }
4270  }
4271  } else {
4272  merger_id = FindNextFreeMerger();
4273  }
4274 
4275  if (merger_id == -1) {
4276  // No free merger (probably it had crashed before)
4277  AskForOutput(sl);
4278  } else {
4279  TMessage sendoutput(kPROOF_SUBMERGER);
4280  sendoutput << Int_t(kSendOutput);
4281  PDB(kSubmerger, 2)
4282  Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4283 
4284  PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4285  if (!fMergers || fMergers->GetSize() <= merger_id) {
4286  Error("RedirectWorker", "#%d not in list ", merger_id);
4287  return;
4288  }
4289  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4290 
4291  TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4292  sendoutput << merger_id;
4293  sendoutput << hname;
4294  sendoutput << mi->GetPort();
4295  s->Send(sendoutput);
4296  mi->AddMergedObjects(output_size);
4297  mi->AddWorker(sl);
4298  }
4299 }
4300 
4301 ////////////////////////////////////////////////////////////////////////////////
4302 /// Return a merger, which is both active and still accepts some workers to be
4303 /// assigned to it. It works on the 'round-robin' basis.
4304 
4306 {
4307  while (fLastAssignedMerger < fMergers->GetSize() &&
4308  (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4309  ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4311  }
4312 
4313  if (fLastAssignedMerger == fMergers->GetSize()) {
4314  fLastAssignedMerger = 0;
4315  } else {
4316  return fLastAssignedMerger++;
4317  }
4318 
4319  while (fLastAssignedMerger < fMergers->GetSize() &&
4320  (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4321  ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4323  }
4324 
4325  if (fLastAssignedMerger == fMergers->GetSize()) {
4326  return -1;
4327  } else {
4328  return fLastAssignedMerger++;
4329  }
4330 }
4331 
4332 ////////////////////////////////////////////////////////////////////////////////
4333 /// Master asks for output from worker sl
4334 
4336 {
4337  TMessage sendoutput(kPROOF_SUBMERGER);
4338  sendoutput << Int_t(kSendOutput);
4339 
4340  PDB(kSubmerger, 2) Info("AskForOutput",
4341  "worker %s was asked to send its output to master",
4342  sl->GetOrdinal());
4343 
4344  sendoutput << -1;
4345  sendoutput << TString("master");
4346  sendoutput << -1;
4347  sl->GetSocket()->Send(sendoutput);
4348  if (IsLite()) fMergePrg.IncreaseNWrks();
4349 }
4350 
4351 ////////////////////////////////////////////////////////////////////////////////
4352 /// Final update of the progress dialog
4353 
4355 {
4356  if (!fPlayer) return;
4357 
4358  // Handle abort ...
4360  if (fSync)
4361  Info("UpdateDialog",
4362  "processing was aborted - %lld events processed",
4364 
4365  if (GetRemoteProtocol() > 11) {
4366  // New format
4367  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4368  } else {
4370  }
4371  Emit("StopProcess(Bool_t)", kTRUE);
4372  }
4373 
4374  // Handle stop ...
4376  if (fSync)
4377  Info("UpdateDialog",
4378  "processing was stopped - %lld events processed",
4380 
4381  if (GetRemoteProtocol() > 25) {
4382  // New format
4383  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4384  } else if (GetRemoteProtocol() > 11) {
4385  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4386  } else {
4388  }
4389  Emit("StopProcess(Bool_t)", kFALSE);
4390  }
4391 
4392  // Final update of the dialog box
4393  if (GetRemoteProtocol() > 25) {
4394  // New format
4395  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4396  10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4397  (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4398  } else if (GetRemoteProtocol() > 11) {
4399  // New format
4400  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4401  7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4402  (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4403  } else {
4404  EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4405  }
4406 }
4407 
4408 ////////////////////////////////////////////////////////////////////////////////
4409 /// Activate the a-sync input handler.
4410 
4412 {
4413  TIter next(fSlaves);
4414  TSlave *sl;
4415 
4416  while ((sl = (TSlave*) next()))
4417  if (sl->GetInputHandler())
4418  sl->GetInputHandler()->Add();
4419 }
4420 
4421 ////////////////////////////////////////////////////////////////////////////////
4422 /// De-activate a-sync input handler.
4423 
4425 {
4426  TIter next(fSlaves);
4427  TSlave *sl;
4428 
4429  while ((sl = (TSlave*) next()))
4430  if (sl->GetInputHandler())
4431  sl->GetInputHandler()->Remove();
4432 }
4433 
4434 ////////////////////////////////////////////////////////////////////////////////
4435 /// Get the active mergers count
4436 
4438 {
4439  if (!fMergers) return 0;
4440 
4441  Int_t active_mergers = 0;
4442 
4443  TIter mergers(fMergers);
4444  TMergerInfo *mi = 0;
4445  while ((mi = (TMergerInfo *)mergers())) {
4446  if (mi->IsActive()) active_mergers++;
4447  }
4448 
4449  return active_mergers;
4450 }
4451 
4452 ////////////////////////////////////////////////////////////////////////////////
4453 /// Create a new merger
4454 
4456 {
4457  PDB(kSubmerger, 2)
4458  Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4459 
4460  PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4461 
4462  if (port <= 0) {
4463  PDB(kSubmerger,2)
4464  Info("CreateMerger", "cannot create merger on port %d - exit", port);
4465  return kFALSE;
4466  }
4467 
4468  Int_t workers = -1;
4469  if (!fMergersByHost) {
4470  Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4471  // Number of pure workers, which are not simply divisible by mergers
4472  Int_t rest = fWorkersToMerge % mergersToCreate;
4473  // We add one more worker for each of the first 'rest' mergers being established
4474  if (rest > 0 && fMergers->GetSize() < rest) {
4475  rest = 1;
4476  } else {
4477  rest = 0;
4478  }
4479  workers = (fWorkersToMerge / mergersToCreate) + rest;
4480  } else {
4481  Int_t workersOnHost = 0;
4482  for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4483  if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4484  }
4485  workers = workersOnHost - 1;
4486  }
4487 
4488  TString msg;
4489  msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4490 
4491  if (gProofServ) {
4493  } else {
4494  Printf("%s",msg.Data());
4495  }
4496  TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4497 
4498  TMessage bemerger(kPROOF_SUBMERGER);
4499  bemerger << Int_t(kBeMerger);
4500  bemerger << fMergers->GetSize();
4501  bemerger << workers;
4502  sl->GetSocket()->Send(bemerger);
4503 
4504  PDB(kSubmerger,2) Info("CreateMerger",
4505  "merger #%d (port: %d) for %d workers started",
4506  fMergers->GetSize(), port, workers);
4507 
4508  fMergers->Add(merger);
4509  fWorkersToMerge = fWorkersToMerge - workers;
4510 
4511  fRedirectNext = workers / 2;
4512 
4513  PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4514  return kTRUE;
4515 }
4516 
4517 ////////////////////////////////////////////////////////////////////////////////
4518 /// Add a bad slave server to the bad slave list and remove it from
4519 /// the active list and from the two monitor objects. Assume that the work
4520 /// done by this worker was lost and ask packerizer to reassign it.
4521 
4522 void TProof::MarkBad(TSlave *wrk, const char *reason)
4523 {
4524  std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4525 
4526  // We may have been invalidated in the meanwhile: nothing to do in such a case
4527  if (!IsValid()) return;
4528 
4529  if (!wrk) {
4530  Error("MarkBad", "worker instance undefined: protocol error? ");
4531  return;
4532  }
4533 
4534  // Local URL
4535  static TString thisurl;
4536  if (thisurl.IsNull()) {
4537  if (IsMaster()) {
4538  Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4539  thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4540  if (port > 0) thisurl += TString::Format(":%d", port);
4541  } else {
4542  thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4543  }
4544  }
4545 
4546  if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4547  // Message for notification
4548  const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4549  TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4550  TString msg;
4551  msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4552  src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4553  (reason && strlen(reason)) ? reason : "unknown");
4554  Info("MarkBad", "%s", msg.Data());
4555  // Notify one level up, if the case
4556  // Add some hint for diagnostics
4557  if (gProofServ) {
4558  msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4559  wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4560  } else {
4561  msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4562  }
4563  msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4564  msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4565  msg += TString::Format(" +++\n");
4566  if (gProofServ) {
4567  msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4568  "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4570  } else {
4571  msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4572  "Display(\"*\")\n\n", thisurl.Data());
4573  Printf("%s", msg.Data());
4574  }
4575  } else if (reason) {
4576  if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4577  Info("MarkBad", "worker %s at %s:%d asked to terminate",
4578  wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4579  }
4580  }
4581 
4582  if (IsMaster() && reason) {
4583  if (strcmp(reason, kPROOF_TerminateWorker)) {
4584  // if the reason was not a planned termination
4585  TList *listOfMissingFiles = 0;
4586  if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4587  listOfMissingFiles = new TList();
4588  listOfMissingFiles->SetName("MissingFiles");
4589  if (fPlayer)
4590  fPlayer->AddOutputObject(listOfMissingFiles);
4591  }
4592  // If a query is being processed, assume that the work done by
4593  // the worker was lost and needs to be reassigned.
4594  TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4595  if (packetizer) {
4596  // the worker was lost so do resubmit the packets
4597  packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4598  }
4599  } else {
4600  // Tell the coordinator that we are gone
4601  if (gProofServ) {
4602  TString ord(wrk->GetOrdinal());
4603  Int_t id = ord.Last('.');
4604  if (id != kNPOS) ord.Remove(0, id+1);
4605  gProofServ->ReleaseWorker(ord.Data());
4606  }
4607  }
4608  } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4609  // We are invalid after this
4610  fValid = kFALSE;
4611  }
4612 
4613  fActiveSlaves->Remove(wrk);
4614  FindUniqueSlaves();
4615 
4616  fAllMonitor->Remove(wrk->GetSocket());
4617  fActiveMonitor->Remove(wrk->GetSocket());
4618 
4620 
4621  if (IsMaster()) {
4622  if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4623  // if the reason was a planned termination then delete the worker and
4624  // remove it from all the lists
4625  fSlaves->Remove(wrk);
4626  fBadSlaves->Remove(wrk);
4627  fActiveSlaves->Remove(wrk);
4628  fInactiveSlaves->Remove(wrk);
4629  fUniqueSlaves->Remove(wrk);
4630  fAllUniqueSlaves->Remove(wrk);
4631  fNonUniqueMasters->Remove(wrk);
4632 
4633  // we add it to the list of terminated slave infos instead, so that it
4634  // stays available in the .workers persistent file
4635  TSlaveInfo *si = new TSlaveInfo(
4636  wrk->GetOrdinal(),
4637  Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4638  0, "", wrk->GetWorkDir());
4640  else delete si;
4641 
4642  delete wrk;
4643  } else {
4644  fBadSlaves->Add(wrk);
4645  fActiveSlaves->Remove(wrk);
4646  fUniqueSlaves->Remove(wrk);
4647  fAllUniqueSlaves->Remove(wrk);
4648  fNonUniqueMasters->Remove(wrk);
4650  wrk->Close();
4651  // Update the mergers count, if needed
4652  if (fMergersSet) {
4653  Int_t mergersCount = -1;
4654  TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4655  if (mc) mergersCount = mc->GetVal(); // Value set by user
4656  // Mergers count is set dynamically: recalculate it
4657  if (mergersCount == 0) {
4659  if (activeWorkers > 1) {
4660  fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4661  if (activeWorkers / fMergersCount < 2)
4662  fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4663  }
4664  }
4665  }
4666  }
4667 
4668  // Update session workers files
4669  SaveWorkerInfo();
4670  } else {
4671  // On clients the proof session should be removed from the lists
4672  // and deleted, since it is not valid anymore
4673  fSlaves->Remove(wrk);
4674  if (fManager)
4675  fManager->DiscardSession(this);
4676  }
4677 }
4678 
4679 ////////////////////////////////////////////////////////////////////////////////
4680 /// Add slave with socket s to the bad slave list and remove if from
4681 /// the active list and from the two monitor objects.
4682 
4683 void TProof::MarkBad(TSocket *s, const char *reason)
4684 {
4685  std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4686 
4687  // We may have been invalidated in the meanwhile: nothing to do in such a case
4688  if (!IsValid()) return;
4689 
4690  TSlave *wrk = FindSlave(s);
4691  MarkBad(wrk, reason);
4692 }
4693 
4694 ////////////////////////////////////////////////////////////////////////////////
4695 /// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4696 
4698 {
4699  if (!wrk) {
4700  Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4701  return;
4702  }
4703 
4704  // Send stop message
4705  if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4706  TMessage mess(kPROOF_STOP);
4707  wrk->GetSocket()->Send(mess);
4708  } else {
4709  if (gDebug > 0)
4710  Info("TerminateWorker", "connection to worker is already down: cannot"
4711  " send termination message");
4712  }
4713 
4714  // This is a bad worker from now on
4716 }
4717 
4718 ////////////////////////////////////////////////////////////////////////////////
4719 /// Ask an active worker 'ord' to terminate, i.e. to shutdown
4720 
4721 void TProof::TerminateWorker(const char *ord)
4722 {
4723  if (ord && strlen(ord) > 0) {
4724  Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4725  if (IsMaster()) {
4726  TIter nxw(fSlaves);
4727  TSlave *wrk = 0;
4728  while ((wrk = (TSlave *)nxw())) {
4729  if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4730  TerminateWorker(wrk);
4731  if (!all) break;
4732  }
4733  }
4734  } else {
4735  TMessage mess(kPROOF_STOP);
4736  mess << TString(ord);
4737  Broadcast(mess);
4738  }
4739  }
4740 }
4741 
4742 ////////////////////////////////////////////////////////////////////////////////
4743 /// Ping PROOF. Returns 1 if master server responded.
4744 
4746 {
4747  return Ping(kActive);
4748 }
4749 
4750 ////////////////////////////////////////////////////////////////////////////////
4751 /// Ping PROOF slaves. Returns the number of slaves that responded.
4752 
4754 {
4755  TList *slaves = 0;
4756  if (list == kAll) slaves = fSlaves;
4757  if (list == kActive) slaves = fActiveSlaves;
4758  if (list == kUnique) slaves = fUniqueSlaves;
4759  if (list == kAllUnique) slaves = fAllUniqueSlaves;
4760 
4761  if (slaves->GetSize() == 0) return 0;
4762 
4763  int nsent = 0;
4764  TIter next(slaves);
4765 
4766  TSlave *sl;
4767  while ((sl = (TSlave *)next())) {
4768  if (sl->IsValid()) {
4769  if (sl->Ping() == -1) {
4770  MarkBad(sl, "ping unsuccessful");
4771  } else {
4772  nsent++;
4773  }
4774  }
4775  }
4776 
4777  return nsent;
4778 }
4779 
4780 ////////////////////////////////////////////////////////////////////////////////
4781 /// Ping PROOF slaves. Returns the number of slaves that responded.
4782 
4784 {
4785  TList *slaves = fSlaves;
4786 
4787  if (slaves->GetSize() == 0) return;
4788 
4789  TIter next(slaves);
4790 
4791  TSlave *sl;
4792  while ((sl = (TSlave *)next())) {
4793  if (sl->IsValid()) {
4794  sl->Touch();
4795  }
4796  }
4797 
4798  return;
4799 }
4800 
4801 ////////////////////////////////////////////////////////////////////////////////
4802 /// Print status of PROOF cluster.
4803 
4804 void TProof::Print(Option_t *option) const
4805 {
4806  TString secCont;
4807 
4808  if (TestBit(TProof::kIsClient)) {
4809  Printf("Connected to: %s (%s)", GetMaster(),
4810  IsValid() ? "valid" : "invalid");
4811  Printf("Port number: %d", GetPort());
4812  Printf("User: %s", GetUser());
4813  Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4814  Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4816  TSlave *sl = (TSlave *)fActiveSlaves->First();
4817  if (sl) {
4818  TString sc;
4819  if (sl->GetSocket()->GetSecContext())
4820  Printf("Security context: %s",
4821  sl->GetSocket()->GetSecContext()->AsString(sc));
4822  Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4823  } else {
4824  Printf("Security context: Error - No connection");
4825  Printf("Proofd protocol version: Error - No connection");
4826  }
4827  Printf("Client protocol version: %d", GetClientProtocol());
4828  Printf("Remote protocol version: %d", GetRemoteProtocol());
4829  Printf("Log level: %d", GetLogLevel());
4830  Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4831  Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4832  if (IsValid())
4833  const_cast<TProof*>(this)->SendPrint(option);
4834  } else {
4835  const_cast<TProof*>(this)->AskStatistics();
4836  if (IsParallel())
4837  Printf("*** Master server %s (parallel mode, %d workers):",
4839  else
4840  Printf("*** Master server %s (sequential mode):",
4841  gProofServ->GetOrdinal());
4842 
4843  Printf("Master host name: %s", gSystem->HostName());
4844  Printf("Port number: %d", GetPort());
4845  if (strlen(gProofServ->GetGroup()) > 0) {
4846  Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4847  } else {
4848  Printf("User: %s", GetUser());
4849  }
4850  TString ver;
4851  ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4852  if (gSystem->Getenv("ROOTVERSIONTAG"))
4853  ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4854  Printf("ROOT version|rev|tag: %s", ver.Data());
4855  Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4857  Printf("Protocol version: %d", GetClientProtocol());
4858  Printf("Image name: %s", GetImage());
4859  Printf("Working directory: %s", gSystem->WorkingDirectory());
4860  Printf("Config directory: %s", GetConfDir());
4861  Printf("Config file: %s", GetConfFile());
4862  Printf("Log level: %d", GetLogLevel());
4863  Printf("Number of workers: %d", GetNumberOfSlaves());
4864  Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4865  Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4866  Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4867  Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4868  Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4869  Printf("Total real time used (s): %.3f", GetRealTime());
4870  Printf("Total CPU time used (s): %.3f", GetCpuTime());
4871  if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4872  Printf("List of workers:");
4873  TList masters;
4874  TIter nextslave(fSlaves);
4875  while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4876  if (!sl->IsValid()) continue;
4877 
4878  if (sl->GetSlaveType() == TSlave::kSlave) {
4879  sl->Print(option);
4880  } else if (sl->GetSlaveType() == TSlave::kMaster) {
4881  TMessage mess(kPROOF_PRINT);
4882  mess.WriteString(option);
4883  if (sl->GetSocket()->Send(mess) == -1)
4884  const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4885  else
4886  masters.Add(sl);
4887  } else {
4888  Error("Print", "TSlave is neither Master nor Worker");
4889  R__ASSERT(0);
4890  }
4891  }
4892  const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4893  }
4894  }
4895 }
4896 
4897 ////////////////////////////////////////////////////////////////////////////////
4898 /// Extract from opt information about output handling settings.
4899 /// The understood keywords are:
4900 /// of=<file>, outfile=<file> output file location
4901 /// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4902 /// mutually exclusive,execution stops
4903 /// if both are found)
4904 /// sft[=<opt>], savetofile[=<opt>] control saving to file
4905 ///
4906 /// For 'mvf', the <opt> integer has the following meaning:
4907 /// <opt> = <how>*10 + <force>
4908 /// <force> = 0 save to file if memory threshold is reached
4909 /// (the memory threshold is set by the cluster
4910 /// admin); in case an output file is defined, the
4911 /// files are merged at the end;
4912 /// 1 save results to file.
4913 /// <how> = 0 save at the end of the query
4914 /// 1 save results after each packet (to reduce the
4915 /// loss in case of crash).
4916 ///
4917 /// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4918 /// to save results after each packet.
4919 ///
4920 /// The separator from the next option is either a ' ' or a ';'
4921 ///
4922 /// All recognized settings are removed from the input string opt.
4923 /// If action == 0, set up the output file accordingly, if action == 1 clean related
4924 /// output file settings.
4925 /// If the final target file is local then 'target' is set to the final local path
4926 /// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4927 ///
4928 /// Output file settings are in the form
4929 ///
4930 /// <previous_option>of=name <next_option>
4931 /// <previous_option>outfile=name,...;<next_option>
4932 ///
4933 /// The separator from the next option is either a ' ' or a ';'
4934 /// Called interanally by TProof::Process.
4935 ///
4936 /// Returns 0 on success, -1 on error.
4937 
4939 {
4940  TString outfile, dsname, stfopt;
4941  if (action == 0) {
4942  TString tagf, tagd, tags, oo;
4943  Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4944  while (opt.Tokenize(oo, from, "[; ]")) {
4945  if (oo.BeginsWith("of=")) {
4946  tagf = "of=";
4947  iof = opt.Index(tagf);
4948  } else if (oo.BeginsWith("outfile=")) {
4949  tagf = "outfile=";
4950  iof = opt.Index(tagf);
4951  } else if (oo.BeginsWith("ds")) {
4952  tagd = "ds";
4953  iod = opt.Index(tagd);
4954  } else if (oo.BeginsWith("dataset")) {
4955  tagd = "dataset";
4956  iod = opt.Index(tagd);
4957  } else if (oo.BeginsWith("stf")) {
4958  tags = "stf";
4959  ios = opt.Index(tags);
4960  } else if (oo.BeginsWith("savetofile")) {
4961  tags = "savetofile";
4962  ios = opt.Index(tags);
4963  }
4964  }
4965  // Check consistency
4966  if (iof != kNPOS && iod != kNPOS) {
4967  Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4968  return -1;
4969  }
4970 
4971  // Check output file first
4972  if (iof != kNPOS) {
4973  from = iof + tagf.Length();
4974  if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4975  Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4976  return -1;
4977  }
4978  // For removal from original options string
4979  tagf += outfile;
4980  }
4981  // Check dataset
4982  if (iod != kNPOS) {
4983  from = iod + tagd.Length();
4984  if (!opt.Tokenize(dsname, from, "[; ]"))
4985  if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4986  // For removal from original options string
4987  tagd += dsname;
4988  // The name may be empty or beginning with a '='
4989  if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4990  if (dsname.Contains("|V")) {
4991  target = "ds|V";
4992  dsname.ReplaceAll("|V", "");
4993  }
4994  if (dsname.IsNull()) dsname = "dataset_<qtag>";
4995  }
4996  // Check stf
4997  if (ios != kNPOS) {
4998  from = ios + tags.Length();
4999  if (!opt.Tokenize(stfopt, from, "[; ]"))
5000  if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
5001  // For removal from original options string
5002  tags += stfopt;
5003  // It must be digit
5004  if (!stfopt.IsNull()) {
5005  if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
5006  if (!stfopt.IsNull()) {
5007  if (!stfopt.IsDigit()) {
5008  Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
5009  return -1;
5010  }
5011  } else {
5012  // Default
5013  stfopt = "1";
5014  }
5015  } else {
5016  // Default
5017  stfopt = "1";
5018  }
5019  }
5020  // Remove from original options string
5021  opt.ReplaceAll(tagf, "");
5022  opt.ReplaceAll(tagd, "");
5023  opt.ReplaceAll(tags, "");
5024  }
5025 
5026  // Parse now
5027  if (action == 0) {
5028  // Output file
5029  if (!outfile.IsNull()) {
5030  if (!outfile.BeginsWith("master:")) {
5032  Warning("HandleOutputOptions",
5033  "directory '%s' for the output file does not exists or is not writable:"
5034  " saving to master", gSystem->DirName(outfile.Data()));
5035  outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5036  } else {
5037  if (!IsLite()) {
5038  // The target file is local, so we need to retrieve it
5039  target = outfile;
5040  if (!stfopt.IsNull()) {
5041  outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5042  } else {
5043  outfile = "";
5044  }
5045  }
5046  }
5047  }
5048  if (outfile.BeginsWith("master:")) {
5049  outfile.ReplaceAll("master:", "");
5050  if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5051  // Get the master data dir
5052  TString ddir, emsg;
5053  if (!IsLite()) {
5054  if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5055  TObjString *os = fMacroLog.GetLineWith("const char");
5056  if (os) {
5057  Ssiz_t fst = os->GetString().First('\"');
5058  Ssiz_t lst = os->GetString().Last('\"');
5059  ddir = os->GetString()(fst+1, lst-fst-1);
5060  } else {
5061  emsg = "could not find 'const char *' string in macro log! cannot continue";
5062  }
5063  } else {
5064  emsg = "could not retrieve master data directory info! cannot continue";
5065  }
5066  if (!emsg.IsNull()) {
5067  Error("HandleOutputOptions", "%s", emsg.Data());
5068  return -1;
5069  }
5070  }
5071  if (!ddir.IsNull()) ddir += "/";
5072  if (outfile.IsNull()) {
5073  outfile.Form("%s<file>", ddir.Data());
5074  } else {
5075  outfile.Insert(0, TString::Format("%s", ddir.Data()));
5076  }
5077  }
5078  }
5079  // Set the parameter
5080  if (!outfile.IsNull()) {
5081  if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5082  SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5083  }
5084  }
5085  // Dataset creation
5086  if (!dsname.IsNull()) {
5087  dsname.Insert(0, "ds:");
5088  // Set the parameter
5089  SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5090  // Check the Save-To-File option
5091  if (!stfopt.IsNull()) {
5092  Int_t ostf = (Int_t) stfopt.Atoi();
5093  if (ostf%10 <= 0) {
5094  Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5095  stfopt.Form("%d", ostf+1);
5096  }
5097  } else {
5098  // Minimal setting
5099  stfopt = "1";
5100  }
5101  }
5102  // Save-To-File options
5103  if (!stfopt.IsNull()) {
5104  // Set the parameter
5105  SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5106  }
5107  } else {
5108  // Retrieve the file, if required
5109  if (GetOutputList()) {
5110  if (target == "ds|V") {
5111  // Find the dataset
5112  dsname = "";
5113  TIter nxo(GetOutputList());
5114  TObject *o = 0;
5115  while ((o = nxo())) {
5117  VerifyDataSet(o->GetName());
5118  dsname = o->GetName();
5119  break;
5120  }
5121  }
5122  if (!dsname.IsNull()) {
5123  TFileCollection *fc = GetDataSet(dsname);
5124  if (fc) {
5125  fc->Print();
5126  } else {
5127  Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5128  }
5129  } else {
5130  Warning("HandleOutputOptions", "dataset not found!");
5131  }
5132  } else {
5133  Bool_t targetcopied = kFALSE;
5134  TProofOutputFile *pf = 0;
5135  if (!target.IsNull())
5137  if (pf) {
5138  // Copy the file
5139  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5140  TUrl(target, kTRUE).GetUrl())) {
5141  if (TFile::Cp(pf->GetOutputFileName(), target)) {
5142  Printf(" Output successfully copied to %s", target.Data());
5143  targetcopied = kTRUE;
5144  } else {
5145  Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5146  }
5147  }
5148  }
5149  TFile *fout = 0;
5150  TObject *o = 0;
5151  TIter nxo(GetOutputList());
5152  Bool_t swapcopied = kFALSE;
5153  while ((o = nxo())) {
5154  TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5155  if (pof) {
5156  if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5157  if (pof == pf && targetcopied) continue;
5158  // Copy the file
5159  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5160  TUrl(target, kTRUE).GetUrl())) {
5161  if (TFile::Cp(pof->GetOutputFileName(), target)) {
5162  Printf(" Output successfully copied to %s", target.Data());
5163  swapcopied = kTRUE;
5164  } else {
5165  Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5166  }
5167  }
5168  } else if (pof->IsRetrieve()) {
5169  // Retrieve this file to the local path indicated in the title
5170  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5171  TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5172  if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5173  Printf(" Output successfully copied to %s", pof->GetTitle());
5174  } else {
5175  Warning("HandleOutputOptions",
5176  "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5177  }
5178  }
5179  }
5180  }
5181  }
5182  if (!target.IsNull() && !swapcopied) {
5183  if (!fout && !pf) {
5184  fout = TFile::Open(target, "RECREATE");
5185  if (!fout || (fout && fout->IsZombie())) {
5186  SafeDelete(fout);
5187  Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5188  }
5189  }
5190  if (fout) {
5191  nxo.Reset();
5192  while ((o = nxo())) {
5193  TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5194  if (!pof) {
5195  // Write the object to the open output file
5196  o->Write();
5197  }
5198  }
5199  }
5200  }
5201  // Clean-up
5202  if (fout) {
5203  fout->Close();
5204  SafeDelete(fout);
5205  Printf(" Output saved to %s", target.Data());
5206  }
5207  }
5208  }
5209  // Remove the parameter
5210  DeleteParameters("PROOF_DefaultOutputOption");
5211  // Remove the parameter
5212  DeleteParameters("PROOF_SavePartialResults");
5213  }
5214  // Done
5215  return 0;
5216 }
5217 
5218 ////////////////////////////////////////////////////////////////////////////////
5219 /// Extract from opt in optfb information about wanted feedback settings.
5220 /// Feedback are removed from the input string opt.
5221 /// If action == 0, set up feedback accordingly, if action == 1 clean related
5222 /// feedback settings (using info in optfb, if available, or reparsing opt).
5223 ///
5224 /// Feedback requirements are in the form
5225 ///
5226 /// <previous_option>fb=name1,name2,name3,... <next_option>
5227 /// <previous_option>feedback=name1,name2,name3,...;<next_option>
5228 ///
5229 /// The special name 'stats' triggers feedback about events and packets.
5230 /// The separator from the next option is either a ' ' or a ';'.
5231 /// Called interanally by TProof::Process.
5232 
5233 void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5234 {
5235  Ssiz_t from = 0;
5236  if (action == 0 || (action == 1 && optfb.IsNull())) {
5237  TString tag("fb=");
5238  Ssiz_t ifb = opt.Index(tag);
5239  if (ifb == kNPOS) {
5240  tag = "feedback=";
5241  ifb = opt.Index(tag);
5242  }
5243  if (ifb == kNPOS) return;
5244  from = ifb + tag.Length();
5245 
5246  if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5247  Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5248  return;
5249  }
5250  // Remove from original options string
5251  tag += optfb;
5252  opt.ReplaceAll(tag, "");
5253  }
5254 
5255  // Parse now
5256  TString nm, startdraw, stopdraw;
5257  from = 0;
5258  while (optfb.Tokenize(nm, from, ",")) {
5259  // Special name first
5260  if (nm == "stats") {
5261  if (action == 0) {
5262  startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5263  gROOT->ProcessLine(startdraw.Data());
5264  SetParameter("PROOF_StatsHist", "");
5265  AddFeedback("PROOF_EventsHist");
5266  AddFeedback("PROOF_PacketsHist");
5267  AddFeedback("PROOF_ProcPcktHist");
5268  } else {
5269  stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5270  " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5271  " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5272  gROOT->ProcessLine(stopdraw.Data());
5273  DeleteParameters("PROOF_StatsHist");
5274  RemoveFeedback("PROOF_EventsHist");
5275  RemoveFeedback("PROOF_PacketsHist");
5276  RemoveFeedback("PROOF_ProcPcktHist");
5277  }
5278  } else {
5279  if (action == 0) {
5280  // Enable or
5281  AddFeedback(nm);
5282  startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5283  gROOT->ProcessLine(startdraw.Data());
5284  } else {
5285  // ... or disable
5286  RemoveFeedback(nm);
5287  stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5288  " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5289  " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5290  gROOT->ProcessLine(stopdraw.Data());
5291  }
5292  }
5293  }
5294 }
5295 
5296 ////////////////////////////////////////////////////////////////////////////////
5297 /// Process a data set (TDSet) using the specified selector (.C) file or
5298 /// Tselector object
5299 /// Entry- or event-lists should be set in the data set object using
5300 /// TDSet::SetEntryList.
5301 /// The return value is -1 in case of error and TSelector::GetStatus() in
5302 /// in case of success.
5303 
5304 Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5306 {
5307  if (!IsValid() || !fPlayer) return -1;
5308 
5309  // Set PROOF to running state
5311 
5312  TString opt(option), optfb, outfile;
5313  // Enable feedback, if required
5314  if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5315  // Define output file, either from 'opt' or the default one
5316  if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5317 
5318  // Resolve query mode
5319  fSync = (GetQueryMode(opt) == kSync);
5320 
5321  if (fSync && (!IsIdle() || IsWaiting())) {
5322  // Already queued or processing queries: switch to asynchronous mode
5323  Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5324  fSync = kFALSE;
5325  opt.ReplaceAll("SYNC","");
5326  opt += "ASYN";
5327  }
5328 
5329  // Cleanup old temporary datasets
5330  if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5332  fRunningDSets->Delete();
5333  }
5334 
5335  // deactivate the default application interrupt handler
5336  // ctrl-c's will be forwarded to PROOF to stop the processing
5337  TSignalHandler *sh = 0;
5338  if (fSync) {
5339  if (gApplication)
5341  }
5342 
5343  // Make sure we get a fresh result
5344  fOutputList.Clear();
5345 
5346  // Make sure that the workers ready list is empty
5347  if (fWrksOutputReady) {
5350  }
5351 
5352  // Reset time measurements
5353  fQuerySTW.Reset();
5354 
5355  Long64_t rv = -1;
5356  if (selector && strlen(selector)) {
5357  rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5358  } else if (fSelector) {
5359  rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5360  } else {
5361  Error("Process", "neither a selecrot file nor a selector object have"
5362  " been specified: cannot process!");
5363  }
5364 
5365  // This is the end of merging
5366  fQuerySTW.Stop();
5367  Float_t rt = fQuerySTW.RealTime();
5368  // Update the query content
5369  TQueryResult *qr = GetQueryResult();
5370  if (qr) {
5371  qr->SetTermTime(rt);
5372  qr->SetPrepTime(fPrepTime);
5373  }
5374 
5375  // Disable feedback, if required
5376  if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5377  // Finalise output file settings (opt is ignored in here)
5378  if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5379 
5380  // Retrieve status from the output list
5381  if (rv >= 0) {
5382  TParameter<Long64_t> *sst =
5383  (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5384  if (sst) rv = sst->GetVal();
5385  }
5386 
5387  if (fSync) {
5388  // reactivate the default application interrupt handler
5389  if (sh)
5391  // Save the performance info, if required
5392  if (!fPerfTree.IsNull()) {
5393  if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5394  // Must be re-enabled each time
5395  SetPerfTree(0);
5396  }
5397  }
5398 
5399  return rv;
5400 }
5401 
5402 ////////////////////////////////////////////////////////////////////////////////
5403 /// Process a data set (TFileCollection) using the specified selector (.C) file
5404 /// or TSelector object.
5405 /// The default tree is analyzed (i.e. the first one found). To specify another
5406 /// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5407 /// The return value is -1 in case of error and TSelector::GetStatus() in
5408 /// in case of success.
5409 
5412 {
5413  if (!IsValid() || !fPlayer) return -1;
5414 
5415  if (fProtocol < 17) {
5416  Info("Process", "server version < 5.18/00:"
5417  " processing of TFileCollection not supported");
5418  return -1;
5419  }
5420 
5421  // We include the TFileCollection to the input list and we create a
5422  // fake TDSet with infor about it
5423  TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5424  fPlayer->AddInput(fc);
5425 
5426 
5427  Long64_t retval = -1;
5428  if (selector && strlen(selector)) {
5429  retval = Process(dset, selector, option, nentries, first);
5430  } else if (fSelector) {
5431  retval = Process(dset, fSelector, option, nentries, first);
5432  } else {
5433  Error("Process", "neither a selecrot file nor a selector object have"
5434  " been specified: cannot process!");
5435  }
5436  fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5437 
5438  // Cleanup
5439  if (IsLite() && !fSync) {
5440  if (!fRunningDSets) fRunningDSets = new TList;
5441  fRunningDSets->Add(dset);
5442  } else {
5443  delete dset;
5444  }
5445 
5446  return retval;
5447 }
5448 
5449 ////////////////////////////////////////////////////////////////////////////////
5450 /// Process a dataset which is stored on the master with name 'dsetname'.
5451 /// The syntax for dsetname is name[#[dir/]objname], e.g.
5452 /// "mydset" analysis of the first tree in the top dir of the dataset
5453 /// named "mydset"
5454 /// "mydset#T" analysis tree "T" in the top dir of the dataset
5455 /// named "mydset"
5456 /// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5457 /// named "mydset"
5458 /// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5459 /// dataset named "mydset"
5460 /// The component 'name' in its more general form contains also the group and
5461 /// user name following "/<group>/<user>/<dsname>". Each of these components
5462 /// can contain one or more wildcards '*', in which case all the datasets matching
5463 /// the expression are added together as a global dataset (wildcard support has
5464 /// been added in version 5.27/02).
5465 /// The last argument 'elist' specifies an entry- or event-list to be used as
5466 /// event selection.
5467 /// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5468 /// at once in a more flexible way that the one provided by wildcarding. There
5469 /// are three possibilities:
5470 /// 1) specifying the dataset names separated by the OR operator '|', e.g.
5471 /// dsetname = "<dset1>|<dset2>|<dset3>|..."
5472 /// in this case the datasets are a seen as a global unique dataset
5473 /// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5474 /// dsetname = "<dset1>,<dset2> <dset3>,..."
5475 /// in this case the datasets are processed one after the other and the
5476 /// selector is notified when switching dataset via a bit in the current
5477 /// processed element.
5478 /// 3) giving the path of a textfile where the dataset names are specified
5479 /// on one or multiple lines; the lines found are joined as in 1), unless
5480 /// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5481 /// with the dataset names listed in 'datasets.txt') in which case they are
5482 /// treated as in 2); the file is open in raw mode with TFile::Open and
5483 /// therefore it cane be remote, e.g. on a Web server.
5484 /// Each <dsetj> has the format specified above for the single dataset processing,
5485 /// included wildcarding (the name of the tree and subdirectory must be same for
5486 /// all the datasets).
5487 /// In the case of multiple datasets, 'elist' is treated a global entry list.
5488 /// It is possible to specify per-dataset entry lists using the syntax
5489 /// "mydset[#adir/[T]]?enl=entrylist"
5490 /// or
5491 /// "mydset[#adir/[T]]<<entrylist"
5492 /// Here 'entrylist' is a tag identifying, in the order :
5493 /// i. a named entry-list in the input list or in the input data list
5494 /// ii. a named entry-list in memory (in gDirectory)
5495 /// iii. the path of a file containing the entry-list to be used
5496 /// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5497 /// data list.
5498 /// The return value is -1 in case of error and TSelector::GetStatus() in
5499 /// in case of success.
5500 
5501 Long64_t TProof::Process(const char *dsetname, const char *selector,
5502  Option_t *option, Long64_t nentries,
5503  Long64_t first, TObject *elist)
5504 {
5505  if (fProtocol < 13) {
5506  Info("Process", "processing 'by name' not supported by the server");
5507  return -1;
5508  }
5509 
5510  TString dsname, fname(dsetname);
5511  // If the 'dsetname' corresponds to an existing and readable file we will try to
5512  // interpretate its content as names of datasets to be processed. One line can contain
5513  // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5514  // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5515  // joined with ','.
5516  const char *separator = (fname.EndsWith(",")) ? "," : "|";
5517  if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5518  if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5519  TUrl uf(fname, kTRUE);
5520  uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5521  TFile *f = TFile::Open(uf.GetUrl());
5522  if (f && !(f->IsZombie())) {
5523  const Int_t blen = 8192;
5524  char buf[blen];
5525  Long64_t rest = f->GetSize();
5526  while (rest > 0) {
5527  Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5528  if (f->ReadBuffer(buf, len)) {
5529  Error("Process", "problems reading from file '%s'", fname.Data());
5530  dsname = "";
5531  break;
5532  }
5533  buf[len] = '\0';
5534  dsname += buf;
5535  rest -= len;
5536  }
5537  f->Close();
5538  SafeDelete(f);
5539  // We fail if a failure occured
5540  if (rest > 0) return -1;
5541  } else {
5542  Error("Process", "could not open file '%s'", fname.Data());
5543  return -1;
5544  }
5545  }
5546  if (dsname.IsNull()) {
5547  dsname = dsetname;
5548  } else {
5549  // Remove trailing '\n'
5550  if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5551  // Replace all '\n' with the proper separator
5552  dsname.ReplaceAll("\n", separator);
5553  if (gDebug > 0) {
5554  Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5555  Info("Process", " '%s'", dsname.Data());
5556  }
5557  }
5558 
5559  TString names(dsname), name, enl, newname;
5560  // If multi-dataset check if server supports it
5561  if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5562  Info("Process", "multi-dataset processing not supported by the server");
5563  return -1;
5564  }
5565 
5566  TEntryList *el = 0;
5567  TString dsobj, dsdir;
5568  Int_t from = 0;
5569  while (names.Tokenize(name, from, "[, |]")) {
5570 
5571  newname = name;
5572  // Extract the specific entry-list, if any
5573  enl = "";
5574  Int_t ienl = name.Index("?enl=");
5575  if (ienl == kNPOS) {
5576  ienl = name.Index("<<");
5577  if (ienl != kNPOS) {
5578  newname.Remove(ienl);
5579  ienl += strlen("<<");
5580  }
5581  } else {
5582  newname.Remove(ienl);
5583  ienl += strlen("?enl=");
5584  }
5585 
5586  // Check the name syntax first
5587  TString obj, dir("/");
5588  Int_t idxc = newname.Index("#");
5589  if (idxc != kNPOS) {
5590  Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5591  if (idxs != kNPOS) {
5592  obj = newname(idxs+1, newname.Length());
5593  dir = newname(idxc+1, newname.Length());
5594  dir.Remove(dir.Index("/") + 1);
5595  newname.Remove(idxc);
5596  } else {
5597  obj = newname(idxc+1, newname.Length());
5598  newname.Remove(idxc);
5599  }
5600  } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5601  // protection against using ':' instead of '#'
5602  Error("Process", "bad name syntax (%s): please use"
5603  " a '#' after the dataset name", name.Data());
5604  dsname.ReplaceAll(name, "");
5605  continue;
5606  }
5607  if (dsobj.IsNull() && dsdir.IsNull()) {
5608  // The first one specifies obj and dir
5609  dsobj = obj;
5610  dsdir = dir;
5611  } else if (obj != dsobj || dir != dsdir) {
5612  // Inconsistent specification: not supported
5613  Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5614  }
5615  // Process the entry-list name, if any
5616  if (ienl != kNPOS) {
5617  // Get entrylist name or path
5618  enl = name(ienl, name.Length());
5619  el = 0;
5620  TObject *oel = 0;
5621  // If not in the input list ...
5622  TList *inpl = GetInputList();
5623  if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5624  // ... check the heap
5625  if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5626  if ((el = dynamic_cast<TEntryList *>(oel))) {
5627  // Add to the input list (input data not available on master where
5628  // this info will be processed)
5629  if (fProtocol >= 28)
5630  if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5631  }
5632  }
5633  // If not in the heap, check a file, if any
5634  if (!el) {
5635  if (!gSystem->AccessPathName(enl)) {
5636  TFile *f = TFile::Open(enl);
5637  if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5638  TIter nxk(f->GetListOfKeys());
5639  TKey *k = 0;
5640  while ((k = (TKey *) nxk())) {
5641  if (!strcmp(k->GetClassName(), "TEntryList")) {
5642  if (!el) {
5643  if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5644  // Add to the input list (input data not available on master where
5645  // this info will be processed)
5646  if (fProtocol >= 28) {
5647  if (!(inpl->FindObject(el->GetName()))) {
5648  el = (TEntryList *) el->Clone();
5649  AddInput(el);
5650  }
5651  } else {
5652  el = (TEntryList *) el->Clone();
5653  }
5654  }
5655  } else if (strcmp(el->GetName(), k->GetName())) {
5656  Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5657  "if this is not what you want, load first the content in memory"
5658  "and select it by name ", enl.Data());
5659  }
5660  }
5661  }
5662  } else {
5663  Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5664  }
5665  }
5666  }
5667  // Transmit the information
5668  if (fProtocol >= 28) {
5669  newname += "?enl=";
5670  if (el) {
5671  // An entry list object is avalaible in the input list: add its name
5672  newname += el->GetName();
5673  } else {
5674  // The entry list object was not found: send the name, the future entry list manager will
5675  // find it on the server side
5676  newname += enl;
5677  }
5678  }
5679  }
5680  // Adjust the name for this dataset
5681  dsname.ReplaceAll(name, newname);
5682  }
5683 
5684  // Create the dataset object
5685  TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5686  // Set entry list
5687  if (el && fProtocol < 28) {
5688  dset->SetEntryList(el);
5689  } else {
5690  dset->SetEntryList(elist);
5691  }
5692  // Run
5693  Long64_t retval = -1;
5694  if (selector && strlen(selector)) {
5695  retval = Process(dset, selector, option, nentries, first);
5696  } else if (fSelector) {
5697  retval = Process(dset, fSelector, option, nentries, first);
5698  } else {
5699  Error("Process", "neither a selector file nor a selector object have"
5700  " been specified: cannot process!");
5701  }
5702  // Cleanup
5703  if (IsLite() && !fSync) {
5704  if (!fRunningDSets) fRunningDSets = new TList;
5705  fRunningDSets->Add(dset);
5706  } else {
5707  delete dset;
5708  }
5709 
5710  return retval;
5711 }
5712 
5713 ////////////////////////////////////////////////////////////////////////////////
5714 /// Generic (non-data based) selector processing: the Process() method of the
5715 /// specified selector (.C) or TSelector object is called 'n' times.
5716 /// The return value is -1 in case of error and TSelector::GetStatus() in
5717 /// in case of success.
5718 
5719 Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5720 {
5721  if (!IsValid()) return -1;
5722 
5723  if (fProtocol < 16) {
5724  Info("Process", "server version < 5.17/04: generic processing not supported");
5725  return -1;
5726  }
5727 
5728  // Fake data set
5729  TDSet *dset = new TDSet;
5730  dset->SetBit(TDSet::kEmpty);
5731 
5732  Long64_t retval = -1;
5733  if (selector && strlen(selector)) {
5734  retval = Process(dset, selector, option, n);
5735  } else if (fSelector) {
5736  retval = Process(dset, fSelector, option, n);
5737  } else {
5738  Error("Process", "neither a selector file nor a selector object have"
5739  " been specified: cannot process!");
5740  }
5741 
5742  // Cleanup
5743  if (IsLite() && !fSync) {
5744  if (!fRunningDSets) fRunningDSets = new TList;
5745  fRunningDSets->Add(dset);
5746  } else {
5747  delete dset;
5748  }
5749  return retval;
5750 }
5751 
5752 ////////////////////////////////////////////////////////////////////////////////
5753 /// Process a data set (TDSet) using the specified selector object.
5754 /// Entry- or event-lists should be set in the data set object using
5755 /// TDSet::SetEntryList.
5756 /// The return value is -1 in case of error and TSelector::GetStatus() in
5757 /// in case of success.
5758 
5761 {
5762  if (fProtocol < 34) {
5763  Error("Process", "server version < 5.33/02:"
5764  "processing by object not supported");
5765  return -1;
5766  }
5767  if (!selector) {
5768  Error("Process", "selector object undefined!");
5769  return -1;
5770  }
5771  fSelector = selector;
5772  Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5773  fSelector = 0;
5774  // Done
5775  return rc;
5776 }
5777 
5778 ////////////////////////////////////////////////////////////////////////////////
5779 /// Process a data set (TFileCollection) using the specified selector object
5780 /// The default tree is analyzed (i.e. the first one found). To specify another
5781 /// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5782 /// The return value is -1 in case of error and TSelector::GetStatus() in
5783 /// in case of success.
5784 
5787 {
5788  if (fProtocol < 34) {
5789  Error("Process", "server version < 5.33/02:"
5790  "processing by object not supported");
5791  return -1;
5792  }
5793  if (!selector) {
5794  Error("Process", "selector object undefined!");
5795  return -1;
5796  }
5797  fSelector = selector;
5798  Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5799  fSelector = 0;
5800  // Done
5801  return rc;
5802 }
5803 
5804 ////////////////////////////////////////////////////////////////////////////////
5805 /// Process with name of dataset and TSelector object
5806 
5807 Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5808  Option_t *option, Long64_t nentries,
5809  Long64_t first, TObject *elist)
5810 {
5811  if (fProtocol < 34) {
5812  Error("Process", "server version < 5.33/02:"
5813  "processing by object not supported");
5814  return -1;
5815  }
5816  if (!selector) {
5817  Error("Process", "selector object undefined!");
5818  return -1;
5819  }
5820  fSelector = selector;
5821  Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5822  fSelector = 0;
5823  // Done
5824  return rc;
5825 }
5826 
5827 ////////////////////////////////////////////////////////////////////////////////
5828 /// Generic (non-data based) selector processing: the Process() method of the
5829 /// specified selector is called 'n' times.
5830 /// The return value is -1 in case of error and TSelector::GetStatus() in
5831 /// in case of success.
5832 
5834 {
5835  if (fProtocol < 34) {
5836  Error("Process", "server version < 5.33/02:"
5837  "processing by object not supported");
5838  return -1;
5839  }
5840  if (!selector) {
5841  Error("Process", "selector object undefined!");
5842  return -1;
5843  }
5844  fSelector = selector;
5845  Long64_t rc = Process((const char*)0, n, option);
5846  fSelector = 0;
5847  // Done
5848  return rc;
5849 }
5850 
5851 ////////////////////////////////////////////////////////////////////////////////
5852 /// Get reference for the qry-th query in fQueries (as
5853 /// displayed by ShowQueries).
5854 
5856 {
5857  ref = "";
5858  if (qry > 0) {
5859  if (!fQueries)
5860  GetListOfQueries();
5861  if (fQueries) {
5862  TIter nxq(fQueries);
5863  TQueryResult *qr = 0;
5864  while ((qr = (TQueryResult *) nxq()))
5865  if (qr->GetSeqNum() == qry) {
5866  ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5867  return 0;
5868  }
5869  }
5870  }
5871  return -1;
5872 }
5873 
5874 ////////////////////////////////////////////////////////////////////////////////
5875 /// Finalize the qry-th query in fQueries.
5876 /// If force, force retrieval if the query is found in the local list
5877 /// but has already been finalized (default kFALSE).
5878 /// If query < 0, finalize current query.
5879 /// Return 0 on success, -1 on error
5880 
5882 {
5883  if (fPlayer) {
5884  if (qry > 0) {
5885  TString ref;
5886  if (GetQueryReference(qry, ref) == 0) {
5887  return Finalize(ref, force);
5888  } else {
5889  Info("Finalize", "query #%d not found", qry);
5890  }
5891  } else {
5892  // The last query
5893  return Finalize("", force);
5894  }
5895  }
5896  return -1;
5897 }
5898 
5899 ////////////////////////////////////////////////////////////////////////////////
5900 /// Finalize query with reference ref.
5901 /// If force, force retrieval if the query is found in the local list
5902 /// but has already been finalized (default kFALSE).
5903 /// If ref = 0, finalize current query.
5904 /// Return 0 on success, -1 on error
5905 
5906 Long64_t TProof::Finalize(const char *ref, Bool_t force)
5907 {
5908  if (fPlayer) {
5909  // Get the pointer to the query
5910  TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5911  : GetQueryResult();
5913  TString xref(ref);
5914  if (!qr) {
5915  if (!xref.IsNull()) {
5916  retrieve = kTRUE;
5917  }
5918  } else {
5919  if (qr->IsFinalized()) {
5920  if (force) {
5921  retrieve = kTRUE;
5922  } else {
5923  Info("Finalize","query already finalized:"
5924  " use Finalize(<qry>,kTRUE) to force new retrieval");
5925  qr = 0;
5926  }
5927  } else {
5928  retrieve = kTRUE;
5929  xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5930  }
5931  }
5932  if (retrieve) {
5933  Retrieve(xref.Data());
5934  qr = fPlayer->GetQueryResult(xref.Data());
5935  }
5936  if (qr)
5937  return fPlayer->Finalize(qr);
5938  }
5939  return -1;
5940 }
5941 
5942 ////////////////////////////////////////////////////////////////////////////////
5943 /// Send retrieve request for the qry-th query in fQueries.
5944 /// If path is defined save it to path.
5945 
5946 Int_t TProof::Retrieve(Int_t qry, const char *path)
5947 {
5948  if (qry > 0) {
5949  TString ref;
5950  if (GetQueryReference(qry, ref) == 0)
5951  return Retrieve(ref, path);
5952  else
5953  Info("Retrieve", "query #%d not found", qry);
5954  } else {
5955  Info("Retrieve","positive argument required - do nothing");
5956  }
5957  return -1;
5958 }
5959 
5960 ////////////////////////////////////////////////////////////////////////////////
5961 /// Send retrieve request for the query specified by ref.
5962 /// If path is defined save it to path.
5963 /// Generic method working for all queries known by the server.
5964 
5965 Int_t TProof::Retrieve(const char *ref, const char *path)
5966 {
5967  if (ref) {
5969  m << TString(ref);
5970  Broadcast(m, kActive);
5972 
5973  // Archive it locally, if required
5974  if (path) {
5975 
5976  // Get pointer to query
5977  TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5978 
5979  if (qr) {
5980 
5981  TFile *farc = TFile::Open(path,"UPDATE");
5982  if (!farc || (farc && !(farc->IsOpen()))) {
5983  Info("Retrieve", "archive file cannot be open (%s)", path);
5984  return 0;
5985  }
5986  farc->cd();
5987 
5988  // Update query status
5989  qr->SetArchived(path);
5990 
5991  // Write to file
5992  qr->Write();
5993 
5994  farc->Close();
5995  SafeDelete(farc);
5996 
5997  } else {
5998  Info("Retrieve", "query not found after retrieve");
5999  return -1;
6000  }
6001  }
6002 
6003  return 0;
6004  }
6005  return -1;
6006 }
6007 
6008 ////////////////////////////////////////////////////////////////////////////////
6009 /// Send remove request for the qry-th query in fQueries.
6010 
6012 {
6013  if (qry > 0) {
6014  TString ref;
6015  if (GetQueryReference(qry, ref) == 0)
6016  return Remove(ref, all);
6017  else
6018  Info("Remove", "query #%d not found", qry);
6019  } else {
6020  Info("Remove","positive argument required - do nothing");
6021  }
6022  return -1;
6023 }
6024 
6025 ////////////////////////////////////////////////////////////////////////////////
6026 /// Send remove request for the query specified by ref.
6027 /// If all = TRUE remove also local copies of the query, if any.
6028 /// Generic method working for all queries known by the server.
6029 /// This method can be also used to reset the list of queries
6030 /// waiting to be processed: for that purpose use ref == "cleanupqueue".
6031 
6032 Int_t TProof::Remove(const char *ref, Bool_t all)
6033 {
6034  if (all) {
6035  // Remove also local copies, if any
6036  if (fPlayer)
6037  fPlayer->RemoveQueryResult(ref);
6038  }
6039 
6040  if (IsLite()) return 0;
6041 
6042  if (ref) {
6044  m << TString(ref);
6045  Broadcast(m, kActive);
6047  return 0;
6048  }
6049  return -1;
6050 }
6051 
6052 ////////////////////////////////////////////////////////////////////////////////
6053 /// Send archive request for the qry-th query in fQueries.
6054 
6055 Int_t TProof::Archive(Int_t qry, const char *path)
6056 {
6057  if (qry > 0) {
6058  TString ref;
6059  if (GetQueryReference(qry, ref) == 0)
6060  return Archive(ref, path);
6061  else
6062  Info("Archive", "query #%d not found", qry);
6063  } else {
6064  Info("Archive","positive argument required - do nothing");
6065  }
6066  return -1;
6067 }
6068 
6069 ////////////////////////////////////////////////////////////////////////////////
6070 /// Send archive request for the query specified by ref.
6071 /// Generic method working for all queries known by the server.
6072 /// If ref == "Default", path is understood as a default path for
6073 /// archiving.
6074 
6075 Int_t TProof::Archive(const char *ref, const char *path)
6076 {
6077  if (ref) {
6079  m << TString(ref) << TString(path);
6080  Broadcast(m, kActive);
6082  return 0;
6083  }
6084  return -1;
6085 }
6086 
6087 ////////////////////////////////////////////////////////////////////////////////
6088 /// Send cleanup request for the session specified by tag.
6089 
6090 Int_t TProof::CleanupSession(const char *sessiontag)
6091 {
6092  if (sessiontag) {
6094  m << TString(sessiontag);
6095  Broadcast(m, kActive);
6097  return 0;
6098  }
6099  return -1;
6100 }
6101 
6102 ////////////////////////////////////////////////////////////////////////////////
6103 /// Change query running mode to the one specified by 'mode'.
6104 
6106 {
6107  fQueryMode = mode;
6108 
6109  if (gDebug > 0)
6110  Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6111  "Sync" : "Async");
6112 }
6113 
6114 ////////////////////////////////////////////////////////////////////////////////
6115 /// Find out the query mode based on the current setting and 'mode'.
6116 
6118 {
6119  EQueryMode qmode = fQueryMode;
6120 
6121  if (mode && (strlen(mode) > 0)) {
6122  TString m(mode);
6123  m.ToUpper();
6124  if (m.Contains("ASYN")) {
6125  qmode = kAsync;
6126  } else if (m.Contains("SYNC")) {
6127  qmode = kSync;
6128  }
6129  }
6130 
6131  if (gDebug > 0)
6132  Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6133  "Sync" : "Async");
6134 
6135  return qmode;
6136 }
6137 
6138 ////////////////////////////////////////////////////////////////////////////////
6139 /// Execute the specified drawing action on a data set (TDSet).
6140 /// Event- or Entry-lists should be set in the data set object using
6141 /// TDSet::SetEntryList.
6142 /// Returns -1 in case of error or number of selected events otherwise.
6143 
6144 Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6145  const char *selection, Option_t *option,
6147 {
6148  if (!IsValid() || !fPlayer) return -1;
6149 
6150  // Make sure that asynchronous processing is not active
6151  if (!IsIdle()) {
6152  Info("DrawSelect","not idle, asynchronous Draw not supported");
6153  return -1;
6154  }
6155  TString opt(option);
6156  Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6157  if (idx != kNPOS)
6158  opt.Replace(idx,4,"");
6159 
6160  return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6161 }
6162 
6163 ////////////////////////////////////////////////////////////////////////////////
6164 /// Execute the specified drawing action on a data set which is stored on the
6165 /// master with name 'dsetname'.
6166 /// The syntax for dsetname is name[#[dir/]objname], e.g.
6167 /// "mydset" analysis of the first tree in the top dir of the dataset
6168 /// named "mydset"
6169 /// "mydset#T" analysis tree "T" in the top dir of the dataset
6170 /// named "mydset"
6171 /// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6172 /// named "mydset"
6173 /// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6174 /// dataset named "mydset"
6175 /// The last argument 'enl' specifies an entry- or event-list to be used as
6176 /// event selection.
6177 /// The return value is -1 in case of error and TSelector::GetStatus() in
6178 /// in case of success.
6179 
6180 Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6181  const char *selection, Option_t *option,
6183 {
6184  if (fProtocol < 13) {
6185  Info("Process", "processing 'by name' not supported by the server");
6186  return -1;
6187  }
6188 
6189  TString name(dsetname);
6190  TString obj;
6191  TString dir = "/";
6192  Int_t idxc = name.Index("#");
6193  if (idxc != kNPOS) {
6194  Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6195  if (idxs != kNPOS) {
6196  obj = name(idxs+1, name.Length());
6197  dir = name(idxc+1, name.Length());
6198  dir.Remove(dir.Index("/") + 1);
6199  name.Remove(idxc);
6200  } else {
6201  obj = name(idxc+1, name.Length());
6202  name.Remove(idxc);
6203  }
6204  } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6205  // protection against using ':' instead of '#'
6206  Error("DrawSelect", "bad name syntax (%s): please use"
6207  " a '#' after the dataset name", dsetname);
6208  return -1;
6209  }
6210 
6211  TDSet *dset = new TDSet(name, obj, dir);
6212  // Set entry-list, if required
6213  dset->SetEntryList(enl);
6214  Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6215  delete dset;
6216  return retval;
6217 }
6218 
6219 ////////////////////////////////////////////////////////////////////////////////
6220 /// Send STOPPROCESS message to master and workers.
6221 
6222 void TProof::StopProcess(Bool_t abort, Int_t timeout)
6223 {
6224  PDB(kGlobal,2)
6225  Info("StopProcess","enter %d", abort);
6226 
6227  if (!IsValid())
6228  return;
6229 
6230  // Flag that we have been stopped
6232  SetRunStatus(rst);
6233 
6234  if (fPlayer)
6235  fPlayer->StopProcess(abort, timeout);
6236 
6237  // Stop any blocking 'Collect' request; on masters we do this only if
6238  // aborting; when stopping, we still need to receive the results
6239  if (TestBit(TProof::kIsClient) || abort)
6241 
6242  if (fSlaves->GetSize() == 0)
6243  return;
6244 
6245  // Notify the remote counterpart
6246  TSlave *sl;
6247  TIter next(fSlaves);
6248  while ((sl = (TSlave *)next()))
6249  if (sl->IsValid())
6250  // Ask slave to progate the stop/abort request
6251  sl->StopProcess(abort, timeout);
6252 }
6253 
6254 ////////////////////////////////////////////////////////////////////////////////
6255 /// Signal to disable related switches
6256 
6258 {
6259  Emit("DisableGoAsyn()");
6260 }
6261 
6262 ////////////////////////////////////////////////////////////////////////////////
6263 /// Send GOASYNC message to the master.
6264 
6266 {
6267  if (!IsValid()) return;
6268 
6269  if (GetRemoteProtocol() < 22) {
6270  Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6271  return;
6272  }
6273 
6274  if (fSync && !IsIdle()) {
6276  Broadcast(m);
6277  } else {
6278  Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6279  }
6280 }
6281 
6282 ////////////////////////////////////////////////////////////////////////////////
6283 /// Receive the log file of the slave with socket s.
6284 
6286 {
6287  const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6288  char buf[kMAXBUF];
6289 
6290  // If macro saving is enabled prepare macro
6294  }
6295 
6296  // Append messages to active logging unit
6297  Int_t fdout = -1;
6298  if (!fLogToWindowOnly) {
6299  fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6300  if (fdout < 0) {
6301  Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6302  " will not log msgs", fdout);
6303  return;
6304  }
6305  lseek(fdout, (off_t) 0, SEEK_END);
6306  }
6307 
6308  Int_t left, rec, r;
6309  Long_t filesize = 0;
6310 
6311  while (filesize < size) {
6312  left = Int_t(size - filesize);
6313  if (left >= kMAXBUF)
6314  left = kMAXBUF-1;
6315  rec = s->RecvRaw(&buf, left);
6316  filesize = (rec > 0) ? (filesize + rec) : filesize;
6317  if (!fLogToWindowOnly && !fSaveLogToMacro) {
6318  if (rec > 0) {
6319 
6320  char *p = buf;
6321  r = rec;
6322  while (r) {
6323  Int_t w;
6324 
6325  w = write(fdout, p, r);
6326 
6327  if (w < 0) {
6328  SysError("RecvLogFile", "error writing to unit: %d", fdout);
6329  break;
6330  }
6331  r -= w;
6332  p += w;
6333  }
6334  } else if (rec < 0) {
6335  Error("RecvLogFile", "error during receiving log file");
6336  break;
6337  }
6338  }
6339  if (rec > 0) {
6340  buf[rec] = 0;
6341  EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6342  // If macro saving is enabled add to TMacro
6343  if (fSaveLogToMacro) fMacroLog.AddLine(buf);
6344  }
6345  }
6346 
6347  // If idle restore logs to main session window
6348  if (fRedirLog && IsIdle() && !TestBit(TProof::kIsMaster))
6349  fRedirLog = kFALSE;
6350 }
6351 
6352 ////////////////////////////////////////////////////////////////////////////////
6353 /// Notify locally 'msg' to the appropriate units (file, stdout, window)
6354 /// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6355 
6356 void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6357 {
6358  // Must have somenthing to notify
6359  Int_t len = 0;
6360  if (!msg || (len = strlen(msg)) <= 0)
6361  return;
6362 
6363  // Get suffix length if any
6364  Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6365 
6366  // Append messages to active logging unit
6367  Int_t fdout = -1;
6368  if (!fLogToWindowOnly) {
6369  fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6370  if (fdout < 0) {
6371  Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6372  " will not notify msgs", fdout);
6373  return;
6374  }
6375  lseek(fdout, (off_t) 0, SEEK_END);
6376  }
6377 
6378  if (!fLogToWindowOnly) {
6379  // Write to output unit (stdout or a log file)
6380  if (len > 0) {
6381  char *p = (char *)msg;
6382  Int_t r = len;
6383  while (r) {
6384  Int_t w = write(fdout, p, r);
6385  if (w < 0) {
6386  SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6387  break;
6388  }
6389  r -= w;
6390  p += w;
6391  }
6392  // Add a suffix, if requested
6393  if (lsfx > 0)
6394  if (write(fdout, sfx, lsfx) != lsfx)
6395  SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6396  }
6397  }
6398  if (len > 0) {
6399  // Publish the message to the separate window (if the latter is missing
6400  // the message will just get lost)
6401  EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6402  }
6403 
6404  // If idle restore logs to main session window
6405  if (fRedirLog && IsIdle())
6406  fRedirLog = kFALSE;
6407 }
6408 
6409 ////////////////////////////////////////////////////////////////////////////////
6410 /// Log a message into the appropriate window by emitting a signal.
6411 
6412 void TProof::LogMessage(const char *msg, Bool_t all)
6413 {
6414  PDB(kGlobal,1)
6415  Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6416  all ? "true" : "false");
6417 
6418  if (gROOT->IsBatch()) {
6419  PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6420  return;
6421  }
6422 
6423  if (msg)
6424  EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6425 
6426  // Re-position at the beginning of the file, if requested.
6427  // This is used by the dialog when it re-opens the log window to
6428  // provide all the session messages
6429  if (all)
6430  lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6431 
6432  const Int_t kMAXBUF = 32768;
6433  char buf[kMAXBUF];
6434  Int_t len;
6435  do {
6436  while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6437  TSystem::GetErrno() == EINTR)
6439 
6440  if (len < 0) {
6441  Error("LogMessage", "error reading log file");
6442  break;
6443  }
6444 
6445  if (len > 0) {
6446  buf[len] = 0;
6447  EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6448  }
6449 
6450  } while (len > 0);
6451 }
6452 
6453 ////////////////////////////////////////////////////////////////////////////////
6454 /// Send to all active slaves servers the current slave group size
6455 /// and their unique id. Returns number of active slaves.
6456 /// Returns -1 in case of error.
6457 
6459 {
6460  if (!IsValid()) return -1;
6461  if (TestBit(TProof::kIsClient)) return 0;
6462  if (!fSendGroupView) return 0;
6464 
6466  TSlave *sl;
6467 
6468  int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6469  char str[32];
6470 
6471  while ((sl = (TSlave *)next())) {
6472  snprintf(str, 32, "%d %d", cnt, size);
6473  if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6474  MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6475  bad++;
6476  } else
6477  cnt++;
6478  }
6479 
6480  // Send the group view again in case there was a change in the
6481  // group size due to a bad slave
6482 
6483  if (bad) SendGroupView();
6484 
6485  return GetNumberOfActiveSlaves();
6486 }
6487 
6488 ////////////////////////////////////////////////////////////////////////////////
6489 /// Static method to extract the filename (if any) form a CINT command.
6490 /// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6491 /// appliable.
6492 
6493 Bool_t TProof::GetFileInCmd(const char *cmd, TString &fn)
6494 {
6495  TString s = cmd;
6496  s = s.Strip(TString::kBoth);
6497 
6498  if (s.Length() > 0 &&
6499  (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6500  TString file = s(2, s.Length());
6501  TString acm, arg, io;
6502  fn = gSystem->SplitAclicMode(file, acm, arg, io);
6503  if (!fn.IsNull())
6504  return kTRUE;
6505  }
6506 
6507  // Not found
6508  return kFALSE;
6509 }
6510 
6511 ////////////////////////////////////////////////////////////////////////////////
6512 /// Send command to be executed on the PROOF master and/or slaves.
6513 /// If plusMaster is kTRUE then exeucte on slaves and master too.
6514 /// Command can be any legal command line command. Commands like
6515 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6516 /// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6517 /// succes.
6518 
6519 Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6520 {
6521  return Exec(cmd, kActive, plusMaster);
6522 }
6523 
6524 ////////////////////////////////////////////////////////////////////////////////
6525 /// Send command to be executed on the PROOF master and/or slaves.
6526 /// Command can be any legal command line command. Commands like
6527 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6528 /// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6529 /// succes.
6530 
6531 Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6532 {
6533  if (!IsValid()) return -1;
6534 
6535  TString s = cmd;
6536  s = s.Strip(TString::kBoth);
6537 
6538  if (!s.Length()) return 0;
6539 
6540  // check for macro file and make sure the file is available on all slaves
6541  TString filename;
6542  if (TProof::GetFileInCmd(s.Data(), filename)) {
6543  char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6544  if (fn) {
6545  if (GetNumberOfUniqueSlaves() > 0) {
6546  if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6547  Error("Exec", "file %s could not be transfered", fn);
6548  delete [] fn;
6549  return -1;
6550  }
6551  } else {
6552  TString scmd = s(0,3) + fn;
6553  Int_t n = SendCommand(scmd, list);
6554  delete [] fn;
6555  return n;
6556  }
6557  } else {
6558  Error("Exec", "macro %s not found", filename.Data());
6559  return -1;
6560  }
6561  delete [] fn;
6562  }
6563 
6564  if (plusMaster) {
6565  if (IsLite()) {
6566  gROOT->ProcessLine(cmd);
6567  } else {
6568  DeactivateWorker("*");
6569  Int_t res = SendCommand(cmd, list);
6570  ActivateWorker("restore");
6571  if (res < 0)
6572  return res;
6573  }
6574  }
6575  return SendCommand(cmd, list);
6576 }
6577 
6578 ////////////////////////////////////////////////////////////////////////////////
6579 /// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6580 /// Command can be any legal command line command. Commands like
6581 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6582 /// to the PROOF cluster.
6583 /// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6584 /// TMacro, accessible via TMacro::GetMacroLog();
6585 /// Returns -1 in case of error, >=0 in case of succes.
6586 
6587 Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6588 {
6589  if (!IsValid()) return -1;
6590 
6591  TString s = cmd;
6592  s = s.Strip(TString::kBoth);
6593 
6594  if (!s.Length()) return 0;
6595 
6596  Int_t res = 0;
6597  if (IsLite()) {
6598  gROOT->ProcessLine(cmd);
6599  } else {
6600  Bool_t oldRedirLog = fRedirLog;
6601  fRedirLog = kTRUE;
6602  // Deactivate all workers
6603  DeactivateWorker("*");
6604  fRedirLog = kFALSE;
6605  // Reactivate the target ones, if needed
6606  if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6607  // Honour log-to-macro-saving settings
6608  Bool_t oldSaveLog = fSaveLogToMacro;
6609  fSaveLogToMacro = logtomacro;
6610  res = SendCommand(cmd, kActive);
6611  fSaveLogToMacro = oldSaveLog;
6612  fRedirLog = kTRUE;
6613  ActivateWorker("restore");
6614  fRedirLog = oldRedirLog;
6615  }
6616  // Done
6617  return res;
6618 }
6619 
6620 ////////////////////////////////////////////////////////////////////////////////
6621 /// Send command to be executed on the PROOF master and/or slaves.
6622 /// Command can be any legal command line command, however commands
6623 /// like ".x file.C" or ".L file.C" will not cause the file.C to be
6624 /// transfered to the PROOF cluster. In that case use TProof::Exec().
6625 /// Returns the status send by the remote server as part of the
6626 /// kPROOF_LOGDONE message. Typically this is the return code of the
6627 /// command on the remote side. Returns -1 in case of error.
6628 
6629 Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6630 {
6631  if (!IsValid()) return -1;
6632 
6633  Broadcast(cmd, kMESS_CINT, list);
6634  Collect(list);
6635 
6636  return fStatus;
6637 }
6638 
6639 ////////////////////////////////////////////////////////////////////////////////
6640 /// Get value of environment variable 'env' on node 'ord'
6641 
6642 TString TProof::Getenv(const char *env, const char *ord)
6643 {
6644  // The command to be executed
6645  TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6646  if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6647  // Get the line
6648  TObjString *os = fMacroLog.GetLineWith("const char");
6649  if (os) {
6650  TString info;
6651  Ssiz_t from = 0;
6652  os->GetString().Tokenize(info, from, "\"");
6653  os->GetString().Tokenize(info, from, "\"");
6654  if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6655  return info;
6656  }
6657  return TString("");
6658 }
6659 
6660 ////////////////////////////////////////////////////////////////////////////////
6661 /// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6662 
6663 Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6664 {
6665  // The command to be executed
6666  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6667  // Exectute the command saving the logs to macro
6668  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6669  // Get the line
6670  TObjString *os = fMacroLog.GetLineWith("const char");
6671  Int_t rc = -1;
6672  if (os) {
6673  Ssiz_t fst = os->GetString().First('\"');
6674  Ssiz_t lst = os->GetString().Last('\"');
6675  TString info = os->GetString()(fst+1, lst-fst-1);
6676  if (info.IsDigit()) {
6677  env = info.Atoi();
6678  rc = 0;
6679  if (gDebug > 0)
6680  Printf("%s: %d", rcenv, env);
6681  }
6682  }
6683  return rc;
6684 }
6685 
6686 ////////////////////////////////////////////////////////////////////////////////
6687 /// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6688 
6689 Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6690 {
6691  // The command to be executed
6692  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6693  // Exectute the command saving the logs to macro
6694  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6695  // Get the line
6696  TObjString *os = fMacroLog.GetLineWith("const char");
6697  Int_t rc = -1;
6698  if (os) {
6699  Ssiz_t fst = os->GetString().First('\"');
6700  Ssiz_t lst = os->GetString().Last('\"');
6701  TString info = os->GetString()(fst+1, lst-fst-1);
6702  if (info.IsFloat()) {
6703  env = info.Atof();
6704  rc = 0;
6705  if (gDebug > 0)
6706  Printf("%s: %f", rcenv, env);
6707  }
6708  }
6709  return rc;
6710 }
6711 
6712 ////////////////////////////////////////////////////////////////////////////////
6713 /// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6714 
6715 Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6716 {
6717  // The command to be executed
6718  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6719  // Exectute the command saving the logs to macro
6720  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6721  // Get the line
6722  TObjString *os = fMacroLog.GetLineWith("const char");
6723  Int_t rc = -1;
6724  if (os) {
6725  Ssiz_t fst = os->GetString().First('\"');
6726  Ssiz_t lst = os->GetString().Last('\"');
6727  env = os->GetString()(fst+1, lst-fst-1);
6728  rc = 0;
6729  if (gDebug > 0)
6730  Printf("%s: %s", rcenv, env.Data());
6731  }
6732  return rc;
6733 }
6734 
6735 ////////////////////////////////////////////////////////////////////////////////
6736 /// Transfer the current state of the master to the active slave servers.
6737 /// The current state includes: the current working directory, etc.
6738 /// Returns the number of active slaves. Returns -1 in case of error.
6739 
6741 {
6742  if (!IsValid()) return -1;
6743 
6744  // Go to the new directory, reset the interpreter environment and
6745  // tell slave to delete all objects from its new current directory.
6746  Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6747 
6748  return GetParallel();
6749 }
6750 
6751 ////////////////////////////////////////////////////////////////////////////////
6752 /// Transfer the current state of the master to the active slave servers.
6753 /// The current state includes: the current working directory, etc.
6754 /// Returns the number of active slaves. Returns -1 in case of error.
6755 
6757 {
6758  if (!IsValid()) return -1;
6759 
6760  // Go to the new directory, reset the interpreter environment and
6761  // tell slave to delete all objects from its new current directory.
6762  Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6763 
6764  return GetParallel();
6765 }
6766 
6767 ////////////////////////////////////////////////////////////////////////////////
6768 /// Transfer the initial (i.e. current) state of the master to all
6769 /// slave servers. Currently the initial state includes: log level.
6770 /// Returns the number of active slaves. Returns -1 in case of error.
6771 
6773 {
6774  if (!IsValid()) return -1;
6775 
6777 
6778  return GetNumberOfActiveSlaves();
6779 }
6780 
6781 ////////////////////////////////////////////////////////////////////////////////
6782 /// Check if a file needs to be send to the slave. Use the following
6783 /// algorithm:
6784 /// - check if file appears in file map
6785 /// - if yes, get file's modtime and check against time in map,
6786 /// if modtime not same get md5 and compare against md5 in map,
6787 /// if not same return kTRUE.
6788 /// - if no, get file's md5 and modtime and store in file map, ask
6789 /// slave if file exists with specific md5, if yes return kFALSE,
6790 /// if no return kTRUE.
6791 /// The options 'cpopt' define if to copy things from cache to sandbox and what.
6792 /// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6793 /// must be set in cpopt; the default is copy everything.
6794 /// Returns kTRUE in case file needs to be send, returns kFALSE in case
6795 /// file is already on remote node.
6796 
6797 Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6798 {
6799  Bool_t sendto = kFALSE;
6800 
6801  // create worker based filename
6802  TString sn = slave->GetName();
6803  sn += ":";
6804  sn += slave->GetOrdinal();
6805  sn += ":";
6806  sn += gSystem->BaseName(file);
6807 
6808  // check if file is in map
6809  FileMap_t::const_iterator it;
6810  if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6811  // file in map
6812  MD5Mod_t md = (*it).second;
6813  if (md.fModtime != modtime) {
6814  TMD5 *md5 = TMD5::FileChecksum(file);
6815  if (md5) {
6816  if ((*md5) != md.fMD5) {
6817  sendto = kTRUE;
6818  md.fMD5 = *md5;
6819  md.fModtime = modtime;
6820  fFileMap[sn] = md;
6821  // When on the master, the master and/or slaves may share
6822  // their file systems and cache. Therefore always make a
6823  // check for the file. If the file already exists with the
6824  // expected md5 the kPROOF_CHECKFILE command will cause the
6825  // file to be copied from cache to slave sandbox.
6826  if (TestBit(TProof::kIsMaster)) {
6827  sendto = kFALSE;
6828  TMessage mess(kPROOF_CHECKFILE);
6829  mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6830  slave->GetSocket()->Send(mess);
6831 
6832  fCheckFileStatus = 0;
6834  sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6835  }
6836  }
6837  delete md5;
6838  } else {
6839  Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6840  return kFALSE;
6841  }
6842  }
6843  } else {
6844  // file not in map
6845  TMD5 *md5 = TMD5::FileChecksum(file);
6846  MD5Mod_t md;
6847  if (md5) {
6848  md.fMD5 = *md5;
6849  md.fModtime = modtime;
6850  fFileMap[sn] = md;
6851  delete md5;
6852  } else {
6853  Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6854  return kFALSE;
6855  }
6856  TMessage mess(kPROOF_CHECKFILE);
6857  mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6858  slave->GetSocket()->Send(mess);
6859 
6860  fCheckFileStatus = 0;
6862  sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6863  }
6864 
6865  return sendto;
6866 }
6867 
6868 ////////////////////////////////////////////////////////////////////////////////
6869 /// Send a file to master or slave servers. Returns number of slaves
6870 /// the file was sent to, maybe 0 in case master and slaves have the same
6871 /// file system image, -1 in case of error.
6872 /// If defined, send to worker 'wrk' only.
6873 /// If defined, the full path of the remote path will be rfile.
6874 /// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6875 /// (to copy to the cache on a different name use rfile = "cache:newname").
6876 /// The mask 'opt' is an or of ESendFileOpt:
6877 ///
6878 /// kAscii (0x0) if set true ascii file transfer is used
6879 /// kBinary (0x1) if set true binary file transfer is used
6880 /// kForce (0x2) if not set an attempt is done to find out
6881 /// whether the file really needs to be downloaded
6882 /// (a valid copy may already exist in the cache
6883 /// from a previous run); the bit is set by
6884 /// UploadPackage, since the check is done elsewhere.
6885 /// kForward (0x4) if set, ask server to forward the file to slave
6886 /// or submaster (meaningless for slave servers).
6887 /// kCpBin (0x8) Retrieve from the cache the binaries associated
6888 /// with the file
6889 /// kCp (0x10) Retrieve the files from the cache
6890 ///
6891 
6892 Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6893 {
6894  if (!IsValid()) return -1;
6895 
6896  // Use the active slaves list ...
6897  TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6898  // ... or the specified slave, if any
6899  if (wrk) {
6900  slaves = new TList();
6901  slaves->Add(wrk);
6902  }
6903 
6904  if (slaves->GetSize() == 0) return 0;
6905 
6906 #ifndef R__WIN32
6907  Int_t fd = open(file, O_RDONLY);
6908 #else
6909  Int_t fd = open(file, O_RDONLY | O_BINARY);
6910 #endif
6911  if (fd < 0) {
6912  SysError("SendFile", "cannot open file %s", file);
6913  return -1;
6914  }
6915 
6916  // Get info about the file
6917  Long64_t size = -1;
6918  Long_t id, flags, modtime = 0;
6919  if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6920  Error("SendFile", "cannot stat file %s", file);
6921  close(fd);
6922  return -1;
6923  }
6924  if (size == 0) {
6925  Error("SendFile", "empty file %s", file);
6926  close(fd);
6927  return -1;
6928  }
6929 
6930  // Decode options
6931  Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6932  Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6933  Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6934 
6935  // Copy options
6936  Int_t cpopt = 0;
6937  if ((opt & kCp)) cpopt |= kCp;
6938  if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6939 
6940  const Int_t kMAXBUF = 32768; //16384 //65536;
6941  char buf[kMAXBUF];
6942  Int_t nsl = 0;
6943 
6944  TIter next(slaves);
6945  TSlave *sl;
6946  TString fnam(rfile);
6947  if (fnam == "cache") {
6948  fnam += TString::Format(":%s", gSystem->BaseName(file));
6949  } else if (fnam.IsNull()) {
6950  fnam = gSystem->BaseName(file);
6951  }
6952  // List on which we will collect the results
6953  fStatus = 0;
6954  while ((sl = (TSlave *)next())) {
6955  if (!sl->IsValid())
6956  continue;
6957 
6958  Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6959  // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6960  // is false. Masters might still need to send the file to newly added
6961  // slaves.
6962  PDB(kPackage,2) {
6963  const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6964  Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6965  file, sl->GetName(), sl->GetOrdinal(), sendto);
6966  }
6967  if (sl->fSlaveType == TSlave::kSlave && !sendto)
6968  continue;
6969  // The value of 'size' is used as flag remotely, so we need to
6970  // reset it to 0 if we are not going to send the file
6971  Long64_t siz = sendto ? size : 0;
6972  snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6973  if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6974  MarkBad(sl, "could not send kPROOF_SENDFILE request");
6975  continue;
6976  }
6977 
6978  if (sendto) {
6979 
6980  lseek(fd, 0, SEEK_SET);
6981 
6982  Int_t len;
6983  do {
6984  while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6986 
6987  if (len < 0) {
6988  SysError("SendFile", "error reading from file %s", file);
6990  close(fd);
6991  return -1;
6992  }
6993 
6994  if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6995  SysError("SendFile", "error writing to slave %s:%s (now offline)",
6996  sl->GetName(), sl->GetOrdinal());
6997  MarkBad(sl, "sendraw failure");
6998  sl = 0;
6999  break;
7000  }
7001 
7002  } while (len > 0);
7003 
7004  nsl++;
7005  }
7006  // Wait for the operation to be done
7007  if (sl)
7009  }
7010 
7011  close(fd);
7012 
7013  // Cleanup temporary list, if any
7014  if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
7015  SafeDelete(slaves);
7016 
7017  // We return failure is at least one unique worker failed
7018  return (fStatus != 0) ? -1 : nsl;
7019 }
7020 
7021 ////////////////////////////////////////////////////////////////////////////////
7022 /// Sends an object to master and workers and expect them to send back a
7023 /// message with the output of its TObject::Print(). Returns -1 on error, the
7024 /// number of workers that received the objects on success.
7025 
7027 {
7028  if (!IsValid() || !obj) return -1;
7029  TMessage mess(kPROOF_ECHO);
7030  mess.WriteObject(obj);
7031  return Broadcast(mess);
7032 }
7033 
7034 ////////////////////////////////////////////////////////////////////////////////
7035 /// Sends a string to master and workers and expect them to echo it back to
7036 /// the client via a message. It is a special case of the generic Echo()
7037 /// that works with TObjects. Returns -1 on error, the number of workers that
7038 /// received the message on success.
7039 
7040 Int_t TProof::Echo(const char *str)
7041 {
7042  TObjString *os = new TObjString(str);
7043  Int_t rv = Echo(os);
7044  delete os;
7045  return rv;
7046 }
7047 
7048 ////////////////////////////////////////////////////////////////////////////////
7049 /// Send object to master or slave servers. Returns number of slaves object
7050 /// was sent to, -1 in case of error.
7051 
7053 {
7054  if (!IsValid() || !obj) return -1;
7055 
7056  TMessage mess(kMESS_OBJECT);
7057 
7058  mess.WriteObject(obj);
7059  return Broadcast(mess, list);
7060 }
7061 
7062 ////////////////////////////////////////////////////////////////////////////////
7063 /// Send print command to master server. Returns number of slaves message
7064 /// was sent to. Returns -1 in case of error.
7065 
7067 {
7068  if (!IsValid()) return -1;
7069 
7070  Broadcast(option, kPROOF_PRINT, kActive);
7071  return Collect(kActive, fCollectTimeout);
7072 }
7073 
7074 ////////////////////////////////////////////////////////////////////////////////
7075 /// Set server logging level.
7076 
7078 {
7079  char str[32];
7080  fLogLevel = level;
7081  gProofDebugLevel = level;
7083  snprintf(str, 32, "%d %u", level, mask);
7085 }
7086 
7087 ////////////////////////////////////////////////////////////////////////////////
7088 /// Switch ON/OFF the real-time logging facility. When this option is
7089 /// ON, log messages from processing are sent back as they come, instead of
7090 /// being sent back at the end in one go. This may help debugging or monitoring
7091 /// in some cases, but, depending on the amount of log, it may have significant
7092 /// consequencies on the load over the network, so it must be used with care.
7093 
7095 {
7096  if (IsValid()) {
7098  mess << on;
7099  Broadcast(mess);
7100  } else {
7101  Warning("SetRealTimeLog","session is invalid - do nothing");
7102  }
7103 }
7104 
7105 ////////////////////////////////////////////////////////////////////////////////
7106 /// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7107 /// selection is done (if nodes is less than the available nodes).
7108 /// Returns the number of parallel slaves. Returns -1 in case of error.
7109 
7111 {
7112  if (!IsValid()) return -1;
7113 
7114  if (TestBit(TProof::kIsMaster)) {
7115  if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7116  return SendCurrentState();
7117  } else {
7118  if (nodes < 0) {
7119  PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7120  } else {
7121  PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7122  nodes == 1 ? "" : "s");
7123  }
7124  TMessage mess(kPROOF_PARALLEL);
7125  mess << nodes << random;
7126  Broadcast(mess);
7128  Int_t n = GetParallel();
7129  PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7130  return n;
7131  }
7132 }
7133 
7134 ////////////////////////////////////////////////////////////////////////////////
7135 /// Tell PROOF how many slaves to use in parallel. Returns the number of
7136 /// parallel slaves. Returns -1 in case of error.
7137 
7139 {
7140  // If delayed startup reset settings, if required
7141  if (fDynamicStartup && nodes < 0) {
7142  if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7143  }
7144 
7145  Int_t n = SetParallelSilent(nodes, random);
7146  if (TestBit(TProof::kIsClient)) {
7147  if (n < 1) {
7148  Printf("PROOF set to sequential mode");
7149  } else {
7150  TString subfix = (n == 1) ? "" : "s";
7151  if (random)
7152  subfix += ", randomly selected";
7153  Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7154  }
7155  } else if (fDynamicStartup && nodes >= 0) {
7156  if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7157  gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7158  }
7159  return n;
7160 }
7161 
7162 ////////////////////////////////////////////////////////////////////////////////
7163 /// Add nWorkersToAdd workers to current list of workers. This function is
7164 /// works on the master only, and only when an analysis is ongoing. A message
7165 /// is sent back to the client when we go "more" parallel.
7166 /// Returns -1 on error, number of total (not added!) workers on success.
7167 
7169 {
7170  if (!IsValid() || !IsMaster() || IsIdle()) {
7171  Error("GoMoreParallel", "can't invoke here -- should not happen!");
7172  return -1;
7173  }
7174  if (!gProofServ && !IsLite()) {
7175  Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7176  return -1;
7177  }
7178 
7179  TSlave *sl = 0x0;
7180  TIter next( fSlaves );
7181  Int_t nAddedWorkers = 0;
7182 
7183  while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7184  (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7185 
7186  // If worker is of an invalid type, break everything: it should not happen!
7187  if ((sl->GetSlaveType() != TSlave::kSlave) &&
7188  (sl->GetSlaveType() != TSlave::kMaster)) {
7189  Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7190  sl->GetName(), sl->GetOrdinal());
7191  R__ASSERT(0);
7192  }
7193 
7194  // Skip current worker if it is not a good candidate
7195  if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7196  (strcmp("IGNORE", sl->GetImage()) == 0)) {
7197  PDB(kGlobal, 2)
7198  Info("GoMoreParallel", "Worker %s:%s won't be considered",
7199  sl->GetName(), sl->GetOrdinal());
7200  continue;
7201  }
7202 
7203  // Worker is good but it is already active: skip it
7204  if (fActiveSlaves->FindObject(sl)) {
7205  Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7206  sl->GetName(), sl->GetOrdinal());
7207  continue;
7208  }
7209 
7210  //
7211  // From here on: worker is a good candidate
7212  //
7213 
7214  if (sl->GetSlaveType() == TSlave::kSlave) {
7216  fActiveSlaves->Add(sl);
7217  fInactiveSlaves->Remove(sl);
7218  fActiveMonitor->Add(sl->GetSocket());
7219  nAddedWorkers++;
7220  PDB(kGlobal, 2)
7221  Info("GoMoreParallel", "Worker %s:%s marked as active!",
7222  sl->GetName(), sl->GetOrdinal());
7223  }
7224  else {
7225  // Can't add masters dynamically: this should not happen!
7226  Error("GoMoreParallel", "Dynamic addition of master is not supported");
7227  R__ASSERT(0);
7228  }
7229 
7230  } // end loop over all slaves
7231 
7232  // Get slave status (will set the slaves fWorkDir correctly)
7233  PDB(kGlobal, 3)
7234  Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7235  AskStatistics();
7236 
7237  // Find active slaves with unique image
7238  PDB(kGlobal, 3)
7239  Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7240  FindUniqueSlaves();
7241 
7242  // Send new group-view to slaves
7243  PDB(kGlobal, 3)
7244  Info("GoMoreParallel", "Will invoke SendGroupView()");
7245  SendGroupView();
7246 
7247  PDB(kGlobal, 3)
7248  Info("GoMoreParallel", "Will invoke GetParallel()");
7249  Int_t nTotalWorkers = GetParallel();
7250 
7251  // Notify the client that we've got more workers, and print info on
7252  // Master's log as well
7253  TString s;
7254  s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7255  nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7256  nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7258  Info("GoMoreParallel", "%s", s.Data());
7259 
7260  return nTotalWorkers;
7261 }
7262 
7263 ////////////////////////////////////////////////////////////////////////////////
7264 /// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7265 /// list is sorted by slave performace the active list will contain first
7266 /// the most performant nodes. Returns the number of active slaves.
7267 /// If random is TRUE, and nodes is less than the number of available workers,
7268 /// a random selection is done.
7269 /// Returns -1 in case of error.
7270 
7272 {
7273  if (!IsValid()) return -1;
7274 
7275  fActiveSlaves->Clear();
7277 
7278  // Prepare the list of candidates first.
7279  // Algorithm depends on random option.
7280  TSlave *sl = 0;
7281  TList *wlst = new TList;
7282  TIter nxt(fSlaves);
7284  while ((sl = (TSlave *)nxt())) {
7285  if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7286  if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7287  if ((sl->GetSlaveType() != TSlave::kSlave) &&
7288  (sl->GetSlaveType() != TSlave::kMaster)) {
7289  Error("GoParallel", "TSlave is neither Master nor Slave");
7290  R__ASSERT(0);
7291  }
7292  // Good candidate
7293  wlst->Add(sl);
7294  // Set it inactive
7295  fInactiveSlaves->Add(sl);
7297  }
7298  }
7299  Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7300  int cnt = 0;
7302  while (cnt < nwrks) {
7303  // Random choice, if requested
7304  if (random) {
7305  Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7306  sl = (TSlave *) wlst->At(iwrk);
7307  } else {
7308  // The first available
7309  sl = (TSlave *) wlst->First();
7310  }
7311  if (!sl) {
7312  Error("GoParallel", "attaching to candidate!");
7313  break;
7314  }
7315  // Remove from the list
7316  wlst->Remove(sl);
7317 
7318  Int_t slavenodes = 0;
7319  if (sl->GetSlaveType() == TSlave::kSlave) {
7321  fActiveSlaves->Add(sl);
7322  fInactiveSlaves->Remove(sl);
7323  fActiveMonitor->Add(sl->GetSocket());
7324  slavenodes = 1;
7325  } else if (sl->GetSlaveType() == TSlave::kMaster) {
7326  fEndMaster = kFALSE;
7327  TMessage mess(kPROOF_PARALLEL);
7328  if (!attach) {
7329  Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7330  mess << nn;
7331  } else {
7332  // To get the number of slaves
7333  mess.SetWhat(kPROOF_LOGFILE);
7334  mess << -1 << -1;
7335  }
7336  if (sl->GetSocket()->Send(mess) == -1) {
7337  MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7338  slavenodes = 0;
7339  } else {
7340  Collect(sl, fCollectTimeout);
7341  if (sl->IsValid()) {
7343  fActiveSlaves->Add(sl);
7344  fInactiveSlaves->Remove(sl);
7345  fActiveMonitor->Add(sl->GetSocket());
7346  if (sl->GetParallel() > 0) {
7347  slavenodes = sl->GetParallel();
7348  } else {
7349  // Sequential mode: the master acts as a worker
7350  slavenodes = 1;
7351  }
7352  } else {
7353  MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7354  slavenodes = 0;
7355  }
7356  }
7357  }
7358  // 'slavenodes' may be different than 1 in multimaster setups
7359  cnt += slavenodes;
7360  }
7361 
7362  // Cleanup list
7363  wlst->SetOwner(0);
7364  SafeDelete(wlst);
7365 
7366  // Get slave status (will set the slaves fWorkDir correctly)
7367  AskStatistics();
7368 
7369  // Find active slaves with unique image
7370  FindUniqueSlaves();
7371 
7372  // Send new group-view to slaves
7373  if (!attach)
7374  SendGroupView();
7375 
7376  Int_t n = GetParallel();
7377 
7378  if (TestBit(TProof::kIsClient)) {
7379  if (n < 1)
7380  printf("PROOF set to sequential mode\n");
7381  else
7382  printf("PROOF set to parallel mode (%d worker%s)\n",
7383  n, n == 1 ? "" : "s");
7384  }
7385 
7386  PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7387  return n;
7388 }
7389 
7390 ////////////////////////////////////////////////////////////////////////////////
7391 /// List contents of the data directory in the sandbox.
7392 /// This is the place where files produced by the client queries are kept
7393 
7395 {
7396  if (!IsValid() || !fManager) return;
7397 
7398  // This is run via the manager
7399  fManager->Find("~/data", "-type f", "all");
7400 }
7401 
7402 ////////////////////////////////////////////////////////////////////////////////
7403 /// Remove files for the data directory.
7404 /// The option 'what' can take the values:
7405 /// kPurge remove all files and directories under '~/data'
7406 /// kUnregistered remove only files not in registered datasets (default)
7407 /// kDataset remove files belonging to dataset 'dsname'
7408 /// User is prompt for confirmation, unless kForceClear is ORed with the option
7409 
7410 void TProof::ClearData(UInt_t what, const char *dsname)
7411 {
7412  if (!IsValid() || !fManager) return;
7413 
7414  // Check whether we need to prompt
7415  TString prompt, a("Y");
7416  Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7417  Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7418 
7419  // If all just send the request
7420  if ((what & TProof::kPurge)) {
7421  // Prompt, if requested
7422  if (doask && !Prompt("Do you really want to remove all data files")) return;
7423  if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7424  Warning("ClearData", "problems purging data directory");
7425  return;
7426  } else if ((what & TProof::kDataset)) {
7427  // We must have got a name
7428  if (!dsname || strlen(dsname) <= 0) {
7429  Error("ClearData", "dataset name mandatory when removing a full dataset");
7430  return;
7431  }
7432  // Check if the dataset is registered
7433  if (!ExistsDataSet(dsname)) {
7434  Error("ClearData", "dataset '%s' does not exists", dsname);
7435  return;
7436  }
7437  // Get the file content
7438  TFileCollection *fc = GetDataSet(dsname);
7439  if (!fc) {
7440  Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7441  return;
7442  }
7443  // Prompt, if requested
7444  TString pmpt = TString::Format("Do you really want to remove all data files"
7445  " of dataset '%s'", dsname);
7446  if (doask && !Prompt(pmpt.Data())) return;
7447 
7448  // Loop through the files
7449  Bool_t rmds = kTRUE;
7450  TIter nxf(fc->GetList());
7451  TFileInfo *fi = 0;
7452  Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7453  while ((fi = (TFileInfo *) nxf())) {
7454  // Fill the host info
7455  TString host, file;
7456  // Take info from the current url
7457  if (!(fi->GetFirstUrl())) {
7458  Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7459  fi->GetName());
7460  continue;
7461  }
7462  TUrl uf(*(fi->GetFirstUrl()));
7463  file = uf.GetFile();
7464  host = uf.GetHost();
7465  // Now search for any "file:" url
7466  Int_t nurl = fi->GetNUrls();
7467  fi->ResetUrl();
7468  TUrl *up = 0;
7469  while (nurl-- && fi->NextUrl()) {
7470  up = fi->GetCurrentUrl();
7471  if (!strcmp(up->GetProtocol(), "file")) {
7472  TString opt(up->GetOptions());
7473  if (opt.BeginsWith("node=")) {
7474  host=opt;
7475  host.ReplaceAll("node=","");
7476  file = up->GetFile();
7477  break;
7478  }
7479  }
7480  }
7481  // Issue a remove request now
7482  if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7483  Error("ClearData", "problems removing '%s'", file.Data());
7484  // Some files not removed: keep the meta info about this dataset
7485  rmds = kFALSE;
7486  }
7487  rfiles++;
7488  ClearDataProgress(rfiles, nfiles);
7489  }
7490  fprintf(stderr, "\n");
7491  if (rmds) {
7492  // All files were removed successfully: remove also the dataset meta info
7493  RemoveDataSet(dsname);
7494  }
7495  } else if (what & TProof::kUnregistered) {
7496 
7497  // Get the existing files
7498  TString outtmp("ProofClearData_");
7499  FILE *ftmp = gSystem->TempFileName(outtmp);
7500  if (!ftmp) {
7501  Error("ClearData", "cannot create temp file for logs");
7502  return;
7503  }
7504  fclose(ftmp);
7506  gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7507  ShowData();
7508  gSystem->RedirectOutput(0, 0, &h);
7509  // Parse the output file now
7510  std::ifstream in;
7511  in.open(outtmp.Data());
7512  if (!in.is_open()) {
7513  Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7514  gSystem->Unlink(outtmp);
7515  return;
7516  }
7517  // Go through
7518  Int_t nfiles = 0;
7519  TMap *afmap = new TMap;
7520  TString line, host, file;
7521  Int_t from = 0;
7522  while (in.good()) {
7523  line.ReadLine(in);
7524  if (line.IsNull()) continue;
7525  while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7526  from = 0;
7527  host = "";
7528  if (!line.Tokenize(host, from, "| ")) continue;
7529  file = "";
7530  if (!line.Tokenize(file, from, "| ")) continue;
7531  if (!host.IsNull() && !file.IsNull()) {
7532  TList *fl = (TList *) afmap->GetValue(host.Data());
7533  if (!fl) {
7534  fl = new TList();
7535  fl->SetName(host);
7536  afmap->Add(new TObjString(host), fl);
7537  }
7538  fl->Add(new TObjString(file));
7539  nfiles++;
7540  PDB(kDataset,2)
7541  Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7542  } else {
7543  Warning("ClearData", "found incomplete line: '%s'", line.Data());
7544  }
7545  }
7546  // Close and remove the file
7547  in.close();
7548  gSystem->Unlink(outtmp);
7549 
7550  // Get registered data files
7551  TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7552  TMap *fcmap = GetDataSets(sel);
7553  if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7554  PDB(kDataset,1)
7555  Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7556  SafeDelete(fcmap);
7557  }
7558 
7559  // Go thorugh and prepare the lists per node
7560  TString opt;
7561  TObjString *os = 0;
7562  if (fcmap) {
7563  TIter nxfc(fcmap);
7564  while ((os = (TObjString *) nxfc())) {
7565  TFileCollection *fc = 0;
7566  if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7567  TFileInfo *fi = 0;
7568  TIter nxfi(fc->GetList());
7569  while ((fi = (TFileInfo *) nxfi())) {
7570  // Get special "file:" url
7571  fi->ResetUrl();
7572  Int_t nurl = fi->GetNUrls();
7573  TUrl *up = 0;
7574  while (nurl-- && fi->NextUrl()) {
7575  up = fi->GetCurrentUrl();
7576  if (!strcmp(up->GetProtocol(), "file")) {
7577  opt = up->GetOptions();
7578  if (opt.BeginsWith("node=")) {
7579  host=opt;
7580  host.ReplaceAll("node=","");
7581  file = up->GetFile();
7582  PDB(kDataset,2)
7583  Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7584  // Remove this from the full list, if there
7585  TList *fl = (TList *) afmap->GetValue(host.Data());
7586  if (fl) {
7587  TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7588  if (fn) {
7589  fl->Remove(fn);
7590  SafeDelete(fn);
7591  nfiles--;
7592  } else {
7593  Warning("ClearData",
7594  "registered file '%s' not found in the full list!",
7595  file.Data());
7596  }
7597  }
7598  break;
7599  }
7600  }
7601  }
7602  }
7603  }
7604  }
7605  // Clean up the the received map
7606  if (fcmap) fcmap->SetOwner(kTRUE);
7607  SafeDelete(fcmap);
7608  }
7609  // List of the files to be removed
7610  Info("ClearData", "%d unregistered files to be removed:", nfiles);
7611  afmap->Print();
7612  // Prompt, if requested
7613  TString pmpt = TString::Format("Do you really want to remove all %d"
7614  " unregistered data files", nfiles);
7615  if (doask && !Prompt(pmpt.Data())) return;
7616 
7617  // Remove one by one; we may implement a bloc remove in the future
7618  Int_t rfiles = 0;
7619  TIter nxls(afmap);
7620  while ((os = (TObjString *) nxls())) {
7621  TList *fl = 0;
7622  if ((fl = (TList *) afmap->GetValue(os))) {
7623  TIter nxf(fl);
7624  TObjString *fn = 0;
7625  while ((fn = (TObjString *) nxf())) {
7626  // Issue a remove request now
7627  if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7628  Error("ClearData", "problems removing '%s' on host '%s'",
7629  fn->GetName(), os->GetName());
7630  }
7631  rfiles++;
7632  ClearDataProgress(rfiles, nfiles);
7633  }
7634  }
7635  }
7636  fprintf(stderr, "\n");
7637  // Final cleanup
7638  afmap->SetOwner(kTRUE);
7639  SafeDelete(afmap);
7640  }
7641 }
7642 
7643 ////////////////////////////////////////////////////////////////////////////////
7644 /// Prompt the question 'p' requiring an answer y,Y,n,N
7645 /// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7646 
7647 Bool_t TProof::Prompt(const char *p)
7648 {
7649  TString pp(p);
7650  if (!pp.Contains("?")) pp += "?";
7651  if (!pp.Contains("[y/N]")) pp += " [y/N]";
7652  TString a = Getline(pp.Data());
7653  if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7654  Printf("Please answer y, Y, n or N");
7655  // Unclear answer: assume negative
7656  return kFALSE;
7657  } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7658  // Explicitly Negative answer
7659  return kFALSE;
7660  }
7661  // Explicitly Positive answer
7662  return kTRUE;
7663 }
7664 
7665 ////////////////////////////////////////////////////////////////////////////////
7666 /// Progress bar for clear data
7667 
7669 {
7670  fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7671  for (Int_t l = 0; l < 20; l++) {
7672  if (r > 0 && t > 0) {
7673  if (l < 20*r/t)
7674  fprintf(stderr, "=");
7675  else if (l == 20*r/t)
7676  fprintf(stderr, ">");
7677  else if (l > 20*r/t)
7678  fprintf(stderr, ".");
7679  } else
7680  fprintf(stderr, "=");
7681  }
7682  fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7683 }
7684 
7685 ////////////////////////////////////////////////////////////////////////////////
7686 /// List contents of file cache. If all is true show all caches also on
7687 /// slaves. If everything is ok all caches are to be the same.
7688 
7690 {
7691  if (!IsValid()) return;
7692 
7693  TMessage mess(kPROOF_CACHE);
7694  mess << Int_t(kShowCache) << all;
7695  Broadcast(mess, kUnique);
7696 
7697  if (all) {
7698  TMessage mess2(kPROOF_CACHE);
7699  mess2 << Int_t(kShowSubCache) << all;
7700  Broadcast(mess2, fNonUniqueMasters);
7701 
7703  } else {
7705  }
7706 }
7707 
7708 ////////////////////////////////////////////////////////////////////////////////
7709 /// Remove file from all file caches. If file is 0 or "" or "*", remove all
7710 /// the files
7711 
7712 void TProof::ClearCache(const char *file)
7713 {
7714  if (!IsValid()) return;
7715 
7716  TMessage mess(kPROOF_CACHE);
7717  mess << Int_t(kClearCache) << TString(file);
7718  Broadcast(mess, kUnique);
7719 
7720  TMessage mess2(kPROOF_CACHE);
7721  mess2 << Int_t(kClearSubCache) << TString(file);
7722  Broadcast(mess2, fNonUniqueMasters);
7723 
7725 
7726  // clear file map so files get send again to remote nodes
7727  fFileMap.clear();
7728 }
7729 
7730 ////////////////////////////////////////////////////////////////////////////////
7731 /// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7732 
7733 void TProof::SystemCmd(const char *cmd, Int_t fdout)
7734 {
7735  if (fdout < 0) {
7736  // Exec directly the command
7737  gSystem->Exec(cmd);
7738  } else {
7739  // Exec via a pipe
7740  FILE *fin = gSystem->OpenPipe(cmd, "r");
7741  if (fin) {
7742  // Now we go
7743  char line[2048];
7744  while (fgets(line, 2048, fin)) {
7745  Int_t r = strlen(line);
7746  if (r > 0) {
7747  if (write(fdout, line, r) < 0) {
7748  ::Warning("TProof::SystemCmd",
7749  "errno %d writing to file descriptor %d",
7750  TSystem::GetErrno(), fdout);
7751  }
7752  } else {
7753  // Done
7754  break;
7755  }
7756  }
7757  gSystem->ClosePipe(fin);
7758  }
7759  }
7760 }
7761 
7762 ////////////////////////////////////////////////////////////////////////////////
7763 /// List contents of package directory. If all is true show all package
7764 /// directories also on slaves. If everything is ok all package directories
7765 /// should be the same. If redir is kTRUE the result is redirected to the log
7766 /// file (option available for internal actions).
7767 
7769 {
7770  if (!IsValid()) return;
7771 
7772  Bool_t oldredir = fRedirLog;
7773  if (redirlog) fRedirLog = kTRUE;
7774 
7775  // Active logging unit
7776  FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7777  if (!fout) {
7778  Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7779  " will not log msgs", fout);
7780  return;
7781  }
7782  lseek(fileno(fout), (off_t) 0, SEEK_END);
7783 
7784  if (TestBit(TProof::kIsClient)) {
7786  // Scan the list of global packages dirs
7788  TNamed *nm = 0;
7789  while ((nm = (TNamed *)nxd())) {
7790  fprintf(fout, "*** Global Package cache %s client:%s ***\n",
7791  nm->GetName(), nm->GetTitle());
7792  fflush(fout);
7793  SystemCmd(TString::Format("%s %s", kLS, nm->GetTitle()), fileno(fout));
7794  fprintf(fout, "\n");
7795  fflush(fout);
7796  }
7797  }
7798  fprintf(fout, "*** Package cache client:%s ***\n", fPackageDir.Data());
7799  fflush(fout);
7800  SystemCmd(TString::Format("%s %s", kLS, fPackageDir.Data()), fileno(fout));
7801  fprintf(fout, "\n");
7802  }
7803 
7804  // Nothing more to do if we are a Lite-session
7805  if (IsLite()) {
7806  fRedirLog = oldredir;
7807  return;
7808  }
7809 
7810  TMessage mess(kPROOF_CACHE);
7811  mess << Int_t(kShowPackages) << all;
7812  Broadcast(mess, kUnique);
7813 
7814  if (all) {
7815  TMessage mess2(kPROOF_CACHE);
7816  mess2 << Int_t(kShowSubPackages) << all;
7817  Broadcast(mess2, fNonUniqueMasters);
7818 
7820  } else {
7822  }
7823  // Restore logging option
7824  fRedirLog = oldredir;
7825 }
7826 
7827 ////////////////////////////////////////////////////////////////////////////////
7828 /// List which packages are enabled. If all is true show enabled packages
7829 /// for all active slaves. If everything is ok all active slaves should
7830 /// have the same packages enabled.
7831 
7833 {
7834  if (!IsValid()) return;
7835 
7836  if (TestBit(TProof::kIsClient)) {
7837  printf("*** Enabled packages on client on %s\n", gSystem->HostName());
7839  while (TObjString *str = (TObjString*) next())
7840  printf("%s\n", str->GetName());
7841  }
7842 
7843  // Nothing more to do if we are a Lite-session
7844  if (IsLite()) return;
7845 
7846  TMessage mess(kPROOF_CACHE);
7847  mess << Int_t(kShowEnabledPackages) << all;
7848  Broadcast(mess);
7850 }
7851 
7852 ////////////////////////////////////////////////////////////////////////////////
7853 /// Remove all packages.
7854 /// Returns 0 in case of success and -1 in case of error.
7855 
7857 {
7858  if (!IsValid()) return -1;
7859 
7860  if (UnloadPackages() == -1)
7861  return -1;
7862 
7863  if (DisablePackages() == -1)
7864  return -1;
7865 
7866  return fStatus;
7867 }
7868 
7869 ////////////////////////////////////////////////////////////////////////////////
7870 /// Remove a specific package.
7871 /// Returns 0 in case of success and -1 in case of error.
7872 
7873 Int_t TProof::ClearPackage(const char *package)
7874 {
7875  if (!IsValid()) return -1;
7876 
7877  if (!package || !package[0]) {
7878  Error("ClearPackage", "need to specify a package name");
7879  return -1;
7880  }
7881 
7882  // if name, erroneously, is a par pathname strip off .par and path
7883  TString pac = package;
7884  if (pac.EndsWith(".par"))
7885  pac.Remove(pac.Length()-4);
7886  pac = gSystem->BaseName(pac);
7887 
7888  if (UnloadPackage(pac) == -1)
7889  return -1;
7890 
7891  if (DisablePackage(pac) == -1)
7892  return -1;
7893 
7894  return fStatus;
7895 }
7896 
7897 ////////////////////////////////////////////////////////////////////////////////
7898 /// Remove a specific package.
7899 /// Returns 0 in case of success and -1 in case of error.
7900 
7901 Int_t TProof::DisablePackage(const char *package)
7902 {
7903  if (!IsValid()) return -1;
7904 
7905  if (!package || !package[0]) {
7906  Error("DisablePackage", "need to specify a package name");
7907  return -1;
7908  }
7909 
7910  // if name, erroneously, is a par pathname strip off .par and path
7911  TString pac = package;
7912  if (pac.EndsWith(".par"))
7913  pac.Remove(pac.Length()-4);
7914  pac = gSystem->BaseName(pac);
7915 
7916  if (DisablePackageOnClient(pac) == -1)
7917  return -1;
7918 
7919  // Nothing more to do if we are a Lite-session
7920  if (IsLite()) return 0;
7921 
7922  Int_t st = -1;
7923  Bool_t done = kFALSE;
7924  if (fManager) {
7925  // Try to do it via XROOTD (new way)
7926  TString path;
7927  path.Form("~/packages/%s", package);
7928  if (fManager->Rm(path, "-rf", "all") != -1) {
7929  path.Append(".par");
7930  if (fManager->Rm(path, "-f", "all") != -1) {
7931  done = kTRUE;
7932  st = 0;
7933  }
7934  }
7935  }
7936  if (!done) {
7937  // Try via TProofServ (old way)
7938  TMessage mess(kPROOF_CACHE);
7939  mess << Int_t(kDisablePackage) << pac;
7940  Broadcast(mess, kUnique);
7941 
7942  TMessage mess2(kPROOF_CACHE);
7943  mess2 << Int_t(kDisableSubPackage) << pac;
7944  Broadcast(mess2, fNonUniqueMasters);
7945 
7947  st = fStatus;
7948  }
7949 
7950  // Done
7951  return st;
7952 }
7953 
7954 ////////////////////////////////////////////////////////////////////////////////
7955 /// Remove a specific package 'pack' from the client.
7956 /// Returns 0 in case of success and -1 in case of error.
7957 
7959 {
7960  TString s;
7961  if (TestBit(TProof::kIsClient)) {
7962  // Remove the package directory and the par file locally
7963  fPackageLock->Lock();
7964  s.Form("%s %s/%s", kRM, fPackageDir.Data(), pack);
7965  gSystem->Exec(s.Data());
7966  s.Form("%s %s/%s.par", kRM, fPackageDir.Data(), pack);
7967  gSystem->Exec(s.Data());
7968  s.Form("%s %s/%s/%s.par", kRM, fPackageDir.Data(), kPROOF_PackDownloadDir, pack);
7969  gSystem->Exec(s.Data());
7970  fPackageLock->Unlock();
7971  // Check the result
7972  s.Form("%s/%s/%s.par", fPackageDir.Data(), kPROOF_PackDownloadDir, pack);
7973  if (!gSystem->AccessPathName(s.Data()))
7974  Warning("DisablePackageOnClient",
7975  "unable to remove cached package PAR file for %s (%s)", pack, s.Data());
7976  s.Form("%s/%s.par", fPackageDir.Data(), pack);
7977  if (!gSystem->AccessPathName(s.Data()))
7978  Warning("DisablePackageOnClient",
7979  "unable to remove package PAR file for %s (%s)", pack, s.Data());
7980  s.Form("%s/%s", fPackageDir.Data(), pack);
7981  if (!gSystem->AccessPathName(s.Data()))
7982  Warning("DisablePackageOnClient",
7983  "unable to remove package directory for %s (%s)", pack, s.Data());
7984  }
7985 
7986  return 0;
7987 }
7988 
7989 ////////////////////////////////////////////////////////////////////////////////
7990 /// Remove all packages.
7991 /// Returns 0 in case of success and -1 in case of error.
7992 
7994 {
7995  if (!IsValid()) return -1;
7996 
7997  // remove all packages on client
7998  if (TestBit(TProof::kIsClient)) {
7999  fPackageLock->Lock();
8000  gSystem->Exec(TString::Format("%s %s/*", kRM, fPackageDir.Data()));
8001  fPackageLock->Unlock();
8002  }
8003 
8004  // Nothing more to do if we are a Lite-session
8005  if (IsLite()) return 0;
8006 
8007  Int_t st = -1;
8008  Bool_t done = kFALSE;
8009  if (fManager) {
8010  // Try to do it via XROOTD (new way)
8011  if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
8012  done = kTRUE;
8013  st = 0;
8014  }
8015  }
8016  if (!done) {
8017 
8018  TMessage mess(kPROOF_CACHE);
8019  mess << Int_t(kDisablePackages);
8020  Broadcast(mess, kUnique);
8021 
8022  TMessage mess2(kPROOF_CACHE);
8023  mess2 << Int_t(kDisableSubPackages);
8024  Broadcast(mess2, fNonUniqueMasters);
8025 
8027  st = fStatus;
8028  }
8029 
8030  // Done
8031  return st;
8032 }
8033 
8034 ////////////////////////////////////////////////////////////////////////////////
8035 /// Build specified package. Executes the PROOF-INF/BUILD.sh
8036 /// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
8037 /// then submit build command to slaves, but don't wait
8038 /// for results. If opt is kCollectBuildResults then collect result
8039 /// from slaves. To be used on the master.
8040 /// If opt = kBuildAll (default) then submit and wait for results
8041 /// (to be used on the client).
8042 /// Returns 0 in case of success and -1 in case of error.
8043 
8044 Int_t TProof::BuildPackage(const char *package,
8045  EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
8046 {
8047  if (!IsValid()) return -1;
8048 
8049  if (!package || !package[0]) {
8050  Error("BuildPackage", "need to specify a package name");
8051  return -1;
8052  }
8053 
8054  // if name, erroneously, is a par pathname strip off .par and path
8055  TString pac = package;
8056  if (pac.EndsWith(".par"))
8057  pac.Remove(pac.Length()-4);
8058  pac = gSystem->BaseName(pac);
8059 
8060  Bool_t buildOnClient = kTRUE;
8061  if (opt == kDontBuildOnClient) {
8062  buildOnClient = kFALSE;
8063  opt = kBuildAll;
8064  }
8065  // Prepare the local package
8066  TString pdir;
8067  Int_t st = 0;
8068  if (buildOnClient) {
8070  if ((st = BuildPackageOnClient(pac, 1, &pdir, chkveropt) != 0)) {
8072  return -1;
8073  }
8074  }
8075 
8076  if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
8077  if (workers) {
8078  TMessage mess(kPROOF_CACHE);
8079  mess << Int_t(kBuildPackage) << pac << chkveropt;
8080  Broadcast(mess, workers);
8081 
8082  } else {
8083  TMessage mess(kPROOF_CACHE);
8084  mess << Int_t(kBuildPackage) << pac << chkveropt;
8085  Broadcast(mess, kUnique);
8086 
8087  TMessage mess2(kPROOF_CACHE);
8088  mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8089  Broadcast(mess2, fNonUniqueMasters);
8090  }
8091  }
8092 
8093  if (opt >= kBuildAll) {
8094  // by first forwarding the build commands to the master and slaves
8095  // and only then building locally we build in parallel
8096  if (buildOnClient) {
8097  st = BuildPackageOnClient(pac, 2, &pdir, chkveropt);
8099  }
8100 
8101 
8102  fStatus = 0;
8103  if (!IsLite() || !buildOnClient) {
8104 
8105  // On the master, workers that fail are deactivated
8106  // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8107  if (workers) {
8108 // Collect(workers, -1, -1, deactivateOnFailure);
8109  Collect(workers);
8110  } else {
8112  }
8113  }
8114 
8115  if (fStatus < 0 || st < 0)
8116  return -1;
8117  }
8118 
8119  return 0;
8120 }
8121 
8122 ////////////////////////////////////////////////////////////////////////////////
8123 /// Build specified package on the client. Executes the PROOF-INF/BUILD.sh
8124 /// script if it exists on the client.
8125 /// If opt == 0, both the preparation and building phases are run.
8126 /// If opt == 1, only the preparation phase (asserting and, eventually, downloading
8127 /// of the package) is done; '*path' contains the full path to the
8128 /// package to be passed in the next call
8129 /// If opt == 2, only the building phase is run using *path .
8130 /// Returns 0 in case of success and -1 in case of error.
8131 /// The code is equivalent to the one in TProofServ.cxx (TProof::kBuildPackage
8132 /// case). Keep in sync in case of changes.
8133 
8134 Int_t TProof::BuildPackageOnClient(const char *pack, Int_t opt, TString *path, Int_t chkveropt)
8135 {
8136  TString downloaddir;
8137  downloaddir.Form("%s/%s", fPackageDir.Data(), kPROOF_PackDownloadDir);
8138 
8139  if (opt != 0 && !path) {
8140  Error("BuildPackageOnClient", "for opt=%d != 0 'patyh' must be defined", opt);
8141  return -1;
8142  }
8143 
8144  if (TestBit(TProof::kIsClient)) {
8145  Int_t status = 0;
8146  TString pdir, ocwd;
8147 
8148  if (opt == 0 || opt == 1) {
8149  // Package path
8150  pdir.Form("%s/%s", fPackageDir.Data(), pack);
8151  if (gSystem->AccessPathName(pdir, kReadPermission) ||
8152  gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
8153  pdir = "";
8154  // Is there a global package with this name?
8156  // Scan the list of global packages dirs
8158  TNamed *nm = 0;
8159  while ((nm = (TNamed *)nxd())) {
8160  pdir = Form("%s/%s", nm->GetTitle(), pack);
8161  if (!gSystem->AccessPathName(pdir, kReadPermission) &&
8162  !gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
8163  // Package found, stop searching
8164  break;
8165  }
8166  pdir = "";
8167  }
8168  }
8169  } else {
8170  // Check if the related PAR file still exists (private versions could have gone:
8171  // in such a case we should take the reference from the repository, by first cleaning
8172  // the existing directory)
8173  TString tpar(pdir);
8174  if (!tpar.EndsWith(".par")) tpar += ".par";
8175  Bool_t badPAR = kTRUE;
8176  FileStat_t stpar;
8177  if (gSystem->GetPathInfo(tpar, stpar) == 0) {
8178 #ifndef WIN32
8179  char ctmp[1024];
8180  if (!R_ISLNK(stpar.fMode) || readlink(tpar.Data(), ctmp, 1024) > 0) {
8181  // The file exists
8182  badPAR = kFALSE;
8183  }
8184 #else
8185  // The file exists
8186  badPAR = kFALSE;
8187 #endif
8188  }
8189  // Cleanup, if bad
8190  if (badPAR) {
8191  // Remove package directory
8192  gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
8193  // Remove link or bad file
8194  gSystem->Exec(TString::Format("%s %s", kRM, tpar.Data()));
8195  // Reset variable
8196  pdir = "";
8197  }
8198  }
8199  // Check if the package was downloaded from the master
8200  Bool_t wasDownloaded = kFALSE;
8201  TString dlpar;
8202  dlpar.Form("%s/%s", downloaddir.Data(), gSystem->BaseName(pack));
8203  if (!dlpar.EndsWith(".par")) dlpar += ".par";
8204  if (!pdir.IsNull()) {
8205  if (!gSystem->AccessPathName(dlpar, kFileExists))
8206  wasDownloaded = kTRUE;
8207  }
8208  if (pdir.IsNull() || wasDownloaded) {
8209  // Try to download it
8210  if (DownloadPackage(pack, downloaddir) != 0) {
8211  Error("BuildPackageOnClient",
8212  "PAR file '%s.par' not found and could not be downloaded", pack);
8213  return -1;
8214  } else {
8215  TMD5 *md5 = TMD5::FileChecksum(dlpar);
8216  if (UploadPackageOnClient(dlpar, kUntar, md5) == -1) {
8217  Error("BuildPackageOnClient",
8218  "PAR file '%s.par' not found and could not be unpacked locally", pack);
8219  delete md5;
8220  return -1;
8221  }
8222  delete md5;
8223  // The package is now linked from the default package dir
8224  pdir.Form("%s/%s", fPackageDir.Data(), pack);
8225  }
8226  } else if (pdir.IsNull()) {
8227  Error("BuildPackageOnClient", "PAR file '%s.par' not found", pack);
8228  return -1;
8229  }
8230  PDB(kPackage, 1)
8231  Info("BuildPackageOnClient", "package %s exists and has PROOF-INF directory", pack);
8232  // We are done if only prepare was requested
8233  if (opt == 1) {
8234  *path = pdir;
8235  return 0;
8236  }
8237  }
8238 
8239  if (opt == 0 || opt == 2) {
8240  if (opt == 2) pdir = path->Data();
8241 
8242  ocwd = gSystem->WorkingDirectory();
8243  gSystem->ChangeDirectory(pdir);
8244 
8245  // check for BUILD.sh and execute
8246  if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
8247 
8248  // read version from file proofvers.txt, and if current version is
8249  // not the same do a "BUILD.sh clean"
8250  Bool_t goodver = kTRUE;
8251  Bool_t savever = kFALSE;
8252  TString v, r;
8253  FILE *f = fopen("PROOF-INF/proofvers.txt", "r");
8254  if (f) {
8255  v.Gets(f);
8256  r.Gets(f);
8257  fclose(f);
8258  if (chkveropt == kCheckROOT || chkveropt == kCheckSVN) {
8259  if (v != gROOT->GetVersion()) goodver = kFALSE;
8260  if (goodver && chkveropt == kCheckSVN)
8261  if (r != gROOT->GetGitCommit()) goodver = kFALSE;
8262  }
8263  }
8264  if (!f || !goodver) {
8265  savever = kTRUE;
8266  Info("BuildPackageOnClient",
8267  "%s: version change (current: %s:%s, build: %s:%s): cleaning ... ",
8268  pack, gROOT->GetVersion(), gROOT->GetGitCommit(), v.Data(), r.Data());
8269  // Hard cleanup: go up the dir tree
8271  // remove package directory
8272  gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
8273  // find gunzip...
8274  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP, kExecutePermission);
8275  if (gunzip) {
8276  TString par = TString::Format("%s.par", pdir.Data());
8277  // untar package
8278  TString cmd(TString::Format(kUNTAR3, gunzip, par.Data()));
8279  status = gSystem->Exec(cmd);
8280  if ((status = gSystem->Exec(cmd))) {
8281  Error("BuildPackageOnClient", "failure executing: %s", cmd.Data());
8282  } else {
8283  // Go down to the package directory
8284  gSystem->ChangeDirectory(pdir);
8285  }
8286  delete [] gunzip;
8287  } else {
8288  Error("BuildPackageOnClient", "%s not found", kGUNZIP);
8289  status = -1;
8290  }
8291  }
8292 
8293  if (gSystem->Exec("export ROOTPROOFCLIENT=\"1\" ; PROOF-INF/BUILD.sh")) {
8294  Error("BuildPackageOnClient", "building package %s on the client failed", pack);
8295  status = -1;
8296  }
8297 
8298  if (savever && !status) {
8299  f = fopen("PROOF-INF/proofvers.txt", "w");
8300  if (f) {
8301  fputs(gROOT->GetVersion(), f);
8302  fputs(TString::Format("\n%s", gROOT->GetGitCommit()), f);
8303  fclose(f);
8304  }
8305  }
8306  } else {
8307  PDB(kPackage, 1)
8308  Info("BuildPackageOnClient",
8309  "package %s exists but has no PROOF-INF/BUILD.sh script", pack);
8310  }
8311 
8312  gSystem->ChangeDirectory(ocwd);
8313 
8314  return status;
8315  }
8316  }
8317  return 0;
8318 }
8319 
8320 ////////////////////////////////////////////////////////////////////////////////
8321 /// Load specified package. Executes the PROOF-INF/SETUP.C script
8322 /// on all active nodes. If notOnClient = true, don't load package
8323 /// on the client. The default is to load the package also on the client.
8324 /// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8325 /// The objects in the list must be streamable; the SETUP macro will be executed
8326 /// like this: SETUP.C(loadopts).
8327 /// Returns 0 in case of success and -1 in case of error.
8328 
8329 Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8330  TList *loadopts, TList *workers)
8331 {
8332  if (!IsValid()) return -1;
8333 
8334  if (!package || !package[0]) {
8335  Error("LoadPackage", "need to specify a package name");
8336  return -1;
8337  }
8338 
8339  // if name, erroneously, is a par pathname strip off .par and path
8340  TString pac = package;
8341  if (pac.EndsWith(".par"))
8342  pac.Remove(pac.Length()-4);
8343  pac = gSystem->BaseName(pac);
8344 
8345  if (!notOnClient)
8346  if (LoadPackageOnClient(pac, loadopts) == -1)
8347  return -1;
8348 
8349  TMessage mess(kPROOF_CACHE);
8350  mess << Int_t(kLoadPackage) << pac;
8351  if (loadopts) mess << loadopts;
8352 
8353  // On the master, workers that fail are deactivated
8354  Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8355 
8356  Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8357 
8358  if (workers) {
8359  PDB(kPackage, 3)
8360  Info("LoadPackage", "Sending load message to selected workers only");
8361  Broadcast(mess, workers);
8362  if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8363  } else {
8364  Broadcast(mess);
8365  Collect(kActive, -1, -1, deactivateOnFailure);
8366  }
8367 
8368  return fStatus;
8369 }
8370 
8371 ////////////////////////////////////////////////////////////////////////////////
8372 /// Load specified package in the client. Executes the PROOF-INF/SETUP.C
8373 /// script on the client. Returns 0 in case of success and -1 in case of error.
8374 /// The code is equivalent to the one in TProofServ.cxx (TProof::kLoadPackage
8375 /// case). Keep in sync in case of changes.
8376 /// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8377 /// The objects in the list must be streamable; the SETUP macro will be executed
8378 /// like this: SETUP.C(loadopts).
8379 /// Returns 0 in case of success and -1 in case of error.
8380 
8381 Int_t TProof::LoadPackageOnClient(const char *pack, TList *loadopts)
8382 {
8383  if (TestBit(TProof::kIsClient)) {
8384  Int_t status = 0;
8385  TString pdir, ocwd;
8386  // If already loaded don't do it again
8387  if (fEnabledPackagesOnClient->FindObject(pack)) {
8388  Info("LoadPackageOnClient", "package %s already loaded", pack);
8389  return 0;
8390  }
8391 
8392  // always follows BuildPackage so no need to check for PROOF-INF
8393  pdir.Form("%s/%s", fPackageDir.Data(), pack);
8394 
8395  if (gSystem->AccessPathName(pdir, kReadPermission)) {
8396  // Is there a global package with this name?
8398  // Scan the list of global packages dirs
8400  TNamed *nm = 0;
8401  while ((nm = (TNamed *)nxd())) {
8402  pdir.Form("%s/%s", nm->GetTitle(), pack);
8403  if (!gSystem->AccessPathName(pdir, kReadPermission)) {
8404  // Package found, stop searching
8405  break;
8406  }
8407  pdir = "";
8408  }
8409  if (pdir.Length() <= 0) {
8410  // Package not found
8411  Error("LoadPackageOnClient", "failure locating %s ...", pack);
8412  return -1;
8413  }
8414  }
8415  }
8416 
8417  ocwd = gSystem->WorkingDirectory();
8418  gSystem->ChangeDirectory(pdir);
8419 
8420  // check for SETUP.C and execute
8421  if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
8422 
8423  // We need to change the name of the function to avoid problems when we load more packages
8424  TString setup;
8425  setup.Form("SETUP_%d_%x", gSystem->GetPid(), TString(pack).Hash());
8426  // setupfn.Form("%s/%s.C", gSystem->TempDirectory(), setup.Data());
8427  TMacro setupmc("PROOF-INF/SETUP.C");
8428  TObjString *setupline = setupmc.GetLineWith("SETUP(");
8429  if (setupline) {
8430  TString setupstring(setupline->GetString());
8431  setupstring.ReplaceAll("SETUP(", TString::Format("%s(", setup.Data()));
8432  setupline->SetString(setupstring);
8433  } else {
8434  // Macro does not contain SETUP()
8435  Warning("LoadPackageOnClient", "macro '%s/PROOF-INF/SETUP.C' does not contain a SETUP()"
8436  " function", pack);
8437  }
8438 
8439  if (!setupmc.Load()) {
8440  // Macro could not be loaded
8441  Error("LoadPackageOnClient", "macro '%s/PROOF-INF/SETUP.C' could not be loaded:"
8442  " cannot continue", pack);
8443  status = -1;
8444  } else {
8445  // Check the signature
8446  TFunction *fun = (TFunction *) gROOT->GetListOfGlobalFunctions()->FindObject(setup);
8447  if (!fun) {
8448  // Notify the upper level
8449  Error("LoadPackageOnClient", "function SETUP() not found in macro '%s/PROOF-INF/SETUP.C':"
8450  " cannot continue", pack);
8451  status = -1;
8452  } else {
8453  TMethodCall callEnv;
8454  // Check the number of arguments
8455  if (fun->GetNargs() == 0) {
8456  // No arguments (basic signature)
8457  callEnv.Init(fun);
8458  // Warn that the argument (if any) if ignored
8459  if (loadopts)
8460  Warning("LoadPackageOnClient", "loaded SETUP() does not take any argument:"
8461  " the specified TList object will be ignored");
8462  } else if (fun->GetNargs() == 1) {
8463  TMethodArg *arg = (TMethodArg *) fun->GetListOfMethodArgs()->First();
8464  if (arg) {
8465  callEnv.Init(fun);
8466  // Check argument type
8467  TString argsig(arg->GetTitle());
8468  if (argsig.BeginsWith("TList")) {
8469  callEnv.ResetParam();
8470  callEnv.SetParam((Long_t) loadopts);
8471  } else if (argsig.BeginsWith("const char")) {
8472  callEnv.ResetParam();
8473  TObjString *os = loadopts ? dynamic_cast<TObjString *>(loadopts->First()) : 0;
8474  if (os) {
8475  callEnv.SetParam((Long_t) os->GetName());
8476  } else {
8477  if (loadopts && loadopts->First()) {
8478  Warning("LoadPackageOnClient", "found object argument of type %s:"
8479  " SETUP expects 'const char *': ignoring",
8480  loadopts->First()->ClassName());
8481  }
8482  callEnv.SetParam((Long_t) 0);
8483  }
8484  } else {
8485  // Notify the upper level
8486  Error("LoadPackageOnClient", "unsupported SETUP signature: SETUP(%s)"
8487  " cannot continue", arg->GetTitle());
8488  status = -1;
8489  }
8490  } else {
8491  // Notify the upper level
8492  Error("LoadPackageOnClient", "cannot get information about the SETUP() argument:"
8493  " cannot continue");
8494  status = -1;
8495  }
8496  } else if (fun->GetNargs() > 1) {
8497  // Notify the upper level
8498  Error("LoadPackageOnClient", "function SETUP() can have at most a 'TList *' argument:"
8499  " cannot continue");
8500  status = -1;
8501  }
8502  // Execute
8503  Long_t setuprc = (status == 0) ? 0 : -1;
8504  if (status == 0) {
8505  callEnv.Execute(setuprc);
8506  if (setuprc < 0) status = -1;
8507  }
8508  }
8509  }
8510  } else {
8511  PDB(kPackage, 1)
8512  Info("LoadPackageOnClient",
8513  "package %s exists but has no PROOF-INF/SETUP.C script", pack);
8514  }
8515 
8516  gSystem->ChangeDirectory(ocwd);
8517 
8518  if (status == 0) {
8519 
8520  // Add package directory to list of include directories to be searched by ACliC
8521  gSystem->AddIncludePath(TString("-I") + pdir);
8522 
8523  // add package directory to list of include directories to be searched by CINT
8524  gROOT->ProcessLine(TString(".I ") + pdir);
8525 
8527  PDB(kPackage, 1)
8528  Info("LoadPackageOnClient", "package %s successfully loaded", pack);
8529  } else
8530  Error("LoadPackageOnClient", "loading package %s on client failed", pack);
8531 
8532  return status;
8533  }
8534  return 0;
8535 }
8536 
8537 ////////////////////////////////////////////////////////////////////////////////
8538 /// Unload specified package.
8539 /// Returns 0 in case of success and -1 in case of error.
8540 
8541 Int_t TProof::UnloadPackage(const char *package)
8542 {
8543  if (!IsValid()) return -1;
8544 
8545  if (!package || !package[0]) {
8546  Error("UnloadPackage", "need to specify a package name");
8547  return -1;
8548  }
8549 
8550  // if name, erroneously, is a par pathname strip off .par and path
8551  TString pac = package;
8552  if (pac.EndsWith(".par"))
8553  pac.Remove(pac.Length()-4);
8554  pac = gSystem->BaseName(pac);
8555 
8556  if (UnloadPackageOnClient(pac) == -1)
8557  return -1;
8558 
8559  // Nothing more to do if we are a Lite-session
8560  if (IsLite()) return 0;
8561 
8562  TMessage mess(kPROOF_CACHE);
8563  mess << Int_t(kUnloadPackage) << pac;
8564  Broadcast(mess);
8565  Collect();
8566 
8567  return fStatus;
8568 }
8569 
8570 ////////////////////////////////////////////////////////////////////////////////
8571 /// Unload a specific package on the client.
8572 /// Returns 0 in case of success and -1 in case of error.
8573 /// The code is equivalent to the one in TProofServ.cxx (TProof::UnloadPackage
8574 /// case). Keep in sync in case of changes.
8575 
8577 {
8578  if (TestBit(TProof::kIsClient)) {
8580  if (pack) {
8581  // Remove entry from include path
8582  TString aclicincpath = gSystem->GetIncludePath();
8583  TString cintincpath = gInterpreter->GetIncludePath();
8584  // remove interpreter part of gSystem->GetIncludePath()
8585  aclicincpath.Remove(aclicincpath.Length() - cintincpath.Length() - 1);
8586  // remove package's include path
8587  aclicincpath.ReplaceAll(TString(" -I") + package, "");
8588  gSystem->SetIncludePath(aclicincpath);
8589 
8590  //TODO reset interpreter include path
8591 
8592  // remove entry from enabled packages list
8594  }
8595 
8596  // cleanup the link
8597  if (!gSystem->AccessPathName(package))
8598  if (gSystem->Unlink(package) != 0)
8599  Warning("UnloadPackageOnClient", "unable to remove symlink to %s", package);
8600 
8601  // delete entry
8602  delete pack;
8603  }
8604  return 0;
8605 }
8606 
8607 ////////////////////////////////////////////////////////////////////////////////
8608 /// Unload all packages.
8609 /// Returns 0 in case of success and -1 in case of error.
8610 
8612 {
8613  if (!IsValid()) return -1;
8614 
8615  if (TestBit(TProof::kIsClient)) {
8616  // Iterate over packages on the client and remove each package
8617  TIter nextpackage(fEnabledPackagesOnClient);
8618  while (TObjString *objstr = dynamic_cast<TObjString*>(nextpackage()))
8619  if (UnloadPackageOnClient(objstr->String()) == -1 )
8620  return -1;
8621  }
8622 
8623  // Nothing more to do if we are a Lite-session
8624  if (IsLite()) return 0;
8625 
8626  TMessage mess(kPROOF_CACHE);
8627  mess << Int_t(kUnloadPackages);
8628  Broadcast(mess);
8629  Collect();
8630 
8631  return fStatus;
8632 }
8633 
8634 ////////////////////////////////////////////////////////////////////////////////
8635 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8636 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8637 /// In case notOnClient = true, don't enable the package on the client.
8638 /// The default is to enable packages also on the client.
8639 /// If specified, enables packages only on the specified workers.
8640 /// Returns 0 in case of success and -1 in case of error.
8641 /// Provided for backward compatibility.
8642 
8643 Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8644  TList *workers)
8645 {
8646  return EnablePackage(package, (TList *)0, notOnClient, workers);
8647 }
8648 
8649 ////////////////////////////////////////////////////////////////////////////////
8650 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8651 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8652 /// In case notOnClient = true, don't enable the package on the client.
8653 /// The default is to enable packages also on the client.
8654 /// It is is possible to specify options for the loading step via 'loadopts';
8655 /// the string will be passed passed as argument to SETUP.
8656 /// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8657 /// plugin version checking during building: possible choices are:
8658 /// off no check; failure may occur at loading
8659 /// on check ROOT version [default]
8660 /// svn check ROOT version and Git commit SHA1.
8661 /// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8662 /// If specified, enables packages only on the specified workers.
8663 /// Returns 0 in case of success and -1 in case of error.
8664 
8665 Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8666  Bool_t notOnClient, TList *workers)
8667 {
8668  TList *optls = 0;
8669  if (loadopts && strlen(loadopts)) {
8670  if (fProtocol > 28) {
8671  TObjString *os = new TObjString(loadopts);
8672  // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8673  os->String().ReplaceAll("checkversion=", "chkv=");
8674  Ssiz_t fcv = kNPOS, lcv = kNPOS;
8675  if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8676  TRegexp re("[; |]");
8677  if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8678  lcv = os->String().Length();
8679  }
8680  TString ocv = os->String()(fcv, lcv - fcv);
8681  Int_t cvopt = -1;
8682  if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8683  cvopt = (Int_t) kDontCheck;
8684  else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8685  cvopt = (Int_t) kCheckROOT;
8686  else if (ocv.EndsWith("=svn") || ocv.EndsWith("=2"))
8687  cvopt = (Int_t) kCheckSVN;
8688  else
8689  Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8690  if (cvopt > -1) {
8691  if (gDebug > 0)
8692  Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8693  optls = new TList;
8694  optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8695  // Remove the special option from; we leave a separator if there were two (one before and one after)
8696  if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8697  if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8698  os->String().ReplaceAll(ocv.Data(), "");
8699  }
8700  }
8701  if (!os->String().IsNull()) {
8702  if (!optls) optls = new TList;
8703  optls->Add(new TObjString(os->String().Data()));
8704  }
8705  if (optls) optls->SetOwner(kTRUE);
8706  } else {
8707  // Notify
8708  Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8709  }
8710  }
8711  // Run
8712  Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8713  // Clean up
8714  SafeDelete(optls);
8715  // Done
8716  return rc;
8717 }
8718 
8719 ////////////////////////////////////////////////////////////////////////////////
8720 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8721 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8722 /// In case notOnClient = true, don't enable the package on the client.
8723 /// The default is to enable packages also on the client.
8724 /// It is is possible to specify a list of objects to be passed to the SETUP
8725 /// functions via 'loadopts'; the objects must be streamable.
8726 /// Returns 0 in case of success and -1 in case of error.
8727 
8728 Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8729  Bool_t notOnClient, TList *workers)
8730 {
8731  if (!IsValid()) return -1;
8732 
8733  if (!package || !package[0]) {
8734  Error("EnablePackage", "need to specify a package name");
8735  return -1;
8736  }
8737 
8738  // if name, erroneously, is a par pathname strip off .par and path
8739  TString pac = package;
8740  if (pac.EndsWith(".par"))
8741  pac.Remove(pac.Length()-4);
8742  pac = gSystem->BaseName(pac);
8743 
8745  if (notOnClient)
8746  opt = kDontBuildOnClient;
8747 
8748  // Get check version option; user settings have priority
8749  Int_t chkveropt = kCheckROOT;
8750  TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8751  if (!ocv.IsNull()) {
8752  if (ocv == "off" || ocv == "0")
8753  chkveropt = (Int_t) kDontCheck;
8754  else if (ocv == "on" || ocv == "1")
8755  chkveropt = (Int_t) kCheckROOT;
8756  else if (ocv == "svn" || ocv == "2")
8757  chkveropt = (Int_t) kCheckSVN;
8758  else
8759  Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8760  }
8761  if (loadopts) {
8762  TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8763  if (pcv) {
8764  chkveropt = pcv->GetVal();
8765  loadopts->Remove(pcv);
8766  delete pcv;
8767  }
8768  }
8769  if (gDebug > 0)
8770  Info("EnablePackage", "using check version option: %d", chkveropt);
8771 
8772  if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8773  return -1;
8774 
8775  TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8776  if (optls && fProtocol <= 28) {
8777  Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8778  optls = 0;
8779  }
8780 
8781  if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8782  return -1;
8783 
8784  // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8786  TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8787  : new TPair(new TObjString(pac), 0);
8789  }
8790 
8791  return 0;
8792 }
8793 
8794 ////////////////////////////////////////////////////////////////////////////////
8795 /// Download a PROOF archive (PAR file) from the master package repository.
8796 /// The PAR file is downloaded in the current directory or in the directory
8797 /// specified by 'dstdir'. If a package with the same name already exists
8798 /// at destination, a check on the MD5 sum is done and the user warned or
8799 /// prompted for action, depending is the file is equal or different.
8800 /// Returns 0 in case of success and -1 in case of error.
8801 
8802 Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8803 {
8804  if (!fManager || !(fManager->IsValid())) {
8805  Error("DownloadPackage", "the manager is undefined!");
8806  return -1;
8807  }
8808 
8809  // Create the default source and destination paths
8810  TString parname(gSystem->BaseName(pack)), src, dst;
8811  if (!parname.EndsWith(".par")) parname += ".par";
8812  src.Form("packages/%s", parname.Data());
8813  if (!dstdir || strlen(dstdir) <= 0) {
8814  dst.Form("./%s", parname.Data());
8815  } else {
8816  // Check the destination directory
8817  FileStat_t st;
8818  if (gSystem->GetPathInfo(dstdir, st) != 0) {
8819  // Directory does not exit: create it
8820  if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8821  Error("DownloadPackage",
8822  "could not create the destination directory '%s' (errno: %d)",
8823  dstdir, TSystem::GetErrno());
8824  return -1;
8825  }
8826  } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8827  Error("DownloadPackage",
8828  "destination path '%s' exist but is not a directory!", dstdir);
8829  return -1;
8830  }
8831  dst.Form("%s/%s", dstdir, parname.Data());
8832  }
8833 
8834  // Make sure the source file exists
8835  FileStat_t stsrc;
8836  RedirectHandle_t rh;
8837  if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8838  Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8839  Int_t rc = fManager->Stat(src, stsrc);
8840  if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8841  Warning("DownloadPackage", "problems restoring output");
8842  if (rc != 0) {
8843  // Check if there is another possible source
8845  TMacro *mp = GetLastLog();
8846  if (mp) {
8847  // Look for global directories
8848  Bool_t isGlobal = kFALSE;
8849  TIter nxl(mp->GetListOfLines());
8850  TObjString *os = 0;
8851  TString globaldir;
8852  while ((os = (TObjString *) nxl())) {
8853  TString s(os->GetName());
8854  if (s.Contains("*** Global Package cache")) {
8855  // Get the directory
8856  s.Remove(0, s.Last(':') + 1);
8857  s.Remove(s.Last(' '));
8858  globaldir = s;
8859  isGlobal = kTRUE;
8860  } else if (s.Contains("*** Package cache")) {
8861  isGlobal = kFALSE;
8862  globaldir = "";
8863  }
8864  // Check for the package
8865  if (isGlobal && s.Contains(parname)) {
8866  src.Form("%s/%s", globaldir.Data(), parname.Data());
8867  break;
8868  }
8869  }
8870  // Cleanup
8871  delete mp;
8872  }
8873  }
8874 
8875  // Do it via the manager
8876  if (fManager->GetFile(src, dst, "silent") != 0) {
8877  Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8878  pack, src.Data(), dst.Data());
8879  return -1;
8880  } else {
8881  Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8882  pack, dst.Data());
8883  }
8884  // Done
8885  return 0;
8886 }
8887 
8888 ////////////////////////////////////////////////////////////////////////////////
8889 /// Upload a PROOF archive (PAR file). A PAR file is a compressed
8890 /// tar file with one special additional directory, PROOF-INF
8891 /// (blatantly copied from Java's jar format). It must have the extension
8892 /// .par. A PAR file can be directly a binary or a source with a build
8893 /// procedure. In the PROOF-INF directory there can be a build script:
8894 /// BUILD.sh to be called to build the package, in case of a binary PAR
8895 /// file don't specify a build script or make it a no-op. Then there is
8896 /// SETUP.C which sets the right environment variables to use the package,
8897 /// like LD_LIBRARY_PATH, etc.
8898 /// The 'opt' allows to specify whether the .PAR should be just unpacked
8899 /// in the existing dir (opt = kUntar, default) or a remove of the existing
8900 /// directory should be executed (opt = kRemoveOld), so triggering a full
8901 /// re-build. The option if effective only for PROOF protocol > 8 .
8902 /// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8903 /// an alternative global directory for global usage. This may require special
8904 /// privileges.
8905 /// If download is kTRUE and the package is not found locally, then it is downloaded
8906 /// from the master repository.
8907 /// Returns 0 in case of success and -1 in case of error.
8908 
8910  TList *workers)
8911 {
8912  if (!IsValid()) return -1;
8913 
8914  TString par(pack), base, name;
8915  if (par.EndsWith(".par")) {
8916  base = gSystem->BaseName(par);
8917  name = base(0, base.Length() - strlen(".par"));
8918  } else {
8919  name = gSystem->BaseName(par);
8920  base.Form("%s.par", name.Data());
8921  par += ".par";
8922  }
8923 
8924  // Default location is the local working dir; then the package dir
8927  TString tried = par;
8928  // Try the package dir
8929  par.Form("%s/%s", fPackageDir.Data(), base.Data());
8931  // Is the package a global one
8933  // Scan the list of global packages dirs
8935  TNamed *nm = 0;
8936  TString pdir;
8937  while ((nm = (TNamed *)nxd())) {
8938  pdir.Form("%s/%s", nm->GetTitle(), name.Data());
8939  if (!gSystem->AccessPathName(pdir, kReadPermission)) {
8940  // Package found, stop searching
8941  break;
8942  }
8943  pdir = "";
8944  }
8945  if (pdir.Length() > 0) {
8946  // Package is in the global dirs
8947  if (gDebug > 0)
8948  Info("UploadPackage", "global package found (%s): no upload needed",
8949  pdir.Data());
8950  return 0;
8951  }
8952  }
8953  Error("UploadPackage", "PAR file '%s' not found; paths tried: %s, %s",
8954  gSystem->BaseName(par), tried.Data(), par.Data());
8955  return -1;
8956  }
8957  }
8958 
8959  // Strategy:
8960  // On the client:
8961  // get md5 of package and check if it is different
8962  // from the one stored in the local package directory. If it is lock
8963  // the package directory and copy the package, unlock the directory.
8964  // On the masters:
8965  // get md5 of package and check if it is different from the
8966  // one stored on the remote node. If it is different lock the remote
8967  // package directory and use TFTP or SendFile to ftp the package to the
8968  // remote node, unlock the directory.
8969 
8970  TMD5 *md5 = TMD5::FileChecksum(par);
8971 
8972  if (TestBit(TProof::kIsClient)) {
8973  if (!md5 || (md5 && UploadPackageOnClient(par, opt, md5) == -1)) {
8974  if (md5) delete md5;
8975  return -1;
8976  }
8977  }
8978 
8979  // Nothing more to do if we are a Lite-session
8980  if (IsLite()) {
8981  delete md5;
8982  return 0;
8983  }
8984 
8985  TString smsg;
8986  smsg.Form("+%s", base.Data());
8987 
8988  TMessage mess(kPROOF_CHECKFILE);
8989  mess << smsg << (*md5);
8990  TMessage mess2(kPROOF_CHECKFILE);
8991  smsg.Replace(0, 1, "-");
8992  mess2 << smsg << (*md5);
8993  TMessage mess3(kPROOF_CHECKFILE);
8994  smsg.Replace(0, 1, "=");
8995  mess3 << smsg << (*md5);
8996 
8997  delete md5;
8998 
8999  if (fProtocol > 8) {
9000  // Send also the option
9001  mess << (UInt_t) opt;
9002  mess2 << (UInt_t) opt;
9003  mess3 << (UInt_t) opt;
9004  }
9005 
9006  // Loop over all slaves with unique fs image, or to a selected
9007  // list of workers, if specified
9008  if (!workers)
9009  workers = fUniqueSlaves;
9010  TIter next(workers);
9011  TSlave *sl = 0;
9012  while ((sl = (TSlave *) next())) {
9013  if (!sl->IsValid())
9014  continue;
9015 
9016  sl->GetSocket()->Send(mess);
9017 
9018  fCheckFileStatus = 0;
9020  if (fCheckFileStatus == 0) {
9021 
9022  if (fProtocol > 5) {
9023  // remote directory is locked, upload file over the open channel
9024  smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
9025  if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
9026  Error("UploadPackage", "%s: problems uploading file %s",
9027  sl->GetOrdinal(), par.Data());
9028  return -1;
9029  }
9030  } else {
9031  // old servers receive it via TFTP
9032  TFTP ftp(TString("root://")+sl->GetName(), 1);
9033  if (!ftp.IsZombie()) {
9034  smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
9035  ftp.cd(smsg.Data());
9036  ftp.put(par, base.Data());
9037  }
9038  }
9039 
9040  // install package and unlock dir
9041  sl->GetSocket()->Send(mess2);
9042  fCheckFileStatus = 0;
9044  if (fCheckFileStatus == 0) {
9045  Error("UploadPackage", "%s: unpacking of package %s failed",
9046  sl->GetOrdinal(), base.Data());
9047  return -1;
9048  }
9049  }
9050  }
9051 
9052  // loop over all other master nodes
9053  TIter nextmaster(fNonUniqueMasters);
9054  TSlave *ma;
9055  while ((ma = (TSlave *) nextmaster())) {
9056  if (!ma->IsValid())
9057  continue;
9058 
9059  ma->GetSocket()->Send(mess3);
9060 
9061  fCheckFileStatus = 0;
9063  if (fCheckFileStatus == 0) {
9064  // error -> package should have been found
9065  Error("UploadPackage", "package %s did not exist on submaster %s",
9066  base.Data(), ma->GetOrdinal());
9067  return -1;
9068  }
9069  }
9070 
9071  return 0;
9072 }
9073 
9074 ////////////////////////////////////////////////////////////////////////////////
9075 /// Upload a package on the client in ~/.proof/packages.
9076 /// The 'opt' allows to specify whether the .PAR should be just unpacked
9077 /// in the existing dir (opt = kUntar, default) or a remove of the existing
9078 /// directory should be executed (opt = kRemoveOld), thereby triggering a full
9079 /// re-build. This option if effective only for PROOF protocol > 8.
9080 /// Returns 0 in case of success and -1 in case of error.
9081 
9083 {
9084  // Strategy:
9085  // get md5 of package and check if it is different
9086  // from the one stored in the local package directory. If it is lock
9087  // the package directory and copy the package, unlock the directory.
9088 
9089  Int_t status = 0;
9090 
9091  if (TestBit(TProof::kIsClient)) {
9092  // Make sure that 'par' is the real path and not a symlink
9093  TString par(parpack);
9094 #ifndef WIN32
9095  char ctmp[4096];
9096  ssize_t sz = readlink(par.Data(), ctmp, 4096);
9097  if (sz >= 4096) sz = 4095;
9098  if (sz > 0) {
9099  ctmp[sz] = '\0';
9100  par = ctmp;
9101  } else if (TSystem::GetErrno() != EINVAL) {
9102  Warning("UploadPackageOnClient",
9103  "could not resolve the symbolik link '%s'", par.Data());
9104  }
9105 #endif
9106  // The fPackageDir directory exists (has been created in Init());
9107  // create symlink to the par file in the fPackageDir (needed by
9108  // master in case we run on the localhost)
9109  fPackageLock->Lock();
9110 
9111  // Check if the requested PAR has been downloaded: if not, clean any
9112  // existing downloaded file with the same name: this is because now
9113  // the client has its own version of the package and should not check
9114  // the master repository anymore for updates
9115  TString downloadpath;
9116  downloadpath.Form("%s/%s/%s", fPackageDir.Data(),
9118  if (!gSystem->AccessPathName(downloadpath, kFileExists) && downloadpath != par) {
9119  if (gSystem->Unlink(downloadpath) != 0) {
9120  Warning("UploadPackageOnClient",
9121  "problems removing downloaded version of '%s' (%s):\n"
9122  "may imply inconsistencies in subsequent updates",
9123  gSystem->BaseName(par), downloadpath.Data());
9124  }
9125  }
9126  TString lpar;
9127  lpar.Form("%s/%s", fPackageDir.Data(), gSystem->BaseName(par));
9128  FileStat_t stat;
9129  Int_t st = gSystem->GetPathInfo(lpar, stat);
9130  // check if symlink, if so unlink, if not give error
9131  // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
9132  // existing file, but if fIsLink is true the symlink exists
9133  if (stat.fIsLink)
9134  gSystem->Unlink(lpar);
9135  else if (st == 0) {
9136  Error("UploadPackageOnClient", "cannot create symlink %s on client, "
9137  "another item with same name already exists",
9138  lpar.Data());
9139  fPackageLock->Unlock();
9140  return -1;
9141  }
9142  if (!gSystem->IsAbsoluteFileName(par)) {
9143  TString fpar = par;
9145  } else
9146  gSystem->Symlink(par, lpar);
9147  // TODO: On Windows need to copy instead of symlink
9148 
9149  TString cmd;
9150  // Compare md5
9151  TString packnam = par(0, par.Length() - 4); // strip off ".par"
9152  packnam = gSystem->BaseName(packnam); // strip off path
9153  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
9154  TMD5 *md5local = TMD5::ReadChecksum(md5f);
9155  if (!md5local || (*md5) != (*md5local)) {
9156  // if not, unzip and untar package in package directory
9157  if ((opt & TProof::kRemoveOld)) {
9158  // remove any previous package directory with same name
9159  cmd.Form("%s %s/%s", kRM, fPackageDir.Data(), packnam.Data());
9160  if (gSystem->Exec(cmd.Data()))
9161  Error("UploadPackageOnClient", "failure executing: %s", cmd.Data());
9162  }
9163  // find gunzip
9164  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
9166  if (gunzip) {
9167  // untar package
9168  cmd.Form(kUNTAR2, gunzip, par.Data(), fPackageDir.Data());
9169  if (gSystem->Exec(cmd.Data()))
9170  Error("Uploadpackage", "failure executing: %s", cmd.Data());
9171  delete [] gunzip;
9172  } else
9173  Error("UploadPackageOnClient", "%s not found", kGUNZIP);
9174 
9175  // check that fPackageDir/packnam now exists
9176  if (gSystem->AccessPathName(fPackageDir + "/" + packnam, kWritePermission)) {
9177  // par file did not unpack itself in the expected directory, failure
9178  Error("UploadPackageOnClient",
9179  "package %s did not unpack into %s/%s", par.Data(), fPackageDir.Data(),
9180  packnam.Data());
9181  status = -1;
9182  } else {
9183  // store md5 in package/PROOF-INF/md5.txt
9184  TMD5::WriteChecksum(md5f, md5);
9185  }
9186  }
9187  fPackageLock->Unlock();
9188  delete md5local;
9189  }
9190  return status;
9191 }
9192 
9193 ////////////////////////////////////////////////////////////////////////////////
9194 /// Load the specified macro on master, workers and, if notOnClient is
9195 /// kFALSE, on the client. The macro file is uploaded if new or updated.
9196 /// Additional files to be uploaded (or updated, if needed) can be specified
9197 /// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
9198 /// If existing in the same directory, a header basename(macro).h or .hh, is also
9199 /// uploaded.
9200 /// The default is to load the macro also on the client; notOnClient can be used
9201 /// to avoid loading on the client.
9202 /// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
9203 /// only, and collection is not done; if uniqueWorkers is kFALSE, collection
9204 /// from the previous request is done, and broadcasting + collection from the
9205 /// other workers is done.
9206 /// The wrks arg can be used on the master to limit the set of workers.
9207 /// Returns 0 in case of success and -1 in case of error.
9208 
9209 Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
9210  TList *wrks)
9211 {
9212  if (!IsValid()) return -1;
9213 
9214  if (!macro || !macro[0]) {
9215  Error("Load", "need to specify a macro name");
9216  return -1;
9217  }
9218 
9219  if (TestBit(TProof::kIsClient) && !wrks) {
9220 
9221  // Extract the file implementation name first
9222  TString addsname, implname = macro;
9223  Ssiz_t icom = implname.Index(",");
9224  if (icom != kNPOS) {
9225  addsname = implname(icom + 1, implname.Length());
9226  implname.Remove(icom);
9227  }
9228  TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
9229  TString bmsg(basemacro), acmode, args, io;
9230  implname = gSystem->SplitAclicMode(implname, acmode, args, io);
9231 
9232  // Macro names must have a standard format
9233  Int_t dot = implname.Last('.');
9234  if (dot == kNPOS) {
9235  Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
9236  return -1;
9237  }
9238 
9239  // Is there any associated header file
9240  Bool_t hasHeader = kTRUE;
9241  TString headname = implname;
9242  headname.Remove(dot);
9243  headname += ".h";
9244  if (gSystem->AccessPathName(headname, kReadPermission)) {
9245  TString h = headname;
9246  headname.Remove(dot);
9247  headname += ".hh";
9248  if (gSystem->AccessPathName(headname, kReadPermission)) {
9249  hasHeader = kFALSE;
9250  if (gDebug > 0)
9251  Info("Load", "no associated header file found: tried: %s %s",
9252  h.Data(), headname.Data());
9253  }
9254  }
9255 
9256  // Is there any additional file ?
9257  TString addincs;
9258  TList addfiles;
9259  if (!addsname.IsNull()) {
9260  TString fn;
9261  Int_t from = 0;
9262  while (addsname.Tokenize(fn, from, ",")) {
9264  Error("Load", "additional file '%s' not found", fn.Data());
9265  return -1;
9266  }
9267  // Create the additional include statement
9268  if (!notOnClient) {
9269  TString dirn(gSystem->DirName(fn));
9270  if (addincs.IsNull()) {
9271  addincs.Form("-I%s", dirn.Data());
9272  } else if (!addincs.Contains(dirn)) {
9273  addincs += TString::Format(" -I%s", dirn.Data());
9274  }
9275  }
9276  // Remember these files ...
9277  addfiles.Add(new TObjString(fn));
9278  }
9279  }
9280 
9281  // Send files now; the md5 check is run here; see SendFile for more
9282  // details.
9283  if (SendFile(implname, kAscii | kForward , "cache") == -1) {
9284  Error("Load", "problems sending implementation file %s", implname.Data());
9285  return -1;
9286  }
9287  if (hasHeader)
9288  if (SendFile(headname, kAscii | kForward , "cache") == -1) {
9289  Error("Load", "problems sending header file %s", headname.Data());
9290  return -1;
9291  }
9292  // Additional files
9293  if (addfiles.GetSize() > 0) {
9294  TIter nxfn(&addfiles);
9295  TObjString *os = 0;
9296  while ((os = (TObjString *) nxfn())) {
9297  // These files need to be available everywhere, cache and sandbox
9298  if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
9299  Error("Load", "problems sending additional file %s", os->GetName());
9300  return -1;
9301  }
9302  // Add the base names to the message broadcasted
9303  bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
9304  }
9305  addfiles.SetOwner(kTRUE);
9306  }
9307 
9308  // The files are now on the workers: now we send the loading request
9309  TMessage mess(kPROOF_CACHE);
9310  if (GetRemoteProtocol() < 34) {
9311  mess << Int_t(kLoadMacro) << basemacro;
9312  // This may be needed
9313  AddIncludePath("../../cache");
9314  } else {
9315  mess << Int_t(kLoadMacro) << bmsg;
9316  }
9317  Broadcast(mess, kActive);
9318 
9319  // Load locally, if required
9320  if (!notOnClient) {
9321  // Mofify the include path
9322  TString oldincs = gSystem->GetIncludePath();
9323  if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
9324 
9325  // By first forwarding the load command to the master and workers
9326  // and only then loading locally we load/build in parallel
9327  gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
9328 
9329  // Restore include path
9330  if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
9331 
9332  // Update the macro path
9334  TString np(gSystem->DirName(macro));
9335  if (!np.IsNull()) {
9336  np += ":";
9337  if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
9338  Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
9339  mp.Insert(ip, np);
9340  TROOT::SetMacroPath(mp);
9341  if (gDebug > 0)
9342  Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
9343  }
9344  }
9345  }
9346 
9347  // Wait for master and workers to be done
9348  Collect(kActive);
9349 
9350  if (IsLite()) {
9351  PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
9352  if (!fLoadedMacros) {
9353  fLoadedMacros = new TList();
9355  }
9356  // if wrks is specified the macro should already be loaded on the master.
9357  fLoadedMacros->Add(new TObjString(macro));
9358  }
9359 
9360  } else {
9361  // On master
9362 
9363  // The files are now on the workers: now we send the loading request first
9364  // to the unique workers, so that the eventual compilation occurs only once.
9365  TString basemacro = gSystem->BaseName(macro);
9366  TMessage mess(kPROOF_CACHE);
9367 
9368  if (uniqueWorkers) {
9369  mess << Int_t(kLoadMacro) << basemacro;
9370  if (wrks) {
9371  Broadcast(mess, wrks);
9372  Collect(wrks);
9373  } else {
9374  Broadcast(mess, kUnique);
9375  }
9376  } else {
9377  // Wait for the result of the previous sending
9378  Collect(kUnique);
9379 
9380  // We then send a tuned loading request to the other workers
9381  TList others;
9382  TSlave *wrk = 0;
9383  TIter nxw(fActiveSlaves);
9384  while ((wrk = (TSlave *)nxw())) {
9385  if (!fUniqueSlaves->FindObject(wrk)) {
9386  others.Add(wrk);
9387  }
9388  }
9389 
9390  // Do not force compilation, if it was requested
9391  Int_t ld = basemacro.Last('.');
9392  if (ld != kNPOS) {
9393  Int_t lpp = basemacro.Index("++", ld);
9394  if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
9395  }
9396  mess << Int_t(kLoadMacro) << basemacro;
9397  Broadcast(mess, &others);
9398  Collect(&others);
9399  }
9400 
9401  PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
9402  if (!fLoadedMacros) {
9403  fLoadedMacros = new TList();
9405  }
9406  // if wrks is specified the macro should already be loaded on the master.
9407  if (!wrks)
9408  fLoadedMacros->Add(new TObjString(macro));
9409  }
9410 
9411  // Done
9412  return 0;
9413 }
9414 
9415 ////////////////////////////////////////////////////////////////////////////////
9416 /// Add 'libpath' to the lib path search.
9417 /// Multiple paths can be specified at once separating them with a comma or
9418 /// a blank.
9419 /// Return 0 on success, -1 otherwise
9420 
9421 Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
9422  Bool_t doCollect)
9423 {
9424  if ((!libpath || !libpath[0])) {
9425  if (gDebug > 0)
9426  Info("AddDynamicPath", "list is empty - nothing to do");
9427  return 0;
9428  }
9429 
9430  // Do it also on clients, if required
9431  if (onClient)
9432  HandleLibIncPath("lib", kTRUE, libpath);
9433 
9435  m << TString("lib") << (Bool_t)kTRUE;
9436 
9437  // Add paths
9438  if (libpath && strlen(libpath)) {
9439  m << TString(libpath);
9440  } else {
9441  m << TString("-");
9442  }
9443 
9444  // Tell the server to send back or not
9445  m << (Int_t)doCollect;
9446 
9447  // Forward the request
9448  if (wrks) {
9449  Broadcast(m, wrks);
9450  if (doCollect)
9451  Collect(wrks, fCollectTimeout);
9452  } else {
9453  Broadcast(m);
9455  }
9456 
9457  return 0;
9458 }
9459 
9460 ////////////////////////////////////////////////////////////////////////////////
9461 /// Add 'incpath' to the inc path search.
9462 /// Multiple paths can be specified at once separating them with a comma or
9463 /// a blank.
9464 /// Return 0 on success, -1 otherwise
9465 
9466 Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
9467  Bool_t doCollect)
9468 {
9469  if ((!incpath || !incpath[0])) {
9470  if (gDebug > 0)
9471  Info("AddIncludePath", "list is empty - nothing to do");
9472  return 0;
9473  }
9474 
9475  // Do it also on clients, if required
9476  if (onClient)
9477  HandleLibIncPath("inc", kTRUE, incpath);
9478 
9480  m << TString("inc") << (Bool_t)kTRUE;
9481 
9482  // Add paths
9483  if (incpath && strlen(incpath)) {
9484  m << TString(incpath);
9485  } else {
9486  m << TString("-");
9487  }
9488 
9489  // Tell the server to send back or not
9490  m << (Int_t)doCollect;
9491 
9492  // Forward the request
9493  if (wrks) {
9494  Broadcast(m, wrks);
9495  if (doCollect)
9496  Collect(wrks, fCollectTimeout);
9497  } else {
9498  Broadcast(m);
9500  }
9501 
9502  return 0;
9503 }
9504 
9505 ////////////////////////////////////////////////////////////////////////////////
9506 /// Remove 'libpath' from the lib path search.
9507 /// Multiple paths can be specified at once separating them with a comma or
9508 /// a blank.
9509 /// Return 0 on success, -1 otherwise
9510 
9511 Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
9512 {
9513  if ((!libpath || !libpath[0])) {
9514  if (gDebug > 0)
9515  Info("RemoveDynamicPath", "list is empty - nothing to do");
9516  return 0;
9517  }
9518 
9519  // Do it also on clients, if required
9520  if (onClient)
9521  HandleLibIncPath("lib", kFALSE, libpath);
9522 
9524  m << TString("lib") <<(Bool_t)kFALSE;
9525 
9526  // Add paths
9527  if (libpath && strlen(libpath))
9528  m << TString(libpath);
9529  else
9530  m << TString("-");
9531 
9532  // Forward the request
9533  Broadcast(m);
9535 
9536  return 0;
9537 }
9538 
9539 ////////////////////////////////////////////////////////////////////////////////
9540 /// Remove 'incpath' from the inc path search.
9541 /// Multiple paths can be specified at once separating them with a comma or
9542 /// a blank.
9543 /// Return 0 on success, -1 otherwise
9544 
9545 Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
9546 {
9547  if ((!incpath || !incpath[0])) {
9548  if (gDebug > 0)
9549  Info("RemoveIncludePath", "list is empty - nothing to do");
9550  return 0;
9551  }
9552 
9553  // Do it also on clients, if required
9554  if (onClient)
9555  HandleLibIncPath("in", kFALSE, incpath);
9556 
9558  m << TString("inc") << (Bool_t)kFALSE;
9559 
9560  // Add paths
9561  if (incpath && strlen(incpath))
9562  m << TString(incpath);
9563  else
9564  m << TString("-");
9565 
9566  // Forward the request
9567  Broadcast(m);
9569 
9570  return 0;
9571 }
9572 
9573 ////////////////////////////////////////////////////////////////////////////////
9574 /// Handle lib, inc search paths modification request
9575 
9576 void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
9577 {
9578  TString type(what);
9579  TString path(dirs);
9580 
9581  // Check type of action
9582  if ((type != "lib") && (type != "inc")) {
9583  Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
9584  return;
9585  }
9586 
9587  // Separators can be either commas or blanks
9588  path.ReplaceAll(","," ");
9589 
9590  // Decompose lists
9591  TObjArray *op = 0;
9592  if (path.Length() > 0 && path != "-") {
9593  if (!(op = path.Tokenize(" "))) {
9594  Warning("HandleLibIncPath","decomposing path %s", path.Data());
9595  return;
9596  }
9597  }
9598 
9599  if (add) {
9600 
9601  if (type == "lib") {
9602 
9603  // Add libs
9604  TIter nxl(op, kIterBackward);
9605  TObjString *lib = 0;
9606  while ((lib = (TObjString *) nxl())) {
9607  // Expand path
9608  TString xlib = lib->GetName();
9609  gSystem->ExpandPathName(xlib);
9610  // Add to the dynamic lib search path if it exists and can be read
9611  if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9612  TString newlibpath = gSystem->GetDynamicPath();
9613  // In the first position after the working dir
9614  Int_t pos = 0;
9615  if (newlibpath.BeginsWith(".:"))
9616  pos = 2;
9617  if (newlibpath.Index(xlib) == kNPOS) {
9618  newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9619  gSystem->SetDynamicPath(newlibpath);
9620  }
9621  } else {
9622  if (gDebug > 0)
9623  Info("HandleLibIncPath",
9624  "libpath %s does not exist or cannot be read - not added", xlib.Data());
9625  }
9626  }
9627 
9628  } else {
9629 
9630  // Add incs
9631  TIter nxi(op);
9632  TObjString *inc = 0;
9633  while ((inc = (TObjString *) nxi())) {
9634  // Expand path
9635  TString xinc = inc->GetName();
9636  gSystem->ExpandPathName(xinc);
9637  // Add to the dynamic lib search path if it exists and can be read
9638  if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9639  TString curincpath = gSystem->GetIncludePath();
9640  if (curincpath.Index(xinc) == kNPOS)
9641  gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9642  } else
9643  if (gDebug > 0)
9644  Info("HandleLibIncPath",
9645  "incpath %s does not exist or cannot be read - not added", xinc.Data());
9646  }
9647  }
9648 
9649 
9650  } else {
9651 
9652  if (type == "lib") {
9653 
9654  // Remove libs
9655  TIter nxl(op);
9656  TObjString *lib = 0;
9657  while ((lib = (TObjString *) nxl())) {
9658  // Expand path
9659  TString xlib = lib->GetName();
9660  gSystem->ExpandPathName(xlib);
9661  // Remove from the dynamic lib search path
9662  TString newlibpath = gSystem->GetDynamicPath();
9663  newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9664  gSystem->SetDynamicPath(newlibpath);
9665  }
9666 
9667  } else {
9668 
9669  // Remove incs
9670  TIter nxi(op);
9671  TObjString *inc = 0;
9672  while ((inc = (TObjString *) nxi())) {
9673  TString newincpath = gSystem->GetIncludePath();
9674  newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9675  // Remove the interpreter path (added anyhow internally)
9676  newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9677  gSystem->SetIncludePath(newincpath);
9678  }
9679  }
9680  }
9681 }
9682 
9683 ////////////////////////////////////////////////////////////////////////////////
9684 /// Get from the master the list of names of the packages available.
9685 
9687 {
9688  if (!IsValid())
9689  return (TList *)0;
9690 
9691  TMessage mess(kPROOF_CACHE);
9692  mess << Int_t(kListPackages);
9693  Broadcast(mess);
9695 
9696  return fAvailablePackages;
9697 }
9698 
9699 ////////////////////////////////////////////////////////////////////////////////
9700 /// Get from the master the list of names of the packages enabled.
9701 
9703 {
9704  if (!IsValid())
9705  return (TList *)0;
9706 
9707  TMessage mess(kPROOF_CACHE);
9708  mess << Int_t(kListEnabledPackages);
9709  Broadcast(mess);
9711 
9712  return fEnabledPackages;
9713 }
9714 
9715 ////////////////////////////////////////////////////////////////////////////////
9716 /// Print a progress bar on stderr. Used in batch mode.
9717 
9719  Float_t procTime, Long64_t bytesread)
9720 {
9721  if (fPrintProgress) {
9722  Bool_t redirlog = fRedirLog;
9723  fRedirLog = kFALSE;
9724  // Call the external function
9725  (*fPrintProgress)(total, processed, procTime, bytesread);
9726  fRedirLog = redirlog;
9727  return;
9728  }
9729 
9730  fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9731 
9732  for (int l = 0; l < 20; l++) {
9733  if (total > 0) {
9734  if (l < 20*processed/total)
9735  fprintf(stderr, "=");
9736  else if (l == 20*processed/total)
9737  fprintf(stderr, ">");
9738  else if (l > 20*processed/total)
9739  fprintf(stderr, ".");
9740  } else
9741  fprintf(stderr, "=");
9742  }
9743  Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9744  Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9745  TString sunit("B/s");
9746  if (evtrti > 0.) {
9747  Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9748  if (mbsrti > 0.) {
9749  const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9750  if (mbsrti >= toG) {
9751  mbsrti /= toG;
9752  sunit = "GB/s";
9753  } else if (mbsrti >= toM) {
9754  mbsrti /= toM;
9755  sunit = "MB/s";
9756  } else if (mbsrti >= toK) {
9757  mbsrti /= toK;
9758  sunit = "kB/s";
9759  }
9760  fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9761  (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9762  } else {
9763  fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9764  (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9765  }
9766  } else {
9767  fprintf(stderr, "| %.02f %%\r",
9768  (total ? ((100.0*processed)/total) : 100.0));
9769  }
9770  if (processed >= total) {
9771  fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9772  }
9773 }
9774 
9775 ////////////////////////////////////////////////////////////////////////////////
9776 /// Get query progress information. Connect a slot to this signal
9777 /// to track progress.
9778 
9780 {
9781  if (fPrintProgress) {
9782  // Call the external function
9783  return (*fPrintProgress)(total, processed, -1., -1);
9784  }
9785 
9786  PDB(kGlobal,1)
9787  Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9788 
9789  if (gROOT->IsBatch()) {
9790  // Simple progress bar
9791  if (total > 0)
9792  PrintProgress(total, processed);
9793  } else {
9794  EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9795  }
9796 }
9797 
9798 ////////////////////////////////////////////////////////////////////////////////
9799 /// Get query progress information. Connect a slot to this signal
9800 /// to track progress.
9801 
9802 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
9803  Float_t initTime, Float_t procTime,
9804  Float_t evtrti, Float_t mbrti)
9805 {
9806  PDB(kGlobal,1)
9807  Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9808  initTime, procTime, evtrti, mbrti);
9809 
9810  if (gROOT->IsBatch()) {
9811  // Simple progress bar
9812  if (total > 0)
9813  PrintProgress(total, processed, procTime, bytesread);
9814  } else {
9815  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9816  7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9817  }
9818 }
9819 
9820 ////////////////////////////////////////////////////////////////////////////////
9821 /// Get query progress information. Connect a slot to this signal
9822 /// to track progress.
9823 
9824 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
9825  Float_t initTime, Float_t procTime,
9826  Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9827 {
9828  PDB(kGlobal,1)
9829  Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9830  initTime, procTime, evtrti, mbrti, actw, eses);
9831 
9832  if (gROOT->IsBatch()) {
9833  // Simple progress bar
9834  if (total > 0)
9835  PrintProgress(total, processed, procTime, bytesread);
9836  } else {
9837  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9838  10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9839  }
9840 }
9841 
9842 ////////////////////////////////////////////////////////////////////////////////
9843 /// Get list of feedback objects. Connect a slot to this signal
9844 /// to monitor the feedback object.
9845 
9847 {
9848  PDB(kGlobal,1)
9849  Info("Feedback","%d objects", objs->GetSize());
9850  PDB(kFeedback,1) {
9851  Info("Feedback","%d objects", objs->GetSize());
9852  objs->ls();
9853  }
9854 
9855  Emit("Feedback(TList *objs)", (Long_t) objs);
9856 }
9857 
9858 ////////////////////////////////////////////////////////////////////////////////
9859 /// Close progress dialog.
9860 
9862 {
9863  PDB(kGlobal,1)
9864  Info("CloseProgressDialog",
9865  "called: have progress dialog: %d", fProgressDialogStarted);
9866 
9867  // Nothing to do if not there
9869  return;
9870 
9871  Emit("CloseProgressDialog()");
9872 }
9873 
9874 ////////////////////////////////////////////////////////////////////////////////
9875 /// Reset progress dialog.
9876 
9877 void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9878  Long64_t ent)
9879 {
9880  PDB(kGlobal,1)
9881  Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9882 
9883  EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9884  4, sel, sz, fst, ent);
9885 }
9886 
9887 ////////////////////////////////////////////////////////////////////////////////
9888 /// Send startup message.
9889 
9890 void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9891 {
9892  PDB(kGlobal,1)
9893  Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9894 
9895  EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9896  4, msg, st, done, total);
9897 }
9898 
9899 ////////////////////////////////////////////////////////////////////////////////
9900 /// Send dataset preparation status.
9901 
9902 void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9903 {
9904  PDB(kGlobal,1)
9905  Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9906 
9907  EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9908  4, msg, st, done, total);
9909 }
9910 
9911 ////////////////////////////////////////////////////////////////////////////////
9912 /// Send or notify data set status
9913 
9914 void TProof::SendDataSetStatus(const char *action, UInt_t done,
9915  UInt_t tot, Bool_t st)
9916 {
9917  if (IsLite()) {
9918  if (tot) {
9919  TString type = "files";
9920  Int_t frac = (Int_t) (done*100.)/tot;
9921  char msg[512] = {0};
9922  if (frac >= 100) {
9923  snprintf(msg, 512, "%s: OK (%d %s) \n",
9924  action,tot, type.Data());
9925  } else {
9926  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9927  action, done, tot, frac);
9928  }
9929  if (fSync)
9930  fprintf(stderr,"%s", msg);
9931  else
9932  NotifyLogMsg(msg, 0);
9933  }
9934  return;
9935  }
9936 
9937  if (TestBit(TProof::kIsMaster)) {
9939  mess << TString(action) << tot << done << st;
9940  gProofServ->GetSocket()->Send(mess);
9941  }
9942 }
9943 
9944 ////////////////////////////////////////////////////////////////////////////////
9945 /// Notify availability of a query result.
9946 
9947 void TProof::QueryResultReady(const char *ref)
9948 {
9949  PDB(kGlobal,1)
9950  Info("QueryResultReady","ref: %s", ref);
9951 
9952  Emit("QueryResultReady(const char*)",ref);
9953 }
9954 
9955 ////////////////////////////////////////////////////////////////////////////////
9956 /// Validate a TDSet.
9957 
9959 {
9960  if (dset->ElementsValid()) return;
9961 
9962  TList nodes;
9963  nodes.SetOwner();
9964 
9965  TList slholder;
9966  slholder.SetOwner();
9967  TList elemholder;
9968  elemholder.SetOwner();
9969 
9970  // build nodelist with slaves and elements
9971  TIter nextSlave(GetListOfActiveSlaves());
9972  while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9973  TList *sllist = 0;
9974  TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9975  if (!p) {
9976  sllist = new TList;
9977  sllist->SetName(sl->GetName());
9978  slholder.Add(sllist);
9979  TList *elemlist = new TList;
9980  elemlist->SetName(TString(sl->GetName())+"_elem");
9981  elemholder.Add(elemlist);
9982  nodes.Add(new TPair(sllist, elemlist));
9983  } else {
9984  sllist = dynamic_cast<TList*>(p->Key());
9985  }
9986  if (sllist) sllist->Add(sl);
9987  }
9988 
9989  // add local elements to nodes
9990  TList nonLocal; // list of nonlocal elements
9991  // make two iterations - first add local elements - then distribute nonlocals
9992  for (Int_t i = 0; i < 2; i++) {
9993  Bool_t local = i>0?kFALSE:kTRUE;
9994  TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9995  while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9996  if (elem->GetValid()) continue;
9997  TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9998  if (p) {
9999  TList *eli = dynamic_cast<TList*>(p->Value());
10000  TList *sli = dynamic_cast<TList*>(p->Key());
10001  if (eli && sli) {
10002  eli->Add(elem);
10003 
10004  // order list by elements/slave
10005  TPair *p2 = p;
10006  Bool_t stop = kFALSE;
10007  while (!stop) {
10008  TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
10009  if (p3) {
10010  TList *p3v = dynamic_cast<TList*>(p3->Value());
10011  TList *p3k = dynamic_cast<TList*>(p3->Key());
10012  if (p3v && p3k) {
10013  Int_t nelem = p3v->GetSize();
10014  Int_t nsl = p3k->GetSize();
10015  if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
10016  else stop = kTRUE;
10017  }
10018  } else {
10019  stop = kTRUE;
10020  }
10021  }
10022 
10023  if (p2!=p) {
10024  nodes.Remove(p->Key());
10025  nodes.AddAfter(p2->Key(), p);
10026  }
10027  } else {
10028  Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
10029  continue;
10030  }
10031 
10032  } else {
10033  if (local) {
10034  nonLocal.Add(elem);
10035  } else {
10036  Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
10037  }
10038  }
10039  }
10040  }
10041 
10042  // send to slaves
10043  TList usedslaves;
10044  TIter nextNode(&nodes);
10045  SetDSet(dset); // set dset to be validated in Collect()
10046  while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
10047  TList *slaves = dynamic_cast<TList*>(node->Key());
10048  TList *setelements = dynamic_cast<TList*>(node->Value());
10049  if (!slaves || !setelements) continue;
10050  // distribute elements over the slaves
10051  Int_t nslaves = slaves->GetSize();
10052  Int_t nelements = setelements->GetSize();
10053  for (Int_t i=0; i<nslaves; i++) {
10054 
10055  TDSet copyset(dset->GetType(), dset->GetObjName(),
10056  dset->GetDirectory());
10057  for (Int_t j = (i*nelements)/nslaves;
10058  j < ((i+1)*nelements)/nslaves;
10059  j++) {
10060  TDSetElement *elem =
10061  dynamic_cast<TDSetElement*>(setelements->At(j));
10062  if (elem) {
10063  copyset.Add(elem->GetFileName(), elem->GetObjName(),
10064  elem->GetDirectory(), elem->GetFirst(),
10065  elem->GetNum(), elem->GetMsd());
10066  }
10067  }
10068 
10069  if (copyset.GetListOfElements()->GetSize()>0) {
10071  mesg << &copyset;
10072 
10073  TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
10074  if (sl) {
10075  PDB(kGlobal,1) Info("ValidateDSet",
10076  "Sending TDSet with %d elements to slave %s"
10077  " to be validated",
10078  copyset.GetListOfElements()->GetSize(),
10079  sl->GetOrdinal());
10080  sl->GetSocket()->Send(mesg);
10081  usedslaves.Add(sl);
10082  }
10083  }
10084  }
10085  }
10086 
10087  PDB(kGlobal,1)
10088  Info("ValidateDSet","Calling Collect");
10089  Collect(&usedslaves);
10090  SetDSet(0);
10091 }
10092 
10093 ////////////////////////////////////////////////////////////////////////////////
10094 /// Add data objects that might be needed during the processing of
10095 /// the selector (see Process()). This object can be very large, so they
10096 /// are distributed in an optimized way using a dedicated file.
10097 /// If push is TRUE the input data are sent over even if no apparent change
10098 /// occured to the list.
10099 
10101 {
10102  if (obj) {
10103  if (!fInputData) fInputData = new TList;
10104  if (!fInputData->FindObject(obj)) {
10105  fInputData->Add(obj);
10107  }
10108  }
10109  if (push) SetBit(TProof::kNewInputData);
10110 }
10111 
10112 ////////////////////////////////////////////////////////////////////////////////
10113 /// Remove obj form the input data list; if obj is null (default), clear the
10114 /// input data info.
10115 
10117 {
10118  if (!obj) {
10119  if (fInputData) {
10122  }
10124 
10125  // Also remove any info about input data in the input list
10126  TObject *o = 0;
10127  TList *in = GetInputList();
10128  while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
10129  in->Remove(o);
10130  while ((o = GetInputList()->FindObject("PROOF_InputData")))
10131  in->Remove(o);
10132 
10133  // ... and reset the file
10134  fInputDataFile = "";
10136 
10137  } else if (fInputData) {
10138  Int_t sz = fInputData->GetSize();
10139  while (fInputData->FindObject(obj))
10140  fInputData->Remove(obj);
10141  // Flag for update, if anything changed
10142  if (sz != fInputData->GetSize())
10144  }
10145 }
10146 
10147 ////////////////////////////////////////////////////////////////////////////////
10148 /// Remove obj 'name' form the input data list;
10149 
10150 void TProof::ClearInputData(const char *name)
10151 {
10152  TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
10153  if (obj) ClearInputData(obj);
10154 }
10155 
10156 ////////////////////////////////////////////////////////////////////////////////
10157 /// Set the file to be used to optimally distribute the input data objects.
10158 /// If the file exists the object in the file are added to those in the
10159 /// fInputData list. If the file path is null, a default file will be created
10160 /// at the moment of sending the processing request with the content of
10161 /// the fInputData list. See also SendInputDataFile.
10162 
10163 void TProof::SetInputDataFile(const char *datafile)
10164 {
10165  if (datafile && strlen(datafile) > 0) {
10166  if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
10168  fInputDataFile = datafile;
10169  } else {
10170  if (!fInputDataFile.IsNull())
10172  fInputDataFile = "";
10173  }
10174  // Make sure that the chosen file is readable
10177  fInputDataFile = "";
10178  }
10179 }
10180 
10181 ////////////////////////////////////////////////////////////////////////////////
10182 /// Send the input data objects to the master; the objects are taken from the
10183 /// dedicated list and / or the specified file.
10184 /// If the fInputData is empty the specified file is sent over.
10185 /// If there is no specified file, a file named "inputdata.root" is created locally
10186 /// with the content of fInputData and sent over to the master.
10187 /// If both fInputData and the specified file are not empty, a copy of the file
10188 /// is made locally and augmented with the content of fInputData.
10189 
10191 {
10192  // Prepare the file
10193  TString dataFile;
10194  PrepareInputDataFile(dataFile);
10195 
10196  // Send it, if not empty
10197  if (dataFile.Length() > 0) {
10198 
10199  Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
10200  BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
10201 
10202  // Set the name in the input list
10203  TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
10204  AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
10205  }
10206 }
10207 
10208 ////////////////////////////////////////////////////////////////////////////////
10209 /// Prepare the file with the input data objects to be sent the master; the
10210 /// objects are taken from the dedicated list and / or the specified file.
10211 /// If the fInputData is empty the specified file is sent over.
10212 /// If there is no specified file, a file named "inputdata.root" is created locally
10213 /// with the content of fInputData and sent over to the master.
10214 /// If both fInputData and the specified file are not empty, a copy of the file
10215 /// is made locally and augmented with the content of fInputData.
10216 
10218 {
10219  // Save info about new data for usage in this call;
10221  // Next time we need some change
10223 
10224  // Check the list
10225  Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
10226  // Check the file
10227  Bool_t file_ok = kFALSE;
10230  // It must contain something
10232  if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
10233  file_ok = kTRUE;
10234  }
10235 
10236  // Remove any info about input data in the input list
10237  TObject *o = 0;
10238  TList *in = GetInputList();
10239  while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
10240  in->Remove(o);
10241  while ((o = GetInputList()->FindObject("PROOF_InputData")))
10242  in->Remove(o);
10243 
10244  // We must have something to send
10245  dataFile = "";
10246  if (!list_ok && !file_ok) return;
10247 
10248  // Three cases:
10249  if (file_ok && !list_ok) {
10250  // Just send the file
10251  dataFile = fInputDataFile;
10252  } else if (!file_ok && list_ok) {
10254  // Nothing to do, if no new data
10255  if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
10256  // Create the file first
10257  TFile *f = TFile::Open(fInputDataFile, "RECREATE");
10258  if (f) {
10259  f->cd();
10261  TObject *obj;
10262  while ((obj = next())) {
10263  obj->Write(0, TObject::kSingleKey, 0);
10264  }
10265  f->Close();
10266  SafeDelete(f);
10267  } else {
10268  Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
10269  return;
10270  }
10271  dataFile = fInputDataFile;
10272  } else if (file_ok && list_ok) {
10273  dataFile = kPROOF_InputDataFile;
10274  // Create the file if not existing or there are new data
10275  if (newdata || gSystem->AccessPathName(dataFile)) {
10276  // Cleanup previous file if obsolete
10277  if (!gSystem->AccessPathName(dataFile))
10278  gSystem->Unlink(dataFile);
10279  if (dataFile != fInputDataFile) {
10280  // Make a local copy first
10281  if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
10282  Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
10283  return;
10284  }
10285  }
10286  // Add the input data list
10287  TFile *f = TFile::Open(dataFile, "UPDATE");
10288  if (f) {
10289  f->cd();
10291  TObject *obj = 0;
10292  while ((obj = next())) {
10293  obj->Write(0, TObject::kSingleKey, 0);
10294  }
10295  f->Close();
10296  SafeDelete(f);
10297  } else {
10298  Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
10299  return;
10300  }
10301  }
10302  }
10303 
10304  // Done
10305  return;
10306 }
10307 
10308 ////////////////////////////////////////////////////////////////////////////////
10309 /// Add objects that might be needed during the processing of
10310 /// the selector (see Process()).
10311 
10313 {
10314  if (fPlayer) fPlayer->AddInput(obj);
10315 }
10316 
10317 ////////////////////////////////////////////////////////////////////////////////
10318 /// Clear input object list.
10319 
10321 {
10322  if (fPlayer) fPlayer->ClearInput();
10323 
10324  // the system feedback list is always in the input list
10326 }
10327 
10328 ////////////////////////////////////////////////////////////////////////////////
10329 /// Get input list.
10330 
10332 {
10333  return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
10334 }
10335 
10336 ////////////////////////////////////////////////////////////////////////////////
10337 /// Get specified object that has been produced during the processing
10338 /// (see Process()).
10339 
10341 {
10342 
10344  // Can be called by MarkBad on the master before the player is initialized
10345  return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
10346 
10347  // This checks also associated output files
10348  return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
10349 }
10350 
10351 ////////////////////////////////////////////////////////////////////////////////
10352 /// Find object 'name' in list 'out' or in the files specified in there
10353 
10355 {
10356  TObject *o = 0;
10357  if (!name || (name && strlen(name) <= 0) ||
10358  !out || (out && out->GetSize() <= 0)) return o;
10359  if ((o = out->FindObject(name))) return o;
10360 
10361  // For the time being we always check for all the files; this may require
10362  // some caching
10363  TProofOutputFile *pf = 0;
10364  TIter nxo(out);
10365  while ((o = nxo())) {
10366  if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
10367  TFile *f = 0;
10368  if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
10369  TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
10370  f = TFile::Open(fn.Data());
10371  if (!f || (f && f->IsZombie())) {
10372  ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
10373  }
10374  }
10375  if (f && (o = f->Get(name))) return o;
10376  }
10377  }
10378 
10379  // Done, unsuccessfully
10380  return o;
10381 }
10382 
10383 ////////////////////////////////////////////////////////////////////////////////
10384 /// Get list with all object created during processing (see Process()).
10385 
10387 {
10388  if (fOutputList.GetSize() > 0) return &fOutputList;
10389  if (fPlayer) {
10391  return &fOutputList;
10392  }
10393  return (TList *)0;
10394 }
10395 
10396 ////////////////////////////////////////////////////////////////////////////////
10397 /// Set input list parameter. If the parameter is already
10398 /// set it will be set to the new value.
10399 
10400 void TProof::SetParameter(const char *par, const char *value)
10401 {
10402  if (!fPlayer) {
10403  Warning("SetParameter", "player undefined! Ignoring");
10404  return;
10405  }
10406 
10407  TList *il = fPlayer->GetInputList();
10408  TObject *item = il->FindObject(par);
10409  if (item) {
10410  il->Remove(item);
10411  delete item;
10412  }
10413  il->Add(new TNamed(par, value));
10414 }
10415 
10416 ////////////////////////////////////////////////////////////////////////////////
10417 /// Set an input list parameter.
10418 
10420 {
10421  if (!fPlayer) {
10422  Warning("SetParameter", "player undefined! Ignoring");
10423  return;
10424  }
10425 
10426  TList *il = fPlayer->GetInputList();
10427  TObject *item = il->FindObject(par);
10428  if (item) {
10429  il->Remove(item);
10430  delete item;
10431  }
10432  il->Add(new TParameter<Int_t>(par, value));
10433 }
10434 
10435 ////////////////////////////////////////////////////////////////////////////////
10436 /// Set an input list parameter.
10437 
10439 {
10440  if (!fPlayer) {
10441  Warning("SetParameter", "player undefined! Ignoring");
10442  return;
10443  }
10444 
10445  TList *il = fPlayer->GetInputList();
10446  TObject *item = il->FindObject(par);
10447  if (item) {
10448  il->Remove(item);
10449  delete item;
10450  }
10451  il->Add(new TParameter<Long_t>(par, value));
10452 }
10453 
10454 ////////////////////////////////////////////////////////////////////////////////
10455 /// Set an input list parameter.
10456 
10458 {
10459  if (!fPlayer) {
10460  Warning("SetParameter", "player undefined! Ignoring");
10461  return;
10462  }
10463 
10464  TList *il = fPlayer->GetInputList();
10465  TObject *item = il->FindObject(par);
10466  if (item) {
10467  il->Remove(item);
10468  delete item;
10469  }
10470  il->Add(new TParameter<Long64_t>(par, value));
10471 }
10472 
10473 ////////////////////////////////////////////////////////////////////////////////
10474 /// Set an input list parameter.
10475 
10477 {
10478  if (!fPlayer) {
10479  Warning("SetParameter", "player undefined! Ignoring");
10480  return;
10481  }
10482 
10483  TList *il = fPlayer->GetInputList();
10484  TObject *item = il->FindObject(par);
10485  if (item) {
10486  il->Remove(item);
10487  delete item;
10488  }
10489  il->Add(new TParameter<Double_t>(par, value));
10490 }
10491 
10492 ////////////////////////////////////////////////////////////////////////////////
10493 /// Get specified parameter. A parameter set via SetParameter() is either
10494 /// a TParameter or a TNamed or 0 in case par is not defined.
10495 
10496 TObject *TProof::GetParameter(const char *par) const
10497 {
10498  if (!fPlayer) {
10499  Warning("GetParameter", "player undefined! Ignoring");
10500  return (TObject *)0;
10501  }
10502 
10503  TList *il = fPlayer->GetInputList();
10504  return il->FindObject(par);
10505 }
10506 
10507 ////////////////////////////////////////////////////////////////////////////////
10508 /// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
10509 /// or exact name (e.g. PROOF_MaxSlavesPerNode).
10510 
10511 void TProof::DeleteParameters(const char *wildcard)
10512 {
10513  if (!fPlayer) return;
10514 
10515  if (!wildcard) wildcard = "";
10516  TRegexp re(wildcard, kTRUE);
10517  Int_t nch = strlen(wildcard);
10518 
10519  TList *il = fPlayer->GetInputList();
10520  if (il) {
10521  TObject *p = 0;
10522  TIter next(il);
10523  while ((p = next())) {
10524  TString s = p->GetName();
10525  if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
10526  il->Remove(p);
10527  delete p;
10528  }
10529  }
10530 }
10531 
10532 ////////////////////////////////////////////////////////////////////////////////
10533 /// Show the input list parameters specified by the wildcard.
10534 /// Default is the special PROOF control parameters (PROOF_*).
10535 
10536 void TProof::ShowParameters(const char *wildcard) const
10537 {
10538  if (!fPlayer) return;
10539 
10540  if (!wildcard) wildcard = "";
10541  TRegexp re(wildcard, kTRUE);
10542  Int_t nch = strlen(wildcard);
10543 
10544  TList *il = fPlayer->GetInputList();
10545  TObject *p;
10546  TIter next(il);
10547  while ((p = next())) {
10548  TString s = p->GetName();
10549  if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
10550  if (p->IsA() == TNamed::Class()) {
10551  Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
10552  } else if (p->IsA() == TParameter<Long_t>::Class()) {
10553  Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
10554  } else if (p->IsA() == TParameter<Long64_t>::Class()) {
10555  Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
10556  } else if (p->IsA() == TParameter<Double_t>::Class()) {
10557  Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
10558  } else {
10559  Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
10560  }
10561  }
10562 }
10563 
10564 ////////////////////////////////////////////////////////////////////////////////
10565 /// Add object to feedback list.
10566 
10567 void TProof::AddFeedback(const char *name)
10568 {
10569  PDB(kFeedback, 3)
10570  Info("AddFeedback", "Adding object \"%s\" to feedback", name);
10571  if (fFeedback->FindObject(name) == 0)
10572  fFeedback->Add(new TObjString(name));
10573 }
10574 
10575 ////////////////////////////////////////////////////////////////////////////////
10576 /// Remove object from feedback list.
10577 
10578 void TProof::RemoveFeedback(const char *name)
10579 {
10580  TObject *obj = fFeedback->FindObject(name);
10581  if (obj != 0) {
10582  fFeedback->Remove(obj);
10583  delete obj;
10584  }
10585 }
10586 
10587 ////////////////////////////////////////////////////////////////////////////////
10588 /// Clear feedback list.
10589 
10591 {
10592  fFeedback->Delete();
10593 }
10594 
10595 ////////////////////////////////////////////////////////////////////////////////
10596 /// Show items in feedback list.
10597 
10599 {
10600  if (fFeedback->GetSize() == 0) {
10601  Info("","no feedback requested");
10602  return;
10603  }
10604 
10605  fFeedback->Print();
10606 }
10607 
10608 ////////////////////////////////////////////////////////////////////////////////
10609 /// Return feedback list.
10610 
10612 {
10613  return fFeedback;
10614 }
10615 
10616 ////////////////////////////////////////////////////////////////////////////////
10617 /// Creates a tree header (a tree with nonexisting files) object for
10618 /// the DataSet.
10619 
10621 {
10623  TSlave *sl = (TSlave*) l->First();
10624  if (sl == 0) {
10625  Error("GetTreeHeader", "No connection");
10626  return 0;
10627  }
10628 
10629  TSocket *soc = sl->GetSocket();
10631 
10632  msg << dset;
10633 
10634  soc->Send(msg);
10635 
10636  TMessage *reply;
10637  Int_t d = -1;
10638  if (fProtocol >= 20) {
10640  reply = (TMessage *) fRecvMessages->First();
10641  } else {
10642  d = soc->Recv(reply);
10643  }
10644  if (!reply) {
10645  Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10646  return 0;
10647  }
10648 
10649  TString s1;
10650  TTree *t = 0;
10651  (*reply) >> s1;
10652  if (s1 == "Success")
10653  (*reply) >> t;
10654 
10655  PDB(kGlobal, 1) {
10656  if (t) {
10657  Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10658  s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10659  } else {
10660  Info("GetTreeHeader", "tree header retrieval failed");
10661  }
10662  }
10663  delete reply;
10664 
10665  return t;
10666 }
10667 
10668 ////////////////////////////////////////////////////////////////////////////////
10669 /// Draw feedback creation proxy. When accessed via TProof avoids
10670 /// link dependency on libProofPlayer.
10671 
10673 {
10674  return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10675 }
10676 
10677 ////////////////////////////////////////////////////////////////////////////////
10678 /// Set draw feedback option.
10679 
10681 {
10682  if (fPlayer) fPlayer->SetDrawFeedbackOption(f, opt);
10683 }
10684 
10685 ////////////////////////////////////////////////////////////////////////////////
10686 /// Delete draw feedback object.
10687 
10689 {
10691 }
10692 
10693 ////////////////////////////////////////////////////////////////////////////////
10694 /// FIXME: to be written
10695 
10697 {
10698  return 0;
10699 /*
10700  TMessage msg(kPROOF_GETOUTPUTLIST);
10701  TList* slaves = fActiveSlaves;
10702  Broadcast(msg, slaves);
10703  TMonitor mon;
10704  TList* outputList = new TList();
10705 
10706  TIter si(slaves);
10707  TSlave *slave;
10708  while ((slave = (TSlave*)si.Next()) != 0) {
10709  PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10710  slave->GetSocket(), slave->GetName());
10711  mon.Add(slave->GetSocket());
10712  }
10713  mon.ActivateAll();
10714  ((TProof*)gProof)->DeActivateAsyncInput();
10715  ((TProof*)gProof)->fCurrentMonitor = &mon;
10716 
10717  while (mon.GetActive() != 0) {
10718  TSocket *sock = mon.Select();
10719  if (!sock) {
10720  Error("GetOutputList","TMonitor::.Select failed!");
10721  break;
10722  }
10723  mon.DeActivate(sock);
10724  TMessage *reply;
10725  if (sock->Recv(reply) <= 0) {
10726  MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10727 // Error("GetOutputList","Recv failed! for slave-%d (%s)",
10728 // slave->GetOrdinal(), slave->GetName());
10729  continue;
10730  }
10731  if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10732 // Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10733 // slave->GetOrdinal(), slave->GetName());
10734  MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10735  continue;
10736  }
10737  TList* l;
10738 
10739  (*reply) >> l;
10740  TIter next(l);
10741  TNamed *n;
10742  while ( (n = dynamic_cast<TNamed*> (next())) ) {
10743  if (!outputList->FindObject(n->GetName()))
10744  outputList->Add(n);
10745  }
10746  delete reply;
10747  }
10748  ((TProof*)gProof)->fCurrentMonitor = 0;
10749 
10750  return outputList;
10751 */
10752 }
10753 
10754 ////////////////////////////////////////////////////////////////////////////////
10755 /// Build the PROOF's structure in the browser.
10756 
10758 {
10759  b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10760  b->Add(&fMaster, fMaster.Class(), "fMaster");
10761  b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10762  b->Add(fChains, fChains->Class(), "fChains");
10763 
10764  if (fPlayer) {
10765  b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10766  if (fPlayer->GetOutputList())
10767  b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10768  if (fPlayer->GetListOfResults())
10770  fPlayer->GetListOfResults()->Class(), "ListOfResults");
10771  }
10772 }
10773 
10774 ////////////////////////////////////////////////////////////////////////////////
10775 /// Set a new PROOF player.
10776 
10778 {
10779  if (fPlayer)
10780  delete fPlayer;
10781  fPlayer = player;
10782 };
10783 
10784 ////////////////////////////////////////////////////////////////////////////////
10785 /// Construct a TProofPlayer object. The player string specifies which
10786 /// player should be created: remote, slave, sm (supermaster) or base.
10787 /// Default is remote. Socket is needed in case a slave player is created.
10788 
10790 {
10791  if (!player)
10792  player = "remote";
10793 
10794  SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10795  return GetPlayer();
10796 }
10797 
10798 ////////////////////////////////////////////////////////////////////////////////
10799 /// Add chain to data set
10800 
10802 {
10803  fChains->Add(chain);
10804 }
10805 
10806 ////////////////////////////////////////////////////////////////////////////////
10807 /// Remove chain from data set
10808 
10810 {
10811  fChains->Remove(chain);
10812 }
10813 
10814 ////////////////////////////////////////////////////////////////////////////////
10815 /// Ask for remote logs in the range [start, end]. If start == -1 all the
10816 /// messages not yet received are sent back.
10817 
10819 {
10820  if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10821 
10822  TMessage msg(kPROOF_LOGFILE);
10823 
10824  msg << start << end;
10825 
10826  Broadcast(msg, kActive);
10828 }
10829 
10830 ////////////////////////////////////////////////////////////////////////////////
10831 /// Fill a TMacro with the log lines since the last reading (fLogFileR)
10832 /// Return (TMacro *)0 if no line was logged.
10833 /// The returned TMacro must be deleted by the caller.
10834 
10836 {
10837  TMacro *maclog = 0;
10838 
10839  // Save present offset
10840  off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10841  if (nowlog < 0) {
10842  SysError("GetLastLog",
10843  "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10844  return maclog;
10845  }
10846 
10847  // Get extremes
10848  off_t startlog = nowlog;
10849  off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10850  if (endlog < 0) {
10851  SysError("GetLastLog",
10852  "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10853  return maclog;
10854  }
10855 
10856  // Perhaps nothing to log
10857  UInt_t tolog = (UInt_t)(endlog - startlog);
10858  if (tolog <= 0) return maclog;
10859 
10860  // Set starting point
10861  if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10862  SysError("GetLastLog",
10863  "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10864  return maclog;
10865  }
10866 
10867  // Create the output object
10868  maclog = new TMacro;
10869 
10870  // Now we go
10871  char line[2048];
10872  Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10873  while (fgets(line, wanted, fLogFileR)) {
10874  Int_t r = strlen(line);
10875  if (r > 0) {
10876  if (line[r-1] == '\n') line[r-1] = '\0';
10877  maclog->AddLine(line);
10878  } else {
10879  // Done
10880  break;
10881  }
10882  tolog -= r;
10883  wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10884  }
10885 
10886  // Restore original pointer
10887  if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10888  Warning("GetLastLog",
10889  "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10890  }
10891 
10892  // Done
10893  return maclog;
10894 }
10895 
10896 ////////////////////////////////////////////////////////////////////////////////
10897 /// Display log of query pq into the log window frame
10898 
10900 {
10901  if (!pq) return;
10902 
10903  TList *lines = pq->GetLogFile()->GetListOfLines();
10904  if (lines) {
10905  TIter nxl(lines);
10906  TObjString *l = 0;
10907  while ((l = (TObjString *)nxl()))
10908  EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10909  }
10910 }
10911 
10912 ////////////////////////////////////////////////////////////////////////////////
10913 /// Display on screen the content of the temporary log file for query
10914 /// in reference
10915 
10916 void TProof::ShowLog(const char *queryref)
10917 {
10918  // Make sure we have all info (GetListOfQueries retrieves the
10919  // head info only)
10920  Retrieve(queryref);
10921 
10922  if (fPlayer) {
10923  if (queryref) {
10924  if (fPlayer->GetListOfResults()) {
10925  TIter nxq(fPlayer->GetListOfResults());
10926  TQueryResult *qr = 0;
10927  while ((qr = (TQueryResult *) nxq()))
10928  if (strstr(queryref, qr->GetTitle()) &&
10929  strstr(queryref, qr->GetName()))
10930  break;
10931  if (qr) {
10932  PutLog(qr);
10933  return;
10934  }
10935 
10936  }
10937  }
10938  }
10939 }
10940 
10941 ////////////////////////////////////////////////////////////////////////////////
10942 /// Display on screen the content of the temporary log file.
10943 /// If qry == -2 show messages from the last (current) query.
10944 /// If qry == -1 all the messages not yet displayed are shown (default).
10945 /// If qry == 0, all the messages in the file are shown.
10946 /// If qry > 0, only the messages related to query 'qry' are shown.
10947 /// For qry != -1 the original file offset is restored at the end
10948 
10950 {
10951  // Save present offset
10952  off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10953  if (nowlog < 0) {
10954  SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10955  return;
10956  }
10957 
10958  // Get extremes
10959  off_t startlog = nowlog;
10960  off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10961  if (endlog < 0) {
10962  SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10963  return;
10964  }
10965 
10966  lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10967  if (qry == 0) {
10968  startlog = 0;
10969  lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10970  } else if (qry != -1) {
10971 
10972  TQueryResult *pq = 0;
10973  if (qry == -2) {
10974  // Pickup the last one
10975  pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10976  if (!pq) {
10977  GetListOfQueries();
10978  if (fQueries)
10979  pq = (TQueryResult *)(fQueries->Last());
10980  }
10981  } else if (qry > 0) {
10982  TList *queries = GetQueryResults();
10983  if (queries) {
10984  TIter nxq(queries);
10985  while ((pq = (TQueryResult *)nxq()))
10986  if (qry == pq->GetSeqNum())
10987  break;
10988  }
10989  if (!pq) {
10990  queries = GetListOfQueries();
10991  TIter nxq(queries);
10992  while ((pq = (TQueryResult *)nxq()))
10993  if (qry == pq->GetSeqNum())
10994  break;
10995  }
10996  }
10997  if (pq) {
10998  PutLog(pq);
10999  return;
11000  } else {
11001  if (gDebug > 0)
11002  Info("ShowLog","query %d not found in list", qry);
11003  qry = -1;
11004  }
11005  }
11006 
11007  // Number of bytes to log
11008  UInt_t tolog = (UInt_t)(endlog - startlog);
11009 
11010  // Perhaps nothing
11011  if (tolog <= 0)
11012 
11013  // Set starting point
11014  lseek(fileno(fLogFileR), startlog, SEEK_SET);
11015 
11016  // Now we go
11017  Int_t np = 0;
11018  char line[2048];
11019  Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
11020  while (fgets(line, wanted, fLogFileR)) {
11021 
11022  Int_t r = strlen(line);
11023  if (!SendingLogToWindow()) {
11024  if (line[r-1] != '\n') line[r-1] = '\n';
11025  if (r > 0) {
11026  char *p = line;
11027  while (r) {
11028  Int_t w = write(fileno(stdout), p, r);
11029  if (w < 0) {
11030  SysError("ShowLog", "error writing to stdout");
11031  break;
11032  }
11033  r -= w;
11034  p += w;
11035  }
11036  }
11037  tolog -= strlen(line);
11038  np++;
11039 
11040  // Ask if more is wanted
11041  if (!(np%10)) {
11042  const char *opt = Getline("More (y/n)? [y]");
11043  if (opt[0] == 'n')
11044  break;
11045  }
11046 
11047  // We may be over
11048  if (tolog <= 0)
11049  break;
11050 
11051  // Update wanted bytes
11052  wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
11053  } else {
11054  // Log to window
11055  if (line[r-1] == '\n') line[r-1] = 0;
11056  LogMessage(line, kFALSE);
11057  }
11058  }
11059  if (!SendingLogToWindow()) {
11060  // Avoid screwing up the prompt
11061  if (write(fileno(stdout), "\n", 1) != 1)
11062  SysError("ShowLog", "error writing to stdout");
11063  }
11064 
11065  // Restore original pointer
11066  if (qry > -1)
11067  lseek(fileno(fLogFileR), nowlog, SEEK_SET);
11068 }
11069 
11070 ////////////////////////////////////////////////////////////////////////////////
11071 /// Set session with 'id' the default one. If 'id' is not found in the list,
11072 /// the current session is set as default
11073 
11075 {
11076  if (GetManager()) {
11077  TProofDesc *d = GetManager()->GetProofDesc(id);
11078  if (d) {
11079  if (d->GetProof()) {
11080  gProof = d->GetProof();
11081  return;
11082  }
11083  }
11084 
11085  // Id not found or undefined: set as default this session
11086  gProof = this;
11087  }
11088 
11089  return;
11090 }
11091 
11092 ////////////////////////////////////////////////////////////////////////////////
11093 /// Detach this instance to its proofserv.
11094 /// If opt is 'S' or 's' the remote server is shutdown
11095 
11097 {
11098  // Nothing to do if not in contact with proofserv
11099  if (!IsValid()) return;
11100 
11101  // Get worker and socket instances
11102  TSlave *sl = (TSlave *) fActiveSlaves->First();
11103  TSocket *s = 0;
11104  if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
11105  Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
11106  return;
11107  }
11108 
11109  Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
11110 
11111  // If processing, try to stop processing first
11112  if (shutdown && !IsIdle()) {
11113  // Remove pending requests
11114  Remove("cleanupqueue");
11115  // Do not wait for ever, but al least 20 seconds
11116  Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
11117  timeout = (timeout > 20) ? timeout : 20;
11118  // Send stop signal
11119  StopProcess(kFALSE, (Long_t) (timeout / 2));
11120  // Receive results
11121  Collect(kActive, timeout);
11122  }
11123 
11124  // Avoid spurious messages: deactivate new inputs ...
11126 
11127  // ... and discard existing ones
11128  sl->FlushSocket();
11129 
11130  // Close session (we always close the connection)
11131  Close(opt);
11132 
11133  // Close the progress dialog, if any
11136 
11137  // Update info in the table of our manager, if any
11138  if (GetManager() && GetManager()->QuerySessions("L")) {
11139  TIter nxd(GetManager()->QuerySessions("L"));
11140  TProofDesc *d = 0;
11141  while ((d = (TProofDesc *)nxd())) {
11142  if (d->GetProof() == this) {
11143  d->SetProof(0);
11144  GetManager()->QuerySessions("L")->Remove(d);
11145  break;
11146  }
11147  }
11148  }
11149 
11150  // Invalidate this instance
11151  fValid = kFALSE;
11152 
11153  return;
11154 }
11155 
11156 ////////////////////////////////////////////////////////////////////////////////
11157 /// Set an alias for this session. If reconnection is supported, the alias
11158 /// will be communicated to the remote coordinator so that it can be recovered
11159 /// when reconnecting
11160 
11161 void TProof::SetAlias(const char *alias)
11162 {
11163  // Set it locally
11164  TNamed::SetTitle(alias);
11166  // Set the name at the same value
11167  TNamed::SetName(alias);
11168 
11169  // Nothing to do if not in contact with coordinator
11170  if (!IsValid()) return;
11171 
11172  if (!IsProofd() && TestBit(TProof::kIsClient)) {
11173  TSlave *sl = (TSlave *) fActiveSlaves->First();
11174  if (sl)
11175  sl->SetAlias(alias);
11176  }
11177 
11178  return;
11179 }
11180 
11181 ////////////////////////////////////////////////////////////////////////////////
11182 /// *** This function is deprecated and will disappear in future versions ***
11183 /// *** It is just a wrapper around TFile::Cp.
11184 /// *** Please use TProofMgr::UploadFiles.
11185 ///
11186 /// Upload a set of files and save the list of files by name dataSetName.
11187 /// The 'files' argument is a list of TFileInfo objects describing the files
11188 /// as first url.
11189 /// The mask 'opt' is a combination of EUploadOpt:
11190 /// kAppend (0x1) if set true files will be appended to
11191 /// the dataset existing by given name
11192 /// kOverwriteDataSet (0x2) if dataset with given name exited it
11193 /// would be overwritten
11194 /// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
11195 /// kOverwriteAllFiles (0x8) overwrite all files that may exist
11196 /// kOverwriteNoFiles (0x10) overwrite none
11197 /// kAskUser (0x0) ask user before overwriteng dataset/files
11198 /// The default value is kAskUser.
11199 /// The user will be asked to confirm overwriting dataset or files unless
11200 /// specified opt provides the answer!
11201 /// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
11202 /// skippedFiles argument. The function will add to this list TFileInfo
11203 /// objects describing all files that existed on the cluster and were
11204 /// not uploaded.
11205 ///
11206 /// Communication Summary
11207 /// Client Master
11208 /// |------------>DataSetName----------->|
11209 /// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
11210 /// (*)|-------> call RegisterDataSet ------->|
11211 /// (*) - optional
11212 
11213 Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
11214 {
11215  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
11216 
11217  return -1;
11218 }
11219 
11220 ////////////////////////////////////////////////////////////////////////////////
11221 /// *** This function is deprecated and will disappear in future versions ***
11222 /// *** It is just a wrapper around TFile::Cp.
11223 /// *** Please use TProofMgr::UploadFiles.
11224 ///
11225 /// Upload a set of files and save the list of files by name dataSetName.
11226 /// The mask 'opt' is a combination of EUploadOpt:
11227 /// kAppend (0x1) if set true files will be appended to
11228 /// the dataset existing by given name
11229 /// kOverwriteDataSet (0x2) if dataset with given name exited it
11230 /// would be overwritten
11231 /// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
11232 /// kOverwriteAllFiles (0x8) overwrite all files that may exist
11233 /// kOverwriteNoFiles (0x10) overwrite none
11234 /// kAskUser (0x0) ask user before overwriteng dataset/files
11235 /// The default value is kAskUser.
11236 /// The user will be asked to confirm overwriting dataset or files unless
11237 /// specified opt provides the answer!
11238 /// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
11239 /// skippedFiles argument. The function will add to this list TFileInfo
11240 /// objects describing all files that existed on the cluster and were
11241 /// not uploaded.
11242 ///
11243 
11244 Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
11245 {
11246  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
11247 
11248  return -1;
11249 }
11250 
11251 ////////////////////////////////////////////////////////////////////////////////
11252 /// *** This function is deprecated and will disappear in future versions ***
11253 /// *** It is just a wrapper around TFile::Cp.
11254 /// *** Please use TProofMgr::UploadFiles.
11255 ///
11256 /// Upload files listed in "file" to PROOF cluster.
11257 /// Where file = name of file containing list of files and
11258 /// dataset = dataset name and opt is a combination of EUploadOpt bits.
11259 /// Each file description (line) can include wildcards.
11260 /// Check TFileInfo compatibility
11261 
11262 Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
11263 {
11264  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
11265 
11266  // Done
11267  return -1;
11268 }
11269 
11270 ////////////////////////////////////////////////////////////////////////////////
11271 /// Register the 'dataSet' on the cluster under the current
11272 /// user, group and the given 'dataSetName'.
11273 /// If a dataset with the same name already exists the action fails unless 'opts'
11274 /// contains 'O', in which case the old dataset is overwritten, or contains 'U',
11275 /// in which case 'newDataSet' is added to the existing dataset (duplications are
11276 /// ignored, if any).
11277 /// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
11278 /// is configured to allow so). By default the dataset is not verified.
11279 /// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
11280 /// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
11281 /// If 'opts' contains 'S' validation would be run serially (meaningful only if
11282 /// validation is required).
11283 /// Returns kTRUE on success.
11284 
11285 Bool_t TProof::RegisterDataSet(const char *dataSetName,
11286  TFileCollection *dataSet, const char *optStr)
11287 {
11288  // Check TFileInfo compatibility
11289  if (fProtocol < 17) {
11290  Info("RegisterDataSet",
11291  "functionality not available: the server does not have dataset support");
11292  return kFALSE;
11293  }
11294 
11295  if (!dataSetName || strlen(dataSetName) <= 0) {
11296  Info("RegisterDataSet", "specifying a dataset name is mandatory");
11297  return kFALSE;
11298  }
11299 
11300  Bool_t parallelverify = kFALSE;
11301  TString sopt(optStr);
11302  if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
11303  // We do verification in parallel later on; just register for now
11304  parallelverify = kTRUE;
11305  sopt.ReplaceAll("V", "");
11306  }
11307  // This would screw up things remotely, make sure is not there
11308  sopt.ReplaceAll("S", "");
11309 
11310  TMessage mess(kPROOF_DATASETS);
11311  mess << Int_t(kRegisterDataSet);
11312  mess << TString(dataSetName);
11313  mess << sopt;
11314  mess.WriteObject(dataSet);
11315  Broadcast(mess);
11316 
11317  Bool_t result = kTRUE;
11318  Collect();
11319  if (fStatus != 0) {
11320  Error("RegisterDataSet", "dataset was not saved");
11321  result = kFALSE;
11322  return result;
11323  }
11324 
11325  // If old server or not verifying in parallel we are done
11326  if (!parallelverify) return result;
11327 
11328  // If we are here it means that we will verify in parallel
11329  sopt += "V";
11330  if (VerifyDataSet(dataSetName, sopt) < 0){
11331  Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
11332  return kFALSE;
11333  }
11334 
11335  // We are done
11336  return kTRUE;
11337 }
11338 
11339 ////////////////////////////////////////////////////////////////////////////////
11340 /// Set/Change the name of the default tree. The tree name may contain
11341 /// subdir specification in the form "subdir/name".
11342 /// Returns 0 on success, -1 otherwise.
11343 
11344 Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
11345 {
11346  // Check TFileInfo compatibility
11347  if (fProtocol < 23) {
11348  Info("SetDataSetTreeName", "functionality not supported by the server");
11349  return -1;
11350  }
11351 
11352  if (!dataset || strlen(dataset) <= 0) {
11353  Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
11354  return -1;
11355  }
11356 
11357  if (!treename || strlen(treename) <= 0) {
11358  Info("SetDataSetTreeName", "specifying a tree name is mandatory");
11359  return -1;
11360  }
11361 
11362  TUri uri(dataset);
11363  TString fragment(treename);
11364  if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
11365  uri.SetFragment(fragment);
11366 
11367  TMessage mess(kPROOF_DATASETS);
11368  mess << Int_t(kSetDefaultTreeName);
11369  mess << uri.GetUri();
11370  Broadcast(mess);
11371 
11372  Collect();
11373  if (fStatus != 0) {
11374  Error("SetDataSetTreeName", "some error occured: default tree name not changed");
11375  return -1;
11376  }
11377  return 0;
11378 }
11379 
11380 ////////////////////////////////////////////////////////////////////////////////
11381 /// Lists all datasets that match given uri.
11382 /// The 'optStr' can contain a comma-separated list of servers for which the
11383 /// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
11384 /// only the global information in the TFileCollection is retrieved; useful to only
11385 /// get the list of available datasets.
11386 
11387 TMap *TProof::GetDataSets(const char *uri, const char *optStr)
11388 {
11389  if (fProtocol < 15) {
11390  Info("GetDataSets",
11391  "functionality not available: the server does not have dataset support");
11392  return 0;
11393  }
11394  if (fProtocol < 31 && strstr(optStr, ":lite:"))
11395  Warning("GetDataSets", "'lite' option not supported by the server");
11396 
11397  TMessage mess(kPROOF_DATASETS);
11398  mess << Int_t(kGetDataSets);
11399  mess << TString(uri ? uri : "");
11400  mess << TString(optStr ? optStr : "");
11401  Broadcast(mess);
11403 
11404  TMap *dataSetMap = 0;
11405  if (fStatus != 0) {
11406  Error("GetDataSets", "error receiving datasets information");
11407  } else {
11408  // Look in the list
11409  TMessage *retMess = (TMessage *) fRecvMessages->First();
11410  if (retMess && retMess->What() == kMESS_OK) {
11411  if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
11412  Error("GetDataSets", "error receiving datasets");
11413  } else
11414  Error("GetDataSets", "message not found or wrong type (%p)", retMess);
11415  }
11416 
11417  return dataSetMap;
11418 }
11419 
11420 ////////////////////////////////////////////////////////////////////////////////
11421 /// Shows datasets in locations that match the uri.
11422 /// By default shows the user's datasets and global ones
11423 
11424 void TProof::ShowDataSets(const char *uri, const char* optStr)
11425 {
11426  if (fProtocol < 15) {
11427  Info("ShowDataSets",
11428  "functionality not available: the server does not have dataset support");
11429  return;
11430  }
11431 
11432  TMessage mess(kPROOF_DATASETS);
11433  mess << Int_t(kShowDataSets);
11434  mess << TString(uri ? uri : "");
11435  mess << TString(optStr ? optStr : "");
11436  Broadcast(mess);
11437 
11439  if (fStatus != 0)
11440  Error("ShowDataSets", "error receiving datasets information");
11441 }
11442 
11443 ////////////////////////////////////////////////////////////////////////////////
11444 /// Returns kTRUE if 'dataset' exists, kFALSE otherwise
11445 
11446 Bool_t TProof::ExistsDataSet(const char *dataset)
11447 {
11448  if (fProtocol < 15) {
11449  Info("ExistsDataSet", "functionality not available: the server has an"
11450  " incompatible version of TFileInfo");
11451  return kFALSE;
11452  }
11453 
11454  if (!dataset || strlen(dataset) <= 0) {
11455  Error("ExistsDataSet", "dataset name missing");
11456  return kFALSE;
11457  }
11458 
11460  msg << Int_t(kCheckDataSetName) << TString(dataset);
11461  Broadcast(msg);
11463  if (fStatus == -1) {
11464  // The dataset exists
11465  return kTRUE;
11466  }
11467  // The dataset does not exists
11468  return kFALSE;
11469 }
11470 
11471 ////////////////////////////////////////////////////////////////////////////////
11472 /// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
11473 
11474 void TProof::ClearDataSetCache(const char *dataset)
11475 {
11476  if (fProtocol < 28) {
11477  Info("ClearDataSetCache", "functionality not available on server");
11478  return;
11479  }
11480 
11482  msg << Int_t(kCache) << TString(dataset) << TString("clear");
11483  Broadcast(msg);
11485  // Done
11486  return;
11487 }
11488 
11489 ////////////////////////////////////////////////////////////////////////////////
11490 /// Display the content of the dataset cache, if any (matching 'dataset', if defined).
11491 
11492 void TProof::ShowDataSetCache(const char *dataset)
11493 {
11494  if (fProtocol < 28) {
11495  Info("ShowDataSetCache", "functionality not available on server");
11496  return;
11497  }
11498 
11500  msg << Int_t(kCache) << TString(dataset) << TString("show");
11501  Broadcast(msg);
11503  // Done
11504  return;
11505 }
11506 
11507 ////////////////////////////////////////////////////////////////////////////////
11508 /// Get a list of TFileInfo objects describing the files of the specified
11509 /// dataset.
11510 /// To get the short version (containing only the global meta information)
11511 /// specify optStr = "S:" or optStr = "short:".
11512 /// To get the sub-dataset of files located on a given server(s) specify
11513 /// the list of servers (comma-separated) in the 'optStr' field.
11514 
11515 TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
11516 {
11517  if (fProtocol < 15) {
11518  Info("GetDataSet", "functionality not available: the server has an"
11519  " incompatible version of TFileInfo");
11520  return 0;
11521  }
11522 
11523  if (!uri || strlen(uri) <= 0) {
11524  Info("GetDataSet", "specifying a dataset name is mandatory");
11525  return 0;
11526  }
11527 
11528  TMessage nameMess(kPROOF_DATASETS);
11529  nameMess << Int_t(kGetDataSet);
11530  nameMess << TString(uri);
11531  nameMess << TString(optStr ? optStr: "");
11532  if (Broadcast(nameMess) < 0)
11533  Error("GetDataSet", "sending request failed");
11534 
11536  TFileCollection *fileList = 0;
11537  if (fStatus != 0) {
11538  Error("GetDataSet", "error receiving datasets information");
11539  } else {
11540  // Look in the list
11541  TMessage *retMess = (TMessage *) fRecvMessages->First();
11542  if (retMess && retMess->What() == kMESS_OK) {
11543  if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
11544  Error("GetDataSet", "error reading list of files");
11545  } else
11546  Error("GetDataSet", "message not found or wrong type (%p)", retMess);
11547  }
11548 
11549  return fileList;
11550 }
11551 
11552 ////////////////////////////////////////////////////////////////////////////////
11553 /// display meta-info for given dataset usi
11554 
11555 void TProof::ShowDataSet(const char *uri, const char* opt)
11556 {
11557  TFileCollection *fileList = 0;
11558  if ((fileList = GetDataSet(uri))) {
11559  fileList->Print(opt);
11560  delete fileList;
11561  } else
11562  Warning("ShowDataSet","no such dataset: %s", uri);
11563 }
11564 
11565 ////////////////////////////////////////////////////////////////////////////////
11566 /// Remove the specified dataset from the PROOF cluster.
11567 /// Files are not deleted.
11568 
11569 Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
11570 {
11571  TMessage nameMess(kPROOF_DATASETS);
11572  nameMess << Int_t(kRemoveDataSet);
11573  nameMess << TString(uri?uri:"");
11574  nameMess << TString(optStr?optStr:"");
11575  if (Broadcast(nameMess) < 0)
11576  Error("RemoveDataSet", "sending request failed");
11578 
11579  if (fStatus != 0)
11580  return -1;
11581  else
11582  return 0;
11583 }
11584 
11585 ////////////////////////////////////////////////////////////////////////////////
11586 /// Find datasets, returns in a TList all found datasets.
11587 
11588 TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
11589 {
11590  Error ("FindDataSets", "not yet implemented");
11591  return (TList *) 0;
11592 }
11593 
11594 ////////////////////////////////////////////////////////////////////////////////
11595 /// Allows users to request staging of a particular dataset. Requests are
11596 /// saved in a special dataset repository and must be honored by the endpoint.
11597 
11599 {
11600  if (fProtocol < 35) {
11601  Error("RequestStagingDataSet",
11602  "functionality not supported by the server");
11603  return kFALSE;
11604  }
11605 
11606  TMessage mess(kPROOF_DATASETS);
11607  mess << Int_t(kRequestStaging);
11608  mess << TString(dataset);
11609  Broadcast(mess);
11610 
11611  Collect();
11612  if (fStatus != 0) {
11613  Error("RequestStagingDataSet", "staging request was unsuccessful");
11614  return kFALSE;
11615  }
11616 
11617  return kTRUE;
11618 }
11619 
11620 ////////////////////////////////////////////////////////////////////////////////
11621 /// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11622 /// failure. Dataset not found equals to a failure.
11623 
11625 {
11626  if (fProtocol < 36) {
11627  Error("CancelStagingDataSet",
11628  "functionality not supported by the server");
11629  return kFALSE;
11630  }
11631 
11632  TMessage mess(kPROOF_DATASETS);
11633  mess << Int_t(kCancelStaging);
11634  mess << TString(dataset);
11635  Broadcast(mess);
11636 
11637  Collect();
11638  if (fStatus != 0) {
11639  Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11640  return kFALSE;
11641  }
11642 
11643  return kTRUE;
11644 }
11645 
11646 ////////////////////////////////////////////////////////////////////////////////
11647 /// Obtains a TFileCollection showing the staging status of the specified
11648 /// dataset. A valid dataset manager and dataset staging requests repository
11649 /// must be present on the endpoint.
11650 
11652 {
11653  if (fProtocol < 35) {
11654  Error("GetStagingStatusDataSet",
11655  "functionality not supported by the server");
11656  return NULL;
11657  }
11658 
11659  TMessage nameMess(kPROOF_DATASETS);
11660  nameMess << Int_t(kStagingStatus);
11661  nameMess << TString(dataset);
11662  if (Broadcast(nameMess) < 0) {
11663  Error("GetStagingStatusDataSet", "sending request failed");
11664  return NULL;
11665  }
11666 
11668  TFileCollection *fc = NULL;
11669 
11670  if (fStatus < 0) {
11671  Error("GetStagingStatusDataSet", "problem processing the request");
11672  }
11673  else if (fStatus == 0) {
11674  TMessage *retMess = (TMessage *)fRecvMessages->First();
11675  if (retMess && (retMess->What() == kMESS_OK)) {
11676  fc = (TFileCollection *)(
11677  retMess->ReadObject(TFileCollection::Class()) );
11678  if (!fc)
11679  Error("GetStagingStatusDataSet", "error reading list of files");
11680  }
11681  else {
11682  Error("GetStagingStatusDataSet",
11683  "response message not found or wrong type (%p)", retMess);
11684  }
11685  }
11686  //else {}
11687 
11688  return fc;
11689 }
11690 
11691 ////////////////////////////////////////////////////////////////////////////////
11692 /// Like GetStagingStatusDataSet, but displays results immediately.
11693 
11694 void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11695 {
11697  if (fc) {
11698  fc->Print(opt);
11699  delete fc;
11700  }
11701 }
11702 
11703 ////////////////////////////////////////////////////////////////////////////////
11704 /// Verify if all files in the specified dataset are available.
11705 /// Print a list and return the number of missing files.
11706 /// Returns -1 in case of error.
11707 
11708 Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11709 {
11710  if (fProtocol < 15) {
11711  Info("VerifyDataSet", "functionality not available: the server has an"
11712  " incompatible version of TFileInfo");
11713  return -1;
11714  }
11715 
11716  // Sanity check
11717  if (!uri || (uri && strlen(uri) <= 0)) {
11718  Error("VerifyDataSet", "dataset name is is mandatory");
11719  return -1;
11720  }
11721 
11722  Int_t nmissingfiles = 0;
11723 
11724  TString sopt(optStr);
11725  if (fProtocol < 34 || sopt.Contains("S")) {
11726  sopt.ReplaceAll("S", "");
11727  Info("VerifyDataSet", "Master-only verification");
11728  TMessage nameMess(kPROOF_DATASETS);
11729  nameMess << Int_t(kVerifyDataSet);
11730  nameMess << TString(uri ? uri : "");
11731  nameMess << sopt;
11732  Broadcast(nameMess);
11733 
11735 
11736  if (fStatus < 0) {
11737  Info("VerifyDataSet", "no such dataset %s", uri);
11738  return -1;
11739  } else
11740  nmissingfiles = fStatus;
11741  return nmissingfiles;
11742  }
11743 
11744  // Request for parallel verification: can only be done if we have workers
11745  if (!IsParallel() && !fDynamicStartup) {
11746  Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11747  Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11748  return -1;
11749  }
11750 
11751  // Do parallel verification
11752  return VerifyDataSetParallel(uri, optStr);
11753 }
11754 
11755 ////////////////////////////////////////////////////////////////////////////////
11756 /// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11757 /// TProofLite::VerifyDataSet
11758 
11759 Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11760 {
11761  Int_t nmissingfiles = 0;
11762 
11763  // Let PROOF master prepare node-files map
11764  SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11765 
11766  // Use TPacketizerFile
11767  TString oldpack;
11768  if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11769  SetParameter("PROOF_Packetizer", "TPacketizerFile");
11770 
11771  // Add dataset name
11772  SetParameter("PROOF_VerifyDataSet", uri);
11773  // Add options
11774  SetParameter("PROOF_VerifyDataSetOption", optStr);
11775  SetParameter("PROOF_SavePartialResults", (Int_t)0);
11776  Int_t oldifiip = -1;
11777  if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11778  SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11779 
11780  // TO DO : figure out mss and stageoption
11781  const char* mss="";
11782  SetParameter("PROOF_MSS", mss);
11783  const char* stageoption="";
11784  SetParameter("PROOF_StageOption", stageoption);
11785 
11786  // Process verification in parallel
11787  Process("TSelVerifyDataSet", (Long64_t) 1);
11788 
11789  // Restore packetizer
11790  if (!oldpack.IsNull())
11791  SetParameter("PROOF_Packetizer", oldpack);
11792  else
11793  DeleteParameters("PROOF_Packetizer");
11794 
11795  // Delete or restore parameters
11796  DeleteParameters("PROOF_FilesToProcess");
11797  DeleteParameters("PROOF_VerifyDataSet");
11798  DeleteParameters("PROOF_VerifyDataSetOption");
11799  DeleteParameters("PROOF_MSS");
11800  DeleteParameters("PROOF_StageOption");
11801  if (oldifiip > -1) {
11802  SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11803  } else {
11804  DeleteParameters("PROOF_IncludeFileInfoInPacket");
11805  }
11806  DeleteParameters("PROOF_SavePartialResults");
11807 
11808  // Merge outputs
11809  Int_t nopened = 0;
11810  Int_t ntouched = 0;
11811  Bool_t changed_ds = kFALSE;
11812 
11813  TIter nxtout(GetOutputList());
11814  TObject* obj;
11815  TList *lfiindout = new TList;
11816  while ((obj = nxtout())) {
11817  TList *l = dynamic_cast<TList *>(obj);
11818  if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11819  TIter nxt(l);
11820  TFileInfo *fiindout = 0;
11821  while ((fiindout = (TFileInfo*) nxt())) {
11822  lfiindout->Add(fiindout);
11823  }
11824  }
11825  // Add up number of disppeared files
11826  TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11827  if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11828  nmissingfiles += pdisappeared->GetVal();
11829  }
11830  TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11831  if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11832  nopened += pnopened->GetVal();
11833  }
11834  TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11835  if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11836  ntouched += pntouched->GetVal();
11837  }
11838  TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11839  if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11840  if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11841  }
11842  }
11843 
11844  Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11845  " # missing files = %d)",
11846  uri, changed_ds, nopened, ntouched, nmissingfiles);
11847  // Done
11848  return nmissingfiles;
11849 }
11850 
11851 ////////////////////////////////////////////////////////////////////////////////
11852 /// returns a map of the quotas of all groups
11853 
11854 TMap *TProof::GetDataSetQuota(const char* optStr)
11855 {
11856  if (IsLite()) {
11857  Info("UploadDataSet", "Lite-session: functionality not implemented");
11858  return (TMap *)0;
11859  }
11860 
11861  TMessage mess(kPROOF_DATASETS);
11862  mess << Int_t(kGetQuota);
11863  mess << TString(optStr?optStr:"");
11864  Broadcast(mess);
11865 
11867  TMap *groupQuotaMap = 0;
11868  if (fStatus < 0) {
11869  Info("GetDataSetQuota", "could not receive quota");
11870  } else {
11871  // Look in the list
11872  TMessage *retMess = (TMessage *) fRecvMessages->First();
11873  if (retMess && retMess->What() == kMESS_OK) {
11874  if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11875  Error("GetDataSetQuota", "error getting quotas");
11876  } else
11877  Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11878  }
11879 
11880  return groupQuotaMap;
11881 }
11882 
11883 ////////////////////////////////////////////////////////////////////////////////
11884 /// shows the quota and usage of all groups
11885 /// if opt contains "U" shows also distribution of usage on user-level
11886 
11888 {
11889  if (fProtocol < 15) {
11890  Info("ShowDataSetQuota",
11891  "functionality not available: the server does not have dataset support");
11892  return;
11893  }
11894 
11895  if (IsLite()) {
11896  Info("UploadDataSet", "Lite-session: functionality not implemented");
11897  return;
11898  }
11899 
11900  TMessage mess(kPROOF_DATASETS);
11901  mess << Int_t(kShowQuota);
11902  mess << TString(opt?opt:"");
11903  Broadcast(mess);
11904 
11905  Collect();
11906  if (fStatus != 0)
11907  Error("ShowDataSetQuota", "error receiving quota information");
11908 }
11909 
11910 ////////////////////////////////////////////////////////////////////////////////
11911 /// If in active in a monitor set ready state
11912 
11914 {
11915  if (fCurrentMonitor)
11917 }
11918 
11919 ////////////////////////////////////////////////////////////////////////////////
11920 /// Make sure that the worker identified by the ordinal number 'ord' is
11921 /// in the active list. The request will be forwarded to the master
11922 /// in direct contact with the worker. If needed, this master will move
11923 /// the worker from the inactive to the active list and rebuild the list
11924 /// of unique workers.
11925 /// Use ord = "*" to activate all inactive workers.
11926 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11927 /// status of which will be modified at once.
11928 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11929 /// or the number of workers with status change (on master; 0 on client).
11930 
11932 {
11933  return ModifyWorkerLists(ord, kTRUE, save);
11934 }
11935 
11936 ////////////////////////////////////////////////////////////////////////////////
11937 /// Remove the worker identified by the ordinal number 'ord' from the
11938 /// the active list. The request will be forwarded to the master
11939 /// in direct contact with the worker. If needed, this master will move
11940 /// the worker from the active to the inactive list and rebuild the list
11941 /// of unique workers.
11942 /// Use ord = "*" to deactivate all active workers.
11943 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11944 /// status of which will be modified at once.
11945 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11946 /// or the number of workers with status change (on master; 0 on client).
11947 
11949 {
11950  return ModifyWorkerLists(ord, kFALSE, save);
11951 }
11952 
11953 ////////////////////////////////////////////////////////////////////////////////
11954 /// Modify the worker active/inactive list by making the worker identified by
11955 /// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11956 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11957 /// status of which will be modified at once.
11958 /// If needed, the request will be forwarded to the master in direct contact
11959 /// with the worker. The end-master will move the worker from one list to the
11960 /// other active and rebuild the list of unique active workers.
11961 /// Use ord = "*" to deactivate all active workers.
11962 /// If save is TRUE the current active list is saved before any modification is
11963 /// done; re-running with ord = "restore" restores the saved list
11964 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11965 /// or the number of workers with status change (on master; 0 on client).
11966 
11968 {
11969  // Make sure the input make sense
11970  if (!ord || strlen(ord) <= 0) {
11971  Info("ModifyWorkerLists",
11972  "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11973  return -1;
11974  }
11975  if (gDebug > 0)
11976  Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11977 
11978  Int_t nwc = 0;
11979  Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11980  if (IsEndMaster()) {
11981  if (restoring) {
11982  // We are asked to restore the previous settings
11983  nwc = RestoreActiveList();
11984  } else {
11985  if (save) SaveActiveList();
11986  }
11987  }
11988 
11989  Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11990 
11991  // Check if this is for us
11993  if (!allord &&
11994  strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11995  return 0;
11996  }
11997 
11998  Bool_t fw = kTRUE; // Whether to forward one step down
11999  Bool_t rs = kFALSE; // Whether to rescan for unique workers
12000 
12001  // Appropriate list pointing
12002  TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
12003  TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
12004 
12005  if (IsEndMaster() && !restoring) {
12006  // Create the hash list of ordinal numbers
12007  THashList *ords = 0;
12008  if (!allord) {
12009  ords = new THashList();
12010  const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
12011  TString oo(ord), o;
12012  Int_t from = 0;
12013  while(oo.Tokenize(o, from, ","))
12014  if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
12015  }
12016  // We do not need to send forward
12017  fw = kFALSE;
12018  // Look for the worker in the initial list
12019  TObject *os = 0;
12020  TSlave *wrk = 0;
12021  if (in->GetSize() > 0) {
12022  TIter nxw(in);
12023  while ((wrk = (TSlave *) nxw())) {
12024  os = 0;
12025  if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
12026  // Add it to the final list
12027  if (!out->FindObject(wrk)) {
12028  out->Add(wrk);
12029  if (add)
12030  fActiveMonitor->Add(wrk->GetSocket());
12031  }
12032  // Remove it from the initial list
12033  in->Remove(wrk);
12034  if (!add) {
12035  fActiveMonitor->Remove(wrk->GetSocket());
12037  } else
12038  wrk->SetStatus(TSlave::kActive);
12039  // Count
12040  nwc++;
12041  // Nothing to forward (ord is unique)
12042  fw = kFALSE;
12043  // Rescan for unique workers (active list modified)
12044  rs = kTRUE;
12045  // We may be done, if not option 'all'
12046  if (!allord && ords) {
12047  if (os) ords->Remove(os);
12048  if (ords->GetSize() == 0) break;
12049  SafeDelete(os);
12050  }
12051  }
12052  }
12053  }
12054  // If some worker not found, notify it if at the end
12055  if (!fw && ords && ords->GetSize() > 0) {
12056  TString oo;
12057  TIter nxo(ords);
12058  while ((os = nxo())) {
12059  TIter nxw(out);
12060  while ((wrk = (TSlave *) nxw()))
12061  if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
12062  if (!wrk) {
12063  if (!oo.IsNull()) oo += ",";
12064  oo += os->GetName();
12065  }
12066  }
12067  if (!oo.IsNull()) {
12068  Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
12069  nwc = -2;
12070  }
12071  }
12072  // Cleanup hash list
12073  if (ords) {
12074  ords->Delete();
12075  SafeDelete(ords);
12076  }
12077  }
12078 
12079  // Rescan for unique workers
12080  if (rs)
12081  FindUniqueSlaves();
12082 
12083  // Forward the request one step down, if needed
12084  Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
12085  if (fw) {
12086  if (fProtocol > 32) {
12088  mess << action << TString(ord);
12089  Broadcast(mess);
12091  if (fStatus != 0) {
12092  nwc = (fStatus < nwc) ? fStatus : nwc;
12093  if (fStatus == -2) {
12094  if (gDebug > 0)
12095  Warning("ModifyWorkerLists", "request not completely full filled");
12096  } else {
12097  Error("ModifyWorkerLists", "request failed");
12098  }
12099  }
12100  } else {
12101  TString oo(ord), o;
12102  if (oo.Contains(","))
12103  Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
12104  Int_t from = 0;
12105  while(oo.Tokenize(o, from, ",")) {
12107  mess << action << o;
12108  Broadcast(mess);
12110  }
12111  }
12112  }
12113  // Done
12114  return nwc;
12115 }
12116 
12117 ////////////////////////////////////////////////////////////////////////////////
12118 /// Save current list of active workers
12119 
12121 {
12123  if (fInactiveSlaves->GetSize() == 0) {
12124  fActiveSlavesSaved = "*";
12125  } else {
12126  TIter nxw(fActiveSlaves);
12127  TSlave *wk = 0;
12128  while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
12129  }
12130 }
12131 
12132 ////////////////////////////////////////////////////////////////////////////////
12133 /// Restore saved list of active workers
12134 
12136 {
12137  // Clear the current active list
12138  DeactivateWorker("*", kFALSE);
12139  // Restore the previous active list
12140  if (!fActiveSlavesSaved.IsNull())
12142 
12143  return 0;
12144 }
12145 
12146 ////////////////////////////////////////////////////////////////////////////////
12147 /// Start a PROOF session on a specific cluster. If cluster is 0 (the
12148 /// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
12149 /// If cluster is "lite://" we start a PROOF-lite session.
12150 /// If cluster is "" (empty string) then we connect to the cluster specified
12151 /// by 'Proof.LocalDefault', defaulting to "lite://".
12152 /// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
12153 /// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
12154 /// Via conffile a specific PROOF config file in the confir directory can be specified.
12155 /// Use loglevel to set the default loging level for debugging.
12156 /// The appropriate instance of TProofMgr is created, if not
12157 /// yet existing. The instantiated TProof object is returned.
12158 /// Use TProof::cd() to switch between PROOF sessions.
12159 /// For more info on PROOF see the TProof ctor.
12160 
12161 TProof *TProof::Open(const char *cluster, const char *conffile,
12162  const char *confdir, Int_t loglevel)
12163 {
12164  const char *pn = "TProof::Open";
12165 
12166  // Make sure libProof and dependents are loaded and TProof can be created,
12167  // dependents are loaded via the information in the [system].rootmap file
12168  if (!cluster) {
12169 
12170  TPluginManager *pm = gROOT->GetPluginManager();
12171  if (!pm) {
12172  ::Error(pn, "plugin manager not found");
12173  return 0;
12174  }
12175 
12176  if (gROOT->IsBatch()) {
12177  ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
12178  return 0;
12179  }
12180  // start PROOF Session Viewer
12181  TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
12182  if (!sv) {
12183  ::Error(pn, "no plugin found for TSessionViewer");
12184  return 0;
12185  }
12186  if (sv->LoadPlugin() == -1) {
12187  ::Error(pn, "plugin for TSessionViewer could not be loaded");
12188  return 0;
12189  }
12190  sv->ExecPlugin(0);
12191  return 0;
12192 
12193  } else {
12194 
12195  TString clst(cluster);
12196 
12197  // Check for PoD cluster
12198  if (PoDCheckUrl( &clst ) < 0) return 0;
12199 
12200  if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
12201  if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
12202 
12203  // Parse input URL
12204  TUrl u(clst);
12205 
12206  // *** GG, 060711: this does not seem to work any more (at XrdClient level)
12207  // *** to be investigated (it is not really needed; static tunnels work).
12208  // Dynamic tunnel:
12209  // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
12210  TString opts(u.GetOptions());
12211  if (!opts.IsNull()) {
12212  Int_t it = opts.Index("tunnel=");
12213  if (it != kNPOS) {
12214  TString sport = opts(it + strlen("tunnel="), opts.Length());
12215  TString host("127.0.0.1");
12216  Int_t port = -1;
12217  Int_t ic = sport.Index(":");
12218  if (ic != kNPOS) {
12219  // Isolate the host
12220  host = sport(0, ic);
12221  sport.Remove(0, ic + 1);
12222  }
12223  if (!sport.IsDigit()) {
12224  // Remove the non digit part
12225  TRegexp re("[^0-9]");
12226  Int_t ind = sport.Index(re);
12227  if (ind != kNPOS)
12228  sport.Remove(ind);
12229  }
12230  // Set the port
12231  if (sport.IsDigit())
12232  port = sport.Atoi();
12233  if (port > 0) {
12234  // Set the relevant variables
12235  ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
12236  gEnv->SetValue("XNet.SOCKS4Host", host);
12237  gEnv->SetValue("XNet.SOCKS4Port", port);
12238  } else {
12239  // Warn parsing problems
12240  ::Warning("TProof::Open",
12241  "problems parsing tunnelling info from options: %s", opts.Data());
12242  }
12243  }
12244  }
12245 
12246  // Find out if we are required to attach to a specific session
12247  Int_t locid = -1;
12248  Bool_t create = kFALSE;
12249  if (opts.Length() > 0) {
12250  if (opts.BeginsWith("N",TString::kIgnoreCase)) {
12251  create = kTRUE;
12252  opts.Remove(0,1);
12253  u.SetOptions(opts);
12254  } else if (opts.IsDigit()) {
12255  locid = opts.Atoi();
12256  }
12257  }
12258 
12259  // Attach-to or create the appropriate manager
12260  TProofMgr *mgr = TProofMgr::Create(u.GetUrl());
12261 
12262  TProof *proof = 0;
12263  if (mgr && mgr->IsValid()) {
12264 
12265  // If XProofd we always attempt an attach first (unless
12266  // explicitly not requested).
12267  Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
12268  if (attach) {
12269  TProofDesc *d = 0;
12270  if (locid < 0)
12271  // Get the list of sessions
12272  d = (TProofDesc *) mgr->QuerySessions("")->First();
12273  else
12274  d = (TProofDesc *) mgr->GetProofDesc(locid);
12275  if (d) {
12276  proof = (TProof*) mgr->AttachSession(d);
12277  if (!proof || !proof->IsValid()) {
12278  if (locid)
12279  ::Error(pn, "new session could not be attached");
12280  SafeDelete(proof);
12281  }
12282  }
12283  }
12284 
12285  // start the PROOF session
12286  if (!proof) {
12287  proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
12288  if (!proof || !proof->IsValid()) {
12289  ::Error(pn, "new session could not be created");
12290  SafeDelete(proof);
12291  }
12292  }
12293  }
12294  return proof;
12295  }
12296 }
12297 
12298 ////////////////////////////////////////////////////////////////////////////////
12299 /// Get instance of the effective manager for 'url'
12300 /// Return 0 on failure.
12301 
12302 TProofMgr *TProof::Mgr(const char *url)
12303 {
12304  if (!url)
12305  return (TProofMgr *)0;
12306 
12307  // Attach or create the relevant instance
12308  return TProofMgr::Create(url);
12309 }
12310 
12311 ////////////////////////////////////////////////////////////////////////////////
12312 /// Wrapper around TProofMgr::Reset(...).
12313 
12314 void TProof::Reset(const char *url, Bool_t hard)
12315 {
12316  if (url) {
12317  TProofMgr *mgr = TProof::Mgr(url);
12318  if (mgr && mgr->IsValid())
12319  mgr->Reset(hard);
12320  else
12321  ::Error("TProof::Reset",
12322  "unable to initialize a valid manager instance");
12323  }
12324 }
12325 
12326 ////////////////////////////////////////////////////////////////////////////////
12327 /// Get environemnt variables.
12328 
12330 {
12331  return fgProofEnvList;
12332 }
12333 
12334 ////////////////////////////////////////////////////////////////////////////////
12335 /// Add an variable to the list of environment variables passed to proofserv
12336 /// on the master and slaves
12337 
12338 void TProof::AddEnvVar(const char *name, const char *value)
12339 {
12340  if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
12341 
12342  if (fgProofEnvList == 0) {
12343  // initialize the list if needed
12344  fgProofEnvList = new TList;
12346  } else {
12347  // replace old entries with the same name
12348  TObject *o = fgProofEnvList->FindObject(name);
12349  if (o != 0) {
12350  fgProofEnvList->Remove(o);
12351  }
12352  }
12353  fgProofEnvList->Add(new TNamed(name, value));
12354 }
12355 
12356 ////////////////////////////////////////////////////////////////////////////////
12357 /// Remove an variable from the list of environment variables passed to proofserv
12358 /// on the master and slaves
12359 
12360 void TProof::DelEnvVar(const char *name)
12361 {
12362  if (fgProofEnvList == 0) return;
12363 
12364  TObject *o = fgProofEnvList->FindObject(name);
12365  if (o != 0) {
12366  fgProofEnvList->Remove(o);
12367  }
12368 }
12369 
12370 ////////////////////////////////////////////////////////////////////////////////
12371 /// Clear the list of environment variables passed to proofserv
12372 /// on the master and slaves
12373 
12375 {
12376  if (fgProofEnvList == 0) return;
12377 
12379 }
12380 
12381 ////////////////////////////////////////////////////////////////////////////////
12382 /// Save information about the worker set in the file .workers in the working
12383 /// dir. Called each time there is a change in the worker setup, e.g. by
12384 /// TProof::MarkBad().
12385 
12387 {
12388  // We must be masters
12390  return;
12391 
12392  // We must have a server defined
12393  if (!gProofServ) {
12394  Error("SaveWorkerInfo","gProofServ undefined");
12395  return;
12396  }
12397 
12398  // The relevant lists must be defined
12399  if (!fSlaves && !fBadSlaves) {
12400  Warning("SaveWorkerInfo","all relevant worker lists is undefined");
12401  return;
12402  }
12403 
12404  // Create or truncate the file first
12405  TString fnwrk = TString::Format("%s/.workers",
12407  FILE *fwrk = fopen(fnwrk.Data(),"w");
12408  if (!fwrk) {
12409  Error("SaveWorkerInfo",
12410  "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
12411  return;
12412  }
12413 
12414  // Do we need to register an additional line for another log?
12415  TString addlogext;
12416  TString addLogTag;
12417  if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
12418  addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
12419  TPMERegexp reLogTag("^__(.*)__\\.log"); // $
12420  if (reLogTag.Match(addlogext) == 2) {
12421  addLogTag = reLogTag[1];
12422  }
12423  else {
12424  addLogTag = "+++";
12425  }
12426  if (gDebug > 0)
12427  Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
12428  }
12429 
12430  // Used to eliminate datetime and PID from workdir to obtain log file name
12431  TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
12432 
12433  // Loop over the list of workers (active is any worker not flagged as bad)
12434  TIter nxa(fSlaves);
12435  TSlave *wrk = 0;
12436  TString logfile;
12437  while ((wrk = (TSlave *) nxa())) {
12438  Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
12439  logfile = wrk->GetWorkDir();
12440  if (re.Match(logfile) == 2) logfile = re[1];
12441  else continue; // invalid (should not happen)
12442  // Write out record for this worker
12443  fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
12444  wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
12445  wrk->GetOrdinal(), logfile.Data());
12446  // Additional line, if required
12447  if (addlogext.Length() > 0) {
12448  fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
12449  wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
12450  wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
12451  }
12452 
12453  }
12454 
12455  // Loop also over the list of bad workers (if they failed to startup they are not in
12456  // the overall list
12457  TIter nxb(fBadSlaves);
12458  while ((wrk = (TSlave *) nxb())) {
12459  logfile = wrk->GetWorkDir();
12460  if (re.Match(logfile) == 2) logfile = re[1];
12461  else continue; // invalid (should not happen)
12462  if (!fSlaves->FindObject(wrk)) {
12463  // Write out record for this worker
12464  fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
12465  wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
12466  wrk->GetOrdinal(), logfile.Data());
12467  }
12468  }
12469 
12470  // Eventually loop over the list of gracefully terminated workers: we'll get
12471  // logfiles from those workers as well. They'll be shown with a special
12472  // status of "2"
12474  TSlaveInfo *sli;
12475  while (( sli = (TSlaveInfo *)nxt() )) {
12476  logfile = sli->GetDataDir();
12477  if (re.Match(logfile) == 2) logfile = re[1];
12478  else continue; // invalid (should not happen)
12479  fprintf(fwrk, "%s 2 %s %s.log\n",
12480  sli->GetName(), sli->GetOrdinal(), logfile.Data());
12481  // Additional line, if required
12482  if (addlogext.Length() > 0) {
12483  fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
12484  sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
12485  logfile.Data(), addlogext.Data());
12486  }
12487  }
12488 
12489  // Close file
12490  fclose(fwrk);
12491 
12492  // We are done
12493  return;
12494 }
12495 
12496 ////////////////////////////////////////////////////////////////////////////////
12497 /// Get the value from the specified parameter from the specified collection.
12498 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12499 /// or value type does not match), 0 otherwise.
12500 
12502 {
12503  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12504  if (obj) {
12505  TNamed *p = dynamic_cast<TNamed*>(obj);
12506  if (p) {
12507  value = p->GetTitle();
12508  return 0;
12509  }
12510  }
12511  return -1;
12512 
12513 }
12514 
12515 ////////////////////////////////////////////////////////////////////////////////
12516 /// Get the value from the specified parameter from the specified collection.
12517 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12518 /// or value type does not match), 0 otherwise.
12519 
12521 {
12522  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12523  if (obj) {
12524  TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
12525  if (p) {
12526  value = p->GetVal();
12527  return 0;
12528  }
12529  }
12530  return -1;
12531 }
12532 
12533 ////////////////////////////////////////////////////////////////////////////////
12534 /// Get the value from the specified parameter from the specified collection.
12535 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12536 /// or value type does not match), 0 otherwise.
12537 
12539 {
12540  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12541  if (obj) {
12542  TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
12543  if (p) {
12544  value = p->GetVal();
12545  return 0;
12546  }
12547  }
12548  return -1;
12549 }
12550 
12551 ////////////////////////////////////////////////////////////////////////////////
12552 /// Get the value from the specified parameter from the specified collection.
12553 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12554 /// or value type does not match), 0 otherwise.
12555 
12557 {
12558  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12559  if (obj) {
12560  TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
12561  if (p) {
12562  value = p->GetVal();
12563  return 0;
12564  }
12565  }
12566  return -1;
12567 }
12568 
12569 ////////////////////////////////////////////////////////////////////////////////
12570 /// Get the value from the specified parameter from the specified collection.
12571 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12572 /// or value type does not match), 0 otherwise.
12573 
12575 {
12576  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12577  if (obj) {
12578  TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
12579  if (p) {
12580  value = p->GetVal();
12581  return 0;
12582  }
12583  }
12584  return -1;
12585 }
12586 
12587 ////////////////////////////////////////////////////////////////////////////////
12588 /// Make sure that dataset is in the form to be processed. This may mean
12589 /// retrieving the relevant info from the dataset manager or from the
12590 /// attached input list.
12591 /// Returns 0 on success, -1 on error
12592 
12594  TDataSetManager *mgr, TString &emsg)
12595 {
12596  emsg = "";
12597 
12598  // We must have something to process
12599  if (!dset || !input || !mgr) {
12600  emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
12601  return -1;
12602  }
12603 
12604  TList *datasets = new TList;
12605  TFileCollection *dataset = 0;
12606  TString lookupopt;
12607  TString dsname(dset->GetName());
12608  // The dataset maybe in the form of a TFileCollection in the input list
12609  if (dsname.BeginsWith("TFileCollection:")) {
12610  // Isolate the real name
12611  dsname.ReplaceAll("TFileCollection:", "");
12612  // Get the object
12613  dataset = (TFileCollection *) input->FindObject(dsname);
12614  if (!dataset) {
12615  emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12616  return -1;
12617  }
12618  // Remove from everywhere
12619  input->RecursiveRemove(dataset);
12620  // Add it to the local list
12621  datasets->Add(new TPair(dataset, new TObjString("")));
12622  // Make sure we lookup everything (unless the client or the administrator
12623  // required something else)
12624  if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12625  lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12626  input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12627  }
12628  }
12629 
12630  // This is the name we parse for additional specifications, such directory
12631  // and object name; for multiple datasets we assume that the directory and
12632  // and object name are the same for all datasets
12633  TString dsnparse;
12634  // The received message included an empty dataset, with only the name
12635  // defined: assume that a dataset, stored on the PROOF master by that
12636  // name, should be processed.
12637  if (!dataset) {
12638 
12639  // First of all check if the full string (except the "entry list" part)
12640  // is the name of a single existing dataset: if it is, don't break it
12641  // into parts
12642  TString dsns( dsname.Data() ), enl;
12643  Ssiz_t eli = dsns.Index("?enl=");
12644  TFileCollection *fc = nullptr;
12645  if (eli != kNPOS) {
12646  enl = dsns(eli+5, dsns.Length());
12647  dsns.Remove(eli, dsns.Length()-eli);
12648  }
12649 
12650  // Check if the entry list is valid. If it has spaces, commas, or pipes,
12651  // it is not considered as valid and we revert to the "multiple datasets"
12652  // case
12653  Bool_t validEnl = ((enl.Index("|") == kNPOS) &&
12654  (enl.Index(",") == kNPOS) && (enl.Index(" ") == kNPOS));
12655 
12656  if (validEnl && (( fc = mgr->GetDataSet(dsns) ))) {
12657 
12658  //
12659  // String corresponds to ONE dataset only
12660  //
12661 
12662  TIter nxfi(fc->GetList());
12663  TFileInfo *fi;
12664  while (( fi = (TFileInfo *)nxfi() ))
12665  fi->SetTitle(dsns.Data());
12666  dataset = fc;
12667  dsnparse = dsns; // without entry list
12668 
12669  // Adds the entry list (or empty string if not specified)
12670  datasets->Add( new TPair(dataset, new TObjString( enl.Data() )) );
12671 
12672  }
12673  else {
12674 
12675  //
12676  // String does NOT correspond to one dataset: check if many datasets
12677  // were specified instead
12678  //
12679 
12680  dsns = dsname.Data();
12681  TString dsn1;
12682  Int_t from1 = 0;
12683  while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12684  TString dsn2;
12685  Int_t from2 = 0;
12686  while (dsn1.Tokenize(dsn2, from2, "|")) {
12687  enl = "";
12688  Int_t ienl = dsn2.Index("?enl=");
12689  if (ienl != kNPOS) {
12690  enl = dsn2(ienl + 5, dsn2.Length());
12691  dsn2.Remove(ienl);
12692  }
12693  if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12694  // Save dataset name in TFileInfo's title to use it in TDset
12695  TIter nxfi(fc->GetList());
12696  TFileInfo *fi;
12697  while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12698  dsnparse = dsn2;
12699  if (!dataset) {
12700  // This is our dataset
12701  dataset = fc;
12702  } else {
12703  // Add it to the dataset
12704  dataset->Add(fc);
12705  SafeDelete(fc);
12706  }
12707  }
12708  }
12709  // The dataset name(s) in the first element
12710  if (dataset) {
12711  if (dataset->GetList()->First())
12712  ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12713  // Add it to the local list
12714  datasets->Add(new TPair(dataset, new TObjString(enl.Data())));
12715  }
12716  // Reset the pointer
12717  dataset = 0;
12718  }
12719 
12720  }
12721 
12722  //
12723  // At this point the dataset(s) to be processed, if any, are found in the
12724  // "datasets" variable
12725  //
12726 
12727  if (!datasets || datasets->GetSize() <= 0) {
12728  emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12729  return -1;
12730  } else {
12731  // Make 'dataset' to point to the first one in the list
12732  if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12733  emsg.Form("dataset pointer is null: corruption? - aborting");
12734  return -1;
12735  }
12736  }
12737  // Apply the lookup option requested by the client or the administartor
12738  // (by default we trust the information in the dataset)
12739  if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12740  lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12741  input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12742  }
12743  } else {
12744  // We were given a named, single, TFileCollection
12745  dsnparse = dsname;
12746  }
12747 
12748  // Logic for the subdir/obj names: try first to see if the dataset name contains
12749  // some info; if not check the settings in the TDSet object itself; if still empty
12750  // check the default tree name / path in the TFileCollection object; if still empty
12751  // use the default as the flow will determine
12752  TString dsTree;
12753  // Get the [subdir/]tree, if any
12754  mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12755  if (dsTree.IsNull()) {
12756  // Use what we have in the original dataset; we need this to locate the
12757  // meta data information
12758  dsTree += dset->GetDirectory();
12759  dsTree += dset->GetObjName();
12760  }
12761  if (!dsTree.IsNull() && dsTree != "/") {
12762  TString tree(dsTree);
12763  Int_t idx = tree.Index("/");
12764  if (idx != kNPOS) {
12765  TString dir = tree(0, idx+1);
12766  tree.Remove(0, idx);
12767  dset->SetDirectory(dir);
12768  }
12769  dset->SetObjName(tree);
12770  } else {
12771  // Use the default obj name from the TFileCollection
12772  dsTree = dataset->GetDefaultTreeName();
12773  }
12774 
12775  // Pass dataset server mapping instructions, if any
12776  TList *srvmapsref = TDataSetManager::GetDataSetSrvMaps();
12777  TList *srvmapslist = srvmapsref;
12778  TString srvmaps;
12779  if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12780  srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12781  if (gProofServ) {
12782  TString msg;
12783  if (srvmapsref && !srvmapslist) {
12784  msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12785  } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12786  msg.Form("+++ Info: dataset server mapping(s) modified by user");
12787  } else if (!srvmapsref && srvmapslist) {
12788  msg.Form("+++ Info: dataset server mapping(s) added by user");
12789  }
12791  }
12792  }
12793 
12794  // Flag multi-datasets
12795  if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12796  // Loop over the list of datasets
12797  TList *listOfMissingFiles = new TList;
12798  TEntryList *entrylist = 0;
12799  TPair *pair = 0;
12800  TIter nxds(datasets);
12801  while ((pair = (TPair *) nxds())) {
12802  // File Collection
12803  dataset = (TFileCollection *) pair->Key();
12804  // Entry list, if any
12805  TEntryList *enl = 0;
12806  TObjString *os = (TObjString *) pair->Value();
12807  if (strlen(os->GetName())) {
12808  if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12809  if (gProofServ)
12811  " entry list %s not found", os->GetName()));
12812  }
12813  if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12814  if (gProofServ)
12816  " no sub-lists in entry-list!"));
12817  }
12818  }
12819  TList *missingFiles = new TList;
12820  TSeqCollection* files = dataset->GetList();
12821  if (gDebug > 0) files->Print();
12822  Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12823  if (dset->TestBit(TDSet::kMultiDSet)) {
12824  TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12825  ds->SetSrvMaps(srvmapslist);
12826  if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12827  emsg.Form("error integrating dataset %s", dataset->GetName());
12828  continue;
12829  }
12830  // Add the TDSet object to the multi-dataset
12831  dset->Add(ds);
12832  // Add entry list if any
12833  if (enl) ds->SetEntryList(enl);
12834  } else {
12835  dset->SetSrvMaps(srvmapslist);
12836  if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12837  emsg.Form("error integrating dataset %s", dataset->GetName());
12838  continue;
12839  }
12840  if (enl) entrylist = enl;
12841  }
12842  if (missingFiles) {
12843  // The missing files objects have to be removed from the dataset
12844  // before delete.
12845  TIter next(missingFiles);
12846  TObject *file;
12847  while ((file = next())) {
12848  dataset->GetList()->Remove(file);
12849  listOfMissingFiles->Add(file);
12850  }
12851  missingFiles->SetOwner(kFALSE);
12852  missingFiles->Clear();
12853  }
12854  SafeDelete(missingFiles);
12855  }
12856  // Cleanup; we need to do this because pairs do no delete their content
12857  nxds.Reset();
12858  while ((pair = (TPair *) nxds())) {
12859  if (pair->Key()) delete pair->Key();
12860  if (pair->Value()) delete pair->Value();
12861  }
12862  datasets->SetOwner(kTRUE);
12863  SafeDelete(datasets);
12864 
12865  // Cleanup the server mapping list, if created by the user
12866  if (srvmapslist && srvmapslist != srvmapsref) {
12867  srvmapslist->SetOwner(kTRUE);
12868  SafeDelete(srvmapslist);
12869  }
12870 
12871  // Set the global entrylist, if required
12872  if (entrylist) dset->SetEntryList(entrylist);
12873 
12874  // Make sure it will be sent back merged with other similar lists created
12875  // during processing; this list will be transferred by the player to the
12876  // output list, once the latter has been created (see TProofPlayerRemote::Process)
12877  if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12878  listOfMissingFiles->SetName("MissingFiles");
12879  input->Add(listOfMissingFiles);
12880  }
12881 
12882  // Done
12883  return 0;
12884 }
12885 
12886 ////////////////////////////////////////////////////////////////////////////////
12887 /// Save input data file from 'cachedir' into the sandbox or create a the file
12888 /// with input data objects
12889 
12890 Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12891 {
12892  TList *input = 0;
12893 
12894  // We must have got something to process
12895  if (!qr || !(input = qr->GetInputList()) ||
12896  !cachedir || strlen(cachedir) <= 0) return 0;
12897 
12898  // There must be some input data or input data file
12899  TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12900  TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12901  if (!data && !inputdata) return 0;
12902  // Default dstination filename
12903  if (!data)
12904  input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12905 
12906  TString dstname(data->GetTitle()), srcname;
12907  Bool_t fromcache = kFALSE;
12908  if (dstname.BeginsWith("cache:")) {
12909  fromcache = kTRUE;
12910  dstname.ReplaceAll("cache:", "");
12911  srcname.Form("%s/%s", cachedir, dstname.Data());
12912  if (gSystem->AccessPathName(srcname)) {
12913  emsg.Form("input data file not found in cache (%s)", srcname.Data());
12914  return -1;
12915  }
12916  }
12917 
12918  // If from cache, just move the cache file
12919  if (fromcache) {
12920  if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12921  emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12922  return -1;
12923  }
12924  } else {
12925  // Create the file
12926  if (inputdata && inputdata->GetSize() > 0) {
12927  TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12928  if (f) {
12929  f->cd();
12930  inputdata->Write();
12931  f->Close();
12932  delete f;
12933  } else {
12934  emsg.Form("could not create %s", dstname.Data());
12935  return -1;
12936  }
12937  } else {
12938  emsg.Form("no input data!");
12939  return -1;
12940  }
12941  }
12942  ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12943 
12944  // Save the file name and clean up the data list
12945  data->SetTitle(dstname);
12946  if (inputdata) {
12947  input->Remove(inputdata);
12948  inputdata->SetOwner();
12949  delete inputdata;
12950  }
12951 
12952  // Done
12953  return 0;
12954 }
12955 
12956 ////////////////////////////////////////////////////////////////////////////////
12957 /// Send the input data file to the workers
12958 
12960 {
12961  TList *input = 0;
12962 
12963  // We must have got something to process
12964  if (!qr || !(input = qr->GetInputList())) return 0;
12965 
12966  // There must be some input data or input data file
12967  TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12968  if (!inputdata) return 0;
12969 
12970  TString fname(inputdata->GetTitle());
12971  if (gSystem->AccessPathName(fname)) {
12972  emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12973  return -1;
12974  }
12975 
12976  // PROOF session must available
12977  if (!p || !p->IsValid()) {
12978  emsg.Form("TProof object undefined or invalid: protocol error!");
12979  return -1;
12980  }
12981 
12982  // Send to unique workers and submasters
12983  p->BroadcastFile(fname, TProof::kBinary, "cache");
12984 
12985  // Done
12986  return 0;
12987 }
12988 
12989 ////////////////////////////////////////////////////////////////////////////////
12990 /// Get the input data from the file defined in the input list
12991 
12992 Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12993 {
12994  // We must have got something to process
12995  if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12996 
12997  // There must be some input data or input data file
12998  TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12999  if (!inputdata) return 0;
13000 
13001  TString fname;
13002  fname.Form("%s/%s", cachedir, inputdata->GetTitle());
13003  if (gSystem->AccessPathName(fname)) {
13004  emsg.Form("input data file not found in cache (%s)", fname.Data());
13005  return -1;
13006  }
13007 
13008  // List of added objects (for proper cleaning ...)
13009  TList *added = new TList;
13010  added->SetName("PROOF_InputObjsFromFile");
13011  // Read the input data into the input list
13012  TFile *f = TFile::Open(fname.Data());
13013  if (f) {
13014  TList *keys = (TList *) f->GetListOfKeys();
13015  if (!keys) {
13016  emsg.Form("could not get list of object keys from file");
13017  return -1;
13018  }
13019  TIter nxk(keys);
13020  TKey *k = 0;
13021  while ((k = (TKey *)nxk())) {
13022  TObject *o = f->Get(k->GetName());
13023  if (o) {
13024  input->Add(o);
13025  added->Add(o);
13026  }
13027  }
13028  // Add the file as last one
13029  if (added->GetSize() > 0) {
13030  added->Add(f);
13031  input->Add(added);
13032  } else {
13033  // Cleanup the file now
13034  f->Close();
13035  delete f;
13036  }
13037  } else {
13038  emsg.Form("could not open %s", fname.Data());
13039  return -1;
13040  }
13041 
13042  // Done
13043  return 0;
13044 }
13045 
13046 ////////////////////////////////////////////////////////////////////////////////
13047 /// Start the log viewer window usign the plugin manager
13048 
13049 void TProof::LogViewer(const char *url, Int_t idx)
13050 {
13051  if (!gROOT->IsBatch()) {
13052  // Get the handler, if not yet done
13053  if (!fgLogViewer) {
13054  if ((fgLogViewer =
13055  gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
13056  if (fgLogViewer->LoadPlugin() == -1) {
13057  fgLogViewer = 0;
13058  ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
13059  return;
13060  }
13061  }
13062  }
13063  if (fgLogViewer) {
13064  // Execute the plug-in
13065  TString u = (url && strlen(url) <= 0) ? "lite" : url;
13066  fgLogViewer->ExecPlugin(2, u.Data(), idx);
13067  }
13068  } else {
13069  if (url && strlen(url) > 0) {
13070  ::Info("TProof::LogViewer",
13071  "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
13072  } else if (url && strlen(url) <= 0) {
13073  ::Info("TProof::LogViewer",
13074  "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
13075  } else {
13076  ::Info("TProof::LogViewer",
13077  "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
13078  }
13079  }
13080  // Done
13081  return;
13082 }
13083 
13084 ////////////////////////////////////////////////////////////////////////////////
13085 /// Enable/Disable the graphic progress dialog.
13086 /// By default the dialog is enabled
13087 
13089 {
13090  if (on)
13092  else
13094 }
13095 
13096 ////////////////////////////////////////////////////////////////////////////////
13097 /// Show information about missing files during query described by 'qr' or the
13098 /// last query if qr is null (default).
13099 /// A short summary is printed in the end.
13100 
13102 {
13103  TQueryResult *xqr = (qr) ? qr : GetQueryResult();
13104  if (!xqr) {
13105  Warning("ShowMissingFiles", "no (last) query found: do nothing");
13106  return;
13107  }
13108 
13109  // Get the list, if any
13110  TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
13111  if (!missing) {
13112  Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
13113  return;
13114  }
13115 
13116  Int_t nmf = 0, ncf = 0;
13117  Long64_t msz = 0, mszzip = 0, mev = 0;
13118  // Scan the list
13119  TFileInfo *fi = 0;
13120  TIter nxf(missing);
13121  while ((fi = (TFileInfo *) nxf())) {
13122  char status = 'M';
13123  if (fi->TestBit(TFileInfo::kCorrupted)) {
13124  ncf++;
13125  status = 'C';
13126  } else {
13127  nmf++;
13128  }
13129  TFileInfoMeta *im = fi->GetMetaData();
13130  if (im) {
13131  if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
13132  if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
13133  mev += im->GetEntries();
13134  Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
13135  } else {
13136  Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
13137  }
13138  }
13139 
13140  // Final notification
13141  if (msz <= 0) msz = -1;
13142  if (mszzip <= 0) mszzip = -1;
13143  Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
13144  if (msz > 0. || mszzip > 0.) {
13145  Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
13146  " about %.2f%% of the total (%lld bytes, %lld zipped)",
13147  nmf, ncf, mev, xf * 100., msz, mszzip);
13148  } else {
13149  Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
13150  " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
13151  }
13152 }
13153 
13154 ////////////////////////////////////////////////////////////////////////////////
13155 /// Get a TFileCollection with the files missing in the query described by 'qr'
13156 /// or the last query if qr is null (default).
13157 /// Return a null pointer if none were found, for whatever reason.
13158 /// The caller is responsible for the returned object.
13159 
13161 {
13162  TFileCollection *fc = 0;
13163 
13164  TQueryResult *xqr = (qr) ? qr : GetQueryResult();
13165  if (!xqr) {
13166  Warning("GetMissingFiles", "no (last) query found: do nothing");
13167  return fc;
13168  }
13169 
13170  // Get the list, if any
13171  TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
13172  if (!missing) {
13173  if (gDebug > 0)
13174  Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
13175  return fc;
13176  }
13177 
13178  // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
13179  TString fcname("unknown");
13180  TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
13181  if (ds) {
13182  fcname.Form("%s.m0", ds->GetName());
13183  Int_t j = 1;
13184  while (gDirectory->FindObject(fcname) && j < 1000)
13185  fcname.Form("%s.m%d", ds->GetName(), j++);
13186  }
13187  fc = new TFileCollection(fcname, "Missing Files");
13188  if (ds) fc->SetDefaultTreeName(ds->GetObjName());
13189  // Scan the list
13190  TFileInfo *fi = 0;
13191  TIter nxf(missing);
13192  while ((fi = (TFileInfo *) nxf())) {
13193  fc->Add((TFileInfo *) fi->Clone());
13194  }
13195  fc->Update();
13196  // Done
13197  return fc;
13198 }
13199 
13200 ////////////////////////////////////////////////////////////////////////////////
13201 /// Enable/Disable saving of the performance tree
13202 
13203 void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
13204 {
13205  if (pf && strlen(pf) > 0) {
13206  fPerfTree = pf;
13207  SetParameter("PROOF_StatsHist", "");
13208  SetParameter("PROOF_StatsTrace", "");
13209  if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
13210  Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
13211  } else {
13212  fPerfTree = "";
13213  DeleteParameters("PROOF_StatsHist");
13214  DeleteParameters("PROOF_StatsTrace");
13215  DeleteParameters("PROOF_SlaveStatsTrace");
13216  Info("SetPerfTree", "saving of the performance tree disabled");
13217  }
13218 }
13219 
13220 ////////////////////////////////////////////////////////////////////////////////
13221 /// Save performance information from TPerfStats to file 'pf'.
13222 /// If 'ref' is defined, do it for query 'ref'.
13223 /// Return 0 on sucecss, -1 in case of any error
13224 
13225 Int_t TProof::SavePerfTree(const char *pf, const char *ref)
13226 {
13227  if (!IsValid()) {
13228  Error("SafePerfTree", "this TProof instance is invalid!");
13229  return -1;
13230  }
13231 
13232  TList *outls = GetOutputList();
13233  TString sref;
13234  if (ref && strlen(ref) > 0) {
13235  if (!fPlayer) {
13236  Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
13237  return -1;
13238  }
13239  TQueryResult *qr = fPlayer->GetQueryResult(ref);
13240  if (!qr) {
13241  Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
13242  return -1;
13243  }
13244  outls = qr->GetOutputList();
13245  sref.Form(" for requested query '%s'", ref);
13246  }
13247  if (!outls || (outls && outls->GetSize() <= 0)) {
13248  Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
13249  return -1;
13250  }
13251 
13252  TString fn = fPerfTree;
13253  if (pf && strlen(pf)) fn = pf;
13254  if (fn.IsNull()) fn = "perftree.root";
13255 
13256  TFile f(fn, "RECREATE");
13257  if (f.IsZombie()) {
13258  Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
13259  } else {
13260  f.cd();
13261  TIter nxo(outls);
13262  TObject* obj = 0;
13263  while ((obj = nxo())) {
13264  TString objname(obj->GetName());
13265  if (objname.BeginsWith("PROOF_")) {
13266  // Must list the objects since other PROOF_ objects exist
13267  // besides timing objects
13268  if (objname == "PROOF_PerfStats" ||
13269  objname == "PROOF_PacketsHist" ||
13270  objname == "PROOF_EventsHist" ||
13271  objname == "PROOF_NodeHist" ||
13272  objname == "PROOF_LatencyHist" ||
13273  objname == "PROOF_ProcTimeHist" ||
13274  objname == "PROOF_CpuTimeHist")
13275  obj->Write();
13276  }
13277  }
13278  f.Close();
13279  }
13280  Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
13281 
13282  // Done
13283  return 0;
13284 }
const char * GetHost() const
Definition: TUrl.h:76
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
TList * GetListOfBadSlaves() const
Definition: TProof.h:695
virtual TQueryResult * GetQueryResult(const char *ref)=0
const char * GetSessionDir() const
Definition: TProofServ.h:260
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:259
void AddInputData(TObject *obj, Bool_t push=kFALSE)
Add data objects that might be needed during the processing of the selector (see Process()).
Definition: TProof.cxx:10100
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition: TProof.cxx:2012
virtual void DeleteDrawFeedback(TDrawFeedback *f)=0
Bool_t IsRetrieve() const
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
const char * GetDefaultTreeName() const
Returns the tree set with SetDefaultTreeName if set Returns the name of the first tree in the meta da...
TList * GetOutputList()
Definition: TQueryResult.h:139
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition: TProof.cxx:3106
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:912
virtual Int_t GetEntries() const
Definition: TCollection.h:92
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition: TProof.cxx:7394
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:823
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Int_t AddProcessed(TSlave *, TProofProgressStatus *, Double_t, TList **)
void AddFeedback(const char *name)
Add object to feedback list.
Definition: TProof.cxx:10567
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition: TProof.cxx:7733
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1213
double par[1]
Definition: unuranDistr.cxx:38
void RecvLogFile(TSocket *s, Int_t size)
Receive the log file of the slave with socket s.
Definition: TProof.cxx:6285
void Interrupt(EUrgent type, ESlaves list=kActive)
Send interrupt to master or slave servers.
Definition: TProof.cxx:2283
void SetSessionTag(const char *st)
Definition: TSlave.h:165
double read(const std::string &file_name)
reading
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:851
virtual Int_t SendGroupPriority(const char *, Int_t)
Definition: TSlave.h:114
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition: TProof.cxx:9779
const Long64_t kPROOF_DynWrkPollInt_s
Definition: TProof.h:164
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:929
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition: TProof.cxx:11161
const char * GetOutputFileName() const
virtual TList * GetInputList() const =0
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form: ~~~ {.cpp} [path/]macro.C[+|++[k|f|g|O|c|s|d|v|-]][(args)]...
Definition: TSystem.cxx:3994
virtual void AddOutput(TList *out)=0
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:711
An array of TObjects.
Definition: TObjArray.h:39
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TFile.cxx:1279
TString fPerfTree
Definition: TProof.h:591
const char * GetOrdinal() const
Definition: TSlave.h:135
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8611
float xmin
Definition: THbookFile.cxx:93
TString fPackageDir
Definition: TProof.h:563
const char *const kGUNZIP
Definition: TProof.h:173
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition: TProof.cxx:4411
Bool_t IsWaiting() const
Definition: TProof.h:977
tuple buffer
Definition: tree.py:99
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2084
const char * GetHostName() const
Definition: TInetAddress.h:75
void SetPort(Int_t port)
Definition: TUrl.h:97
virtual TFileCollection * GetStagingStatusDataSet(const char *dataset)
Obtains a TFileCollection showing the staging status of the specified dataset.
Definition: TProof.cxx:11651
static Bool_t GetFileInCmd(const char *cmd, TString &fn)
Static method to extract the filename (if any) form a CINT command.
Definition: TProof.cxx:6493
Int_t GetSeqNum() const
Definition: TQueryResult.h:123
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:108
Bool_t fIsWaiting
Definition: TProof.h:539
Bool_t R_ISLNK(Int_t mode)
Definition: TSystem.h:130
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7856
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
TMonitor * fAllUniqueMonitor
Definition: TProof.h:517
void MarkBad(TSlave *wrk, const char *reason=0)
Add a bad slave server to the bad slave list and remove it from the active list and from the two moni...
Definition: TProof.cxx:4522
virtual void AddInput(TObject *inp)=0
long long Long64_t
Definition: RtypesCore.h:69
Int_t fBusSpeed
Definition: TSystem.h:167
void Activate(TList *slaves=0)
Activate slave server list.
Definition: TProof.cxx:2396
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition: TProof.cxx:10809
const char * GetDataDir() const
Definition: TProof.h:255
TSocket * GetSocket() const
Definition: TSlave.h:138
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition: TProof.cxx:11446
Int_t fPhysRam
Definition: TSystem.h:169
Bool_t IsWorker() const
static double p3(double t, double a, double b, double c, double d)
virtual ~TProof()
Clean up PROOF environment.
Definition: TProof.cxx:650
Bool_t IsValid() const
Definition: TProof.h:973
void PrepareInputDataFile(TString &dataFile)
Prepare the file with the input data objects to be sent the master; the objects are taken from the de...
Definition: TProof.cxx:10217
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:55
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition: TProof.cxx:8643
virtual void MarkBad(TSlave *, TProofProgressStatus *, TList **)
void ClearData(UInt_t what=kUnregistered, const char *dsname=0)
Remove files for the data directory.
Definition: TProof.cxx:7410
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition: TProof.cxx:13203
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:865
virtual const char * GetName() const
Return name of this collection.
tuple random
Definition: hsimple.py:62
virtual Bool_t RegisterDataSet(const char *name, TFileCollection *dataset, const char *optStr="")
Register the 'dataSet' on the cluster under the current user, group and the given 'dataSetName'...
Definition: TProof.cxx:11285
virtual Long64_t DrawSelect(TDSet *dset, const char *varexp, const char *selection="", Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)
Execute the specified drawing action on a data set (TDSet).
Definition: TProof.cxx:6144
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:473
Bool_t IsFinalized() const
Definition: TQueryResult.h:153
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition: TUrl.cxx:518
void SetRealTimeLog(Bool_t on=kTRUE)
Switch ON/OFF the real-time logging facility.
Definition: TProof.cxx:7094
TString fConfDir
Definition: TProof.h:603
EUrgent
Definition: TProof.h:419
virtual EQueryAction GetWorkers(TList *workers, Int_t &prioritychange, Bool_t resume=kFALSE)
Get list of workers to be used from now on.
ERunStatus
Definition: TProof.h:396
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
double write(int n, const std::string &file_name, const std::string &vector_type, int compress=0)
writing
Long64_t GetTotBytes() const
Definition: TFileInfo.h:155
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
const char *const kLS
Definition: TProof.h:169
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
Int_t fOtherQueries
Definition: TProof.h:554
virtual void FlushSocket()
Definition: TSlave.h:109
const double pi
const char Int_t const char TProof Int_t const char const char * msd
Definition: TXSlave.cxx:46
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
TMonitor * mon
Definition: hserv2.C:32
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual Double_t Rndm(Int_t i=0)
Machine independent random number generator.
Definition: TRandom.cxx:512
Int_t fWorkersToMerge
Definition: TProof.h:585
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10789
Int_t GetRemoteProtocol() const
Definition: TProof.h:949
return c
Float_t fCpuTime
Definition: TProof.h:521
const char Option_t
Definition: RtypesCore.h:62
Bool_t fSync
Definition: TProof.h:537
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4804
void SetPrepTime(Float_t preptime)
Definition: TQueryResult.h:105
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3638
const char * GetUser() const
Definition: TSlave.h:132
virtual Bool_t IsValid() const
Definition: TSocket.h:162
float ymin
Definition: THbookFile.cxx:93
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'. ...
Definition: TProof.cxx:2415
const char * GetObjName() const
Definition: TDSet.h:229
virtual Int_t Reconnect()
Definition: TSocket.h:168
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition: TProof.cxx:11913
void SetPasswd(const char *pw)
Definition: TUrl.h:92
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:213
TList * fWrksOutputReady
Definition: TProof.h:593
virtual void SetMaxDrawQueries(Int_t max)=0
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition: TProof.cxx:1667
void EmitVA(const char *signal_name, Int_t, const T &...params)
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:520
TString fOS
Definition: TSystem.h:162
virtual void ShowDataSetCache(const char *dataset=0)
Display the content of the dataset cache, if any (matching 'dataset', if defined).
Definition: TProof.cxx:11492
void ShowParameters(const char *wildcard="PROOF_*") const
Show the input list parameters specified by the wildcard.
Definition: TProof.cxx:10536
This class represents a WWW compatible URL.
Definition: TUrl.h:41
Long64_t fBytesRead
Definition: TSlave.h:96
Bool_t fMergersSet
Definition: TProof.h:582
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
Int_t fMergedWorkers
Definition: TProof.h:282
#define assert(cond)
Definition: unittest.h:542
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition: TProof.cxx:1541
TList * GetWorkers()
Definition: TProof.h:298
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1311
const char Int_t perf
Definition: TXSlave.cxx:46
virtual Long64_t DrawSelect(TDSet *set, const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10777
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
This class implements a data set to be used for PROOF processing.
Definition: TDSet.h:153
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
TList * GetOutputNames()
FIXME: to be written.
Definition: TProof.cxx:10696
std::istream & ReadLine(std::istream &str, Bool_t skipWhite=kTRUE)
Read a line from stream upto newline skipping any whitespace.
Definition: Stringio.cxx:65
TProofMgr * GetManager()
Definition: TProof.h:1073
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual TList * GetListOfKeys() const
void TerminateWorker(TSlave *wrk)
Ask an active worker 'wrk' to terminate, i.e. to shutdown.
Definition: TProof.cxx:4697
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TSlave * GetMerger()
Definition: TProof.h:300
Int_t GetPort() const
Definition: TInetAddress.h:77
const char * GetProtocol() const
Definition: TUrl.h:73
TH1 * h
Definition: legend2.C:5
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:684
virtual void FindUniqueSlaves()
Add to the fUniqueSlave list the active slaves that have a unique (user) file system image...
Definition: TProof.cxx:1919
void Interrupt()
Definition: TMonitor.h:75
Int_t FindNextFreeMerger()
Return a merger, which is both active and still accepts some workers to be assigned to it...
Definition: TProof.cxx:4305
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:10400
virtual void StoreFeedback(TObject *slave, TList *out)=0
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
Definition: TFileInfo.cxx:258
The PROOF manager interacts with the PROOF server coordinator to create or destroy a PROOF session...
Definition: TProofMgr.h:53
void SetROOTVersion(const char *rv)
Definition: TSlave.h:163
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:2017
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
const char *const kPROOF_WorkDir
Definition: TProof.h:150
static const TList * GetEnvVars()
Get environemnt variables.
Definition: TProof.cxx:12329
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
virtual EExitStatus GetExitStatus() const =0
virtual void Add()
Add signal handler to system signal handler list.
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition: TFile.cxx:1596
virtual TFileCollection * GetDataSet(const char *dataset, const char *optStr="")
Get a list of TFileInfo objects describing the files of the specified dataset.
Definition: TProof.cxx:11515
TList * fAllUniqueSlaves
Definition: TProof.h:513
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:10386
void SetArchCompiler(const char *ac)
Definition: TSlave.h:162
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:536
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7901
TString fImage
Definition: TProof.h:604
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1088
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
Regular expression class.
Definition: TRegexp.h:35
TFileCollection * GetMissingFiles(TQueryResult *qr=0)
Get a TFileCollection with the files missing in the query described by 'qr' or the last query if qr i...
Definition: TProof.cxx:13160
Int_t BuildPackage(const char *package, EBuildPackageOpt opt=kBuildAll, Int_t chkveropt=kCheckROOT, TList *workers=0)
Build specified package.
Definition: TProof.cxx:8044
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:856
Bool_t Notify()
Definition: TTimer.cxx:65
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
static const char * filename()
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:53
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition: TProof.cxx:1898
#define R__ASSERT(e)
Definition: TError.h:98
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:184
virtual Bool_t IsProofd() const
Definition: TProofMgr.h:86
TMacro * GetLogFile() const
Definition: TQueryResult.h:134
#define gROOT
Definition: TROOT.h:344
TString fLogFileName
Definition: TProof.h:542
Int_t GetNWrks() const
const char * GetConfFile() const
Definition: TProof.h:941
Int_t fPerfIndex
Definition: TProof.h:246
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition: TMonitor.cxx:168
virtual void StopProcess(Bool_t abort, Int_t timeout)
Sent stop/abort request to PROOF server.
Definition: TSlave.cxx:635
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:33
const char * GetFileName() const
Int_t LoadPlugin()
Load the plugin library for this handler.
#define O_BINARY
Definition: civetweb.c:273
virtual void SetCurrentQuery(TQueryResult *q)=0
const char * GetOrdinal() const
Definition: TProof.h:258
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1395
Bool_t IsZombie() const
Definition: TObject.h:141
TList * fQueries
Definition: TProof.h:553
Basic string class.
Definition: TString.h:137
const char * GetSessionTag() const
Definition: TProof.h:945
virtual void Touch()
Definition: TSlave.h:169
virtual void Add()
Add file event handler to system file handler list.
virtual void Progress(Long64_t total, Long64_t processed)=0
void SetDSet(TDSet *dset)
Definition: TProof.h:775
virtual void SetInterruptHandler(Bool_t)
Definition: TSlave.h:160
TString fGroup
Definition: TProof.h:499
TString fDataDir
Definition: TProof.h:245
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition: TMonitor.cxx:498
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition: TProof.cxx:12386
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:980
bool Bool_t
Definition: RtypesCore.h:59
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition: TProof.cxx:10578
TArc * a
Definition: textangle.C:12
TList * fUniqueSlaves
Definition: TProof.h:512
virtual Bool_t JoinProcess(TList *workers)=0
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition: TProof.cxx:13088
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition: TProof.cxx:6412
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:600
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition: TProof.cxx:6105
Bool_t IsProofd() const
Definition: TProof.h:970
Long64_t GetZipBytes() const
Definition: TFileInfo.h:156
void SetUser(const char *user)
Definition: TUrl.h:91
TList * fWaitingSlaves
Definition: TProof.h:552
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition: TProof.cxx:2482
const char *const kRM
Definition: TProof.h:168
#define gInterpreter
Definition: TInterpreter.h:502
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition: TProof.cxx:2021
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1459
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition: TMonitor.cxx:241
void ShowLog(Int_t qry=-1)
Display on screen the content of the temporary log file.
Definition: TProof.cxx:10949
const char *const kPROOF_PackageLockFile
Definition: TProof.h:158
This class represents a RFC 3986 compatible URI.
Definition: TUri.h:39
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:33
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition: TProof.cxx:2122
Definition: TFTP.h:42
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:666
static TPluginHandler * fgLogViewer
Definition: TProof.h:595
TString & Prepend(const char *cs)
Definition: TString.h:604
R__EXTERN TApplication * gApplication
Definition: TApplication.h:171
Float_t fRealTime
Definition: TProof.h:520
TString fHostName
Definition: TProof.h:243
Bool_t Notify()
Handle input.
Definition: TProof.cxx:165
Int_t ModifyWorkerLists(const char *ord, Bool_t add, Bool_t save)
Modify the worker active/inactive list by making the worker identified by the ordinal number 'ord' ac...
Definition: TProof.cxx:11967
Bool_t IsEqual(const TObject *obj) const
Used to compare slaveinfos by ordinal.
Definition: TProof.cxx:207
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
tuple lines
Definition: mrt.py:16
const char * GetGroup() const
Definition: TProofServ.h:255
const char * GetOptions() const
Definition: TUrl.h:80
TString fModel
Definition: TSystem.h:163
Long_t ExecPlugin(int nargs, const T &...params)
Int_t fWorkersToMerge
Definition: TProof.h:280
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition: TProof.cxx:10899
void CloseProgressDialog()
Close progress dialog.
Definition: TProof.cxx:9861
Bool_t IsSync() const
Definition: TProof.h:707
Int_t GetNumberOfQueries()
Number of queries processed by this session.
Definition: TProof.cxx:2112
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
Int_t AddIncludePath(const char *incpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add 'incpath' to the inc path search.
Definition: TProof.cxx:9466
static void ResolveKeywords(TString &fname, const char *path=0)
Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and <build> placeholders in fname...
static void retrieve(const gsl_integration_workspace *workspace, double *a, double *b, double *r, double *e)
Long64_t GetBytesRead() const
Definition: TProof.h:965
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:592
TDSet * fDSet
Definition: TProof.h:534
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7712
void DisableGoAsyn()
Signal to disable related switches.
Definition: TProof.cxx:6257
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
TList * fInputData
Definition: TProof.h:569
Int_t SendObject(const TObject *obj, ESlaves list=kActive)
Send object to master or slave servers.
Definition: TProof.cxx:7052
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6756
TSignalHandler * GetSignalHandler() const
Definition: TApplication.h:112
Int_t BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
Broadcast a raw buffer of specified length to all slaves in the specified list.
Definition: TProof.cxx:2574
const char *const kPROOF_PackDownloadDir
Definition: TProof.h:153
void help()
Definition: csgdemo.C:337
void Reset(Int_t n=-1)
Definition: TProof.h:338
TVirtualProofPlayer * fPlayer
Definition: TProof.h:525
void SetProof(TProof *p)
Definition: TProofMgr.h:189
void Reset()
Definition: TCollection.h:161
TFile * f
Iterator of linked list.
Definition: TList.h:187
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:884
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
TList * fWorkers
Definition: TProof.h:285
virtual Bool_t IsValid() const
Definition: TProofMgr.h:87
const char * GetGroup() const
Definition: TProof.h:943
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
EQueryMode
Definition: TProof.h:375
virtual void DiscardSession(TProof *p)
Discard TProofDesc of session 'p' from the internal list.
Definition: TProofMgr.cxx:366
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:625
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2446
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:264
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition: TProof.cxx:12302
EUploadPackageOpt
Definition: TProof.h:392
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3851
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:749
Int_t fMode
Definition: TSystem.h:138
const char * GetObjName() const
Definition: TDSet.h:122
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition: TFile.cxx:4749
Bool_t fMasterServ
Definition: TProof.h:600
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:9545
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition: TProof.cxx:13225
Bool_t fFinalizationRunning
Definition: TProof.h:588
TSocket * s1
Definition: hserv2.C:36
void NotifyLogMsg(const char *msg, const char *sfx="\n")
Notify locally 'msg' to the appropriate units (file, stdout, window) If defined, 'sfx' is added after...
Definition: TProof.cxx:6356
TFileHandler * GetInputHandler() const
Definition: TSlave.h:148
Long64_t GetNum() const
Definition: TDSet.h:116
TChain chain("h42")
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
const char * Data() const
Definition: TString.h:349
TSignalHandler * fIntHandler
Definition: TProof.h:522
Int_t GetPort() const
Definition: TProof.h:948
Manages an element of a TDSet.
Definition: TDSet.h:68
Int_t fDrawQueries
Definition: TProof.h:555
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
const TString & GetMsd() const
TString fDataPoolUrl
Definition: TProof.h:619
void AddMergedObjects(Int_t objects)
Definition: TProof.h:308
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
const char * GetDirectory() const
Definition: TDSet.h:230
TList * fChains
Definition: TProof.h:527
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
Int_t Update(Long64_t avgsize=-1)
Update accumulated information about the elements of the collection (e.g.
#define SafeDelete(p)
Definition: RConfig.h:436
TPluginHandler * fProgressDialog
Definition: TProof.h:523
TList * fBadSlaves
Definition: TProof.h:608
virtual TList * GetOutputList() const =0
Int_t fLastAssignedMerger
Definition: TProof.h:586
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1294
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:203
Sequenceable collection abstract base class.
Double_t dot(const TVector2 &v1, const TVector2 &v2)
Definition: CsgOps.cxx:333
Bool_t fSendGroupView
list returned by kPROOF_GETSLAVEINFO
Definition: TProof.h:505
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:75
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1373
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition: TProof.cxx:11624
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:289
const char * Export(Bool_t &changed)
Definition: TProof.h:330
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition: TProof.cxx:6222
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2321
virtual FILE * TempFileName(TString &base, const char *dir=0)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition: TSystem.cxx:1410
void UpdateDialog()
Final update of the progress dialog.
Definition: TProof.cxx:4354
#define PDB(mask, level)
Definition: TProofDebug.h:58
Int_t GetNUrls() const
Definition: TFileInfo.h:86
TList * fEnabledPackagesOnClient
Definition: TProof.h:566
THashList * fGlobalPackageDirList
Definition: TProof.h:564
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
const char * ord
Definition: TXSlave.cxx:46
TSlave * CreateSlave(const char *url, const char *ord, Int_t perf, const char *image, const char *workdir)
Create a new TSlave of type TSlave::kSlave.
Definition: TProof.cxx:1860
static const std::string separator("@@@")
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:46
const char * GetMsd() const
Definition: TDSet.h:119
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition: TMonitor.cxx:284
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7077
virtual TDSetElement * GetNextPacket(TSlave *slave, TMessage *r)=0
void Class()
Definition: Class.C:29
Int_t DownloadPackage(const char *par, const char *dstdir=0)
Download a PROOF archive (PAR file) from the master package repository.
Definition: TProof.cxx:8802
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition: TProof.cxx:6117
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition: TProof.cxx:4424
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
TString fOrdinal
Definition: TProof.h:242
virtual void ReleaseWorker(const char *)
Definition: TProofServ.h:318
virtual void ShowCache(Bool_t all=kFALSE)
List contents of file cache.
Definition: TProof.cxx:7689
Int_t fRedirectNext
Definition: TProof.h:589
virtual Int_t Rm(const char *, const char *=0, const char *=0)
Run 'rm' on 'what'. Locally it is just a call to TSystem::Unlink .
Definition: TProofMgr.cxx:1065
int d
Definition: tornado.py:11
ClassImp(TProof) Bool_t TProofInterruptHandler
TProof interrupt handler.
Definition: TProof.cxx:112
void Init(const TFunction *func)
Initialize the method invocation environment based on the TFunction object.
const char *const kPROOF_WorkerIdleTO
Definition: TProof.h:161
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1705
Int_t BuildPackageOnClient(const char *package, Int_t opt=0, TString *path=0, Int_t chkveropt=kCheckROOT)
Build specified package on the client.
Definition: TProof.cxx:8134
Int_t fParallel
Definition: TSlave.h:101
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriory.
Definition: TMessage.cxx:207
void SetInputDataFile(const char *datafile)
Set the file to be used to optimally distribute the input data objects.
Definition: TProof.cxx:10163
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition: TProof.cxx:11555
static double p2(double t, double a, double b, double c)
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:754
const char * GetMaster() const
Definition: TProof.h:939
Int_t LoadPackageOnClient(const char *package, TList *loadopts=0)
Load specified package in the client.
Definition: TProof.cxx:8381
static TList * GetDataSetSrvMaps()
Static getter for server mapping list.
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1575
bool BeginsWith(const std::string &theString, const std::string &theSubstring)
virtual UInt_t Integer(UInt_t imax)
Returns a random integer on [ 0, imax-1 ].
Definition: TRandom.cxx:320
TProofLockPath * fPackageLock
Definition: TProof.h:565
Int_t Collect(const TSlave *sl, Long_t timeout=-1, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect responses from slave sl.
Definition: TProof.cxx:2676
static void LogViewer(const char *url=0, Int_t sessionidx=0)
Start the log viewer window usign the plugin manager.
Definition: TProof.cxx:13049
TList * GetListOfElements() const
Definition: TDSet.h:231
void Deactivate()
Definition: TProof.h:313
void ResetMergePrg()
Reset the merge progress notificator.
Definition: TProof.cxx:2472
A sorted doubly linked list.
Definition: TSortedList.h:30
void Info(const char *location, const char *msgfmt,...)
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition: TProof.cxx:11387
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition: TProof.cxx:7168
Int_t Init(const char *masterurl, const char *conffile, const char *confdir, Int_t loglevel, const char *alias=0)
Start the PROOF environment.
Definition: TProof.cxx:747
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition: TProof.cxx:11424
TString fConfFile
Definition: TProof.h:602
virtual void AddEventsProcessed(Long64_t ev)=0
TString & Append(const char *cs)
Definition: TString.h:492
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1038
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition: TProof.cxx:2971
ESlaveStatus fStatus
Definition: TProof.h:248
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
void ShowFeedback() const
Show items in feedback list.
Definition: TProof.cxx:10598
tuple np
Definition: multifit.py:30
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1511
TString fOrdinal
Definition: TSlave.h:90
TSlave * CreateSubmaster(const char *url, const char *ord, const char *image, const char *msd, Int_t nwk=1)
Create a new TSlave of type TSlave::kMaster.
Definition: TProof.cxx:1882
void Validate()
Validate the TDSet by opening files.
Definition: TDSet.cxx:1568
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition: TProof.cxx:7668
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to 'id'.
Definition: TProofMgr.cxx:324
const char * GetUser() const
Definition: TProof.h:942
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1951
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'...
Definition: TProof.cxx:2155
static TProof * Open(const char *url=0, const char *conffile=0, const char *confdir=0, Int_t loglevel=0)
Start a PROOF session on a specific cluster.
Definition: TProof.cxx:12161
Bool_t IsParallel() const
Definition: TProof.h:975
TList * fSlaves
Definition: TProof.h:606
Int_t fNotIdle
Definition: TProof.h:536
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
Int_t UploadDataSet(const char *, TList *, const char *=0, Int_t=0, TList *=0)
*** This function is deprecated and will disappear in future versions *** *** It is just a wrapper ar...
Definition: TProof.cxx:11213
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:30
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition: TSlave.cxx:516
XFontStruct * id
Definition: TGX11.cxx:108
Method or function calling interface.
Definition: TMethodCall.h:41
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
const char * GetWorkDir() const
Definition: TSlave.h:131
void SetDirectory(const char *dir)
Set/change directory.
Definition: TDSet.cxx:1019
const Bool_t kSortDescending
Definition: TList.h:41
friend class TProofInputHandler
Definition: TProof.h:350
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2193
TList * fInactiveSlaves
Definition: TProof.h:511
void SetSrvMaps(TList *srvmaps=0)
Set (or unset) the list for mapping servers coordinate for files.
Definition: TDSet.cxx:1150
A container class for query results.
Definition: TQueryResult.h:44
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition: TProof.cxx:2146
Int_t ActivateWorker(const char *ord, Bool_t save=kTRUE)
Make sure that the worker identified by the ordinal number 'ord' is in the active list...
Definition: TProof.cxx:11931
PrintProgress_t fPrintProgress
Definition: TProof.h:574
Int_t fCollectTimeout
Definition: TProof.h:617
Long64_t GetEntries() const
Definition: TQueryResult.h:130
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2328
Long_t fModtime
Definition: TProof.h:530
virtual void Close(Option_t *opt="")
Close slave socket.
Definition: TSlave.cxx:277
const char * GetWorkDir() const
Definition: TProofServ.h:256
void Error(const char *location, const char *msgfmt,...)
TProofMergePrg fMergePrg
Definition: TProof.h:550
static TList * fgProofEnvList
Definition: TProof.h:579
void HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
Handle lib, inc search paths modification request.
Definition: TProof.cxx:9576
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2095
char * out
Definition: TBase64.cxx:29
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
virtual Int_t SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
void SetManager(TProofMgr *mgr)
Set manager and schedule its destruction after this for clean operations.
Definition: TProof.cxx:1314
Bool_t IsLite() const
Definition: TProof.h:969
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:10496
static Int_t PoDCheckUrl(TString *_cluster)
This a private API function.
Definition: TProof.cxx:343
void Emit(const char *signal)
Acitvate signal without args.
Definition: TQObject.cxx:559
virtual Int_t GetFile(const char *, const char *, const char *=0)
Definition: TProofMgr.h:132
Long64_t GetFirst() const
Definition: TDSet.h:114
std::recursive_mutex fCloseMutex
Definition: TProof.h:576
void SetTermTime(Float_t termtime)
Definition: TQueryResult.h:108
virtual TProof * AttachSession(Int_t, Bool_t=kFALSE)
Dummy version provided for completeness.
Definition: TProofMgr.cxx:123
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
virtual void SetStatus(Int_t st)
Definition: TSlave.h:117
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning...
Definition: TProof.cxx:1060
Bool_t fIsPollingWorkers
Definition: TProof.h:506
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition: TProof.cxx:509
virtual void ClearInput()=0
void AddInput(TObject *obj)
Add obj to the input list.
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:594
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
Int_t UploadPackageOnClient(const char *package, EUploadPackageOpt opt, TMD5 *md5)
Upload a package on the client in ~/.proof/packages.
Definition: TProof.cxx:9082
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition: TProof.cxx:6090
const char * GetProofWorkDir() const
Definition: TSlave.h:130
Int_t GetSlaveType() const
Definition: TSlave.h:143
Bool_t fRedirLog
Definition: TProof.h:541
const char * pwd()
Definition: TSystem.h:411
void AddChain(TChain *chain)
Add chain to data set.
Definition: TProof.cxx:10801
TMonitor * fUniqueMonitor
Definition: TProof.h:516
void SetMergedWorker()
Increase number of already merged workers by 1.
Definition: TProof.cxx:294
const char *const kPROOF_ConfFile
Definition: TProof.h:148
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition: TProof.cxx:12135
Int_t fL2Cache
Definition: TSystem.h:168
const TString & GetOrdinal() const
FileMap_t fFileMap
Definition: TProof.h:533
Int_t UnloadPackageOnClient(const char *package)
Unload a specific package on the client.
Definition: TProof.cxx:8576
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition: TProof.cxx:11074
Bool_t ElementsValid()
Check if all elements are valid.
Definition: TDSet.cxx:1534
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition: TProof.cxx:6011
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8909
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition: TProof.cxx:1994
TMonitor * fAllMonitor
Definition: TProof.h:609
Int_t GetPort() const
Definition: TUrl.h:87
const char Int_t const char TProof Int_t const char * workdir
Definition: TXSlave.cxx:46
virtual void AddQueryResult(TQueryResult *q)=0
const char * GetName() const
Returns name of object.
Definition: TSlave.h:128
Int_t Archive(Int_t query, const char *url)
Send archive request for the qry-th query in fQueries.
Definition: TProof.cxx:6055
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
void InitMembers()
Default initializations.
Definition: TProof.cxx:523
Named parameter, streamable and storable.
Definition: TParameter.h:49
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition: TMacro.cxx:245
friend class TProofInterruptHandler
Definition: TProof.h:351
TSocket * GetSocket() const
Definition: TProofServ.h:270
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition: TProof.cxx:12314
tuple outfile
Definition: mrt.py:21
const TString & GetWorkDir() const
TThread * t[5]
Definition: threadsh1.C:13
TString fUser
Definition: TSystem.h:152
float ymax
Definition: THbookFile.cxx:93
Int_t fLogLevel
Definition: TProof.h:500
TProofMgr * fManager
Definition: TProof.h:621
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition: TProof.cxx:10688
const char * GetName() const
Returns name of object.
virtual void Find(const char *="~/", const char *=0, const char *=0)
Definition: TProofMgr.h:123
const char *const kPROOF_TerminateWorker
Definition: TProof.h:160
TList * fActiveSlaves
Definition: TProof.h:508
void QueryResultReady(const char *ref)
Notify availability of a query result.
Definition: TProof.cxx:9947
Bool_t fSaveLogToMacro
Definition: TProof.h:547
virtual void HandleRecvHisto(TMessage *mess)=0
void SendDataSetStatus(const char *msg, UInt_t n, UInt_t tot, Bool_t st)
Send or notify data set status.
Definition: TProof.cxx:9914
Bool_t fValid
Definition: TProof.h:495
Bool_t fDataReady
Definition: TProof.h:610
const char * GetFileName() const
Definition: TDSet.h:113
void DecreaseNWrks()
Definition: TProof.h:335
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1559
The purpose of this class is to provide a complete node description for masters, submasters and worke...
virtual Long64_t Finalize(Bool_t force=kFALSE, Bool_t sync=kFALSE)=0
virtual TObject * GetOutput(const char *name) const =0
Int_t fCpus
Definition: TSystem.h:165
TString GetString() const
Definition: TObjString.h:50
const char * GetPrefix() const
Definition: TProofServ.h:289
ROOT::R::TRInterface & r
Definition: Object.C:4
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4783
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
Definition: TFileInfo.cxx:422
Int_t DisablePackages()
Remove all packages.
Definition: TProof.cxx:7993
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2207
SysInfo_t fSysInfo
Definition: TProof.h:247
Double_t length(const TVector2 &v)
Definition: CsgOps.cxx:347
Bool_t fIsLink
Definition: TSystem.h:143
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition: TProof.cxx:11598
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
TString fWorkDir
Definition: TProof.h:498
const TString GetUri() const
Returns the whole URI - an implementation of chapter 5.3 component recomposition. ...
Definition: TUri.cxx:139
static Int_t WriteChecksum(const char *file, const TMD5 *md5)
Writes checksum in ASCII format to specified file.
Definition: TMD5.cxx:451
SVector< double, 2 > v
Definition: Dict.h:5
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition: TSlave.cxx:499
ERunStatus fRunStatus
Definition: TProof.h:538
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition: TProof.cxx:5855
TString fWorkDir
Definition: TSlave.h:86
const char * GetName() const
Returns name of object.
Definition: TParameter.h:76
virtual TProof * CreateSession(const char *=0, const char *=0, Int_t=-1)
Create a new remote session (master and associated workers).
Definition: TProofMgr.cxx:386
void ShowDataSetQuota(Option_t *opt=0)
shows the quota and usage of all groups if opt contains "U" shows also distribution of usage on user-...
Definition: TProof.cxx:11887
TList * GetListOfSlaves() const
Definition: TProof.h:692
TMonitor * fCurrentMonitor
Definition: TProof.h:518
THashList * GetList()
Int_t BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
Broadcast an object to all slaves in the specified list.
Definition: TProof.cxx:2550
Int_t Add(TFileInfo *info)
Add TFileInfo to the collection.
const char * GetDataPoolUrl() const
Definition: TProof.h:1079
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
Int_t GetLogLevel() const
Definition: TProof.h:952
TList * GetListOfLines() const
Definition: TMacro.h:53
virtual void SetInitTime()=0
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:675
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7768
const char *const kPROOF_ConfDir
Definition: TProof.h:149
Bool_t Gets(FILE *fp, Bool_t chop=kTRUE)
Read one line from the stream, including the , or until EOF.
Definition: Stringio.cxx:198
void SaveActiveList()
Save current list of active workers.
Definition: TProof.cxx:12120
Bool_t ParseUri(const char *uri, TString *dsGroup=0, TString *dsUser=0, TString *dsName=0, TString *dsTree=0, Bool_t onlyCurrent=kFALSE, Bool_t wildcards=kFALSE)
Parses a (relative) URI that describes a DataSet on the cluster.
Int_t fSeqNum
Definition: TProof.h:557
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1716
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:285
Collection abstract base class.
Definition: TCollection.h:48
void SetActive(Bool_t=kTRUE)
Definition: TProof.h:1024
SysInfo_t GetSysInfo() const
Definition: TProof.h:259
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
TObject * Value() const
Definition: TMap.h:125
virtual void ClearDataSetCache(const char *dataset=0)
Clear the content of the dataset cache, if any (matching 'dataset', if defined).
Definition: TProof.cxx:11474
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition: TProof.cxx:2135
virtual Int_t VerifyDataSet(const char *dataset, const char *optStr="")
Verify if all files in the specified dataset are available.
Definition: TProof.cxx:11708
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
TList * fSlaveInfo
Definition: TProof.h:504
unsigned int UInt_t
Definition: RtypesCore.h:42
TList * GetInputList()
Definition: TQueryResult.h:128
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
Enable/Disable PROOF processing on the current default Proof (gProof).
Definition: TChain.cxx:2734
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TMarker * m
Definition: textangle.C:8
TMacro fMacroLog
Definition: TProof.h:548
bool verbose
Int_t GetPort()
Definition: TProof.h:301
char * Form(const char *fmt,...)
Long64_t GetEntries() const
Definition: TFileInfo.h:151
TObject * GetOutput(const char *name)
Get specified object that has been produced during the processing (see Process()).
Definition: TProof.cxx:10340
Class to steer the merging of files produced on the workers.
bool first
Definition: line3Dfit.C:48
tuple w
Definition: qtexample.py:51
Bool_t IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
See if the data is ready to be analyzed.
Definition: TProof.cxx:2247
void IncreaseIdx()
Definition: TProof.h:337
This class implements a plugin library manager.
virtual void SetMerging(Bool_t on=kTRUE)=0
virtual Int_t Echo(const TObject *obj)
Sends an object to master and workers and expect them to send back a message with the output of its T...
Definition: TProof.cxx:7026
virtual Int_t Stat(const char *, FileStat_t &, const char *=0)
Definition: TProofMgr.h:130
const char *const kUNTAR2
Definition: TProof.h:171
TLine * l
Definition: textangle.C:4
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
static void AddEnvVar(const char *name, const char *value)
Add an variable to the list of environment variables passed to proofserv on the master and slaves...
Definition: TProof.cxx:12338
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1056
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:12374
Bool_t CheckFile(const char *file, TSlave *sl, Long_t modtime, Int_t cpopt=(kCp|kCpBin))
Check if a file needs to be send to the slave.
Definition: TProof.cxx:6797
virtual Int_t Reset(Bool_t hard=kFALSE, const char *usr=0)
Send a cleanup request for the sessions associated with the current user.
Definition: TProofMgr.cxx:306
Bool_t SetFragment(const TString &fragment)
Set fragment component of URI: fragment = *( pchar / "/" / "?" ).
Definition: TUri.cxx:497
virtual Long64_t Process(TDSet *dset, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)
Process a data set (TDSet) using the specified selector (.C) file or Tselector object Entry- or event...
Definition: TProof.cxx:5304
Bool_t fProgressDialogStarted
Definition: TProof.h:524
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:657
const Int_t kPROOF_Protocol
Definition: TProof.h:146
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition: TProof.cxx:6458
float xmax
Definition: THbookFile.cxx:93
TStopwatch fQuerySTW
Definition: TProof.h:627
Bool_t fMergersByHost
Definition: TProof.h:583
TString fInputDataFile
Definition: TProof.h:570
Int_t Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6531
void SetStatus(ESlaveStatus stat)
Definition: TProof.h:260
Bool_t IsNull() const
Definition: TString.h:387
virtual TObjLink * FirstLink() const
Definition: TList.h:101
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1604
FILE * fLogFileR
Definition: TProof.h:544
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3654
void SetName(const char *name)
Definition: TCollection.h:116
Int_t fProtocol
Definition: TProof.h:605
const char * GetUrl()
Definition: TProof.h:947
Int_t SendFile(const char *file, Int_t opt=(kBinary|kForward|kCp|kCpBin), const char *rfile=0, TSlave *sl=0)
Send a file to master or slave servers.
Definition: TProof.cxx:6892
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
Long64_t GetEntries() const
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition: TProof.cxx:4259
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition: TMonitor.cxx:250
void PrintProgress(Long64_t total, Long64_t processed, Float_t procTime=-1., Long64_t bytesread=-1)
Print a progress bar on stderr. Used in batch mode.
Definition: TProof.cxx:9718
Bool_t fLogToWindowOnly
Definition: TProof.h:545
TString & String()
Definition: TObjString.h:52
void ReleaseMonitor(TMonitor *mon)
Release the used monitor to be used, making sure to delete newly created monitors.
Definition: TProof.cxx:2661
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1567
TList * fFeedback
Definition: TProof.h:526
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition: TProof.cxx:9902
const char * GetUser() const
Definition: TProofServ.h:254
Int_t DisablePackageOnClient(const char *package)
Remove a specific package 'pack' from the client.
Definition: TProof.cxx:7958
const char * GetImage() const
Definition: TProofServ.h:257
void AddInput(TObject *obj)
Add objects that might be needed during the processing of the selector (see Process()).
Definition: TProof.cxx:10312
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:675
TString fMsd
Definition: TProof.h:244
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2227
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9958
Float_t fPrepTime
Definition: TProof.h:628
#define Printf
Definition: TGeoToOCC.h:18
TH1F * total
Definition: threadsh2.C:15
TList * fRunningDSets
Definition: TProof.h:615
TList * GetFeedbackList() const
Return feedback list.
Definition: TProof.cxx:10611
const char * GetImage() const
Definition: TSlave.h:129
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition: TProof.cxx:10835
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition: TProof.cxx:11759
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:9511
Bool_t fDynamicStartup
Definition: TProof.h:623
static TSlave * Create(const char *url, const char *ord, Int_t perf, const char *image, TProof *proof, Int_t stype, const char *workdir, const char *msd, Int_t nwk=1)
Static method returning the appropriate TSlave object for the remote server.
Definition: TSlave.cxx:447
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void GoAsynchronous()
Send GOASYNC message to the master.
Definition: TProof.cxx:6265
virtual void RemoveQueryResult(const char *ref)=0
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition: TSlave.cxx:661
void ClearInputData(TObject *obj=0)
Remove obj form the input data list; if obj is null (default), clear the input data info...
Definition: TProof.cxx:10116
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6629
Int_t AssertPath(const char *path, Bool_t writable)
Make sure that 'path' exists; if 'writable' is kTRUE, make also sure that the path is writable...
Definition: TProof.cxx:1282
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:581
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1625
void Print(Option_t *option="") const
Print slave info.
Definition: TProof.cxx:221
Int_t LoadPackage(const char *package, Bool_t notOnClient=kFALSE, TList *loadopts=0, TList *workers=0)
Load specified package.
Definition: TProof.cxx:8329
void SetHost(const char *host)
Definition: TUrl.h:93
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
Float_t GetRealTime() const
Definition: TProof.h:966
int Ssiz_t
Definition: RtypesCore.h:63
Int_t GetPerfIdx() const
Definition: TSlave.h:136
The packetizer is a load balancing object created for each query.
TList * GetInputList()
Get input list.
Definition: TProof.cxx:10331
TString fName
Definition: TSlave.h:83
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition: TSystem.cxx:1419
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition: TProof.cxx:4938
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition: TProof.cxx:327
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:932
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:106
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:546
Bool_t fEndMaster
Definition: TProof.h:561
tuple tree
Definition: tree.py:24
void Close(Option_t *option="")
Close all open slave servers.
Definition: TProof.cxx:1805
TList * GetListOfActiveSlaves() const
Definition: TProof.h:761
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3728
virtual Int_t GetSize() const
Definition: TCollection.h:95
void SetFeedback(TString &opt, TString &optfb, Int_t action)
Extract from opt in optfb information about wanted feedback settings.
Definition: TProof.cxx:5233
virtual Bool_t IsLite() const
Definition: TProofMgr.h:85
void SetDefaultTreeName(const char *treeName)
Int_t GetStatus() const
Definition: TSlave.h:144
const char *const kPROOF_InputDataFile
Definition: TProof.h:162
TDrawFeedback * CreateDrawFeedback()
Draw feedback creation proxy.
Definition: TProof.cxx:10672
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
virtual Long64_t GetEventsProcessed() const =0
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:264
tuple file
Definition: fildir.py:20
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:10511
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:126
Int_t SetParallelSilent(Int_t nodes, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7110
Long64_t fBytesRead
Definition: TProof.h:519
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
Int_t GoParallel(Int_t nodes, Bool_t accept=kFALSE, Bool_t random=kFALSE)
Go in parallel mode with at most "nodes" slaves.
Definition: TProof.cxx:7271
Int_t fMergersCount
Definition: TProof.h:584
void SetObjName(const char *objname)
Set/change object name.
Definition: TDSet.cxx:1004
double Double_t
Definition: RtypesCore.h:55
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:307
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition: TSystem.cxx:1285
ESlaves
Definition: TProof.h:598
Int_t Lock()
Locks the directory.
Int_t GetParallel() const
Definition: TSlave.h:145
virtual void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)=0
TObject * Key() const
Definition: TMap.h:124
static Int_t GetInputData(TList *input, const char *cachedir, TString &emsg)
Get the input data from the file defined in the input list.
Definition: TProof.cxx:12992
void ClearInput()
Clear input object list.
Definition: TProof.cxx:10320
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition: TDSet.cxx:1872
TList * fEnabledPackages
Definition: TProof.h:614
virtual void Remove()
Remove signal handler from system signal handler list.
void Feedback(TList *objs)
Get list of feedback objects.
Definition: TProof.cxx:9846
TList * fNonUniqueMasters
Definition: TProof.h:514
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:44
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void dir(char *path=0)
Definition: rootalias.C:30
TList * fRecvMessages
Definition: TProof.h:503
const char * GetOrdinal() const
Definition: TProofServ.h:266
TString fCpuType
Definition: TSystem.h:164
TNamed()
Definition: TNamed.h:40
virtual void SendInputDataFile()
Send the input data objects to the master; the objects are taken from the dedicated list and / or the...
Definition: TProof.cxx:10190
TList * fEnabledPackagesOnCluster
Definition: TProof.h:567
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition: TProof.h:342
static RooMathCoreReg dummy
void Detach(Option_t *opt="")
Detach this instance to its proofserv.
Definition: TProof.cxx:11096
Bool_t Contains(const char *name) const
Definition: TCollection.h:84
int nentries
Definition: THbookFile.cxx:89
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1821
void SetNWrks(Int_t n)
Definition: TProof.h:339
Bool_t IsMaster() const
Definition: TProof.h:972
EBuildPackageOpt
Definition: TProof.h:479
UInt_t What() const
Definition: TMessage.h:80
virtual TQueryResult * GetCurrentQuery() const =0
void SetRunStatus(ERunStatus rst)
Definition: TProof.h:710
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition: TProof.cxx:10620
TList * GetEnabledPackages() const
Definition: TProofServ.h:280
void ShowMissingFiles(TQueryResult *qr=0)
Show information about missing files during query described by 'qr' or the last query if qr is null (...
Definition: TProof.cxx:13101
Int_t Unlock()
Unlock the directory.
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:349
Int_t GetSandbox(TString &sb, Bool_t assert=kFALSE, const char *rc=0)
Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
Definition: TProof.cxx:1033
void ShowQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2172
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1333
Float_t fRealTime
Definition: TSlave.h:97
void SetArchived(const char *archfile)
Set (or update) query in archived state.
void ResetUrl()
Definition: TFileInfo.h:80
virtual void Remove()
Remove file event handler from system file handler list.
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job...
Definition: TProof.cxx:319
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition: TProof.cxx:5881
EQueryMode fQueryMode
Definition: TProof.h:622
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition: TPRegexp.cxx:704
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:221
#define name(a, b)
Definition: linkTestLib0.cpp:5
TString fImage
Definition: TSlave.h:84
const char * GetName() const
Returns name of object.
Definition: TProof.h:257
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition: TProof.cxx:6642
Int_t UnloadPackage(const char *package)
Unload specified package.
Definition: TProof.cxx:8541
FILE * fLogFileW
Definition: TProof.h:543
Mother of all ROOT objects.
Definition: TObject.h:58
Float_t GetCpuTime() const
Definition: TProof.h:967
Int_t fStatus
Definition: TSlave.h:100
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
const char * GetPackageDir() const
Definition: TProofServ.h:261
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
const char Int_t const char TProof * proof
Definition: TXSlave.cxx:46
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:557
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1793
char Char_t
Definition: RtypesCore.h:29
TSelector * fSelector
Definition: TProof.h:625
Int_t BufferSize() const
Definition: TBuffer.h:94
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition: TProof.cxx:3047
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition: TProof.cxx:1985
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition: TProof.cxx:9702
TString fActiveSlavesSaved
Definition: TProof.h:509
TProofInputHandler(const TProofInputHandler &)
virtual Bool_t Add(const char *file, const char *objname=0, const char *dir=0, Long64_t first=0, Long64_t num=-1, const char *msd=0)
Add file to list of files to be analyzed.
Definition: TDSet.cxx:1030
Bool_t SendingLogToWindow() const
Definition: TProof.h:1052
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7832
Int_t GetRC(const char *RCenv, Int_t &env, const char *ord="0")
Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'.
Definition: TProof.cxx:6663
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:246
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:126
Bool_t IsIdle() const
Definition: TProof.h:976
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition: TROOT.cxx:2480
R__EXTERN TProofServ * gProofServ
Definition: TProofServ.h:360
Int_t UploadDataSetFromFile(const char *, const char *, const char *=0, Int_t=0, TList *=0)
*** This function is deprecated and will disappear in future versions *** *** It is just a wrapper ar...
Definition: TProof.cxx:11262
Bool_t IsTty() const
Definition: TProof.h:974
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
Definition: TProofMgr.cxx:228
const char * GetConfDir() const
Definition: TProof.h:940
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:103
Int_t Length() const
Definition: TBuffer.h:96
Class that contains a list of TFileInfo's and accumulated meta data information about its entries...
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:635
TMap * GetDataSetQuota(const char *optStr="")
returns a map of the quotas of all groups
Definition: TProof.cxx:11854
const char * GetMsd() const
Definition: TSlave.h:146
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:68
Utility class to draw objects in the feedback list during queries.
Definition: TDrawFeedback.h:39
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition: TProof.cxx:4437
TProofOutputList fOutputList
Definition: TProof.h:572
Int_t Compare(const void *item1, const void *item2)
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition: TProof.cxx:4745
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:56
static char fgCr[4]
Definition: TProof.h:326
Int_t fSessionID
Definition: TProof.h:559
A chain is a collection of files containg TTree objects.
Definition: TChain.h:35
void WriteObject(const TObject *obj)
Write object to message buffer.
Definition: TMessage.cxx:418
void SetOptions(const char *opt)
Definition: TUrl.h:96
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2029
const TString & GetNodeName() const
Int_t fCpuSpeed
Definition: TSystem.h:166
const char *const kUNTAR3
Definition: TProof.h:172
void SetParam(Long_t l)
Add a long method parameter.
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition: TProof.cxx:2003
static Int_t SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
Save input data file from 'cachedir' into the sandbox or create a the file with input data objects...
Definition: TProof.cxx:12890
#define NULL
Definition: Rtypes.h:82
Bool_t IsTopMaster() const
Definition: TProofServ.h:308
static TList * ParseDataSetSrvMaps(const TString &srvmaps)
Create a server mapping list from the content of 'srvmaps' Return the list (owned by the caller) or 0...
Int_t fStatus
Definition: TProof.h:501
void ClearFeedback()
Clear feedback list.
Definition: TProof.cxx:10590
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7138
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1258
const char * GetDir(Bool_t raw=kFALSE) const
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition: TProof.cxx:305
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:183
Int_t GetClientProtocol() const
Definition: TProof.h:950
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
Float_t fCpuTime
Definition: TSlave.h:98
Int_t AddDynamicPath(const char *libpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add 'libpath' to the lib path search.
Definition: TProof.cxx:9421
const char * GetType() const
Definition: TDSet.h:228
void Reset()
Definition: TStopwatch.h:54
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition: TProof.cxx:9686
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:3895
Int_t GetPort() const
Definition: TSlave.h:134
virtual Int_t AddOutputObject(TObject *obj)=0
Bool_t IsActive()
Definition: TProof.h:314
TList * fAvailablePackages
Definition: TProof.h:613
A TTree object has a header with a name and a title.
Definition: TTree.h:98
Int_t fCheckFileStatus
Definition: TProof.h:502
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition: TProof.cxx:10680
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:280
#define gDirectory
Definition: TDirectory.h:221
Long64_t fTotalBytes
Definition: TProof.h:612
double result[121]
Class describing a generic file including meta information.
Definition: TFileInfo.h:50
Int_t SendInitialState()
Transfer the initial (i.e.
Definition: TProof.cxx:6772
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition: TProof.cxx:5946
void ResetBit(UInt_t f)
Definition: TObject.h:172
TProofMgr::EServType fServType
Definition: TProof.h:620
void AttachList(TList *alist)
Attach to list 'alist'.
const AParamType & GetVal() const
Definition: TParameter.h:77
TList * GetEnabledPackages() const
Definition: TProof.h:773
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1191
virtual void ActivateAll()
Activate all de-activated sockets.
Definition: TMonitor.cxx:268
Abstract interface for the PROOF player.
TList * fTerminatedSlaveInfos
Definition: TProof.h:607
Int_t BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list=kAllUnique)
Broadcast the group priority to all workers in the specified list.
Definition: TProof.cxx:2458
virtual Bool_t IsValid() const
Definition: TSlave.h:154
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition: TProof.cxx:2042
TProof * fProof
Definition: TProof.h:227
TList * FindDataSets(const char *searchString, const char *optStr="")
Find datasets, returns in a TList all found datasets.
Definition: TProof.cxx:11588
const char * GetImage() const
Definition: TProof.h:946
Bool_t Prompt(const char *p)
Prompt the question 'p' requiring an answer y,Y,n,N Return kTRUE is the answer was y or Y...
Definition: TProof.cxx:7647
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition: TProof.cxx:11694
TList * fLoadedMacros
Definition: TProof.h:578
virtual Int_t RemoveDataSet(const char *dataset, const char *optStr="")
Remove the specified dataset from the PROOF cluster.
Definition: TProof.cxx:11569
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition: TProof.cxx:4335
const Bool_t kIterBackward
Definition: TCollection.h:44
Int_t GetPerfIndex() const
static TProofMgr * Create(const char *url, Int_t loglevel=-1, const char *alias=0, Bool_t xpd=kTRUE)
Static method returning the appropriate TProofMgr object using the plugin manager.
Definition: TProofMgr.cxx:498
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
virtual Int_t Load(const char *macro, Bool_t notOnClient=kFALSE, Bool_t uniqueOnly=kTRUE, TList *wrks=0)
Load the specified macro on master, workers and, if notOnClient is kFALSE, on the client...
Definition: TProof.cxx:9209
Class describing a PROOF worker server.
Definition: TSlave.h:50
Container class for processing statistics.
virtual Int_t SetDataSetTreeName(const char *dataset, const char *treename)
Set/Change the name of the default tree.
Definition: TProof.cxx:11344
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:39
const TString & GetImage() const
static TMD5 * ReadChecksum(const char *file)
Returns checksum stored in ASCII in specified file.
Definition: TMD5.cxx:421
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:901
TInetAddress GetInetAddress() const
Definition: TSocket.h:143
const Bool_t kTRUE
Definition: Rtypes.h:91
Long64_t fBytesReady
Definition: TProof.h:611
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition: TProof.cxx:10818
void ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst, Long64_t ent)
Reset progress dialog.
Definition: TProof.cxx:9877
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7873
void SetString(const char *s)
Definition: TObjString.h:49
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:459
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
Int_t SendPrint(Option_t *option="")
Send print command to master server.
Definition: TProof.cxx:7066
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:379
TString fMaster
Definition: TProof.h:497
Bool_t fTty
Definition: TProof.h:496
float value
Definition: math.cpp:443
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition: TProof.cxx:9890
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
const char * GetName() const
Returns name of object.
Definition: TMap.h:120
Int_t DeactivateWorker(const char *ord, Bool_t save=kTRUE)
Remove the worker identified by the ordinal number 'ord' from the the active list.
Definition: TProof.cxx:11948
TList * fMergers
Definition: TProof.h:587
TUrl fUrl
Definition: TProof.h:601
Int_t Nint(T x)
Definition: TMath.h:480
ESlaveType fSlaveType
Definition: TSlave.h:99
static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
Definition: civetweb.c:1917
tuple all
Definition: na49view.py:13
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2311
const Int_t n
Definition: legend1.C:16
virtual Int_t SetupServ(Int_t stype, const char *conffile)
Init a PROOF slave object.
Definition: TSlave.cxx:179
static void DelEnvVar(const char *name)
Remove an variable from the list of environment variables passed to proofserv on the master and slave...
Definition: TProof.cxx:12360
TMonitor * fActiveMonitor
Definition: TProof.h:515
TString fProofWorkDir
Definition: TSlave.h:85
const char * GetUser() const
Definition: TUrl.h:74
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
virtual TList * GetListOfResults() const =0
TSocket * fSocket
Definition: TProof.h:226
virtual TVirtualPacketizer * GetPacketizer() const
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition: TProof.cxx:10757
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition: TMacro.cxx:137
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:453
virtual void UpdateAutoBin(const char *name, Double_t &xmin, Double_t &xmax, Double_t &ymin, Double_t &ymax, Double_t &zmin, Double_t &zmax)=0
const char * GetFile() const
Definition: TUrl.h:78
const char * cnt
Definition: TXMLSetup.cxx:75
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:372
Int_t GetPort() const
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition: TProof.cxx:3061
virtual TDrawFeedback * CreateDrawFeedback(TProof *p)=0
Long64_t fLastPollWorkers_s
Definition: TProof.h:507
void ResetInterrupt()
Definition: TMonitor.h:76
virtual void SetIncludePath(const char *includePath)
IncludePath should contain the list of compiler flags to indicate where to find user defined header f...
Definition: TSystem.cxx:3930
Bool_t IsEndMaster() const
Definition: TProof.h:702
Int_t BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
Broadcast file to all workers in the specified list.
Definition: TProof.cxx:2617
Int_t fMaxDrawQueries
Definition: TProof.h:556
const char * GetDirectory() const
Return directory where to look for object.
Definition: TDSet.cxx:234
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition: TProof.cxx:12959
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:299
TProof * GetProof() const
Definition: TProofMgr.h:174
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition: TProof.cxx:4015
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898
virtual TList * GetLists() const
Definition: TEntryList.h:75
const char Int_t const char * image
Definition: TXSlave.cxx:46
void IncreaseNWrks()
Definition: TProof.h:336
void SetOrdinal(const char *ord)
Definition: TProof.h:262
const char *const kPROOF_PackDir
Definition: TProof.h:152
void SetInputHandler(TFileHandler *ih)
Adopt and register input handler for this slave.
Definition: TSlave.cxx:394
static Int_t AssertDataSet(TDSet *dset, TList *input, TDataSetManager *mgr, TString &emsg)
Make sure that dataset is in the form to be processed.
Definition: TProof.cxx:12593
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition: TProof.cxx:4455
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:592
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904