Logo ROOT   6.14/05
Reference Guide
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 #include "TPackMgr.h"
102 
103 #include <mutex>
104 
106 
107 // Rotating indicator
108 char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
109 
110 TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
111 TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
112 
114 
115 //----- PROOF Interrupt signal handler -----------------------------------------
116 ////////////////////////////////////////////////////////////////////////////////
117 /// TProof interrupt handler.
118 
120 {
121  if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
122 
123  // Cannot ask the user : abort any remote processing
125 
126  } else {
127  // Real stop or request to switch to asynchronous?
128  const char *a = 0;
129  if (fProof->GetRemoteProtocol() < 22) {
130  a = Getline("\nSwitch to asynchronous mode not supported remotely:"
131  "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
132  } else {
133  a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
134  " any other key to continue: ");
135  }
136  if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
137 
138  Info("Notify","Processing interrupt signal ... %c", a[0]);
139 
140  // Stop or abort any remote processing
141  Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
142  fProof->StopProcess(abort);
143 
144  } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
145  // Stop any remote processing
147  }
148  }
149 
150  return kTRUE;
151 }
152 
153 //----- Input handler for messages from TProofServ -----------------------------
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Constructor
156 
158  : TFileHandler(s->GetDescriptor(),1),
159  fSocket(s), fProof(p)
160 {
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// Handle input
165 
167 {
169  return kTRUE;
170 }
171 
172 
173 //------------------------------------------------------------------------------
174 
176 
177 ////////////////////////////////////////////////////////////////////////////////
178 /// Used to sort slaveinfos by ordinal.
179 
181 {
182  if (!obj) return 1;
183 
184  const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
185 
186  if (!si) return fOrdinal.CompareTo(obj->GetName());
187 
188  const char *myord = GetOrdinal();
189  const char *otherord = si->GetOrdinal();
190  while (myord && otherord) {
191  Int_t myval = atoi(myord);
192  Int_t otherval = atoi(otherord);
193  if (myval < otherval) return 1;
194  if (myval > otherval) return -1;
195  myord = strchr(myord, '.');
196  if (myord) myord++;
197  otherord = strchr(otherord, '.');
198  if (otherord) otherord++;
199  }
200  if (myord) return -1;
201  if (otherord) return 1;
202  return 0;
203 }
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// Used to compare slaveinfos by ordinal.
207 
209 {
210  if (!obj) return kFALSE;
211  const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
212  if (!si) return kFALSE;
213  return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////////
217 /// Print slave info. If opt = "active" print only the active
218 /// slaves, if opt="notactive" print only the not active slaves,
219 /// if opt = "bad" print only the bad slaves, else
220 /// print all slaves.
221 
222 void TSlaveInfo::Print(Option_t *opt) const
223 {
224  TString stat = fStatus == kActive ? "active" :
225  fStatus == kBad ? "bad" :
226  "not active";
227 
228  Bool_t newfmt = kFALSE;
229  TString oo(opt);
230  if (oo.Contains("N")) {
231  newfmt = kTRUE;
232  oo.ReplaceAll("N","");
233  }
234  if (oo == "active" && fStatus != kActive) return;
235  if (oo == "notactive" && fStatus != kNotActive) return;
236  if (oo == "bad" && fStatus != kBad) return;
237 
238  if (newfmt) {
239  TString msd, si, datadir;
240  if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
241  if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
242  if (fSysInfo.fCpus > 0) {
243  si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
244  fSysInfo.fCpus, fSysInfo.fPhysRam);
245  } else {
246  si.Form("| %s", fHostName.Data());
247  }
248  Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
249 
250  } else {
251  TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
252 
253  std::cout << "Slave: " << fOrdinal
254  << " hostname: " << fHostName
255  << " msd: " << msd
256  << " perf index: " << fPerfIndex
257  << " " << stat
258  << std::endl;
259  }
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Setter for fSysInfo
264 
266 {
267  fSysInfo.fOS = si.fOS; // OS
268  fSysInfo.fModel = si.fModel; // computer model
269  fSysInfo.fCpuType = si.fCpuType; // type of cpu
270  fSysInfo.fCpus = si.fCpus; // number of cpus
271  fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
272  fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
273  fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
274  fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
275 }
276 
278 
279 //------------------------------------------------------------------------------
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Destructor
283 
285 {
286  // Just delete the list, the objects are owned by other list
287  if (fWorkers) {
288  fWorkers->SetOwner(kFALSE);
289  SafeDelete(fWorkers);
290  }
291 }
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Increase number of already merged workers by 1
294 
296 {
297  if (AreAllWorkersMerged())
298  Error("SetMergedWorker", "all workers have been already merged before!");
299  else
300  fMergedWorkers++;
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Add new worker to the list of workers to be merged by this merger
305 
307 {
308  if (!fWorkers)
309  fWorkers = new TList();
310  if (fWorkersToMerge == fWorkers->GetSize()) {
311  Error("AddWorker", "all workers have been already assigned to this merger");
312  return;
313  }
314  fWorkers->Add(sl);
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Return if merger has already merged all workers, i.e. if it has finished its merging job
319 
321 {
322  return (fWorkersToMerge == fMergedWorkers);
323 }
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 /// Return if the determined number of workers has been already assigned to this merger
327 
329 {
330  if (!fWorkers)
331  return kFALSE;
332 
333  return (fWorkers->GetSize() == fWorkersToMerge);
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// This a private API function.
338 /// It checks whether the connection string contains a PoD cluster protocol.
339 /// If it does, then the connection string will be changed to reflect
340 /// a real PROOF connection string for a PROOF cluster managed by PoD.
341 /// PoD: http://pod.gsi.de .
342 /// Return -1 if the PoD request failed; return 0 otherwise.
343 
344 static Int_t PoDCheckUrl(TString *_cluster)
345 {
346  if ( !_cluster )
347  return 0;
348 
349  // trim spaces from both sides of the string
350  *_cluster = _cluster->Strip( TString::kBoth );
351  // PoD protocol string
352  const TString pod_prot("pod");
353 
354  // URL test
355  // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
356  TUrl url( _cluster->Data() );
357  if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
358  return 0;
359 
360  // PoD cluster is used
361  // call pod-info in a batch mode (-b).
362  // pod-info will find either a local PoD cluster or
363  // a remote one, manged by pod-remote.
364  *_cluster = gSystem->GetFromPipe("pod-info -c -b");
365  if( 0 == _cluster->Length() ) {
366  Error("PoDCheckUrl", "PoD server is not running");
367  return -1;
368  }
369  return 0;
370 }
371 
372 ////////////////////////////////////////////////////////////////////////////////
373 /// Create a PROOF environment. Starting PROOF involves either connecting
374 /// to a master server, which in turn will start a set of slave servers, or
375 /// directly starting as master server (if master = ""). Masterurl is of
376 /// the form: [proof[s]://]host[:port]. Conffile is the name of the config
377 /// file describing the remote PROOF cluster (this argument alows you to
378 /// describe different cluster configurations).
379 /// The default is proof.conf. Confdir is the directory where the config
380 /// file and other PROOF related files are (like motd and noproof files).
381 /// Loglevel is the log level (default = 1). User specified custom config
382 /// files will be first looked for in $HOME/.conffile.
383 
384 TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
385  Int_t loglevel, const char *alias, TProofMgr *mgr)
386  : fUrl(masterurl)
387 {
388  // Default initializations
389  InitMembers();
390 
391  // This may be needed during init
392  fManager = mgr;
393 
394  // Default server type
396 
397  // Default query mode
398  fQueryMode = kSync;
399 
400  // Parse the main URL, adjusting the missing fields and setting the relevant
401  // bits
404 
405  // Protocol and Host
406  if (!masterurl || strlen(masterurl) <= 0) {
407  fUrl.SetProtocol("proof");
408  fUrl.SetHost("__master__");
409  } else if (!(strstr(masterurl, "://"))) {
410  fUrl.SetProtocol("proof");
411  }
412  // Port
413  if (fUrl.GetPort() == TUrl(" ").GetPort())
414  fUrl.SetPort(TUrl("proof:// ").GetPort());
415 
416  // Make sure to store the FQDN, so to get a solid reference for subsequent checks
417  if (!strcmp(fUrl.GetHost(), "__master__"))
418  fMaster = fUrl.GetHost();
419  else if (!strlen(fUrl.GetHost()))
420  fMaster = gSystem->GetHostByName(gSystem->HostName()).GetHostName();
421  else
422  fMaster = gSystem->GetHostByName(fUrl.GetHost()).GetHostName();
423 
424  // Server type
425  if (strlen(fUrl.GetOptions()) > 0) {
426  TString opts(fUrl.GetOptions());
427  if (!(strncmp(fUrl.GetOptions(),"std",3))) {
429  opts.Remove(0,3);
430  fUrl.SetOptions(opts.Data());
431  } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
433  opts.Remove(0,4);
434  fUrl.SetOptions(opts.Data());
435  }
436  }
437 
438  // Instance type
442  if (fMaster == "__master__") {
443  fMasterServ = kTRUE;
446  } else if (fMaster == "prooflite") {
447  // Client and master are merged
448  fMasterServ = kTRUE;
450  }
451  // Flag that we are a client
453  if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
454 
455  Init(masterurl, conffile, confdir, loglevel, alias);
456 
457  // If the user was not set, get it from the master
458  if (strlen(fUrl.GetUser()) <= 0) {
459  TString usr, emsg;
460  if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
461  TObjString *os = fMacroLog.GetLineWith("const char");
462  if (os) {
463  Ssiz_t fst = os->GetString().First('\"');
464  Ssiz_t lst = os->GetString().Last('\"');
465  usr = os->GetString()(fst+1, lst-fst-1);
466  } else {
467  emsg = "could not find 'const char *' string in macro log";
468  }
469  } else {
470  emsg = "could not retrieve user info";
471  }
472  if (!emsg.IsNull()) {
473  // Get user logon name
475  if (pw) {
476  usr = pw->fUser;
477  delete pw;
478  }
479  Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
480  }
481  // Set the user name in the main URL
482  fUrl.SetUser(usr.Data());
483  }
484 
485  // If called by a manager, make sure it stays in last position
486  // for cleaning
487  if (mgr) {
489  gROOT->GetListOfSockets()->Remove(mgr);
490  gROOT->GetListOfSockets()->Add(mgr);
491  }
492 
493  // Old-style server type: we add this to the list and set the global pointer
495  if (!gROOT->GetListOfProofs()->FindObject(this))
496  gROOT->GetListOfProofs()->Add(this);
497 
498  // Still needed by the packetizers: needs to be changed
499  gProof = this;
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 /// Protected constructor to be used by classes deriving from TProof
504 /// (they have to call Init themselves and override StartSlaves
505 /// appropriately).
506 ///
507 /// This constructor simply closes any previous gProof and sets gProof
508 /// to this instance.
509 
511 {
512  // Default initializations
513  InitMembers();
514 
515  if (!gROOT->GetListOfProofs()->FindObject(this))
516  gROOT->GetListOfProofs()->Add(this);
517 
518  gProof = this;
519 }
520 
521 ////////////////////////////////////////////////////////////////////////////////
522 /// Default initializations
523 
525 {
526  fValid = kFALSE;
527  fTty = kFALSE;
528  fRecvMessages = 0;
529  fSlaveInfo = 0;
533  fLastPollWorkers_s = -1;
534  fActiveSlaves = 0;
535  fInactiveSlaves = 0;
536  fUniqueSlaves = 0;
537  fAllUniqueSlaves = 0;
538  fNonUniqueMasters = 0;
539  fActiveMonitor = 0;
540  fUniqueMonitor = 0;
541  fAllUniqueMonitor = 0;
542  fCurrentMonitor = 0;
543  fBytesRead = 0;
544  fRealTime = 0;
545  fCpuTime = 0;
546  fIntHandler = 0;
547  fProgressDialog = 0;
550  fPlayer = 0;
551  fFeedback = 0;
552  fChains = 0;
553  fDSet = 0;
554  fNotIdle = 0;
555  fSync = kTRUE;
557  fIsWaiting = kFALSE;
558  fRedirLog = kFALSE;
559  fLogFileW = 0;
560  fLogFileR = 0;
563  fMacroLog.SetName("ProofLogMacro");
564 
565  fWaitingSlaves = 0;
566  fQueries = 0;
567  fOtherQueries = 0;
568  fDrawQueries = 0;
569  fMaxDrawQueries = 1;
570  fSeqNum = 0;
571 
572  fSessionID = -1;
573  fEndMaster = kFALSE;
574 
575  fPackMgr = 0;
577 
578  fInputData = 0;
579 
580  fPrintProgress = 0;
581 
582  fLoadedMacros = 0;
583 
584  fProtocol = -1;
585  fSlaves = 0;
587  fBadSlaves = 0;
588  fAllMonitor = 0;
589  fDataReady = kFALSE;
590  fBytesReady = 0;
591  fTotalBytes = 0;
592  fAvailablePackages = 0;
593  fEnabledPackages = 0;
594  fRunningDSets = 0;
595 
596  fCollectTimeout = -1;
597 
598  fManager = 0;
599  fQueryMode = kSync;
601 
604  fMergers = 0;
605  fMergersCount = -1;
607  fWorkersToMerge = 0;
609 
610  fPerfTree = "";
611 
612  fWrksOutputReady = 0;
613 
614  fSelector = 0;
615 
616  fPrepTime = 0.;
617 
618  // Check if the user defined a list of environment variables to send over:
619  // include them into the dedicated list
620  if (gSystem->Getenv("PROOF_ENVVARS")) {
621  TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
622  Int_t from = 0;
623  while (envs.Tokenize(env, from, ",")) {
624  if (!env.IsNull()) {
625  if (!gSystem->Getenv(env)) {
626  Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
627  } else {
628  if (!envsfound.IsNull()) envsfound += ",";
629  envsfound += env;
630  TProof::DelEnvVar(env);
631  TProof::AddEnvVar(env, gSystem->Getenv(env));
632  }
633  }
634  }
635  if (envsfound.IsNull()) {
636  Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
637  } else {
638  Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
639  }
640  }
641 
642  // Done
643  return;
644 }
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 /// Clean up PROOF environment.
648 
650 {
651  if (fChains) {
652  while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
653  // remove "chain" from list
654  chain->SetProof(0);
655  RemoveChain(chain);
656  }
657  }
658 
659  // remove links to packages enabled on the client
660  if (TestBit(TProof::kIsClient)) {
661  // iterate over all packages
662  TList *epl = fPackMgr->GetListOfEnabled();
663  TIter nxp(epl);
664  while (TObjString *pck = (TObjString *)(nxp())) {
665  FileStat_t stat;
666  if (gSystem->GetPathInfo(pck->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(pck->String());
672  }
673  }
674  }
675 
676  Close();
702  if (fWrksOutputReady) {
704  delete fWrksOutputReady;
705  }
706 
707  // remove file with redirected logs
708  if (TestBit(TProof::kIsClient)) {
709  if (fLogFileR)
710  fclose(fLogFileR);
711  if (fLogFileW)
712  fclose(fLogFileW);
713  if (fLogFileName.Length() > 0)
715  }
716 
717  // Remove for the global list
718  gROOT->GetListOfProofs()->Remove(this);
719  // ... and from the manager list
720  if (fManager && fManager->IsValid())
721  fManager->DiscardSession(this);
722 
723  if (gProof && gProof == this) {
724  // Set previous as default
725  TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
726  while ((gProof = (TProof *)pvp())) {
727  if (gProof->InheritsFrom(TProof::Class()))
728  break;
729  }
730  }
731 
732  // For those interested in our destruction ...
733  Emit("~TProof()");
734  Emit("CloseWindow()");
735 }
736 
737 ////////////////////////////////////////////////////////////////////////////////
738 /// Start the PROOF environment. Starting PROOF involves either connecting
739 /// to a master server, which in turn will start a set of slave servers, or
740 /// directly starting as master server (if master = ""). For a description
741 /// of the arguments see the TProof ctor. Returns the number of started
742 /// master or slave servers, returns 0 in case of error, in which case
743 /// fValid remains false.
744 
745 Int_t TProof::Init(const char *, const char *conffile,
746  const char *confdir, Int_t loglevel, const char *alias)
747 {
749 
750  fValid = kFALSE;
751 
752  // Connected to terminal?
753  fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
754 
755  // If in attach mode, options is filled with additional info
756  Bool_t attach = kFALSE;
757  if (strlen(fUrl.GetOptions()) > 0) {
758  attach = kTRUE;
759  // A flag from the GUI
760  TString opts = fUrl.GetOptions();
761  if (opts.Contains("GUI")) {
763  opts.Remove(opts.Index("GUI"));
764  fUrl.SetOptions(opts);
765  }
766  }
767 
768  if (TestBit(TProof::kIsMaster)) {
769  // Fill default conf file and conf dir
770  if (!conffile || !conffile[0])
772  if (!confdir || !confdir[0])
774  // The group; the client receives it in the kPROOF_SESSIONTAG message
776  } else {
777  fConfDir = confdir;
778  fConfFile = conffile;
779  }
780 
781  // Analysise the conffile field
782  if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
784 
786  fLogLevel = loglevel;
789  fImage = fMasterServ ? "" : "<local>";
790  fIntHandler = 0;
791  fStatus = 0;
792  fRecvMessages = new TList;
794  fSlaveInfo = 0;
795  fChains = new TList;
796  fAvailablePackages = 0;
797  fEnabledPackages = 0;
798  fRunningDSets = 0;
800  fInputData = 0;
802  fPrintProgress = 0;
803 
804  // Timeout for some collect actions
805  fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
806 
807  // Should the workers be started dynamically; default: no
808  fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
809 
810  // Default entry point for the data pool is the master
812  fDataPoolUrl.Form("root://%s", fMaster.Data());
813  else
814  fDataPoolUrl = "";
815 
816  fProgressDialog = 0;
818 
819  // Default alias is the master name
820  TString al = (alias) ? alias : fMaster.Data();
821  SetAlias(al);
822 
823  // Client logging of messages from the master and slaves
824  fRedirLog = kFALSE;
825  if (TestBit(TProof::kIsClient)) {
826  fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
827  if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
828  Error("Init", "could not create temporary logfile");
829  if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
830  Error("Init", "could not open temp logfile for reading");
831  }
833 
834  // Status of cluster
835  fNotIdle = 0;
836  // Query type
837  fSync = (attach) ? kFALSE : kTRUE;
838  // Not enqueued
839  fIsWaiting = kFALSE;
840 
841  // Counters
842  fBytesRead = 0;
843  fRealTime = 0;
844  fCpuTime = 0;
845 
846  // List of queries
847  fQueries = 0;
848  fOtherQueries = 0;
849  fDrawQueries = 0;
850  fMaxDrawQueries = 1;
851  fSeqNum = 0;
852 
853  // Remote ID of the session
854  fSessionID = -1;
855 
856  // Part of active query
857  fWaitingSlaves = 0;
858 
859  // Make remote PROOF player
860  fPlayer = 0;
861  MakePlayer();
862 
863  fFeedback = new TList;
864  fFeedback->SetOwner();
865  fFeedback->SetName("FeedbackList");
867 
868  // sort slaves by descending performance index
870  fActiveSlaves = new TList;
871  fInactiveSlaves = new TList;
872  fUniqueSlaves = new TList;
873  fAllUniqueSlaves = new TList;
874  fNonUniqueMasters = new TList;
875  fBadSlaves = new TList;
876  fAllMonitor = new TMonitor;
877  fActiveMonitor = new TMonitor;
878  fUniqueMonitor = new TMonitor;
880  fCurrentMonitor = 0;
881 
884 
885  fLoadedMacros = 0;
886  fPackMgr = 0;
887 
888  // Enable optimized sending of streamer infos to use embedded backward/forward
889  // compatibility support between different ROOT versions and different versions of
890  // users classes
891  Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
892  if (enableSchemaEvolution) {
894  } else {
895  Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
896  }
897 
898  if (IsMaster()) {
899  // to make UploadPackage() method work on the master as well.
901  } else {
902 
903  TString sandbox;
904  if (GetSandbox(sandbox, kTRUE) != 0) {
905  Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
906  return 0;
907  }
908 
909  // Package Dir
910  TString packdir = gEnv->GetValue("Proof.PackageDir", "");
911  if (packdir.IsNull())
912  packdir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
913  if (AssertPath(packdir, kTRUE) != 0) {
914  Error("Init", "failure asserting directory %s", packdir.Data());
915  return 0;
916  }
917  fPackMgr = new TPackMgr(packdir);
918  if (gDebug > 0)
919  Info("Init", "package directory set to %s", packdir.Data());
920  }
921 
922  if (!IsMaster()) {
923  // List of directories where to look for global packages
924  TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
925  TProofServ::ResolveKeywords(globpack);
926  Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
927  if (gDebug > 0)
928  Info("Init", " %d global package directories registered", nglb);
929  }
930 
931  // Master may want dynamic startup
932  if (fDynamicStartup) {
933  if (!IsMaster()) {
934  // If on client - start the master
935  if (!StartSlaves(attach))
936  return 0;
937  }
938  } else {
939 
940  // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
941  // result retrieving, ...)
942  Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
943  if (!IsMaster() || !masterOnly) {
944  // Start slaves (the old, static, per-session way)
945  if (!StartSlaves(attach))
946  return 0;
947  // Client: Is Master in dynamic startup mode?
948  if (!IsMaster()) {
949  Int_t dyn = 0;
950  GetRC("Proof.DynamicStartup", dyn);
951  if (dyn != 0) fDynamicStartup = kTRUE;
952  }
953  }
954  }
955  // we are now properly initialized
956  fValid = kTRUE;
957 
958  // De-activate monitor (will be activated in Collect)
960 
961  // By default go into parallel mode
962  Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
963  TNamed *n = 0;
964  if (TProof::GetEnvVars() &&
965  (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
966  TString s(n->GetTitle());
967  if (s.IsDigit()) nwrk = s.Atoi();
968  }
969  GoParallel(nwrk, attach);
970 
971  // Send relevant initial state to slaves
972  if (!attach)
974  else if (!IsIdle())
975  // redirect log
976  fRedirLog = kTRUE;
977 
978  // Done at this point, the alias will be communicated to the coordinator, if any
980  SetAlias(al);
981 
982  SetActive(kFALSE);
983 
984  if (IsValid()) {
985 
986  // Activate input handler
988 
990  gROOT->GetListOfSockets()->Add(this);
991  }
992 
993  AskParallel();
994 
995  return fActiveSlaves->GetSize();
996 }
997 
998 ////////////////////////////////////////////////////////////////////////////////
999 /// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1000 /// Use the existing setting or the default if nothing is found.
1001 /// If 'assert' is kTRUE, make also sure that the path exists.
1002 /// Return 0 on success, -1 on failure
1003 
1004 Int_t TProof::GetSandbox(TString &sb, Bool_t assert, const char *rc)
1005 {
1006  // Get it from 'rc', if defined
1007  if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1008  // Or use the default 'rc'
1009  if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1010  // If nothing found , use the default
1011  if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1012  // Expand special settings
1013  if (sb == ".") {
1014  sb = gSystem->pwd();
1015  } else if (sb == "..") {
1016  sb = gSystem->DirName(gSystem->pwd());
1017  }
1018  gSystem->ExpandPathName(sb);
1019 
1020  // Assert the path, if required
1021  if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1022  // Done
1023  return 0;
1024 }
1025 
1026 ////////////////////////////////////////////////////////////////////////////////
1027 /// The config file field may contain special instructions which need to be
1028 /// parsed at the beginning, e.g. for debug runs with valgrind.
1029 /// Several options can be given separated by a ','
1030 
1031 void TProof::ParseConfigField(const char *config)
1032 {
1033  TString sconf(config), opt;
1034  Ssiz_t from = 0;
1035  Bool_t cpuPin = kFALSE;
1036 
1037  // Analysise the field
1038  const char *cq = (IsLite()) ? "\"" : "";
1039  while (sconf.Tokenize(opt, from, ",")) {
1040  if (opt.IsNull()) continue;
1041 
1042  if (opt.BeginsWith("valgrind")) {
1043  // Any existing valgrind setting? User can give full settings, which we fully respect,
1044  // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1045  // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1046  // will add option "--time-stamp --leak-check=full" to our default options
1047  TString mst, top, sub, wrk, all;
1048  TList *envs = fgProofEnvList;
1049  TNamed *n = 0;
1050  if (envs) {
1051  if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1052  all = n->GetTitle();
1053  if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1054  mst = n->GetTitle();
1055  if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1056  top = n->GetTitle();
1057  if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1058  sub = n->GetTitle();
1059  if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1060  wrk = n->GetTitle();
1061  }
1062  if (all != "" && mst == "") mst = all;
1063  if (all != "" && top == "") top = all;
1064  if (all != "" && sub == "") sub = all;
1065  if (all != "" && wrk == "") wrk = all;
1066  if (all != "" && all.BeginsWith("valgrind_opts:")) {
1067  // The field is used to add an option Reset the setting
1068  Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1069  " must be set again for next run , if any");
1070  TProof::DelEnvVar("PROOF_WRAPPERCMD");
1071  }
1072  TString var, cmd;
1073  cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1074  TString mstlab("NO"), wrklab("NO");
1075  Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1076  !opt.Contains("topmaster") && !opt.Contains("submaster")))
1077  ? kTRUE : kFALSE;
1078  if (doMaster) {
1079  if (!IsLite()) {
1080  // Check if we have to add a var
1081  if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1082  mst.ReplaceAll("valgrind_opts:","");
1083  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1084  TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1085  mstlab = "YES";
1086  } else if (mst != "") {
1087  mstlab = "YES";
1088  }
1089  } else {
1090  if (opt.Contains("master")) {
1091  Warning("ParseConfigField",
1092  "master valgrinding does not make sense for PROOF-Lite: ignoring");
1093  opt.ReplaceAll("master", "");
1094  if (!opt.Contains("workers")) return;
1095  }
1096  if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1097  }
1098  }
1099  if (opt.Contains("topmaster")) {
1100  // Check if we have to add a var
1101  if (top == "" || top.BeginsWith("valgrind_opts:")) {
1102  top.ReplaceAll("valgrind_opts:","");
1103  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1104  TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1105  mstlab = "YES";
1106  } else if (top != "") {
1107  mstlab = "YES";
1108  }
1109  }
1110  if (opt.Contains("submaster")) {
1111  // Check if we have to add a var
1112  if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1113  sub.ReplaceAll("valgrind_opts:","");
1114  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1115  TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1116  mstlab = "YES";
1117  } else if (sub != "") {
1118  mstlab = "YES";
1119  }
1120  }
1121  if (opt.Contains("=workers") || opt.Contains("+workers")) {
1122  // Check if we have to add a var
1123  if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1124  wrk.ReplaceAll("valgrind_opts:","");
1125  var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1126  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1127  TString nwrks("2");
1128  Int_t inw = opt.Index('#');
1129  if (inw != kNPOS) {
1130  nwrks = opt(inw+1, opt.Length());
1131  if (!nwrks.IsDigit()) nwrks = "2";
1132  }
1133  // Set the relevant variables
1134  if (!IsLite()) {
1135  TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1136  } else {
1137  gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1138  }
1139  wrklab = nwrks;
1140  // Register the additional worker log in the session file
1141  // (for the master this is done automatically)
1142  TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1143  } else if (wrk != "") {
1144  wrklab = "ALL";
1145  }
1146  }
1147  // Increase the relevant timeouts
1148  if (!IsLite()) {
1149  TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1150  gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1151  } else {
1152  gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1153  }
1154  // Warn for slowness
1155  Printf(" ");
1156  if (!IsLite()) {
1157  Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1158  } else {
1159  Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1160  }
1161  Printf(" ---> Please be patient: startup may be VERY slow ...");
1162  Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1163  Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1164  Printf(" ");
1165 
1166  } else if (opt.BeginsWith("igprof-pp")) {
1167 
1168  // IgProf profiling on master and worker. PROOF does not set the
1169  // environment for you: proper environment variables (like PATH and
1170  // LD_LIBRARY_PATH) should be set externally
1171 
1172  Printf("*** Requested IgProf performance profiling ***");
1173  TString addLogExt = "__igprof.pp__.log";
1174  TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1175  TString tmp;
1176 
1177  if (IsLite()) {
1178  addLogFmt.Append("\"");
1179  addLogFmt.Prepend("\"");
1180  }
1181 
1182  tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1183  TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1184 
1185  tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1186  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1187 
1188  TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1189 
1190  } else if (opt.BeginsWith("cpupin=")) {
1191  // Enable CPU pinning. Takes as argument the list of processor IDs
1192  // that will be used in order. Processor IDs are numbered from 0,
1193  // use likwid to see how they are organized. A possible parameter
1194  // format would be:
1195  //
1196  // cpupin=3+4+0+9+10+22+7
1197  //
1198  // Only the specified processor IDs will be used in a round-robin
1199  // fashion, dealing with the fact that you can request more workers
1200  // than the number of processor IDs you have specified.
1201  //
1202  // To use all available processors in their order:
1203  //
1204  // cpupin=*
1205 
1206  opt.Remove(0, 7);
1207 
1208  // Remove any char which is neither a number nor a plus '+'
1209  for (Ssiz_t i=0; i<opt.Length(); i++) {
1210  Char_t c = opt[i];
1211  if ((c != '+') && ((c < '0') || (c > '9')))
1212  opt[i] = '_';
1213  }
1214  opt.ReplaceAll("_", "");
1215  TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1216  cpuPin = kTRUE;
1217  } else if (opt.BeginsWith("workers=")) {
1218 
1219  // Request for a given number of workers (within the max) or worker
1220  // startup combination:
1221  // workers=5 start max 5 workers (or less, if less are assigned)
1222  // workers=2x start max 2 workers per node (or less, if less are assigned)
1223  opt.ReplaceAll("workers=","");
1224  TProof::AddEnvVar("PROOF_NWORKERS", opt);
1225  }
1226  }
1227 
1228  // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1229  #ifdef R__LINUX
1230  if (IsLite() && cpuPin) {
1231  Printf("*** Requested CPU pinning ***");
1232  const TList *ev = GetEnvVars();
1233  const char *pinCmd = "taskset -c <cpupin>";
1234  TString val;
1235  TNamed *p;
1236  if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1237  val = p->GetTitle();
1238  val.Insert(val.Length()-1, " ");
1239  val.Insert(val.Length()-1, pinCmd);
1240  }
1241  else {
1242  val.Form("\"%s\"", pinCmd);
1243  }
1244  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1245  }
1246  #endif
1247 }
1248 
1249 ////////////////////////////////////////////////////////////////////////////////
1250 /// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1251 /// that the path is writable
1252 
1253 Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1254 {
1255  if (!inpath || strlen(inpath) <= 0) {
1256  Error("AssertPath", "undefined input path");
1257  return -1;
1258  }
1259 
1260  TString path(inpath);
1261  gSystem->ExpandPathName(path);
1262 
1263  if (gSystem->AccessPathName(path, kFileExists)) {
1264  if (gSystem->mkdir(path, kTRUE) != 0) {
1265  Error("AssertPath", "could not create path %s", path.Data());
1266  return -1;
1267  }
1268  }
1269  // It must be writable
1270  if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1271  if (gSystem->Chmod(path, 0666) != 0) {
1272  Error("AssertPath", "could not make path %s writable", path.Data());
1273  return -1;
1274  }
1275  }
1276 
1277  // Done
1278  return 0;
1279 }
1280 
1281 ////////////////////////////////////////////////////////////////////////////////
1282 /// Set manager and schedule its destruction after this for clean
1283 /// operations.
1284 
1286 {
1287  fManager = mgr;
1288 
1289  if (mgr) {
1291  gROOT->GetListOfSockets()->Remove(mgr);
1292  gROOT->GetListOfSockets()->Add(mgr);
1293  }
1294 }
1295 
1296 ////////////////////////////////////////////////////////////////////////////////
1297 /// Works on the master node only.
1298 /// It starts workers on the machines in workerList and sets the paths,
1299 /// packages and macros as on the master.
1300 /// It is a subbstitute for StartSlaves(...)
1301 /// The code is mostly the master part of StartSlaves,
1302 /// with the parallel startup removed.
1303 
1305 {
1306  if (!IsMaster()) {
1307  Error("AddWorkers", "AddWorkers can only be called on the master!");
1308  return -1;
1309  }
1310 
1311  if (!workerList || !(workerList->GetSize())) {
1312  Error("AddWorkers", "empty list of workers!");
1313  return -2;
1314  }
1315 
1316  // Code taken from master part of StartSlaves with the parllel part removed
1317 
1318  fImage = gProofServ->GetImage();
1319  if (fImage.IsNull())
1320  fImage.Form("%s:%s", TUrl(gSystem->HostName()).GetHostFQDN(), gProofServ->GetWorkDir());
1321 
1322  // Get all workers
1323  UInt_t nSlaves = workerList->GetSize();
1324  UInt_t nSlavesDone = 0;
1325  Int_t ord = 0;
1326 
1327  // Loop over all new workers and start them (if we had already workers it means we are
1328  // increasing parallelism or that is not the first time we are called)
1329  Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1330 
1331  // A list of TSlave objects for workers that are being added
1332  TList *addedWorkers = new TList();
1333  if (!addedWorkers) {
1334  // This is needed to silence Coverity ...
1335  Error("AddWorkers", "cannot create new list for the workers to be added");
1336  return -2;
1337  }
1338  addedWorkers->SetOwner(kFALSE);
1339  TListIter next(workerList);
1340  TObject *to;
1341  TProofNodeInfo *worker;
1342  TSlaveInfo *dummysi = new TSlaveInfo();
1343  while ((to = next())) {
1344  // Get the next worker from the list
1345  worker = (TProofNodeInfo *)to;
1346 
1347  // Read back worker node info
1348  const Char_t *image = worker->GetImage().Data();
1349  const Char_t *workdir = worker->GetWorkDir().Data();
1350  Int_t perfidx = worker->GetPerfIndex();
1351  Int_t sport = worker->GetPort();
1352  if (sport == -1)
1353  sport = fUrl.GetPort();
1354 
1355  // Create worker server
1356  TString fullord;
1357  if (worker->GetOrdinal().Length() > 0) {
1358  fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1359  } else {
1360  fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1361  }
1362 
1363  // Remove worker from the list of workers terminated gracefully
1364  dummysi->SetOrdinal(fullord);
1365  TSlaveInfo *rmsi = (TSlaveInfo *)fTerminatedSlaveInfos->Remove(dummysi);
1366  SafeDelete(rmsi);
1367 
1368  // Create worker server
1369  TString wn(worker->GetNodeName());
1370  if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1371  TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1372  // Add group info in the password firdl, if any
1373  if (strlen(gProofServ->GetGroup()) > 0) {
1374  // Set also the user, otherwise the password is not exported
1375  if (strlen(u.GetUser()) <= 0)
1376  u.SetUser(gProofServ->GetUser());
1378  }
1379  TSlave *slave = 0;
1380  if (worker->IsWorker()) {
1381  slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1382  } else {
1383  slave = CreateSubmaster(u.GetUrl(), fullord,
1384  image, worker->GetMsd(), worker->GetNWrks());
1385  }
1386 
1387  // Add to global list (we will add to the monitor list after
1388  // finalizing the server startup)
1389  Bool_t slaveOk = kTRUE;
1390  fSlaves->Add(slave);
1391  if (slave->IsValid()) {
1392  addedWorkers->Add(slave);
1393  } else {
1394  slaveOk = kFALSE;
1395  fBadSlaves->Add(slave);
1396  Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1397  }
1398 
1399  PDB(kGlobal,3)
1400  Info("AddWorkers", "worker on host %s created"
1401  " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1402 
1403  // Notify opening of connection
1404  nSlavesDone++;
1406  m << TString("Opening connections to workers") << nSlaves
1407  << nSlavesDone << slaveOk;
1408  gProofServ->GetSocket()->Send(m);
1409 
1410  ord++;
1411  } //end of the worker loop
1412  SafeDelete(dummysi);
1413 
1414  // Cleanup
1415  SafeDelete(workerList);
1416 
1417  nSlavesDone = 0;
1418 
1419  // Here we finalize the server startup: in this way the bulk
1420  // of remote operations are almost parallelized
1421  TIter nxsl(addedWorkers);
1422  TSlave *sl = 0;
1423  while ((sl = (TSlave *) nxsl())) {
1424 
1425  // Finalize setup of the server
1426  if (sl->IsValid())
1427  sl->SetupServ(TSlave::kSlave, 0);
1428 
1429  // Monitor good slaves
1430  Bool_t slaveOk = kTRUE;
1431  if (sl->IsValid()) {
1432  fAllMonitor->Add(sl->GetSocket());
1433  PDB(kGlobal,3)
1434  Info("AddWorkers", "worker on host %s finalized"
1435  " and added to list", sl->GetOrdinal());
1436  } else {
1437  slaveOk = kFALSE;
1438  fBadSlaves->Add(sl);
1439  }
1440 
1441  // Notify end of startup operations
1442  nSlavesDone++;
1444  m << TString("Setting up worker servers") << nSlaves
1445  << nSlavesDone << slaveOk;
1446  gProofServ->GetSocket()->Send(m);
1447  }
1448 
1449  // Now set new state on the added workers (on all workers for simplicity)
1450  // use fEnabledPackages, fLoadedMacros,
1451  // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1452  // no need to load packages that are only loaded and not enabled (dyn mode)
1453  Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1454  TNamed *n = 0;
1455  if (TProof::GetEnvVars() &&
1456  (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1457  TString s(n->GetTitle());
1458  if (s.IsDigit()) nwrk = s.Atoi();
1459  }
1460 
1461  if (fDynamicStartup && goMoreParallel) {
1462 
1463  PDB(kGlobal, 3)
1464  Info("AddWorkers", "will invoke GoMoreParallel()");
1465  Int_t nw = GoMoreParallel(nwrk);
1466  PDB(kGlobal, 3)
1467  Info("AddWorkers", "GoMoreParallel()=%d", nw);
1468 
1469  }
1470  else {
1471  // Not in Dynamic Workers mode
1472  PDB(kGlobal, 3)
1473  Info("AddWorkers", "will invoke GoParallel()");
1474  GoParallel(nwrk, kFALSE, 0);
1475  }
1476 
1477  // Set worker processing environment
1478  SetupWorkersEnv(addedWorkers, goMoreParallel);
1479 
1480  // Update list of current workers
1481  PDB(kGlobal, 3)
1482  Info("AddWorkers", "will invoke SaveWorkerInfo()");
1483  SaveWorkerInfo();
1484 
1485  // Inform the client that the number of workers has changed
1486  if (fDynamicStartup && gProofServ) {
1487  PDB(kGlobal, 3)
1488  Info("AddWorkers", "will invoke SendParallel()");
1490 
1491  if (goMoreParallel && fPlayer) {
1492  // In case we are adding workers dynamically to an existing process, we
1493  // should invoke a special player's Process() to set only added workers
1494  // to the proper state
1495  PDB(kGlobal, 3)
1496  Info("AddWorkers", "will send the PROCESS message to selected workers");
1497  fPlayer->JoinProcess(addedWorkers);
1498  // Update merger counters (new workers are not yet active)
1499  fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1500  }
1501  }
1502 
1503  // Cleanup
1504  delete addedWorkers;
1505 
1506  return 0;
1507 }
1508 
1509 ////////////////////////////////////////////////////////////////////////////////
1510 /// Set up packages, loaded macros, include and lib paths ...
1511 
1512 void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1513 {
1514  // Packages
1516  if (packs && packs->GetSize() > 0) {
1517  TIter nxp(packs);
1518  TPair *pck = 0;
1519  while ((pck = (TPair *) nxp())) {
1520  // Upload and Enable methods are intelligent and avoid
1521  // re-uploading or re-enabling of a package to a node that has it.
1522  if (fDynamicStartup && increasingWorkers) {
1523  // Upload only on added workers
1524  PDB(kGlobal, 3)
1525  Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1526  if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1527  EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1528  } else {
1529  PDB(kGlobal, 3)
1530  Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1531  if (UploadPackage(pck->GetName()) >= 0)
1532  EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1533  }
1534  }
1535  }
1536 
1537  // Loaded macros
1538  if (fLoadedMacros) {
1539  TIter nxp(fLoadedMacros);
1540  TObjString *os = 0;
1541  while ((os = (TObjString *) nxp())) {
1542  PDB(kGlobal, 3) {
1543  Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1544  Printf("Loading a macro : %s", os->GetName());
1545  }
1546  Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1547  }
1548  }
1549 
1550  // Dynamic path
1551  TString dyn = gSystem->GetDynamicPath();
1552  dyn.ReplaceAll(":", " ");
1553  dyn.ReplaceAll("\"", " ");
1554  PDB(kGlobal, 3)
1555  Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1556  AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1557 
1558  // Include path
1559  TString inc = gSystem->GetIncludePath();
1560  inc.ReplaceAll("-I", " ");
1561  inc.ReplaceAll("\"", " ");
1562  PDB(kGlobal, 3)
1563  Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1564  AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1565 
1566  // Done
1567  return;
1568 }
1569 
1570 ////////////////////////////////////////////////////////////////////////////////
1571 /// Used for shuting down the workres after a query is finished.
1572 /// Sends each of the workers from the workerList, a kPROOF_STOP message.
1573 /// If the workerList == 0, shutdown all the workers.
1574 
1576 {
1577  if (!IsMaster()) {
1578  Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1579  return -1;
1580  }
1581 
1582  fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1583 
1584  if (!workerList) {
1585  // shutdown all the workers
1586  TIter nxsl(fSlaves);
1587  TSlave *sl = 0;
1588  while ((sl = (TSlave *) nxsl())) {
1589  // Shut down the worker assumig that it is not processing
1590  TerminateWorker(sl);
1591  }
1592 
1593  } else {
1594  if (!(workerList->GetSize())) {
1595  Error("RemoveWorkers", "The list of workers should not be empty!");
1596  return -2;
1597  }
1598 
1599  // Loop over all the workers and stop them
1600  TListIter next(workerList);
1601  TObject *to;
1602  TProofNodeInfo *worker;
1603  while ((to = next())) {
1604  TSlave *sl = 0;
1605  if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1606  // Get the next worker from the list
1607  worker = (TProofNodeInfo *)to;
1608  TIter nxsl(fSlaves);
1609  while ((sl = (TSlave *) nxsl())) {
1610  // Shut down the worker assumig that it is not processing
1611  if (sl->GetName() == worker->GetNodeName())
1612  break;
1613  }
1614  } else if (to->InheritsFrom(TSlave::Class())) {
1615  sl = (TSlave *) to;
1616  } else {
1617  Warning("RemoveWorkers","unknown object type: %s - it should be"
1618  " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1619  }
1620  // Shut down the worker assumig that it is not processing
1621  if (sl) {
1622  if (gDebug > 0)
1623  Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1624  TerminateWorker(sl);
1625  }
1626  }
1627  }
1628 
1629  // Update also the master counter
1630  if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1631 
1632  return 0;
1633 }
1634 
1635 ////////////////////////////////////////////////////////////////////////////////
1636 /// Start up PROOF slaves.
1637 
1639 {
1640  // If this is a master server, find the config file and start slave
1641  // servers as specified in the config file
1642  if (TestBit(TProof::kIsMaster)) {
1643 
1644  Int_t pc = 0;
1645  TList *workerList = new TList;
1646  // Get list of workers
1647  if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1648  TString emsg("no resource currently available for this session: please retry later");
1649  if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1650  gProofServ->SendAsynMessage(emsg.Data());
1651  return kFALSE;
1652  }
1653  // Setup the workers
1654  if (AddWorkers(workerList) < 0)
1655  return kFALSE;
1656 
1657  } else {
1658 
1659  // create master server
1660  Printf("Starting master: opening connection ...");
1661  TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1662 
1663  if (slave->IsValid()) {
1664 
1665  // Notify
1666  fprintf(stderr,"Starting master:"
1667  " connection open: setting up server ... \r");
1668  StartupMessage("Connection to master opened", kTRUE, 1, 1);
1669 
1670  if (!attach) {
1671 
1672  // Set worker interrupt handler
1673  slave->SetInterruptHandler(kTRUE);
1674 
1675  // Finalize setup of the server
1677 
1678  if (slave->IsValid()) {
1679 
1680  // Notify
1681  Printf("Starting master: OK ");
1682  StartupMessage("Master started", kTRUE, 1, 1);
1683 
1684  // check protocol compatibility
1685  // protocol 1 is not supported anymore
1686  if (fProtocol == 1) {
1687  Error("StartSlaves",
1688  "client and remote protocols not compatible (%d and %d)",
1690  slave->Close("S");
1691  delete slave;
1692  return kFALSE;
1693  }
1694 
1695  fSlaves->Add(slave);
1696  fAllMonitor->Add(slave->GetSocket());
1697 
1698  // Unset worker interrupt handler
1699  slave->SetInterruptHandler(kFALSE);
1700 
1701  // Set interrupt PROOF handler from now on
1702  fIntHandler = new TProofInterruptHandler(this);
1703 
1704  // Give-up after 5 minutes
1705  Int_t rc = Collect(slave, 300);
1706  Int_t slStatus = slave->GetStatus();
1707  if (slStatus == -99 || slStatus == -98 || rc == 0) {
1708  fSlaves->Remove(slave);
1709  fAllMonitor->Remove(slave->GetSocket());
1710  if (slStatus == -99)
1711  Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1712  else if (slStatus == -98)
1713  Error("StartSlaves", "could not setup output redirection on master");
1714  else
1715  Error("StartSlaves", "setting up master");
1716  slave->Close("S");
1717  delete slave;
1718  return 0;
1719  }
1720 
1721  if (!slave->IsValid()) {
1722  fSlaves->Remove(slave);
1723  fAllMonitor->Remove(slave->GetSocket());
1724  slave->Close("S");
1725  delete slave;
1726  Error("StartSlaves",
1727  "failed to setup connection with PROOF master server");
1728  return kFALSE;
1729  }
1730 
1731  if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1732  if ((fProgressDialog =
1733  gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1734  if (fProgressDialog->LoadPlugin() == -1)
1735  fProgressDialog = 0;
1736  }
1737  } else {
1738  // Notify
1739  Printf("Starting master: failure");
1740  }
1741  } else {
1742 
1743  // Notify
1744  Printf("Starting master: OK ");
1745  StartupMessage("Master attached", kTRUE, 1, 1);
1746 
1747  if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1748  if ((fProgressDialog =
1749  gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1750  if (fProgressDialog->LoadPlugin() == -1)
1751  fProgressDialog = 0;
1752  }
1753 
1754  fSlaves->Add(slave);
1755  fIntHandler = new TProofInterruptHandler(this);
1756  }
1757 
1758  } else {
1759  delete slave;
1760  // Notify only if verbosity is on: most likely the failure has already been notified
1761  if (gDebug > 0)
1762  Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1763  return kFALSE;
1764  }
1765  }
1766 
1767  return kTRUE;
1768 }
1769 
1770 ////////////////////////////////////////////////////////////////////////////////
1771 /// Close all open slave servers.
1772 /// Client can decide to shutdown the remote session by passing option is 'S'
1773 /// or 's'. Default for clients is detach, if supported. Masters always
1774 /// shutdown the remote counterpart.
1775 
1777 {
1778  { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1779 
1780  fValid = kFALSE;
1781  if (fSlaves) {
1782  if (fIntHandler)
1783  fIntHandler->Remove();
1784 
1785  TIter nxs(fSlaves);
1786  TSlave *sl = 0;
1787  while ((sl = (TSlave *)nxs()))
1788  sl->Close(opt);
1789 
1790  fActiveSlaves->Clear("nodelete");
1791  fUniqueSlaves->Clear("nodelete");
1792  fAllUniqueSlaves->Clear("nodelete");
1793  fNonUniqueMasters->Clear("nodelete");
1794  fBadSlaves->Clear("nodelete");
1795  fInactiveSlaves->Clear("nodelete");
1796  fSlaves->Delete();
1797  }
1798  }
1799 
1801  gROOT->GetListOfSockets()->Remove(this);
1802 
1803  if (fChains) {
1804  while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1805  // remove "chain" from list
1806  chain->SetProof(0);
1807  RemoveChain(chain);
1808  }
1809  }
1810 
1811  if (IsProofd()) {
1812 
1813  gROOT->GetListOfProofs()->Remove(this);
1814  if (gProof && gProof == this) {
1815  // Set previous proofd-related as default
1816  TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1817  while ((gProof = (TProof *)pvp())) {
1818  if (gProof->IsProofd())
1819  break;
1820  }
1821  }
1822  }
1823  }
1824 }
1825 
1826 ////////////////////////////////////////////////////////////////////////////////
1827 /// Create a new TSlave of type TSlave::kSlave.
1828 /// Note: creation of TSlave is private with TProof as a friend.
1829 /// Derived classes must use this function to create slaves.
1830 
1831 TSlave *TProof::CreateSlave(const char *url, const char *ord,
1832  Int_t perf, const char *image, const char *workdir)
1833 {
1834  TSlave* sl = TSlave::Create(url, ord, perf, image,
1835  this, TSlave::kSlave, workdir, 0);
1836 
1837  if (sl->IsValid()) {
1838  sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1839  // must set fParallel to 1 for slaves since they do not
1840  // report their fParallel with a LOG_DONE message
1841  sl->fParallel = 1;
1842  }
1843 
1844  return sl;
1845 }
1846 
1847 
1848 ////////////////////////////////////////////////////////////////////////////////
1849 /// Create a new TSlave of type TSlave::kMaster.
1850 /// Note: creation of TSlave is private with TProof as a friend.
1851 /// Derived classes must use this function to create slaves.
1852 
1853 TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1854  const char *image, const char *msd, Int_t nwk)
1855 {
1856  TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1857  TSlave::kMaster, 0, msd, nwk);
1858 
1859  if (sl->IsValid()) {
1860  sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1861  }
1862 
1863  return sl;
1864 }
1865 
1866 ////////////////////////////////////////////////////////////////////////////////
1867 /// Find slave that has TSocket s. Returns 0 in case slave is not found.
1868 
1870 {
1871  TSlave *sl;
1872  TIter next(fSlaves);
1873 
1874  while ((sl = (TSlave *)next())) {
1875  if (sl->IsValid() && sl->GetSocket() == s)
1876  return sl;
1877  }
1878  return 0;
1879 }
1880 
1881 ////////////////////////////////////////////////////////////////////////////////
1882 /// Add to the fUniqueSlave list the active slaves that have a unique
1883 /// (user) file system image. This information is used to transfer files
1884 /// only once to nodes that share a file system (an image). Submasters
1885 /// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1886 /// list. That list is used to trigger the transferring of files to
1887 /// the submaster's unique slaves without the need to transfer the file
1888 /// to the submaster.
1889 
1891 {
1892  fUniqueSlaves->Clear();
1897 
1898  TIter next(fActiveSlaves);
1899 
1900  while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1901  if (fImage == sl->fImage) {
1902  if (sl->GetSlaveType() == TSlave::kMaster) {
1903  fNonUniqueMasters->Add(sl);
1904  fAllUniqueSlaves->Add(sl);
1905  fAllUniqueMonitor->Add(sl->GetSocket());
1906  }
1907  continue;
1908  }
1909 
1910  TIter next2(fUniqueSlaves);
1911  TSlave *replace_slave = 0;
1912  Bool_t add = kTRUE;
1913  while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1914  if (sl->fImage == sl2->fImage) {
1915  add = kFALSE;
1916  if (sl->GetSlaveType() == TSlave::kMaster) {
1917  if (sl2->GetSlaveType() == TSlave::kSlave) {
1918  // give preference to master
1919  replace_slave = sl2;
1920  add = kTRUE;
1921  } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1922  fNonUniqueMasters->Add(sl);
1923  fAllUniqueSlaves->Add(sl);
1924  fAllUniqueMonitor->Add(sl->GetSocket());
1925  } else {
1926  Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1927  R__ASSERT(0);
1928  }
1929  }
1930  break;
1931  }
1932  }
1933 
1934  if (add) {
1935  fUniqueSlaves->Add(sl);
1936  fAllUniqueSlaves->Add(sl);
1937  fUniqueMonitor->Add(sl->GetSocket());
1938  fAllUniqueMonitor->Add(sl->GetSocket());
1939  if (replace_slave) {
1940  fUniqueSlaves->Remove(replace_slave);
1941  fAllUniqueSlaves->Remove(replace_slave);
1942  fUniqueMonitor->Remove(replace_slave->GetSocket());
1943  fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1944  }
1945  }
1946  }
1947 
1948  // will be actiavted in Collect()
1951 }
1952 
1953 ////////////////////////////////////////////////////////////////////////////////
1954 /// Return number of slaves as described in the config file.
1955 
1957 {
1958  return fSlaves->GetSize();
1959 }
1960 
1961 ////////////////////////////////////////////////////////////////////////////////
1962 /// Return number of active slaves, i.e. slaves that are valid and in
1963 /// the current computing group.
1964 
1966 {
1967  return fActiveSlaves->GetSize();
1968 }
1969 
1970 ////////////////////////////////////////////////////////////////////////////////
1971 /// Return number of inactive slaves, i.e. slaves that are valid but not in
1972 /// the current computing group.
1973 
1975 {
1976  return fInactiveSlaves->GetSize();
1977 }
1978 
1979 ////////////////////////////////////////////////////////////////////////////////
1980 /// Return number of unique slaves, i.e. active slaves that have each a
1981 /// unique different user files system.
1982 
1984 {
1985  return fUniqueSlaves->GetSize();
1986 }
1987 
1988 ////////////////////////////////////////////////////////////////////////////////
1989 /// Return number of bad slaves. This are slaves that we in the config
1990 /// file, but refused to startup or that died during the PROOF session.
1991 
1993 {
1994  return fBadSlaves->GetSize();
1995 }
1996 
1997 ////////////////////////////////////////////////////////////////////////////////
1998 /// Ask the for the statistics of the slaves.
1999 
2001 {
2002  if (!IsValid()) return;
2003 
2006 }
2007 
2008 ////////////////////////////////////////////////////////////////////////////////
2009 /// Get statistics about CPU time, real time and bytes read.
2010 /// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2011 /// and GetBytesRead()
2012 
2014 {
2015  if (fProtocol > 27) {
2016  // This returns the correct result
2017  AskStatistics();
2018  } else {
2019  // AskStatistics is buggy: parse the output of Print()
2020  RedirectHandle_t rh;
2021  gSystem->RedirectOutput(fLogFileName, "a", &rh);
2022  Print();
2023  gSystem->RedirectOutput(0, 0, &rh);
2024  TMacro *mp = GetLastLog();
2025  if (mp) {
2026  // Look for global directories
2027  TIter nxl(mp->GetListOfLines());
2028  TObjString *os = 0;
2029  while ((os = (TObjString *) nxl())) {
2030  TString s(os->GetName());
2031  if (s.Contains("Total MB's processed:")) {
2032  s.ReplaceAll("Total MB's processed:", "");
2033  if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2034  } else if (s.Contains("Total real time used (s):")) {
2035  s.ReplaceAll("Total real time used (s):", "");
2036  if (s.IsFloat()) fRealTime = s.Atof();
2037  } else if (s.Contains("Total CPU time used (s):")) {
2038  s.ReplaceAll("Total CPU time used (s):", "");
2039  if (s.IsFloat()) fCpuTime = s.Atof();
2040  }
2041  }
2042  delete mp;
2043  }
2044  }
2045 
2046  if (verbose) {
2047  Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2048  GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2049  }
2050 }
2051 
2052 ////////////////////////////////////////////////////////////////////////////////
2053 /// Ask the for the number of parallel slaves.
2054 
2056 {
2057  if (!IsValid()) return;
2058 
2061 }
2062 
2063 ////////////////////////////////////////////////////////////////////////////////
2064 /// Ask the master for the list of queries.
2065 
2067 {
2068  if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2069 
2070  Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2072  m << all;
2073  Broadcast(m, kActive);
2075 
2076  // This should have been filled by now
2077  return fQueries;
2078 }
2079 
2080 ////////////////////////////////////////////////////////////////////////////////
2081 /// Number of queries processed by this session
2082 
2084 {
2085  if (fQueries)
2086  return fQueries->GetSize() - fOtherQueries;
2087  return 0;
2088 }
2089 
2090 ////////////////////////////////////////////////////////////////////////////////
2091 /// Set max number of draw queries whose results are saved
2092 
2094 {
2095  if (max > 0) {
2096  if (fPlayer)
2097  fPlayer->SetMaxDrawQueries(max);
2098  fMaxDrawQueries = max;
2099  }
2100 }
2101 
2102 ////////////////////////////////////////////////////////////////////////////////
2103 /// Get max number of queries whose full results are kept in the
2104 /// remote sandbox
2105 
2107 {
2109  m << kFALSE;
2110  Broadcast(m, kActive);
2112 }
2113 
2114 ////////////////////////////////////////////////////////////////////////////////
2115 /// Return pointer to the list of query results in the player
2116 
2118 {
2119  return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2120 }
2121 
2122 ////////////////////////////////////////////////////////////////////////////////
2123 /// Return pointer to the full TQueryResult instance owned by the player
2124 /// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2125 
2127 {
2128  return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2129 }
2130 
2131 ////////////////////////////////////////////////////////////////////////////////
2132 /// Ask the master for the list of queries.
2133 /// Options:
2134 /// "A" show information about all the queries known to the
2135 /// server, i.e. even those processed by other sessions
2136 /// "L" show only information about queries locally available
2137 /// i.e. already retrieved. If "L" is specified, "A" is
2138 /// ignored.
2139 /// "F" show all details available about queries
2140 /// "H" print help menu
2141 /// Default ""
2142 
2144 {
2145  Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2146  if (help) {
2147 
2148  // Help
2149 
2150  Printf("+++");
2151  Printf("+++ Options: \"A\" show all queries known to server");
2152  Printf("+++ \"L\" show retrieved queries");
2153  Printf("+++ \"F\" full listing of query info");
2154  Printf("+++ \"H\" print this menu");
2155  Printf("+++");
2156  Printf("+++ (case insensitive)");
2157  Printf("+++");
2158  Printf("+++ Use Retrieve(<#>) to retrieve the full"
2159  " query results from the master");
2160  Printf("+++ e.g. Retrieve(8)");
2161 
2162  Printf("+++");
2163 
2164  return;
2165  }
2166 
2167  if (!IsValid()) return;
2168 
2169  Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2170 
2171  TObject *pq = 0;
2172  if (!local) {
2173  GetListOfQueries(opt);
2174 
2175  if (!fQueries) return;
2176 
2177  TIter nxq(fQueries);
2178 
2179  // Queries processed by other sessions
2180  if (fOtherQueries > 0) {
2181  Printf("+++");
2182  Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2183  Int_t nq = 0;
2184  while (nq++ < fOtherQueries && (pq = nxq()))
2185  pq->Print(opt);
2186  }
2187 
2188  // Queries processed by this session
2189  Printf("+++");
2190  Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2192  while ((pq = nxq()))
2193  pq->Print(opt);
2194 
2195  } else {
2196 
2197  // Queries processed by this session
2198  Printf("+++");
2199  Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2201 
2202  // Queries available locally
2203  TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2204  if (listlocal) {
2205  Printf("+++");
2206  Printf("+++ Queries available locally: %d", listlocal->GetSize());
2207  TIter nxlq(listlocal);
2208  while ((pq = nxlq()))
2209  pq->Print(opt);
2210  }
2211  }
2212  Printf("+++");
2213 }
2214 
2215 ////////////////////////////////////////////////////////////////////////////////
2216 /// See if the data is ready to be analyzed.
2217 
2218 Bool_t TProof::IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
2219 {
2220  if (!IsValid()) return kFALSE;
2221 
2222  TList submasters;
2223  TIter nextSlave(GetListOfActiveSlaves());
2224  while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2225  if (sl->GetSlaveType() == TSlave::kMaster) {
2226  submasters.Add(sl);
2227  }
2228  }
2229 
2230  fDataReady = kTRUE; //see if any submasters set it to false
2231  fBytesReady = 0;
2232  fTotalBytes = 0;
2233  //loop over submasters and see if data is ready
2234  if (submasters.GetSize() > 0) {
2235  Broadcast(kPROOF_DATA_READY, &submasters);
2236  Collect(&submasters);
2237  }
2238 
2239  bytesready = fBytesReady;
2240  totalbytes = fTotalBytes;
2241 
2242  EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2243 
2244  PDB(kGlobal,2)
2245  Info("IsDataReady", "%lld / %lld (%s)",
2246  bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2247 
2248  return fDataReady;
2249 }
2250 
2251 ////////////////////////////////////////////////////////////////////////////////
2252 /// Send interrupt to master or slave servers.
2253 
2255 {
2256  if (!IsValid()) return;
2257 
2258  TList *slaves = 0;
2259  if (list == kAll) slaves = fSlaves;
2260  if (list == kActive) slaves = fActiveSlaves;
2261  if (list == kUnique) slaves = fUniqueSlaves;
2262  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2263 
2264  if (slaves->GetSize() == 0) return;
2265 
2266  TSlave *sl;
2267  TIter next(slaves);
2268 
2269  while ((sl = (TSlave *)next())) {
2270  if (sl->IsValid()) {
2271 
2272  // Ask slave to progate the interrupt request
2273  sl->Interrupt((Int_t)type);
2274  }
2275  }
2276 }
2277 
2278 ////////////////////////////////////////////////////////////////////////////////
2279 /// Returns number of slaves active in parallel mode. Returns 0 in case
2280 /// there are no active slaves. Returns -1 in case of error.
2281 
2283 {
2284  if (!IsValid()) return -1;
2285 
2286  // iterate over active slaves and return total number of slaves
2287  TIter nextSlave(GetListOfActiveSlaves());
2288  Int_t nparallel = 0;
2289  while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2290  if (sl->GetParallel() >= 0)
2291  nparallel += sl->GetParallel();
2292 
2293  return nparallel;
2294 }
2295 
2296 ////////////////////////////////////////////////////////////////////////////////
2297 /// Returns list of TSlaveInfo's. In case of error return 0.
2298 
2300 {
2301  if (!IsValid()) return 0;
2302 
2303  if (fSlaveInfo == 0) {
2305  fSlaveInfo->SetOwner();
2306  } else {
2307  fSlaveInfo->Delete();
2308  }
2309 
2310  TList masters;
2311  TIter next(GetListOfSlaves());
2312  TSlave *slave;
2313 
2314  while ((slave = (TSlave *) next()) != 0) {
2315  if (slave->GetSlaveType() == TSlave::kSlave) {
2316  const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2317  TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2318  name,
2319  slave->GetPerfIdx());
2320  fSlaveInfo->Add(slaveinfo);
2321 
2322  TIter nextactive(GetListOfActiveSlaves());
2323  TSlave *activeslave;
2324  while ((activeslave = (TSlave *) nextactive())) {
2325  if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2326  slaveinfo->SetStatus(TSlaveInfo::kActive);
2327  break;
2328  }
2329  }
2330 
2331  TIter nextbad(GetListOfBadSlaves());
2332  TSlave *badslave;
2333  while ((badslave = (TSlave *) nextbad())) {
2334  if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2335  slaveinfo->SetStatus(TSlaveInfo::kBad);
2336  break;
2337  }
2338  }
2339  // Get system info if supported
2340  if (slave->IsValid()) {
2341  if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2342  MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2343  else
2344  masters.Add(slave);
2345  }
2346 
2347  } else if (slave->GetSlaveType() == TSlave::kMaster) {
2348  if (slave->IsValid()) {
2349  if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2350  MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2351  else
2352  masters.Add(slave);
2353  }
2354  } else {
2355  Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2356  R__ASSERT(0);
2357  }
2358  }
2359  if (masters.GetSize() > 0) Collect(&masters);
2360 
2361  return fSlaveInfo;
2362 }
2363 
2364 ////////////////////////////////////////////////////////////////////////////////
2365 /// Activate slave server list.
2366 
2368 {
2369  TMonitor *mon = fAllMonitor;
2370  mon->DeActivateAll();
2371 
2372  slaves = !slaves ? fActiveSlaves : slaves;
2373 
2374  TIter next(slaves);
2375  TSlave *sl;
2376  while ((sl = (TSlave*) next())) {
2377  if (sl->IsValid())
2378  mon->Activate(sl->GetSocket());
2379  }
2380 }
2381 
2382 ////////////////////////////////////////////////////////////////////////////////
2383 /// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2384 /// monitored by 'mon'.
2385 
2387 {
2388  TMonitor *m = (mon) ? mon : fCurrentMonitor;
2389  if (m) {
2390  if (on)
2391  m->ActivateAll();
2392  else
2393  m->DeActivateAll();
2394  }
2395 }
2396 
2397 ////////////////////////////////////////////////////////////////////////////////
2398 /// Broadcast the group priority to all workers in the specified list. Returns
2399 /// the number of workers the message was successfully sent to.
2400 /// Returns -1 in case of error.
2401 
2402 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2403 {
2404  if (!IsValid()) return -1;
2405 
2406  if (workers->GetSize() == 0) return 0;
2407 
2408  int nsent = 0;
2409  TIter next(workers);
2410 
2411  TSlave *wrk;
2412  while ((wrk = (TSlave *)next())) {
2413  if (wrk->IsValid()) {
2414  if (wrk->SendGroupPriority(grp, priority) == -1)
2415  MarkBad(wrk, "could not send group priority");
2416  else
2417  nsent++;
2418  }
2419  }
2420 
2421  return nsent;
2422 }
2423 
2424 ////////////////////////////////////////////////////////////////////////////////
2425 /// Broadcast the group priority to all workers in the specified list. Returns
2426 /// the number of workers the message was successfully sent to.
2427 /// Returns -1 in case of error.
2428 
2429 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2430 {
2431  TList *workers = 0;
2432  if (list == kAll) workers = fSlaves;
2433  if (list == kActive) workers = fActiveSlaves;
2434  if (list == kUnique) workers = fUniqueSlaves;
2435  if (list == kAllUnique) workers = fAllUniqueSlaves;
2436 
2437  return BroadcastGroupPriority(grp, priority, workers);
2438 }
2439 
2440 ////////////////////////////////////////////////////////////////////////////////
2441 /// Reset the merge progress notificator
2442 
2444 {
2446 }
2447 
2448 ////////////////////////////////////////////////////////////////////////////////
2449 /// Broadcast a message to all slaves in the specified list. Returns
2450 /// the number of slaves the message was successfully sent to.
2451 /// Returns -1 in case of error.
2452 
2453 Int_t TProof::Broadcast(const TMessage &mess, TList *slaves)
2454 {
2455  if (!IsValid()) return -1;
2456 
2457  if (!slaves || slaves->GetSize() == 0) return 0;
2458 
2459  int nsent = 0;
2460  TIter next(slaves);
2461 
2462  TSlave *sl;
2463  while ((sl = (TSlave *)next())) {
2464  if (sl->IsValid()) {
2465  if (sl->GetSocket()->Send(mess) == -1)
2466  MarkBad(sl, "could not broadcast request");
2467  else
2468  nsent++;
2469  }
2470  }
2471 
2472  return nsent;
2473 }
2474 
2475 ////////////////////////////////////////////////////////////////////////////////
2476 /// Broadcast a message to all slaves in the specified list (either
2477 /// all slaves or only the active slaves). Returns the number of slaves
2478 /// the message was successfully sent to. Returns -1 in case of error.
2479 
2481 {
2482  TList *slaves = 0;
2483  if (list == kAll) slaves = fSlaves;
2484  if (list == kActive) slaves = fActiveSlaves;
2485  if (list == kUnique) slaves = fUniqueSlaves;
2486  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2487 
2488  return Broadcast(mess, slaves);
2489 }
2490 
2491 ////////////////////////////////////////////////////////////////////////////////
2492 /// Broadcast a character string buffer to all slaves in the specified
2493 /// list. Use kind to set the TMessage what field. Returns the number of
2494 /// slaves the message was sent to. Returns -1 in case of error.
2495 
2496 Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2497 {
2498  TMessage mess(kind);
2499  if (str) mess.WriteString(str);
2500  return Broadcast(mess, slaves);
2501 }
2502 
2503 ////////////////////////////////////////////////////////////////////////////////
2504 /// Broadcast a character string buffer to all slaves in the specified
2505 /// list (either all slaves or only the active slaves). Use kind to
2506 /// set the TMessage what field. Returns the number of slaves the message
2507 /// was sent to. Returns -1 in case of error.
2508 
2509 Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2510 {
2511  TMessage mess(kind);
2512  if (str) mess.WriteString(str);
2513  return Broadcast(mess, list);
2514 }
2515 
2516 ////////////////////////////////////////////////////////////////////////////////
2517 /// Broadcast an object to all slaves in the specified list. Use kind to
2518 /// set the TMEssage what field. Returns the number of slaves the message
2519 /// was sent to. Returns -1 in case of error.
2520 
2522 {
2523  TMessage mess(kind);
2524  mess.WriteObject(obj);
2525  return Broadcast(mess, slaves);
2526 }
2527 
2528 ////////////////////////////////////////////////////////////////////////////////
2529 /// Broadcast an object to all slaves in the specified list. Use kind to
2530 /// set the TMEssage what field. Returns the number of slaves the message
2531 /// was sent to. Returns -1 in case of error.
2532 
2534 {
2535  TMessage mess(kind);
2536  mess.WriteObject(obj);
2537  return Broadcast(mess, list);
2538 }
2539 
2540 ////////////////////////////////////////////////////////////////////////////////
2541 /// Broadcast a raw buffer of specified length to all slaves in the
2542 /// specified list. Returns the number of slaves the buffer was sent to.
2543 /// Returns -1 in case of error.
2544 
2545 Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2546 {
2547  if (!IsValid()) return -1;
2548 
2549  if (slaves->GetSize() == 0) return 0;
2550 
2551  int nsent = 0;
2552  TIter next(slaves);
2553 
2554  TSlave *sl;
2555  while ((sl = (TSlave *)next())) {
2556  if (sl->IsValid()) {
2557  if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2558  MarkBad(sl, "could not send broadcast-raw request");
2559  else
2560  nsent++;
2561  }
2562  }
2563 
2564  return nsent;
2565 }
2566 
2567 ////////////////////////////////////////////////////////////////////////////////
2568 /// Broadcast a raw buffer of specified length to all slaves in the
2569 /// specified list. Returns the number of slaves the buffer was sent to.
2570 /// Returns -1 in case of error.
2571 
2572 Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2573 {
2574  TList *slaves = 0;
2575  if (list == kAll) slaves = fSlaves;
2576  if (list == kActive) slaves = fActiveSlaves;
2577  if (list == kUnique) slaves = fUniqueSlaves;
2578  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2579 
2580  return BroadcastRaw(buffer, length, slaves);
2581 }
2582 
2583 ////////////////////////////////////////////////////////////////////////////////
2584 /// Broadcast file to all workers in the specified list. Returns the number of workers
2585 /// the buffer was sent to.
2586 /// Returns -1 in case of error.
2587 
2588 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2589 {
2590  if (!IsValid()) return -1;
2591 
2592  if (wrks->GetSize() == 0) return 0;
2593 
2594  int nsent = 0;
2595  TIter next(wrks);
2596 
2597  TSlave *wrk;
2598  while ((wrk = (TSlave *)next())) {
2599  if (wrk->IsValid()) {
2600  if (SendFile(file, opt, rfile, wrk) < 0)
2601  Error("BroadcastFile",
2602  "problems sending file to worker %s (%s)",
2603  wrk->GetOrdinal(), wrk->GetName());
2604  else
2605  nsent++;
2606  }
2607  }
2608 
2609  return nsent;
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, ESlaves list)
2618 {
2619  TList *wrks = 0;
2620  if (list == kAll) wrks = fSlaves;
2621  if (list == kActive) wrks = fActiveSlaves;
2622  if (list == kUnique) wrks = fUniqueSlaves;
2623  if (list == kAllUnique) wrks = fAllUniqueSlaves;
2624 
2625  return BroadcastFile(file, opt, rfile, wrks);
2626 }
2627 
2628 ////////////////////////////////////////////////////////////////////////////////
2629 /// Release the used monitor to be used, making sure to delete newly created
2630 /// monitors.
2631 
2633 {
2634  if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2635  && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2636  delete mon;
2637  }
2638 }
2639 
2640 ////////////////////////////////////////////////////////////////////////////////
2641 /// Collect responses from slave sl. Returns the number of slaves that
2642 /// responded (=1).
2643 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2644 /// which means wait forever).
2645 /// If defined (>= 0) endtype is the message that stops this collection.
2646 
2647 Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2648 {
2649  Int_t rc = 0;
2650 
2651  TMonitor *mon = 0;
2652  if (!sl->IsValid()) return 0;
2653 
2654  if (fCurrentMonitor == fAllMonitor) {
2655  mon = new TMonitor;
2656  } else {
2657  mon = fAllMonitor;
2658  mon->DeActivateAll();
2659  }
2660  mon->Activate(sl->GetSocket());
2661 
2662  rc = Collect(mon, timeout, endtype, deactonfail);
2663  ReleaseMonitor(mon);
2664  return rc;
2665 }
2666 
2667 ////////////////////////////////////////////////////////////////////////////////
2668 /// Collect responses from the slave servers. Returns the number of slaves
2669 /// that responded.
2670 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2671 /// which means wait forever).
2672 /// If defined (>= 0) endtype is the message that stops this collection.
2673 
2674 Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2675 {
2676  Int_t rc = 0;
2677 
2678  TMonitor *mon = 0;
2679 
2680  if (fCurrentMonitor == fAllMonitor) {
2681  mon = new TMonitor;
2682  } else {
2683  mon = fAllMonitor;
2684  mon->DeActivateAll();
2685  }
2686  TIter next(slaves);
2687  TSlave *sl;
2688  while ((sl = (TSlave*) next())) {
2689  if (sl->IsValid())
2690  mon->Activate(sl->GetSocket());
2691  }
2692 
2693  rc = Collect(mon, timeout, endtype, deactonfail);
2694  ReleaseMonitor(mon);
2695  return rc;
2696 }
2697 
2698 ////////////////////////////////////////////////////////////////////////////////
2699 /// Collect responses from the slave servers. Returns the number of slaves
2700 /// that responded.
2701 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2702 /// which means wait forever).
2703 /// If defined (>= 0) endtype is the message that stops this collection.
2704 
2705 Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2706 {
2707  Int_t rc = 0;
2708  TMonitor *mon = 0;
2709 
2710  if (list == kAll) mon = fAllMonitor;
2711  if (list == kActive) mon = fActiveMonitor;
2712  if (list == kUnique) mon = fUniqueMonitor;
2713  if (list == kAllUnique) mon = fAllUniqueMonitor;
2714  if (fCurrentMonitor == mon) {
2715  // Get a copy
2716  mon = new TMonitor(*mon);
2717  }
2718  mon->ActivateAll();
2719 
2720  rc = Collect(mon, timeout, endtype, deactonfail);
2721  ReleaseMonitor(mon);
2722  return rc;
2723 }
2724 
2725 ////////////////////////////////////////////////////////////////////////////////
2726 /// Collect responses from the slave servers. Returns the number of messages
2727 /// received. Can be 0 if there are no active slaves.
2728 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2729 /// which means wait forever).
2730 /// If defined (>= 0) endtype is the message that stops this collection.
2731 /// Collect also stops its execution from time to time to check for new
2732 /// workers in Dynamic Startup mode.
2733 
2734 Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2735 {
2736  Int_t collectId = gRandom->Integer(9999);
2737 
2738  PDB(kCollect, 3)
2739  Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2740 
2741  // Reset the status flag and clear the messages in the list, if any
2742  fStatus = 0;
2743  fRecvMessages->Clear();
2744 
2745  Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2746 
2747  if (!mon->GetActive(actto)) return 0;
2748 
2750 
2751  // Used by external code to know what we are monitoring
2752  TMonitor *savedMonitor = 0;
2753  if (fCurrentMonitor) {
2754  savedMonitor = fCurrentMonitor;
2755  fCurrentMonitor = mon;
2756  } else {
2757  fCurrentMonitor = mon;
2758  fBytesRead = 0;
2759  fRealTime = 0.0;
2760  fCpuTime = 0.0;
2761  }
2762 
2763  // We want messages on the main window during synchronous collection,
2764  // but we save the present status to restore it at the end
2765  Bool_t saveRedirLog = fRedirLog;
2766  if (!IsIdle() && !IsSync())
2767  fRedirLog = kFALSE;
2768 
2769  int cnt = 0, rc = 0;
2770 
2771  // Timeout counter
2772  Long_t nto = timeout;
2773  PDB(kCollect, 2)
2774  Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2775 
2776  // On clients, handle Ctrl-C during collection
2777  if (fIntHandler)
2778  fIntHandler->Add();
2779 
2780  // Sockets w/o activity during the last 'sto' millisecs are deactivated
2781  Int_t nact = 0;
2782  Long_t sto = -1;
2783  Int_t nsto = 60;
2784  Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2785  mon->ResetInterrupt();
2786  while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2787 
2788  // Dump last waiting sockets, if in debug mode
2789  PDB(kCollect, 2) {
2790  if (nact < 4) {
2791  TList *al = mon->GetListOfActives();
2792  if (al && al->GetSize() > 0) {
2793  Info("Collect"," %d node(s) still active:", al->GetSize());
2794  TIter nxs(al);
2795  TSocket *xs = 0;
2796  while ((xs = (TSocket *)nxs())) {
2797  TSlave *wrk = FindSlave(xs);
2798  if (wrk)
2799  Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2800  else
2801  Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2802  xs->GetInetAddress().GetPort());
2803  }
2804  }
2805  }
2806  }
2807 
2808  // Preemptive poll for new workers on the master only in Dynamic Mode and only
2809  // during processing (TODO: should work on Top Master only)
2811  ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2814  fLastPollWorkers_s = time(0);
2816  PDB(kCollect, 1)
2817  Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2818  }
2819 
2820  // Wait for a ready socket
2821  PDB(kCollect, 3)
2822  Info("Collect", "Will invoke Select() #%04d", collectId);
2823  TSocket *s = mon->Select(1000);
2824 
2825  if (s && s != (TSocket *)(-1)) {
2826  // Get and analyse the info it did receive
2827  rc = CollectInputFrom(s, endtype, deactonfail);
2828  if (rc == 1 || (rc == 2 && !savedMonitor)) {
2829  // Deactivate it if we are done with it
2830  mon->DeActivate(s);
2831  PDB(kCollect, 2)
2832  Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2833  s, mon->GetActive(),
2834  mon->GetListOfActives()->First());
2835  } else if (rc == 2) {
2836  // This end message was for the saved monitor
2837  // Deactivate it if we are done with it
2838  if (savedMonitor) {
2839  savedMonitor->DeActivate(s);
2840  PDB(kCollect, 2)
2841  Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2842  s, savedMonitor->GetActive(),
2843  savedMonitor->GetListOfActives()->First());
2844  }
2845  }
2846 
2847  // Update counter (if no error occured)
2848  if (rc >= 0)
2849  cnt++;
2850  } else {
2851  // If not timed-out, exit if not stopped or not aborted
2852  // (player exits status is finished in such a case); otherwise,
2853  // we still need to collect the partial output info
2854  if (!s)
2856  mon->DeActivateAll();
2857  // Decrease the timeout counter if requested
2858  if (s == (TSocket *)(-1) && nto > 0)
2859  nto--;
2860  }
2861 
2862  // Check if there are workers with ready output to be sent and ask the first to send it
2863  if (IsMaster() && fWrksOutputReady && fWrksOutputReady->GetSize() > 0) {
2864  // Maximum number of concurrent sendings
2865  Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2866  if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2867  mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2868  TIter nxwr(fWrksOutputReady);
2869  TSlave *wrk = 0;
2870  while (mxws && (wrk = (TSlave *) nxwr())) {
2871  if (!wrk->TestBit(TSlave::kOutputRequested)) {
2872  // Ask worker for output
2873  TMessage sendoutput(kPROOF_SENDOUTPUT);
2874  PDB(kCollect, 2)
2875  Info("Collect", "worker %s was asked to send its output to master",
2876  wrk->GetOrdinal());
2877  if (wrk->GetSocket()->Send(sendoutput) != 1) {
2879  mxws--;
2880  }
2881  } else {
2882  // Count
2883  mxws--;
2884  }
2885  }
2886  }
2887 
2888  // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2889  sto = -1;
2890  if (--nsto <= 0) {
2891  sto = (Long_t) actto;
2892  nsto = 60;
2893  }
2894 
2895  } // end loop over active monitors
2896 
2897  // If timed-out, deactivate the remaining sockets
2898  if (nto == 0) {
2899  TList *al = mon->GetListOfActives();
2900  if (al && al->GetSize() > 0) {
2901  // Notify the name of those which did timeout
2902  Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2903  TIter nxs(al);
2904  TSocket *xs = 0;
2905  while ((xs = (TSocket *)nxs())) {
2906  TSlave *wrk = FindSlave(xs);
2907  if (wrk)
2908  Info("Collect"," %s", wrk->GetName());
2909  else
2910  Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2911  xs->GetInetAddress().GetPort());
2912  }
2913  }
2914  mon->DeActivateAll();
2915  }
2916 
2917  // Deactivate Ctrl-C special handler
2918  if (fIntHandler)
2919  fIntHandler->Remove();
2920 
2921  // make sure group view is up to date
2922  SendGroupView();
2923 
2924  // Restore redirection setting
2925  fRedirLog = saveRedirLog;
2926 
2927  // Restore the monitor
2928  fCurrentMonitor = savedMonitor;
2929 
2931 
2932  PDB(kCollect, 3)
2933  Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2934 
2935  return cnt;
2936 }
2937 
2938 ////////////////////////////////////////////////////////////////////////////////
2939 /// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2940 /// them. Returns the number of new workers found, or <0 on errors.
2941 
2943 {
2944  // Requests for worker updates
2945  Int_t dummy = 0;
2946  TList *reqWorkers = new TList();
2947  reqWorkers->SetOwner(kFALSE);
2948 
2949  if (!TestBit(TProof::kIsMaster)) {
2950  Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2951  return -1;
2952  }
2953  if (!gProofServ) {
2954  Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2955  return -1;
2956  }
2957 
2958  gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2959 
2960  // List of new workers only (TProofNodeInfo)
2961  TList *newWorkers = new TList();
2962  newWorkers->SetOwner(kTRUE);
2963 
2964  TIter next(reqWorkers);
2965  TProofNodeInfo *ni;
2966  TString fullOrd;
2967  while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2968 
2969  // Form the full ordinal
2970  fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2971 
2972  TIter nextInner(fSlaves);
2973  TSlave *sl;
2974  Bool_t found = kFALSE;
2975  while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
2976  if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
2977  found = kTRUE;
2978  break;
2979  }
2980  }
2981 
2982  if (found) delete ni;
2983  else {
2984  newWorkers->Add(ni);
2985  PDB(kGlobal, 1)
2986  Info("PollForNewWorkers", "New worker found: %s:%s",
2987  ni->GetNodeName().Data(), fullOrd.Data());
2988  }
2989  }
2990 
2991  delete reqWorkers; // not owner
2992 
2993  Int_t nNewWorkers = newWorkers->GetEntries();
2994 
2995  // Add the new workers
2996  if (nNewWorkers > 0) {
2997  PDB(kGlobal, 1)
2998  Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
2999  Int_t rv = AddWorkers(newWorkers);
3000  if (rv < 0) {
3001  Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3002  return -1;
3003  }
3004  // Don't delete newWorkers: AddWorkers() will do that
3005  }
3006  else {
3007  PDB(kGlobal, 2)
3008  Info("PollForNewWorkers", "No new worker found");
3009  delete newWorkers;
3010  }
3011 
3012  return nNewWorkers;
3013 }
3014 
3015 ////////////////////////////////////////////////////////////////////////////////
3016 /// Remove links to objects in list 'ol' from gDirectory
3017 
3019 {
3020  if (ol) {
3021  TIter nxo(ol);
3022  TObject *o = 0;
3023  while ((o = nxo()))
3024  gDirectory->RecursiveRemove(o);
3025  }
3026 }
3027 
3028 ////////////////////////////////////////////////////////////////////////////////
3029 /// Collect and analyze available input from socket s.
3030 /// Returns 0 on success, -1 if any failure occurs.
3031 
3033 {
3034  TMessage *mess;
3035 
3036  Int_t recvrc = 0;
3037  if ((recvrc = s->Recv(mess)) < 0) {
3038  PDB(kCollect,2)
3039  Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3040  Bool_t bad = kTRUE;
3041  if (recvrc == -5) {
3042  // Broken connection: try reconnection
3044  if (s->Reconnect() == 0) {
3046  bad = kFALSE;
3047  }
3048  }
3049  if (bad)
3050  MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3051  // Ignore this wake up
3052  return -1;
3053  }
3054  if (!mess) {
3055  // we get here in case the remote server died
3056  MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3057  return -1;
3058  }
3059  Int_t rc = 0;
3060 
3061  Int_t what = mess->What();
3062  TSlave *sl = FindSlave(s);
3063  rc = HandleInputMessage(sl, mess, deactonfail);
3064  if (rc == 1 && (endtype >= 0) && (what != endtype))
3065  // This message was for the base monitor in recursive case
3066  rc = 2;
3067 
3068  // We are done successfully
3069  return rc;
3070 }
3071 
3072 ////////////////////////////////////////////////////////////////////////////////
3073 /// Analyze the received message.
3074 /// Returns 0 on success (1 if this the last message from this socket), -1 if
3075 /// any failure occurs.
3076 
3078 {
3079  char str[512];
3080  TObject *obj;
3081  Int_t rc = 0;
3082 
3083  if (!mess || !sl) {
3084  Warning("HandleInputMessage", "given an empty message or undefined worker");
3085  return -1;
3086  }
3087  Bool_t delete_mess = kTRUE;
3088  TSocket *s = sl->GetSocket();
3089  if (!s) {
3090  Warning("HandleInputMessage", "worker socket is undefined");
3091  return -1;
3092  }
3093 
3094  // The message type
3095  Int_t what = mess->What();
3096 
3097  PDB(kCollect,3)
3098  Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3099 
3100  switch (what) {
3101 
3102  case kMESS_OK:
3103  // Add the message to the list
3104  fRecvMessages->Add(mess);
3105  delete_mess = kFALSE;
3106  break;
3107 
3108  case kMESS_OBJECT:
3109  if (fPlayer) fPlayer->HandleRecvHisto(mess);
3110  break;
3111 
3112  case kPROOF_FATAL:
3113  { TString msg;
3114  if ((mess->BufferSize() > mess->Length()))
3115  (*mess) >> msg;
3116  if (msg.IsNull()) {
3117  MarkBad(s, "received kPROOF_FATAL");
3118  } else {
3119  MarkBad(s, msg);
3120  }
3121  }
3122  if (fProgressDialogStarted) {
3123  // Finalize the progress dialog
3124  Emit("StopProcess(Bool_t)", kTRUE);
3125  }
3126  break;
3127 
3128  case kPROOF_STOP:
3129  // Stop collection from this worker
3130  Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3131  sl->GetOrdinal());
3132  rc = 1;
3133  break;
3134 
3135  case kPROOF_GETTREEHEADER:
3136  // Add the message to the list
3137  fRecvMessages->Add(mess);
3138  delete_mess = kFALSE;
3139  rc = 1;
3140  break;
3141 
3142  case kPROOF_TOUCH:
3143  // send a request for touching the remote admin file
3144  {
3145  sl->Touch();
3146  }
3147  break;
3148 
3149  case kPROOF_GETOBJECT:
3150  // send slave object it asks for
3151  mess->ReadString(str, sizeof(str));
3152  obj = gDirectory->Get(str);
3153  if (obj)
3154  s->SendObject(obj);
3155  else
3156  s->Send(kMESS_NOTOK);
3157  break;
3158 
3159  case kPROOF_GETPACKET:
3160  {
3161  PDB(kGlobal,2)
3162  Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3163  TDSetElement *elem = 0;
3164  elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3165 
3166  if (elem != (TDSetElement*) -1) {
3167  TMessage answ(kPROOF_GETPACKET);
3168  answ << elem;
3169  s->Send(answ);
3170 
3171  while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3172  TPair *p = (TPair*) fWaitingSlaves->First();
3173  s = (TSocket*) p->Key();
3174  TMessage *m = (TMessage*) p->Value();
3175 
3176  elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3177  if (elem != (TDSetElement*) -1) {
3179  a << elem;
3180  s->Send(a);
3181  // remove has to happen via Links because TPair does not have
3182  // a Compare() function and therefore RemoveFirst() and
3183  // Remove(TObject*) do not work
3185  delete p;
3186  delete m;
3187  } else {
3188  break;
3189  }
3190  }
3191  } else {
3192  if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3193  fWaitingSlaves->Add(new TPair(s, mess));
3194  delete_mess = kFALSE;
3195  }
3196  }
3197  break;
3198 
3199  case kPROOF_LOGFILE:
3200  {
3201  Int_t size;
3202  (*mess) >> size;
3203  PDB(kGlobal,2)
3204  Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3205  RecvLogFile(s, size);
3206  }
3207  break;
3208 
3209  case kPROOF_LOGDONE:
3210  (*mess) >> sl->fStatus >> sl->fParallel;
3211  PDB(kCollect,2)
3212  Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3213  sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3214  if (sl->fStatus != 0) {
3215  // Return last nonzero status
3216  fStatus = sl->fStatus;
3217  // Deactivate the worker, if required
3218  if (deactonfail) DeactivateWorker(sl->fOrdinal);
3219  }
3220  // Remove from the workers-ready list
3223  fWrksOutputReady->Remove(sl);
3224  }
3225  rc = 1;
3226  break;
3227 
3228  case kPROOF_GETSTATS:
3229  {
3230  (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3231  >> sl->fWorkDir >> sl->fProofWorkDir;
3232  PDB(kCollect,2)
3233  Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3234  TString img;
3235  if ((mess->BufferSize() > mess->Length()))
3236  (*mess) >> img;
3237  // Set image
3238  if (img.IsNull()) {
3239  if (sl->fImage.IsNull())
3240  sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3241  sl->fProofWorkDir.Data());
3242  } else {
3243  sl->fImage = img;
3244  }
3245  PDB(kGlobal,2)
3246  Info("HandleInputMessage",
3247  "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3248 
3249  fBytesRead += sl->fBytesRead;
3250  fRealTime += sl->fRealTime;
3251  fCpuTime += sl->fCpuTime;
3252  rc = 1;
3253  }
3254  break;
3255 
3256  case kPROOF_GETPARALLEL:
3257  {
3258  Bool_t async = kFALSE;
3259  (*mess) >> sl->fParallel;
3260  if ((mess->BufferSize() > mess->Length()))
3261  (*mess) >> async;
3262  rc = (async) ? 0 : 1;
3263  }
3264  break;
3265 
3266  case kPROOF_CHECKFILE:
3267  { // New servers (>= 5.22) send the status
3268  if ((mess->BufferSize() > mess->Length())) {
3269  (*mess) >> fCheckFileStatus;
3270  } else {
3271  // Form old servers this meant success (failure was signaled with the
3272  // dangerous kPROOF_FATAL)
3273  fCheckFileStatus = 1;
3274  }
3275  rc = 1;
3276  }
3277  break;
3278 
3279  case kPROOF_SENDFILE:
3280  { // New server: signals ending of sendfile operation
3281  rc = 1;
3282  }
3283  break;
3284 
3285  case kPROOF_PACKAGE_LIST:
3286  {
3287  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3288  Int_t type = 0;
3289  (*mess) >> type;
3290  switch (type) {
3294  if (fEnabledPackages) {
3296  } else {
3297  Error("HandleInputMessage",
3298  "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3299  }
3300  break;
3301  case TProof::kListPackages:
3304  if (fAvailablePackages) {
3306  } else {
3307  Error("HandleInputMessage",
3308  "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3309  }
3310  break;
3311  default:
3312  Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3313  }
3314  }
3315  break;
3316 
3317  case kPROOF_SENDOUTPUT:
3318  {
3319  // We start measuring the merging time
3320  fPlayer->SetMerging();
3321 
3322  // Worker is ready to send output: make sure the relevant bit is reset
3324  PDB(kGlobal,2)
3325  Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3326  // Create the list if not yet done
3327  if (!fWrksOutputReady) {
3328  fWrksOutputReady = new TList;
3330  }
3331  fWrksOutputReady->Add(sl);
3332  }
3333  break;
3334 
3335  case kPROOF_OUTPUTOBJECT:
3336  {
3337  // We start measuring the merging time
3338  fPlayer->SetMerging();
3339 
3340  PDB(kGlobal,2)
3341  Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3342  Int_t type = 0;
3343  const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3345  Info("HandleInputMessage", "finalization on %s started ...", prefix);
3347  }
3348 
3349  while ((mess->BufferSize() > mess->Length())) {
3350  (*mess) >> type;
3351  // If a query result header, add it to the player list
3352  if (fPlayer) {
3353  if (type == 0) {
3354  // Retrieve query result instance (output list not filled)
3355  TQueryResult *pq =
3357  if (pq) {
3358  // Add query to the result list in TProofPlayer
3359  fPlayer->AddQueryResult(pq);
3360  fPlayer->SetCurrentQuery(pq);
3361  // And clear the output list, as we start merging a new set of results
3362  if (fPlayer->GetOutputList())
3363  fPlayer->GetOutputList()->Clear();
3364  // Add the unique query tag as TNamed object to the input list
3365  // so that it is available in TSelectors for monitoring
3366  TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3367  if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3368  fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3369  fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3370  } else {
3371  Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3372  }
3373  } else if (type > 0) {
3374  // Read object
3375  TObject *o = mess->ReadObject(TObject::Class());
3376  // Increment counter on the client side
3378  TString msg;
3379  Bool_t changed = kFALSE;
3380  msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3381  if (gProofServ) {
3383  } else if (IsTty() || changed) {
3384  fprintf(stderr, "%s\r", msg.Data());
3385  }
3386  // Add or merge it
3387  if ((fPlayer->AddOutputObject(o) == 1)) {
3388  // Remove the object if it has been merged
3389  SafeDelete(o);
3390  }
3391  if (type > 1) {
3392  // Update the merger progress info
3394  if (TestBit(TProof::kIsClient) && !IsLite()) {
3395  // In PROOFLite this has to be done once only in TProofLite::Process
3397  if (pq) {
3399  // Add input objects (do not override remote settings, if any)
3400  TObject *xo = 0;
3401  TIter nxin(fPlayer->GetInputList());
3402  // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3403  if (!pq->GetInputList()) pq->SetInputList(new TList());
3404  while ((xo = nxin()))
3405  if (!pq->GetInputList()->FindObject(xo->GetName()))
3406  pq->AddInput(xo->Clone());
3407  // If the last object, notify the GUI that the result arrived
3408  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3409  }
3410  // Processing is over
3411  UpdateDialog();
3412  }
3413  }
3414  }
3415  } else {
3416  Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3417  }
3418  }
3419  }
3420  break;
3421 
3422  case kPROOF_OUTPUTLIST:
3423  {
3424  // We start measuring the merging time
3425  fPlayer->SetMerging();
3426 
3427  PDB(kGlobal,2)
3428  Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3429  TList *out = 0;
3430  if (fPlayer) {
3431  if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3432  out = (TList *) mess->ReadObject(TList::Class());
3433  } else {
3434  TQueryResult *pq =
3436  if (pq) {
3437  // Add query to the result list in TProofPlayer
3438  fPlayer->AddQueryResult(pq);
3439  fPlayer->SetCurrentQuery(pq);
3440  // To avoid accidental cleanups from anywhere else
3441  // remove objects from gDirectory and clone the list
3442  out = pq->GetOutputList();
3443  CleanGDirectory(out);
3444  out = (TList *) out->Clone();
3445  // Notify the GUI that the result arrived
3446  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3447  } else {
3448  PDB(kGlobal,2)
3449  Info("HandleInputMessage",
3450  "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3451  }
3452  }
3453  if (out) {
3454  out->SetOwner();
3455  fPlayer->AddOutput(out); // Incorporate the list
3456  SafeDelete(out);
3457  } else {
3458  PDB(kGlobal,2)
3459  Info("HandleInputMessage",
3460  "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3461  }
3462  } else {
3463  Warning("HandleInputMessage",
3464  "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3465  }
3466  // On clients at this point processing is over
3467  if (TestBit(TProof::kIsClient) && !IsLite())
3468  UpdateDialog();
3469  }
3470  break;
3471 
3472  case kPROOF_QUERYLIST:
3473  {
3474  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3475  (*mess) >> fOtherQueries >> fDrawQueries;
3476  if (fQueries) {
3477  fQueries->Delete();
3478  delete fQueries;
3479  fQueries = 0;
3480  }
3481  fQueries = (TList *) mess->ReadObject(TList::Class());
3482  }
3483  break;
3484 
3485  case kPROOF_RETRIEVE:
3486  {
3487  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3488  TQueryResult *pq =
3490  if (pq && fPlayer) {
3491  fPlayer->AddQueryResult(pq);
3492  // Notify the GUI that the result arrived
3493  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3494  } else {
3495  PDB(kGlobal,2)
3496  Info("HandleInputMessage",
3497  "kPROOF_RETRIEVE: query result missing or player undefined");
3498  }
3499  }
3500  break;
3501 
3502  case kPROOF_MAXQUERIES:
3503  {
3504  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3505  Int_t max = 0;
3506 
3507  (*mess) >> max;
3508  Printf("Number of queries fully kept remotely: %d", max);
3509  }
3510  break;
3511 
3512  case kPROOF_SERVERSTARTED:
3513  {
3514  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3515 
3516  UInt_t tot = 0, done = 0;
3517  TString action;
3518  Bool_t st = kTRUE;
3519 
3520  (*mess) >> action >> tot >> done >> st;
3521 
3522  if (TestBit(TProof::kIsClient)) {
3523  if (tot) {
3524  TString type = (action.Contains("submas")) ? "submasters"
3525  : "workers";
3526  Int_t frac = (Int_t) (done*100.)/tot;
3527  char msg[512] = {0};
3528  if (frac >= 100) {
3529  snprintf(msg, 512, "%s: OK (%d %s) \n",
3530  action.Data(),tot, type.Data());
3531  } else {
3532  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3533  action.Data(), done, tot, frac);
3534  }
3535  if (fSync)
3536  fprintf(stderr,"%s", msg);
3537  else
3538  NotifyLogMsg(msg, 0);
3539  }
3540  // Notify GUIs
3541  StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3542  } else {
3543 
3544  // Just send the message one level up
3546  m << action << tot << done << st;
3547  gProofServ->GetSocket()->Send(m);
3548  }
3549  }
3550  break;
3551 
3552  case kPROOF_DATASET_STATUS:
3553  {
3554  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3555 
3556  UInt_t tot = 0, done = 0;
3557  TString action;
3558  Bool_t st = kTRUE;
3559 
3560  (*mess) >> action >> tot >> done >> st;
3561 
3562  if (TestBit(TProof::kIsClient)) {
3563  if (tot) {
3564  TString type = "files";
3565  Int_t frac = (Int_t) (done*100.)/tot;
3566  char msg[512] = {0};
3567  if (frac >= 100) {
3568  snprintf(msg, 512, "%s: OK (%d %s) \n",
3569  action.Data(),tot, type.Data());
3570  } else {
3571  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3572  action.Data(), done, tot, frac);
3573  }
3574  if (fSync)
3575  fprintf(stderr,"%s", msg);
3576  else
3577  NotifyLogMsg(msg, 0);
3578  }
3579  // Notify GUIs
3580  DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3581  } else {
3582 
3583  // Just send the message one level up
3585  m << action << tot << done << st;
3586  gProofServ->GetSocket()->Send(m);
3587  }
3588  }
3589  break;
3590 
3591  case kPROOF_STARTPROCESS:
3592  {
3593  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3594 
3595  // For Proof-Lite this variable is the number of workers and is set
3596  // by the player
3597  if (!IsLite()) {
3598  fNotIdle = 1;
3599  fIsWaiting = kFALSE;
3600  }
3601 
3602  // Redirect the output, if needed
3603  fRedirLog = (fSync) ? fRedirLog : kTRUE;
3604 
3605  // The signal is used on masters by XrdProofdProtocol to catch
3606  // the start of processing; on clients it allows to update the
3607  // progress dialog
3608  if (!TestBit(TProof::kIsMaster)) {
3609 
3610  // This is the end of preparation
3611  fQuerySTW.Stop();
3613  PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3614 
3615  TString selec;
3616  Int_t dsz = -1;
3617  Long64_t first = -1, nent = -1;
3618  (*mess) >> selec >> dsz >> first >> nent;
3619  // Start or reset the progress dialog
3620  if (!gROOT->IsBatch()) {
3621  if (fProgressDialog &&
3623  if (!fProgressDialogStarted) {
3624  fProgressDialog->ExecPlugin(5, this,
3625  selec.Data(), dsz, first, nent);
3627  } else {
3628  ResetProgressDialog(selec, dsz, first, nent);
3629  }
3630  }
3632  }
3633  }
3634  }
3635  break;
3636 
3637  case kPROOF_ENDINIT:
3638  {
3639  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3640 
3641  if (TestBit(TProof::kIsMaster)) {
3642  if (fPlayer)
3643  fPlayer->SetInitTime();
3644  }
3645  }
3646  break;
3647 
3648  case kPROOF_SETIDLE:
3649  {
3650  PDB(kGlobal,2)
3651  Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3652 
3653  // The session is idle
3654  if (IsLite()) {
3655  if (fNotIdle > 0) {
3656  fNotIdle--;
3657  PDB(kGlobal,2)
3658  Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3659  } else {
3660  Warning("HandleInputMessage",
3661  "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3662  sl->GetOrdinal());
3663  }
3664  } else {
3665  fNotIdle = 0;
3666  // Check if the query has been enqueued
3667  if ((mess->BufferSize() > mess->Length()))
3668  (*mess) >> fIsWaiting;
3669  }
3670  }
3671  break;
3672 
3673  case kPROOF_QUERYSUBMITTED:
3674  {
3675  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3676 
3677  // We have received the sequential number
3678  (*mess) >> fSeqNum;
3679  Bool_t sync = fSync;
3680  if ((mess->BufferSize() > mess->Length()))
3681  (*mess) >> sync;
3682  if (sync != fSync && fSync) {
3683  // The server required to switch to asynchronous mode
3684  Activate();
3685  fSync = kFALSE;
3686  }
3687  DisableGoAsyn();
3688  // Check if the query has been enqueued
3689  fIsWaiting = kTRUE;
3690  // For Proof-Lite this variable is the number of workers and is set by the player
3691  if (!IsLite())
3692  fNotIdle = 1;
3693 
3694  rc = 1;
3695  }
3696  break;
3697 
3698  case kPROOF_SESSIONTAG:
3699  {
3700  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3701 
3702  // We have received the unique tag and save it as name of this object
3703  TString stag;
3704  (*mess) >> stag;
3705  SetName(stag);
3706  // In the TSlave object
3707  sl->SetSessionTag(stag);
3708  // Server may have also sent the group
3709  if ((mess->BufferSize() > mess->Length()))
3710  (*mess) >> fGroup;
3711  // Server may have also sent the user
3712  if ((mess->BufferSize() > mess->Length())) {
3713  TString usr;
3714  (*mess) >> usr;
3715  if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3716  }
3717  }
3718  break;
3719 
3720  case kPROOF_FEEDBACK:
3721  {
3722  PDB(kGlobal,2)
3723  Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3724  TList *out = (TList *) mess->ReadObject(TList::Class());
3725  out->SetOwner();
3726  if (fPlayer)
3727  fPlayer->StoreFeedback(sl, out); // Adopts the list
3728  else
3729  // Not yet ready: stop collect asap
3730  rc = 1;
3731  }
3732  break;
3733 
3734  case kPROOF_AUTOBIN:
3735  {
3736  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3737 
3738  TString name;
3739  Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3740 
3741  (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3742 
3743  if (fPlayer) fPlayer->UpdateAutoBin(name,xmin,xmax,ymin,ymax,zmin,zmax);
3744 
3745  TMessage answ(kPROOF_AUTOBIN);
3746 
3747  answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3748 
3749  s->Send(answ);
3750  }
3751  break;
3752 
3753  case kPROOF_PROGRESS:
3754  {
3755  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3756 
3757  if (GetRemoteProtocol() > 25) {
3758  // New format
3759  TProofProgressInfo *pi = 0;
3760  (*mess) >> pi;
3761  fPlayer->Progress(sl,pi);
3762  } else if (GetRemoteProtocol() > 11) {
3763  Long64_t total, processed, bytesread;
3764  Float_t initTime, procTime, evtrti, mbrti;
3765  (*mess) >> total >> processed >> bytesread
3766  >> initTime >> procTime
3767  >> evtrti >> mbrti;
3768  if (fPlayer)
3769  fPlayer->Progress(sl, total, processed, bytesread,
3770  initTime, procTime, evtrti, mbrti);
3771 
3772  } else {
3773  // Old format
3774  Long64_t total, processed;
3775  (*mess) >> total >> processed;
3776  if (fPlayer)
3777  fPlayer->Progress(sl, total, processed);
3778  }
3779  }
3780  break;
3781 
3782  case kPROOF_STOPPROCESS:
3783  {
3784  // This message is sent from a worker that finished processing.
3785  // We determine whether it was asked to finish by the
3786  // packetizer or stopped during processing a packet
3787  // (by TProof::RemoveWorkers() or by an external signal).
3788  // In the later case call packetizer->MarkBad.
3789  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3790 
3791  Long64_t events = 0;
3792  Bool_t abort = kFALSE;
3793  TProofProgressStatus *status = 0;
3794 
3795  if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3796  (*mess) >> status >> abort;
3797  } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3798  (*mess) >> events >> abort;
3799  } else {
3800  (*mess) >> events;
3801  }
3802  if (fPlayer) {
3803  if (fProtocol > 18) {
3804  TList *listOfMissingFiles = 0;
3805  if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3806  listOfMissingFiles = new TList();
3807  listOfMissingFiles->SetName("MissingFiles");
3808  if (fPlayer)
3809  fPlayer->AddOutputObject(listOfMissingFiles);
3810  }
3811  if (fPlayer->GetPacketizer()) {
3812  Int_t ret =
3813  fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3814  if (ret > 0)
3815  fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3816  // This object is now owned by the packetizer
3817  status = 0;
3818  }
3819  if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3820  } else {
3821  fPlayer->AddEventsProcessed(events);
3822  }
3823  }
3824  SafeDelete(status);
3825  if (!TestBit(TProof::kIsMaster))
3826  Emit("StopProcess(Bool_t)", abort);
3827  break;
3828  }
3829 
3830  case kPROOF_SUBMERGER:
3831  {
3832  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3833  HandleSubmerger(mess, sl);
3834  }
3835  break;
3836 
3837  case kPROOF_GETSLAVEINFO:
3838  {
3839  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3840 
3841  Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3842  Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3843  TList* tmpinfo = 0;
3844  (*mess) >> tmpinfo;
3845  if (tmpinfo == 0) {
3846  Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3847  } else {
3848  tmpinfo->SetOwner(kFALSE);
3849  Int_t nentries = tmpinfo->GetSize();
3850  for (Int_t i=0; i<nentries; i++) {
3851  TSlaveInfo* slinfo =
3852  dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3853  if (slinfo) {
3854  // If PROOF-Lite
3855  if (IsLite()) slinfo->fHostName = gSystem->HostName();
3856  // Check if we have already a instance for this worker
3857  TIter nxw(fSlaveInfo);
3858  TSlaveInfo *ourwi = 0;
3859  while ((ourwi = (TSlaveInfo *)nxw())) {
3860  if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3861  ourwi->SetSysInfo(slinfo->GetSysInfo());
3862  ourwi->fHostName = slinfo->GetName();
3863  if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3864  ourwi->fDataDir = slinfo->GetDataDir();
3865  break;
3866  }
3867  }
3868  if (!ourwi) {
3869  fSlaveInfo->Add(slinfo);
3870  } else {
3871  slinfo = ourwi;
3872  }
3873  if (slinfo->fStatus != TSlaveInfo::kBad) {
3874  if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3875  if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3876  }
3877  if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3878  slinfo->fMsd = sl->GetMsd();
3879  }
3880  }
3881  delete tmpinfo;
3882  rc = 1;
3883  }
3884  }
3885  break;
3886 
3887  case kPROOF_VALIDATE_DSET:
3888  {
3889  PDB(kGlobal,2)
3890  Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3891  TDSet* dset = 0;
3892  (*mess) >> dset;
3893  if (!fDSet)
3894  Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3895  else
3896  fDSet->Validate(dset);
3897  delete dset;
3898  }
3899  break;
3900 
3901  case kPROOF_DATA_READY:
3902  {
3903  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3904  Bool_t dataready = kFALSE;
3905  Long64_t totalbytes, bytesready;
3906  (*mess) >> dataready >> totalbytes >> bytesready;
3907  fTotalBytes += totalbytes;
3908  fBytesReady += bytesready;
3909  if (dataready == kFALSE) fDataReady = dataready;
3910  }
3911  break;
3912 
3913  case kPROOF_PING:
3914  // do nothing (ping is already acknowledged)
3915  break;
3916 
3917  case kPROOF_MESSAGE:
3918  {
3919  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3920 
3921  // We have received the unique tag and save it as name of this object
3922  TString msg;
3923  (*mess) >> msg;
3924  Bool_t lfeed = kTRUE;
3925  if ((mess->BufferSize() > mess->Length()))
3926  (*mess) >> lfeed;
3927 
3928  if (TestBit(TProof::kIsClient)) {
3929 
3930  if (fSync) {
3931  // Notify locally
3932  fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3933  } else {
3934  // Notify locally taking care of redirection, windows logs, ...
3935  NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3936  }
3937  } else {
3938 
3939  // The message is logged for debugging purposes.
3940  fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3941  if (gProofServ) {
3942  // We hide it during normal operations
3944 
3945  // And send the message one level up
3946  gProofServ->SendAsynMessage(msg, lfeed);
3947  }
3948  }
3949  }
3950  break;
3951 
3952  case kPROOF_VERSARCHCOMP:
3953  {
3954  TString vac;
3955  (*mess) >> vac;
3956  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3957  Int_t from = 0;
3958  TString vers, archcomp;
3959  if (vac.Tokenize(vers, from, "|"))
3960  vac.Tokenize(archcomp, from, "|");
3961  sl->SetArchCompiler(archcomp);
3962  vers.ReplaceAll(":","|");
3963  sl->SetROOTVersion(vers);
3964  }
3965  break;
3966 
3967  default:
3968  {
3969  Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3970  sl->GetOrdinal(), what);
3971  }
3972  break;
3973  }
3974 
3975  // Cleanup
3976  if (delete_mess)
3977  delete mess;
3978 
3979  // We are done successfully
3980  return rc;
3981 }
3982 
3983 ////////////////////////////////////////////////////////////////////////////////
3984 /// Process a message of type kPROOF_SUBMERGER
3985 
3987 {
3988  // Message sub-type
3989  Int_t type = 0;
3990  (*mess) >> type;
3991  TSocket *s = sl->GetSocket();
3992 
3993  switch (type) {
3994  case kOutputSent:
3995  {
3996  if (IsEndMaster()) {
3997  Int_t merger_id = -1;
3998  (*mess) >> merger_id;
3999 
4000  PDB(kSubmerger, 2)
4001  Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4002  sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4003 
4004  if (!fMergers || fMergers->GetSize() <= merger_id) {
4005  Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4006  break;
4007  }
4008  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4009  mi->SetMergedWorker();
4010  if (mi->AreAllWorkersMerged()) {
4011  mi->Deactivate();
4012  if (GetActiveMergersCount() == 0) {
4013  fMergers->Clear();
4014  delete fMergers;
4015  fMergersSet = kFALSE;
4016  fMergersCount = -1;
4017  fLastAssignedMerger = 0;
4018  PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4019  }
4020  }
4021  } else {
4022  PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4023  }
4024  }
4025  break;
4026 
4027  case kMergerDown:
4028  {
4029  Int_t merger_id = -1;
4030  (*mess) >> merger_id;
4031 
4032  PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4033 
4034  if (!fMergers || fMergers->GetSize() <= merger_id) {
4035  Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4036  break;
4037  }
4038 
4039  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4040  if (!mi->IsActive()) {
4041  break;
4042  } else {
4043  mi->Deactivate();
4044  }
4045 
4046  // Stop the invalid merger in the case it is still listening
4047  TMessage stop(kPROOF_SUBMERGER);
4048  stop << Int_t(kStopMerging);
4049  stop << 0;
4050  s->Send(stop);
4051 
4052  // Ask for results from merger (only original results from this node as worker are returned)
4053  AskForOutput(mi->GetMerger());
4054 
4055  // Ask for results from all workers assigned to this merger
4056  TIter nxo(mi->GetWorkers());
4057  TObject * o = 0;
4058  while ((o = nxo())) {
4059  AskForOutput((TSlave *)o);
4060  }
4061  PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4062  }
4063  break;
4064 
4065  case kOutputSize:
4066  {
4067  if (IsEndMaster()) {
4068  PDB(kSubmerger, 2)
4069  Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4070 
4071  const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4072  if (!fFinalizationRunning) {
4073  Info("HandleSubmerger", "finalization on %s started ...", prefix);
4075  }
4076 
4077  Int_t output_size = 0;
4078  Int_t merging_port = 0;
4079  (*mess) >> output_size >> merging_port;
4080 
4081  PDB(kSubmerger, 2) Info("HandleSubmerger",
4082  "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4083  sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4084  TString msg;
4085  if (!fMergersSet) {
4086 
4088 
4089  // First pass - setting number of mergers according to user or dynamically
4090  fMergersCount = -1; // No mergers used if not set by user
4091  TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4092  if (mc) fMergersCount = mc->GetVal(); // Value set by user
4093  TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4094  if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4095 
4096  // Mergers count specified by user but not valid
4097  if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4098  msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4099  prefix, fMergersCount, activeWorkers);
4100  if (gProofServ)
4102  else
4103  Printf("%s",msg.Data());
4104  fMergersCount = 0;
4105  }
4106  // Mergers count will be set dynamically
4107  if ((fMergersCount == 0) && (!fMergersByHost)) {
4108  if (activeWorkers > 1) {
4109  fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4110  if (activeWorkers / fMergersCount < 2)
4111  fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4112  }
4113  if (fMergersCount > 1)
4114  msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4115  prefix, fMergersCount, activeWorkers);
4116  else {
4117  msg.Form("%s: No mergers will be used for %d workers",
4118  prefix, activeWorkers);
4119  fMergersCount = -1;
4120  }
4121  if (gProofServ)
4123  else
4124  Printf("%s",msg.Data());
4125  } else if (fMergersByHost) {
4126  // We force mergers at host level to minimize network traffic
4127  if (activeWorkers > 1) {
4128  fMergersCount = 0;
4129  THashList hosts;
4130  TIter nxwk(fSlaves);
4131  TObject *wrk = 0;
4132  while ((wrk = nxwk())) {
4133  if (!hosts.FindObject(wrk->GetName())) {
4134  hosts.Add(new TObjString(wrk->GetName()));
4135  fMergersCount++;
4136  }
4137  }
4138  }
4139  if (fMergersCount > 1)
4140  msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4141  prefix, fMergersCount, activeWorkers);
4142  else {
4143  msg.Form("%s: No mergers will be used for %d workers",
4144  prefix, activeWorkers);
4145  fMergersCount = -1;
4146  }
4147  if (gProofServ)
4149  else
4150  Printf("%s",msg.Data());
4151  } else {
4152  msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4153  prefix, fMergersCount, activeWorkers);
4154  if (gProofServ)
4156  else
4157  Printf("%s",msg.Data());
4158  }
4159 
4160  // We started merging; we call it here because fMergersCount is still the original number
4161  // and can be saved internally
4163 
4164  // Update merger counters (new workers are not yet active)
4166 
4167  if (fMergersCount > 0) {
4168 
4169  fMergers = new TList();
4170  fLastAssignedMerger = 0;
4171  // Total number of workers, which will not act as mergers ('pure workers')
4172  fWorkersToMerge = (activeWorkers - fMergersCount);
4173  // Establish the first merger
4174  if (!CreateMerger(sl, merging_port)) {
4175  // Cannot establish first merger
4176  AskForOutput(sl);
4177  fWorkersToMerge--;
4178  fMergersCount--;
4179  }
4181  } else {
4182  AskForOutput(sl);
4183  }
4184  fMergersSet = kTRUE;
4185  } else {
4186  // Multiple pass
4187  if (fMergersCount == -1) {
4188  // No mergers. Workers send their outputs directly to master
4189  AskForOutput(sl);
4190  } else {
4191  if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4192  RedirectWorker(s, sl, output_size);
4193  fRedirectNext--;
4194  } else {
4195  Bool_t newMerger = kTRUE;
4196  if (fMergersByHost) {
4197  TIter nxmg(fMergers);
4198  TMergerInfo *mgi = 0;
4199  while ((mgi = (TMergerInfo *) nxmg())) {
4200  if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4201  newMerger = kFALSE;
4202  break;
4203  }
4204  }
4205  }
4206  if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4207  // Still not enough mergers established
4208  if (!CreateMerger(sl, merging_port)) {
4209  // Cannot establish a merger
4210  AskForOutput(sl);
4211  fWorkersToMerge--;
4212  fMergersCount--;
4213  }
4214  } else
4215  RedirectWorker(s, sl, output_size);
4216  }
4217  }
4218  }
4219  } else {
4220  Error("HandleSubMerger","kOutputSize received not on endmaster!");
4221  }
4222  }
4223  break;
4224  }
4225 }
4226 
4227 ////////////////////////////////////////////////////////////////////////////////
4228 /// Redirect output of worker sl to some merger
4229 
4230 void TProof::RedirectWorker(TSocket *s, TSlave * sl, Int_t output_size)
4231 {
4232  Int_t merger_id = -1;
4233 
4234  if (fMergersByHost) {
4235  for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4236  TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4237  if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4238  merger_id = i;
4239  break;
4240  }
4241  }
4242  } else {
4243  merger_id = FindNextFreeMerger();
4244  }
4245 
4246  if (merger_id == -1) {
4247  // No free merger (probably it had crashed before)
4248  AskForOutput(sl);
4249  } else {
4250  TMessage sendoutput(kPROOF_SUBMERGER);
4251  sendoutput << Int_t(kSendOutput);
4252  PDB(kSubmerger, 2)
4253  Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4254 
4255  PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4256  if (!fMergers || fMergers->GetSize() <= merger_id) {
4257  Error("RedirectWorker", "#%d not in list ", merger_id);
4258  return;
4259  }
4260  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4261 
4262  TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4263  sendoutput << merger_id;
4264  sendoutput << hname;
4265  sendoutput << mi->GetPort();
4266  s->Send(sendoutput);
4267  mi->AddMergedObjects(output_size);
4268  mi->AddWorker(sl);
4269  }
4270 }
4271 
4272 ////////////////////////////////////////////////////////////////////////////////
4273 /// Return a merger, which is both active and still accepts some workers to be
4274 /// assigned to it. It works on the 'round-robin' basis.
4275 
4277 {
4278  while (fLastAssignedMerger < fMergers->GetSize() &&
4279  (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4280  ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4282  }
4283 
4284  if (fLastAssignedMerger == fMergers->GetSize()) {
4285  fLastAssignedMerger = 0;
4286  } else {
4287  return fLastAssignedMerger++;
4288  }
4289 
4290  while (fLastAssignedMerger < fMergers->GetSize() &&
4291  (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4292  ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4294  }
4295 
4296  if (fLastAssignedMerger == fMergers->GetSize()) {
4297  return -1;
4298  } else {
4299  return fLastAssignedMerger++;
4300  }
4301 }
4302 
4303 ////////////////////////////////////////////////////////////////////////////////
4304 /// Master asks for output from worker sl
4305 
4307 {
4308  TMessage sendoutput(kPROOF_SUBMERGER);
4309  sendoutput << Int_t(kSendOutput);
4310 
4311  PDB(kSubmerger, 2) Info("AskForOutput",
4312  "worker %s was asked to send its output to master",
4313  sl->GetOrdinal());
4314 
4315  sendoutput << -1;
4316  sendoutput << TString("master");
4317  sendoutput << -1;
4318  sl->GetSocket()->Send(sendoutput);
4319  if (IsLite()) fMergePrg.IncreaseNWrks();
4320 }
4321 
4322 ////////////////////////////////////////////////////////////////////////////////
4323 /// Final update of the progress dialog
4324 
4326 {
4327  if (!fPlayer) return;
4328 
4329  // Handle abort ...
4331  if (fSync)
4332  Info("UpdateDialog",
4333  "processing was aborted - %lld events processed",
4335 
4336  if (GetRemoteProtocol() > 11) {
4337  // New format
4338  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4339  } else {
4341  }
4342  Emit("StopProcess(Bool_t)", kTRUE);
4343  }
4344 
4345  // Handle stop ...
4347  if (fSync)
4348  Info("UpdateDialog",
4349  "processing was stopped - %lld events processed",
4351 
4352  if (GetRemoteProtocol() > 25) {
4353  // New format
4354  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4355  } else if (GetRemoteProtocol() > 11) {
4356  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4357  } else {
4359  }
4360  Emit("StopProcess(Bool_t)", kFALSE);
4361  }
4362 
4363  // Final update of the dialog box
4364  if (GetRemoteProtocol() > 25) {
4365  // New format
4366  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4367  10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4368  (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4369  } else if (GetRemoteProtocol() > 11) {
4370  // New format
4371  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4372  7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4373  (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4374  } else {
4375  EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4376  }
4377 }
4378 
4379 ////////////////////////////////////////////////////////////////////////////////
4380 /// Activate the a-sync input handler.
4381 
4383 {
4384  TIter next(fSlaves);
4385  TSlave *sl;
4386 
4387  while ((sl = (TSlave*) next()))
4388  if (sl->GetInputHandler())
4389  sl->GetInputHandler()->Add();
4390 }
4391 
4392 ////////////////////////////////////////////////////////////////////////////////
4393 /// De-activate a-sync input handler.
4394 
4396 {
4397  TIter next(fSlaves);
4398  TSlave *sl;
4399 
4400  while ((sl = (TSlave*) next()))
4401  if (sl->GetInputHandler())
4402  sl->GetInputHandler()->Remove();
4403 }
4404 
4405 ////////////////////////////////////////////////////////////////////////////////
4406 /// Get the active mergers count
4407 
4409 {
4410  if (!fMergers) return 0;
4411 
4412  Int_t active_mergers = 0;
4413 
4414  TIter mergers(fMergers);
4415  TMergerInfo *mi = 0;
4416  while ((mi = (TMergerInfo *)mergers())) {
4417  if (mi->IsActive()) active_mergers++;
4418  }
4419 
4420  return active_mergers;
4421 }
4422 
4423 ////////////////////////////////////////////////////////////////////////////////
4424 /// Create a new merger
4425 
4427 {
4428  PDB(kSubmerger, 2)
4429  Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4430 
4431  PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4432 
4433  if (port <= 0) {
4434  PDB(kSubmerger,2)
4435  Info("CreateMerger", "cannot create merger on port %d - exit", port);
4436  return kFALSE;
4437  }
4438 
4439  Int_t workers = -1;
4440  if (!fMergersByHost) {
4441  Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4442  // Number of pure workers, which are not simply divisible by mergers
4443  Int_t rest = fWorkersToMerge % mergersToCreate;
4444  // We add one more worker for each of the first 'rest' mergers being established
4445  if (rest > 0 && fMergers->GetSize() < rest) {
4446  rest = 1;
4447  } else {
4448  rest = 0;
4449  }
4450  workers = (fWorkersToMerge / mergersToCreate) + rest;
4451  } else {
4452  Int_t workersOnHost = 0;
4453  for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4454  if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4455  }
4456  workers = workersOnHost - 1;
4457  }
4458 
4459  TString msg;
4460  msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4461 
4462  if (gProofServ) {
4464  } else {
4465  Printf("%s",msg.Data());
4466  }
4467  TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4468 
4469  TMessage bemerger(kPROOF_SUBMERGER);
4470  bemerger << Int_t(kBeMerger);
4471  bemerger << fMergers->GetSize();
4472  bemerger << workers;
4473  sl->GetSocket()->Send(bemerger);
4474 
4475  PDB(kSubmerger,2) Info("CreateMerger",
4476  "merger #%d (port: %d) for %d workers started",
4477  fMergers->GetSize(), port, workers);
4478 
4479  fMergers->Add(merger);
4480  fWorkersToMerge = fWorkersToMerge - workers;
4481 
4482  fRedirectNext = workers / 2;
4483 
4484  PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4485  return kTRUE;
4486 }
4487 
4488 ////////////////////////////////////////////////////////////////////////////////
4489 /// Add a bad slave server to the bad slave list and remove it from
4490 /// the active list and from the two monitor objects. Assume that the work
4491 /// done by this worker was lost and ask packerizer to reassign it.
4492 
4493 void TProof::MarkBad(TSlave *wrk, const char *reason)
4494 {
4495  std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4496 
4497  // We may have been invalidated in the meanwhile: nothing to do in such a case
4498  if (!IsValid()) return;
4499 
4500  if (!wrk) {
4501  Error("MarkBad", "worker instance undefined: protocol error? ");
4502  return;
4503  }
4504 
4505  // Local URL
4506  static TString thisurl;
4507  if (thisurl.IsNull()) {
4508  if (IsMaster()) {
4509  Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4510  thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4511  if (port > 0) thisurl += TString::Format(":%d", port);
4512  } else {
4513  thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4514  }
4515  }
4516 
4517  if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4518  // Message for notification
4519  const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4520  TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4521  TString msg;
4522  msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4523  src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4524  (reason && strlen(reason)) ? reason : "unknown");
4525  Info("MarkBad", "%s", msg.Data());
4526  // Notify one level up, if the case
4527  // Add some hint for diagnostics
4528  if (gProofServ) {
4529  msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4530  wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4531  } else {
4532  msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4533  }
4534  msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4535  msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4536  msg += TString::Format(" +++\n");
4537  if (gProofServ) {
4538  msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4539  "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4541  } else {
4542  msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4543  "Display(\"*\")\n\n", thisurl.Data());
4544  Printf("%s", msg.Data());
4545  }
4546  } else if (reason) {
4547  if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4548  Info("MarkBad", "worker %s at %s:%d asked to terminate",
4549  wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4550  }
4551  }
4552 
4553  if (IsMaster() && reason) {
4554  if (strcmp(reason, kPROOF_TerminateWorker)) {
4555  // if the reason was not a planned termination
4556  TList *listOfMissingFiles = 0;
4557  if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4558  listOfMissingFiles = new TList();
4559  listOfMissingFiles->SetName("MissingFiles");
4560  if (fPlayer)
4561  fPlayer->AddOutputObject(listOfMissingFiles);
4562  }
4563  // If a query is being processed, assume that the work done by
4564  // the worker was lost and needs to be reassigned.
4565  TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4566  if (packetizer) {
4567  // the worker was lost so do resubmit the packets
4568  packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4569  }
4570  } else {
4571  // Tell the coordinator that we are gone
4572  if (gProofServ) {
4573  TString ord(wrk->GetOrdinal());
4574  Int_t id = ord.Last('.');
4575  if (id != kNPOS) ord.Remove(0, id+1);
4576  gProofServ->ReleaseWorker(ord.Data());
4577  }
4578  }
4579  } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4580  // We are invalid after this
4581  fValid = kFALSE;
4582  }
4583 
4584  fActiveSlaves->Remove(wrk);
4585  FindUniqueSlaves();
4586 
4587  fAllMonitor->Remove(wrk->GetSocket());
4588  fActiveMonitor->Remove(wrk->GetSocket());
4589 
4591 
4592  if (IsMaster()) {
4593  if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4594  // if the reason was a planned termination then delete the worker and
4595  // remove it from all the lists
4596  fSlaves->Remove(wrk);
4597  fBadSlaves->Remove(wrk);
4598  fActiveSlaves->Remove(wrk);
4599  fInactiveSlaves->Remove(wrk);
4600  fUniqueSlaves->Remove(wrk);
4601  fAllUniqueSlaves->Remove(wrk);
4602  fNonUniqueMasters->Remove(wrk);
4603 
4604  // we add it to the list of terminated slave infos instead, so that it
4605  // stays available in the .workers persistent file
4606  TSlaveInfo *si = new TSlaveInfo(
4607  wrk->GetOrdinal(),
4608  Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4609  0, "", wrk->GetWorkDir());
4611  else delete si;
4612 
4613  delete wrk;
4614  } else {
4615  fBadSlaves->Add(wrk);
4616  fActiveSlaves->Remove(wrk);
4617  fUniqueSlaves->Remove(wrk);
4618  fAllUniqueSlaves->Remove(wrk);
4619  fNonUniqueMasters->Remove(wrk);
4621  wrk->Close();
4622  // Update the mergers count, if needed
4623  if (fMergersSet) {
4624  Int_t mergersCount = -1;
4625  TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4626  if (mc) mergersCount = mc->GetVal(); // Value set by user
4627  // Mergers count is set dynamically: recalculate it
4628  if (mergersCount == 0) {
4630  if (activeWorkers > 1) {
4631  fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4632  if (activeWorkers / fMergersCount < 2)
4633  fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4634  }
4635  }
4636  }
4637  }
4638 
4639  // Update session workers files
4640  SaveWorkerInfo();
4641  } else {
4642  // On clients the proof session should be removed from the lists
4643  // and deleted, since it is not valid anymore
4644  fSlaves->Remove(wrk);
4645  if (fManager)
4646  fManager->DiscardSession(this);
4647  }
4648 }
4649 
4650 ////////////////////////////////////////////////////////////////////////////////
4651 /// Add slave with socket s to the bad slave list and remove if from
4652 /// the active list and from the two monitor objects.
4653 
4654 void TProof::MarkBad(TSocket *s, const char *reason)
4655 {
4656  std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4657 
4658  // We may have been invalidated in the meanwhile: nothing to do in such a case
4659  if (!IsValid()) return;
4660 
4661  TSlave *wrk = FindSlave(s);
4662  MarkBad(wrk, reason);
4663 }
4664 
4665 ////////////////////////////////////////////////////////////////////////////////
4666 /// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4667 
4669 {
4670  if (!wrk) {
4671  Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4672  return;
4673  }
4674 
4675  // Send stop message
4676  if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4677  TMessage mess(kPROOF_STOP);
4678  wrk->GetSocket()->Send(mess);
4679  } else {
4680  if (gDebug > 0)
4681  Info("TerminateWorker", "connection to worker is already down: cannot"
4682  " send termination message");
4683  }
4684 
4685  // This is a bad worker from now on
4687 }
4688 
4689 ////////////////////////////////////////////////////////////////////////////////
4690 /// Ask an active worker 'ord' to terminate, i.e. to shutdown
4691 
4692 void TProof::TerminateWorker(const char *ord)
4693 {
4694  if (ord && strlen(ord) > 0) {
4695  Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4696  if (IsMaster()) {
4697  TIter nxw(fSlaves);
4698  TSlave *wrk = 0;
4699  while ((wrk = (TSlave *)nxw())) {
4700  if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4701  TerminateWorker(wrk);
4702  if (!all) break;
4703  }
4704  }
4705  } else {
4706  TMessage mess(kPROOF_STOP);
4707  mess << TString(ord);
4708  Broadcast(mess);
4709  }
4710  }
4711 }
4712 
4713 ////////////////////////////////////////////////////////////////////////////////
4714 /// Ping PROOF. Returns 1 if master server responded.
4715 
4717 {
4718  return Ping(kActive);
4719 }
4720 
4721 ////////////////////////////////////////////////////////////////////////////////
4722 /// Ping PROOF slaves. Returns the number of slaves that responded.
4723 
4725 {
4726  TList *slaves = 0;
4727  if (list == kAll) slaves = fSlaves;
4728  if (list == kActive) slaves = fActiveSlaves;
4729  if (list == kUnique) slaves = fUniqueSlaves;
4730  if (list == kAllUnique) slaves = fAllUniqueSlaves;
4731 
4732  if (slaves->GetSize() == 0) return 0;
4733 
4734  int nsent = 0;
4735  TIter next(slaves);
4736 
4737  TSlave *sl;
4738  while ((sl = (TSlave *)next())) {
4739  if (sl->IsValid()) {
4740  if (sl->Ping() == -1) {
4741  MarkBad(sl, "ping unsuccessful");
4742  } else {
4743  nsent++;
4744  }
4745  }
4746  }
4747 
4748  return nsent;
4749 }
4750 
4751 ////////////////////////////////////////////////////////////////////////////////
4752 /// Ping PROOF slaves. Returns the number of slaves that responded.
4753 
4755 {
4756  TList *slaves = fSlaves;
4757 
4758  if (slaves->GetSize() == 0) return;
4759 
4760  TIter next(slaves);
4761 
4762  TSlave *sl;
4763  while ((sl = (TSlave *)next())) {
4764  if (sl->IsValid()) {
4765  sl->Touch();
4766  }
4767  }
4768 
4769  return;
4770 }
4771 
4772 ////////////////////////////////////////////////////////////////////////////////
4773 /// Print status of PROOF cluster.
4774 
4775 void TProof::Print(Option_t *option) const
4776 {
4777  TString secCont;
4778 
4779  if (TestBit(TProof::kIsClient)) {
4780  Printf("Connected to: %s (%s)", GetMaster(),
4781  IsValid() ? "valid" : "invalid");
4782  Printf("Port number: %d", GetPort());
4783  Printf("User: %s", GetUser());
4784  Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4785  Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4787  TSlave *sl = (TSlave *)fActiveSlaves->First();
4788  if (sl) {
4789  TString sc;
4790  if (sl->GetSocket()->GetSecContext())
4791  Printf("Security context: %s",
4792  sl->GetSocket()->GetSecContext()->AsString(sc));
4793  Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4794  } else {
4795  Printf("Security context: Error - No connection");
4796  Printf("Proofd protocol version: Error - No connection");
4797  }
4798  Printf("Client protocol version: %d", GetClientProtocol());
4799  Printf("Remote protocol version: %d", GetRemoteProtocol());
4800  Printf("Log level: %d", GetLogLevel());
4801  Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4802  Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4803  if (IsValid())
4804  const_cast<TProof*>(this)->SendPrint(option);
4805  } else {
4806  const_cast<TProof*>(this)->AskStatistics();
4807  if (IsParallel())
4808  Printf("*** Master server %s (parallel mode, %d workers):",
4810  else
4811  Printf("*** Master server %s (sequential mode):",
4812  gProofServ->GetOrdinal());
4813 
4814  Printf("Master host name: %s", gSystem->HostName());
4815  Printf("Port number: %d", GetPort());
4816  if (strlen(gProofServ->GetGroup()) > 0) {
4817  Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4818  } else {
4819  Printf("User: %s", GetUser());
4820  }
4821  TString ver;
4822  ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4823  if (gSystem->Getenv("ROOTVERSIONTAG"))
4824  ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4825  Printf("ROOT version|rev|tag: %s", ver.Data());
4826  Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4828  Printf("Protocol version: %d", GetClientProtocol());
4829  Printf("Image name: %s", GetImage());
4830  Printf("Working directory: %s", gSystem->WorkingDirectory());
4831  Printf("Config directory: %s", GetConfDir());
4832  Printf("Config file: %s", GetConfFile());
4833  Printf("Log level: %d", GetLogLevel());
4834  Printf("Number of workers: %d", GetNumberOfSlaves());
4835  Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4836  Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4837  Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4838  Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4839  Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4840  Printf("Total real time used (s): %.3f", GetRealTime());
4841  Printf("Total CPU time used (s): %.3f", GetCpuTime());
4842  if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4843  Printf("List of workers:");
4844  TList masters;
4845  TIter nextslave(fSlaves);
4846  while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4847  if (!sl->IsValid()) continue;
4848 
4849  if (sl->GetSlaveType() == TSlave::kSlave) {
4850  sl->Print(option);
4851  } else if (sl->GetSlaveType() == TSlave::kMaster) {
4852  TMessage mess(kPROOF_PRINT);
4853  mess.WriteString(option);
4854  if (sl->GetSocket()->Send(mess) == -1)
4855  const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4856  else
4857  masters.Add(sl);
4858  } else {
4859  Error("Print", "TSlave is neither Master nor Worker");
4860  R__ASSERT(0);
4861  }
4862  }
4863  const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4864  }
4865  }
4866 }
4867 
4868 ////////////////////////////////////////////////////////////////////////////////
4869 /// Extract from opt information about output handling settings.
4870 /// The understood keywords are:
4871 /// of=<file>, outfile=<file> output file location
4872 /// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4873 /// mutually exclusive,execution stops
4874 /// if both are found)
4875 /// sft[=<opt>], savetofile[=<opt>] control saving to file
4876 ///
4877 /// For 'mvf', the <opt> integer has the following meaning:
4878 /// <opt> = <how>*10 + <force>
4879 /// <force> = 0 save to file if memory threshold is reached
4880 /// (the memory threshold is set by the cluster
4881 /// admin); in case an output file is defined, the
4882 /// files are merged at the end;
4883 /// 1 save results to file.
4884 /// <how> = 0 save at the end of the query
4885 /// 1 save results after each packet (to reduce the
4886 /// loss in case of crash).
4887 ///
4888 /// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4889 /// to save results after each packet.
4890 ///
4891 /// The separator from the next option is either a ' ' or a ';'
4892 ///
4893 /// All recognized settings are removed from the input string opt.
4894 /// If action == 0, set up the output file accordingly, if action == 1 clean related
4895 /// output file settings.
4896 /// If the final target file is local then 'target' is set to the final local path
4897 /// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4898 ///
4899 /// Output file settings are in the form
4900 ///
4901 /// <previous_option>of=name <next_option>
4902 /// <previous_option>outfile=name,...;<next_option>
4903 ///
4904 /// The separator from the next option is either a ' ' or a ';'
4905 /// Called interanally by TProof::Process.
4906 ///
4907 /// Returns 0 on success, -1 on error.
4908 
4910 {
4911  TString outfile, dsname, stfopt;
4912  if (action == 0) {
4913  TString tagf, tagd, tags, oo;
4914  Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4915  while (opt.Tokenize(oo, from, "[; ]")) {
4916  if (oo.BeginsWith("of=")) {
4917  tagf = "of=";
4918  iof = opt.Index(tagf);
4919  } else if (oo.BeginsWith("outfile=")) {
4920  tagf = "outfile=";
4921  iof = opt.Index(tagf);
4922  } else if (oo.BeginsWith("ds")) {
4923  tagd = "ds";
4924  iod = opt.Index(tagd);
4925  } else if (oo.BeginsWith("dataset")) {
4926  tagd = "dataset";
4927  iod = opt.Index(tagd);
4928  } else if (oo.BeginsWith("stf")) {
4929  tags = "stf";
4930  ios = opt.Index(tags);
4931  } else if (oo.BeginsWith("savetofile")) {
4932  tags = "savetofile";
4933  ios = opt.Index(tags);
4934  }
4935  }
4936  // Check consistency
4937  if (iof != kNPOS && iod != kNPOS) {
4938  Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4939  return -1;
4940  }
4941 
4942  // Check output file first
4943  if (iof != kNPOS) {
4944  from = iof + tagf.Length();
4945  if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4946  Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4947  return -1;
4948  }
4949  // For removal from original options string
4950  tagf += outfile;
4951  }
4952  // Check dataset
4953  if (iod != kNPOS) {
4954  from = iod + tagd.Length();
4955  if (!opt.Tokenize(dsname, from, "[; ]"))
4956  if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4957  // For removal from original options string
4958  tagd += dsname;
4959  // The name may be empty or beginning with a '='
4960  if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4961  if (dsname.Contains("|V")) {
4962  target = "ds|V";
4963  dsname.ReplaceAll("|V", "");
4964  }
4965  if (dsname.IsNull()) dsname = "dataset_<qtag>";
4966  }
4967  // Check stf
4968  if (ios != kNPOS) {
4969  from = ios + tags.Length();
4970  if (!opt.Tokenize(stfopt, from, "[; ]"))
4971  if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
4972  // For removal from original options string
4973  tags += stfopt;
4974  // It must be digit
4975  if (!stfopt.IsNull()) {
4976  if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
4977  if (!stfopt.IsNull()) {
4978  if (!stfopt.IsDigit()) {
4979  Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
4980  return -1;
4981  }
4982  } else {
4983  // Default
4984  stfopt = "1";
4985  }
4986  } else {
4987  // Default
4988  stfopt = "1";
4989  }
4990  }
4991  // Remove from original options string
4992  opt.ReplaceAll(tagf, "");
4993  opt.ReplaceAll(tagd, "");
4994  opt.ReplaceAll(tags, "");
4995  }
4996 
4997  // Parse now
4998  if (action == 0) {
4999  // Output file
5000  if (!outfile.IsNull()) {
5001  if (!outfile.BeginsWith("master:")) {
5003  Warning("HandleOutputOptions",
5004  "directory '%s' for the output file does not exists or is not writable:"
5005  " saving to master", gSystem->DirName(outfile.Data()));
5006  outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5007  } else {
5008  if (!IsLite()) {
5009  // The target file is local, so we need to retrieve it
5010  target = outfile;
5011  if (!stfopt.IsNull()) {
5012  outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5013  } else {
5014  outfile = "";
5015  }
5016  }
5017  }
5018  }
5019  if (outfile.BeginsWith("master:")) {
5020  outfile.ReplaceAll("master:", "");
5021  if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5022  // Get the master data dir
5023  TString ddir, emsg;
5024  if (!IsLite()) {
5025  if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5026  TObjString *os = fMacroLog.GetLineWith("const char");
5027  if (os) {
5028  Ssiz_t fst = os->GetString().First('\"');
5029  Ssiz_t lst = os->GetString().Last('\"');
5030  ddir = os->GetString()(fst+1, lst-fst-1);
5031  } else {
5032  emsg = "could not find 'const char *' string in macro log! cannot continue";
5033  }
5034  } else {
5035  emsg = "could not retrieve master data directory info! cannot continue";
5036  }
5037  if (!emsg.IsNull()) {
5038  Error("HandleOutputOptions", "%s", emsg.Data());
5039  return -1;
5040  }
5041  }
5042  if (!ddir.IsNull()) ddir += "/";
5043  if (outfile.IsNull()) {
5044  outfile.Form("%s<file>", ddir.Data());
5045  } else {
5046  outfile.Insert(0, TString::Format("%s", ddir.Data()));
5047  }
5048  }
5049  }
5050  // Set the parameter
5051  if (!outfile.IsNull()) {
5052  if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5053  SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5054  }
5055  }
5056  // Dataset creation
5057  if (!dsname.IsNull()) {
5058  dsname.Insert(0, "ds:");
5059  // Set the parameter
5060  SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5061  // Check the Save-To-File option
5062  if (!stfopt.IsNull()) {
5063  Int_t ostf = (Int_t) stfopt.Atoi();
5064  if (ostf%10 <= 0) {
5065  Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5066  stfopt.Form("%d", ostf+1);
5067  }
5068  } else {
5069  // Minimal setting
5070  stfopt = "1";
5071  }
5072  }
5073  // Save-To-File options
5074  if (!stfopt.IsNull()) {
5075  // Set the parameter
5076  SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5077  }
5078  } else {
5079  // Retrieve the file, if required
5080  if (GetOutputList()) {
5081  if (target == "ds|V") {
5082  // Find the dataset
5083  dsname = "";
5084  TIter nxo(GetOutputList());
5085  TObject *o = 0;
5086  while ((o = nxo())) {
5088  VerifyDataSet(o->GetName());
5089  dsname = o->GetName();
5090  break;
5091  }
5092  }
5093  if (!dsname.IsNull()) {
5094  TFileCollection *fc = GetDataSet(dsname);
5095  if (fc) {
5096  fc->Print();
5097  } else {
5098  Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5099  }
5100  } else {
5101  Warning("HandleOutputOptions", "dataset not found!");
5102  }
5103  } else {
5104  Bool_t targetcopied = kFALSE;
5105  TProofOutputFile *pf = 0;
5106  if (!target.IsNull())
5108  if (pf) {
5109  // Copy the file
5110  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5111  TUrl(target, kTRUE).GetUrl())) {
5112  if (TFile::Cp(pf->GetOutputFileName(), target)) {
5113  Printf(" Output successfully copied to %s", target.Data());
5114  targetcopied = kTRUE;
5115  } else {
5116  Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5117  }
5118  }
5119  }
5120  TFile *fout = 0;
5121  TObject *o = 0;
5122  TIter nxo(GetOutputList());
5123  Bool_t swapcopied = kFALSE;
5124  while ((o = nxo())) {
5125  TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5126  if (pof) {
5127  if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5128  if (pof == pf && targetcopied) continue;
5129  // Copy the file
5130  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5131  TUrl(target, kTRUE).GetUrl())) {
5132  if (TFile::Cp(pof->GetOutputFileName(), target)) {
5133  Printf(" Output successfully copied to %s", target.Data());
5134  swapcopied = kTRUE;
5135  } else {
5136  Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5137  }
5138  }
5139  } else if (pof->IsRetrieve()) {
5140  // Retrieve this file to the local path indicated in the title
5141  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5142  TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5143  if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5144  Printf(" Output successfully copied to %s", pof->GetTitle());
5145  } else {
5146  Warning("HandleOutputOptions",
5147  "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5148  }
5149  }
5150  }
5151  }
5152  }
5153  if (!target.IsNull() && !swapcopied) {
5154  if (!fout && !pf) {
5155  fout = TFile::Open(target, "RECREATE");
5156  if (!fout || (fout && fout->IsZombie())) {
5157  SafeDelete(fout);
5158  Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5159  }
5160  }
5161  if (fout) {
5162  nxo.Reset();
5163  while ((o = nxo())) {
5164  TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5165  if (!pof) {
5166  // Write the object to the open output file
5167  o->Write();
5168  }
5169  }
5170  }
5171  }
5172  // Clean-up
5173  if (fout) {
5174  fout->Close();
5175  SafeDelete(fout);
5176  Printf(" Output saved to %s", target.Data());
5177  }
5178  }
5179  }
5180  // Remove the parameter
5181  DeleteParameters("PROOF_DefaultOutputOption");
5182  // Remove the parameter
5183  DeleteParameters("PROOF_SavePartialResults");
5184  }
5185  // Done
5186  return 0;
5187 }
5188 
5189 ////////////////////////////////////////////////////////////////////////////////
5190 /// Extract from opt in optfb information about wanted feedback settings.
5191 /// Feedback are removed from the input string opt.
5192 /// If action == 0, set up feedback accordingly, if action == 1 clean related
5193 /// feedback settings (using info in optfb, if available, or reparsing opt).
5194 ///
5195 /// Feedback requirements are in the form
5196 ///
5197 /// <previous_option>fb=name1,name2,name3,... <next_option>
5198 /// <previous_option>feedback=name1,name2,name3,...;<next_option>
5199 ///
5200 /// The special name 'stats' triggers feedback about events and packets.
5201 /// The separator from the next option is either a ' ' or a ';'.
5202 /// Called interanally by TProof::Process.
5203 
5204 void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5205 {
5206  Ssiz_t from = 0;
5207  if (action == 0 || (action == 1 && optfb.IsNull())) {
5208  TString tag("fb=");
5209  Ssiz_t ifb = opt.Index(tag);
5210  if (ifb == kNPOS) {
5211  tag = "feedback=";
5212  ifb = opt.Index(tag);
5213  }
5214  if (ifb == kNPOS) return;
5215  from = ifb + tag.Length();
5216 
5217  if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5218  Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5219  return;
5220  }
5221  // Remove from original options string
5222  tag += optfb;
5223  opt.ReplaceAll(tag, "");
5224  }
5225 
5226  // Parse now
5227  TString nm, startdraw, stopdraw;
5228  from = 0;
5229  while (optfb.Tokenize(nm, from, ",")) {
5230  // Special name first
5231  if (nm == "stats") {
5232  if (action == 0) {
5233  startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5234  gROOT->ProcessLine(startdraw.Data());
5235  SetParameter("PROOF_StatsHist", "");
5236  AddFeedback("PROOF_EventsHist");
5237  AddFeedback("PROOF_PacketsHist");
5238  AddFeedback("PROOF_ProcPcktHist");
5239  } else {
5240  stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5241  " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5242  " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5243  gROOT->ProcessLine(stopdraw.Data());
5244  DeleteParameters("PROOF_StatsHist");
5245  RemoveFeedback("PROOF_EventsHist");
5246  RemoveFeedback("PROOF_PacketsHist");
5247  RemoveFeedback("PROOF_ProcPcktHist");
5248  }
5249  } else {
5250  if (action == 0) {
5251  // Enable or
5252  AddFeedback(nm);
5253  startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5254  gROOT->ProcessLine(startdraw.Data());
5255  } else {
5256  // ... or disable
5257  RemoveFeedback(nm);
5258  stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5259  " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5260  " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5261  gROOT->ProcessLine(stopdraw.Data());
5262  }
5263  }
5264  }
5265 }
5266 
5267 ////////////////////////////////////////////////////////////////////////////////
5268 /// Process a data set (TDSet) using the specified selector (.C) file or
5269 /// Tselector object
5270 /// Entry- or event-lists should be set in the data set object using
5271 /// TDSet::SetEntryList.
5272 /// The return value is -1 in case of error and TSelector::GetStatus() in
5273 /// in case of success.
5274 
5275 Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5277 {
5278  if (!IsValid() || !fPlayer) return -1;
5279 
5280  // Set PROOF to running state
5282 
5283  TString opt(option), optfb, outfile;
5284  // Enable feedback, if required
5285  if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5286  // Define output file, either from 'opt' or the default one
5287  if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5288 
5289  // Resolve query mode
5290  fSync = (GetQueryMode(opt) == kSync);
5291 
5292  if (fSync && (!IsIdle() || IsWaiting())) {
5293  // Already queued or processing queries: switch to asynchronous mode
5294  Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5295  fSync = kFALSE;
5296  opt.ReplaceAll("SYNC","");
5297  opt += "ASYN";
5298  }
5299 
5300  // Cleanup old temporary datasets
5301  if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5303  fRunningDSets->Delete();
5304  }
5305 
5306  // deactivate the default application interrupt handler
5307  // ctrl-c's will be forwarded to PROOF to stop the processing
5308  TSignalHandler *sh = 0;
5309  if (fSync) {
5310  if (gApplication)
5312  }
5313 
5314  // Make sure we get a fresh result
5315  fOutputList.Clear();
5316 
5317  // Make sure that the workers ready list is empty
5318  if (fWrksOutputReady) {
5321  }
5322 
5323  // Make sure the selector path is in the macro path
5324  TProof::AssertMacroPath(selector);
5325 
5326  // Reset time measurements
5327  fQuerySTW.Reset();
5328 
5329  Long64_t rv = -1;
5330  if (selector && strlen(selector)) {
5331  rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5332  } else if (fSelector) {
5333  rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5334  } else {
5335  Error("Process", "neither a selecrot file nor a selector object have"
5336  " been specified: cannot process!");
5337  }
5338 
5339  // This is the end of merging
5340  fQuerySTW.Stop();
5341  Float_t rt = fQuerySTW.RealTime();
5342  // Update the query content
5343  TQueryResult *qr = GetQueryResult();
5344  if (qr) {
5345  qr->SetTermTime(rt);
5346  qr->SetPrepTime(fPrepTime);
5347  }
5348 
5349  // Disable feedback, if required
5350  if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5351  // Finalise output file settings (opt is ignored in here)
5352  if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5353 
5354  // Retrieve status from the output list
5355  if (rv >= 0) {
5356  TParameter<Long64_t> *sst =
5357  (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5358  if (sst) rv = sst->GetVal();
5359  }
5360 
5361  if (fSync) {
5362  // reactivate the default application interrupt handler
5363  if (sh)
5365  // Save the performance info, if required
5366  if (!fPerfTree.IsNull()) {
5367  if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5368  // Must be re-enabled each time
5369  SetPerfTree(0);
5370  }
5371  }
5372 
5373  return rv;
5374 }
5375 
5376 ////////////////////////////////////////////////////////////////////////////////
5377 /// Process a data set (TFileCollection) using the specified selector (.C) file
5378 /// or TSelector object.
5379 /// The default tree is analyzed (i.e. the first one found). To specify another
5380 /// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5381 /// The return value is -1 in case of error and TSelector::GetStatus() in
5382 /// in case of success.
5383 
5386 {
5387  if (!IsValid() || !fPlayer) return -1;
5388 
5389  if (fProtocol < 17) {
5390  Info("Process", "server version < 5.18/00:"
5391  " processing of TFileCollection not supported");
5392  return -1;
5393  }
5394 
5395  // We include the TFileCollection to the input list and we create a
5396  // fake TDSet with infor about it
5397  TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5398  fPlayer->AddInput(fc);
5399 
5400 
5401  Long64_t retval = -1;
5402  if (selector && strlen(selector)) {
5403  retval = Process(dset, selector, option, nentries, first);
5404  } else if (fSelector) {
5405  retval = Process(dset, fSelector, option, nentries, first);
5406  } else {
5407  Error("Process", "neither a selecrot file nor a selector object have"
5408  " been specified: cannot process!");
5409  }
5410  fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5411 
5412  // Cleanup
5413  if (IsLite() && !fSync) {
5414  if (!fRunningDSets) fRunningDSets = new TList;
5415  fRunningDSets->Add(dset);
5416  } else {
5417  delete dset;
5418  }
5419 
5420  return retval;
5421 }
5422 
5423 ////////////////////////////////////////////////////////////////////////////////
5424 /// Process a dataset which is stored on the master with name 'dsetname'.
5425 /// The syntax for dsetname is name[#[dir/]objname], e.g.
5426 /// "mydset" analysis of the first tree in the top dir of the dataset
5427 /// named "mydset"
5428 /// "mydset#T" analysis tree "T" in the top dir of the dataset
5429 /// named "mydset"
5430 /// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5431 /// named "mydset"
5432 /// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5433 /// dataset named "mydset"
5434 /// The component 'name' in its more general form contains also the group and
5435 /// user name following "/<group>/<user>/<dsname>". Each of these components
5436 /// can contain one or more wildcards '*', in which case all the datasets matching
5437 /// the expression are added together as a global dataset (wildcard support has
5438 /// been added in version 5.27/02).
5439 /// The last argument 'elist' specifies an entry- or event-list to be used as
5440 /// event selection.
5441 /// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5442 /// at once in a more flexible way that the one provided by wildcarding. There
5443 /// are three possibilities:
5444 /// 1) specifying the dataset names separated by the OR operator '|', e.g.
5445 /// dsetname = "<dset1>|<dset2>|<dset3>|..."
5446 /// in this case the datasets are a seen as a global unique dataset
5447 /// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5448 /// dsetname = "<dset1>,<dset2> <dset3>,..."
5449 /// in this case the datasets are processed one after the other and the
5450 /// selector is notified when switching dataset via a bit in the current
5451 /// processed element.
5452 /// 3) giving the path of a textfile where the dataset names are specified
5453 /// on one or multiple lines; the lines found are joined as in 1), unless
5454 /// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5455 /// with the dataset names listed in 'datasets.txt') in which case they are
5456 /// treated as in 2); the file is open in raw mode with TFile::Open and
5457 /// therefore it cane be remote, e.g. on a Web server.
5458 /// Each <dsetj> has the format specified above for the single dataset processing,
5459 /// included wildcarding (the name of the tree and subdirectory must be same for
5460 /// all the datasets).
5461 /// In the case of multiple datasets, 'elist' is treated a global entry list.
5462 /// It is possible to specify per-dataset entry lists using the syntax
5463 /// "mydset[#adir/[T]]?enl=entrylist"
5464 /// or
5465 /// "mydset[#adir/[T]]<<entrylist"
5466 /// Here 'entrylist' is a tag identifying, in the order :
5467 /// i. a named entry-list in the input list or in the input data list
5468 /// ii. a named entry-list in memory (in gDirectory)
5469 /// iii. the path of a file containing the entry-list to be used
5470 /// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5471 /// data list.
5472 /// The return value is -1 in case of error and TSelector::GetStatus() in
5473 /// in case of success.
5474 
5475 Long64_t TProof::Process(const char *dsetname, const char *selector,
5476  Option_t *option, Long64_t nentries,
5477  Long64_t first, TObject *elist)
5478 {
5479  if (fProtocol < 13) {
5480  Info("Process", "processing 'by name' not supported by the server");
5481  return -1;
5482  }
5483 
5484  TString dsname, fname(dsetname);
5485  // If the 'dsetname' corresponds to an existing and readable file we will try to
5486  // interpretate its content as names of datasets to be processed. One line can contain
5487  // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5488  // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5489  // joined with ','.
5490  const char *separator = (fname.EndsWith(",")) ? "," : "|";
5491  if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5492  if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5493  TUrl uf(fname, kTRUE);
5494  uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5495  TFile *f = TFile::Open(uf.GetUrl());
5496  if (f && !(f->IsZombie())) {
5497  const Int_t blen = 8192;
5498  char buf[blen];
5499  Long64_t rest = f->GetSize();
5500  while (rest > 0) {
5501  Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5502  if (f->ReadBuffer(buf, len)) {
5503  Error("Process", "problems reading from file '%s'", fname.Data());
5504  dsname = "";
5505  break;
5506  }
5507  buf[len] = '\0';
5508  dsname += buf;
5509  rest -= len;
5510  }
5511  f->Close();
5512  SafeDelete(f);
5513  // We fail if a failure occured
5514  if (rest > 0) return -1;
5515  } else {
5516  Error("Process", "could not open file '%s'", fname.Data());
5517  return -1;
5518  }
5519  }
5520  if (dsname.IsNull()) {
5521  dsname = dsetname;
5522  } else {
5523  // Remove trailing '\n'
5524  if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5525  // Replace all '\n' with the proper separator
5526  dsname.ReplaceAll("\n", separator);
5527  if (gDebug > 0) {
5528  Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5529  Info("Process", " '%s'", dsname.Data());
5530  }
5531  }
5532 
5533  TString names(dsname), name, enl, newname;
5534  // If multi-dataset check if server supports it
5535  if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5536  Info("Process", "multi-dataset processing not supported by the server");
5537  return -1;
5538  }
5539 
5540  TEntryList *el = 0;
5541  TString dsobj, dsdir;
5542  Int_t from = 0;
5543  while (names.Tokenize(name, from, "[, |]")) {
5544 
5545  newname = name;
5546  // Extract the specific entry-list, if any
5547  enl = "";
5548  Int_t ienl = name.Index("?enl=");
5549  if (ienl == kNPOS) {
5550  ienl = name.Index("<<");
5551  if (ienl != kNPOS) {
5552  newname.Remove(ienl);
5553  ienl += strlen("<<");
5554  }
5555  } else {
5556  newname.Remove(ienl);
5557  ienl += strlen("?enl=");
5558  }
5559 
5560  // Check the name syntax first
5561  TString obj, dir("/");
5562  Int_t idxc = newname.Index("#");
5563  if (idxc != kNPOS) {
5564  Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5565  if (idxs != kNPOS) {
5566  obj = newname(idxs+1, newname.Length());
5567  dir = newname(idxc+1, newname.Length());
5568  dir.Remove(dir.Index("/") + 1);
5569  newname.Remove(idxc);
5570  } else {
5571  obj = newname(idxc+1, newname.Length());
5572  newname.Remove(idxc);
5573  }
5574  } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5575  // protection against using ':' instead of '#'
5576  Error("Process", "bad name syntax (%s): please use"
5577  " a '#' after the dataset name", name.Data());
5578  dsname.ReplaceAll(name, "");
5579  continue;
5580  }
5581  if (dsobj.IsNull() && dsdir.IsNull()) {
5582  // The first one specifies obj and dir
5583  dsobj = obj;
5584  dsdir = dir;
5585  } else if (obj != dsobj || dir != dsdir) {
5586  // Inconsistent specification: not supported
5587  Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5588  }
5589  // Process the entry-list name, if any
5590  if (ienl != kNPOS) {
5591  // Get entrylist name or path
5592  enl = name(ienl, name.Length());
5593  el = 0;
5594  TObject *oel = 0;
5595  // If not in the input list ...
5596  TList *inpl = GetInputList();
5597  if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5598  // ... check the heap
5599  if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5600  if ((el = dynamic_cast<TEntryList *>(oel))) {
5601  // Add to the input list (input data not available on master where
5602  // this info will be processed)
5603  if (fProtocol >= 28)
5604  if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5605  }
5606  }
5607  // If not in the heap, check a file, if any
5608  if (!el) {
5609  if (!gSystem->AccessPathName(enl)) {
5610  TFile *f = TFile::Open(enl);
5611  if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5612  TIter nxk(f->GetListOfKeys());
5613  TKey *k = 0;
5614  while ((k = (TKey *) nxk())) {
5615  if (!strcmp(k->GetClassName(), "TEntryList")) {
5616  if (!el) {
5617  if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5618  // Add to the input list (input data not available on master where
5619  // this info will be processed)
5620  if (fProtocol >= 28) {
5621  if (!(inpl->FindObject(el->GetName()))) {
5622  el = (TEntryList *) el->Clone();
5623  AddInput(el);
5624  }
5625  } else {
5626  el = (TEntryList *) el->Clone();
5627  }
5628  }
5629  } else if (strcmp(el->GetName(), k->GetName())) {
5630  Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5631  "if this is not what you want, load first the content in memory"
5632  "and select it by name ", enl.Data());
5633  }
5634  }
5635  }
5636  } else {
5637  Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5638  }
5639  }
5640  }
5641  // Transmit the information
5642  if (fProtocol >= 28) {
5643  newname += "?enl=";
5644  if (el) {
5645  // An entry list object is avalaible in the input list: add its name
5646  newname += el->GetName();
5647  } else {
5648  // The entry list object was not found: send the name, the future entry list manager will
5649  // find it on the server side
5650  newname += enl;
5651  }
5652  }
5653  }
5654  // Adjust the name for this dataset
5655  dsname.ReplaceAll(name, newname);
5656  }
5657 
5658  // Create the dataset object
5659  TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5660  // Set entry list
5661  if (el && fProtocol < 28) {
5662  dset->SetEntryList(el);
5663  } else {
5664  dset->SetEntryList(elist);
5665  }
5666  // Run
5667  Long64_t retval = -1;
5668  if (selector && strlen(selector)) {
5669  retval = Process(dset, selector, option, nentries, first);
5670  } else if (fSelector) {
5671  retval = Process(dset, fSelector, option, nentries, first);
5672  } else {
5673  Error("Process", "neither a selector file nor a selector object have"
5674  " been specified: cannot process!");
5675  }
5676  // Cleanup
5677  if (IsLite() && !fSync) {
5678  if (!fRunningDSets) fRunningDSets = new TList;
5679  fRunningDSets->Add(dset);
5680  } else {
5681  delete dset;
5682  }
5683 
5684  return retval;
5685 }
5686 
5687 ////////////////////////////////////////////////////////////////////////////////
5688 /// Generic (non-data based) selector processing: the Process() method of the
5689 /// specified selector (.C) or TSelector object is called 'n' times.
5690 /// The return value is -1 in case of error and TSelector::GetStatus() in
5691 /// in case of success.
5692 
5693 Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5694 {
5695  if (!IsValid()) return -1;
5696 
5697  if (fProtocol < 16) {
5698  Info("Process", "server version < 5.17/04: generic processing not supported");
5699  return -1;
5700  }
5701 
5702  // Fake data set
5703  TDSet *dset = new TDSet;
5704  dset->SetBit(TDSet::kEmpty);
5705 
5706  Long64_t retval = -1;
5707  if (selector && strlen(selector)) {
5708  retval = Process(dset, selector, option, n);
5709  } else if (fSelector) {
5710  retval = Process(dset, fSelector, option, n);
5711  } else {
5712  Error("Process", "neither a selector file nor a selector object have"
5713  " been specified: cannot process!");
5714  }
5715 
5716  // Cleanup
5717  if (IsLite() && !fSync) {
5718  if (!fRunningDSets) fRunningDSets = new TList;
5719  fRunningDSets->Add(dset);
5720  } else {
5721  delete dset;
5722  }
5723  return retval;
5724 }
5725 
5726 ////////////////////////////////////////////////////////////////////////////////
5727 /// Process a data set (TDSet) using the specified selector object.
5728 /// Entry- or event-lists should be set in the data set object using
5729 /// TDSet::SetEntryList.
5730 /// The return value is -1 in case of error and TSelector::GetStatus() in
5731 /// in case of success.
5732 
5735 {
5736  if (fProtocol < 34) {
5737  Error("Process", "server version < 5.33/02:"
5738  "processing by object not supported");
5739  return -1;
5740  }
5741  if (!selector) {
5742  Error("Process", "selector object undefined!");
5743  return -1;
5744  }
5745  fSelector = selector;
5746  Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5747  fSelector = 0;
5748  // Done
5749  return rc;
5750 }
5751 
5752 ////////////////////////////////////////////////////////////////////////////////
5753 /// Process a data set (TFileCollection) using the specified selector object
5754 /// The default tree is analyzed (i.e. the first one found). To specify another
5755 /// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
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(fc, (const char*)0, option, nentries, first);
5773  fSelector = 0;
5774  // Done
5775  return rc;
5776 }
5777 
5778 ////////////////////////////////////////////////////////////////////////////////
5779 /// Process with name of dataset and TSelector object
5780 
5781 Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5782  Option_t *option, Long64_t nentries,
5783  Long64_t first, TObject *elist)
5784 {
5785  if (fProtocol < 34) {
5786  Error("Process", "server version < 5.33/02:"
5787  "processing by object not supported");
5788  return -1;
5789  }
5790  if (!selector) {
5791  Error("Process", "selector object undefined!");
5792  return -1;
5793  }
5794  fSelector = selector;
5795  Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5796  fSelector = 0;
5797  // Done
5798  return rc;
5799 }
5800 
5801 ////////////////////////////////////////////////////////////////////////////////
5802 /// Generic (non-data based) selector processing: the Process() method of the
5803 /// specified selector is called 'n' times.
5804 /// The return value is -1 in case of error and TSelector::GetStatus() in
5805 /// in case of success.
5806 
5808 {
5809  if (fProtocol < 34) {
5810  Error("Process", "server version < 5.33/02:"
5811  "processing by object not supported");
5812  return -1;
5813  }
5814  if (!selector) {
5815  Error("Process", "selector object undefined!");
5816  return -1;
5817  }
5818  fSelector = selector;
5819  Long64_t rc = Process((const char*)0, n, option);
5820  fSelector = 0;
5821  // Done
5822  return rc;
5823 }
5824 
5825 ////////////////////////////////////////////////////////////////////////////////
5826 /// Get reference for the qry-th query in fQueries (as
5827 /// displayed by ShowQueries).
5828 
5830 {
5831  ref = "";
5832  if (qry > 0) {
5833  if (!fQueries)
5834  GetListOfQueries();
5835  if (fQueries) {
5836  TIter nxq(fQueries);
5837  TQueryResult *qr = 0;
5838  while ((qr = (TQueryResult *) nxq()))
5839  if (qr->GetSeqNum() == qry) {
5840  ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5841  return 0;
5842  }
5843  }
5844  }
5845  return -1;
5846 }
5847 
5848 ////////////////////////////////////////////////////////////////////////////////
5849 /// Finalize the qry-th query in fQueries.
5850 /// If force, force retrieval if the query is found in the local list
5851 /// but has already been finalized (default kFALSE).
5852 /// If query < 0, finalize current query.
5853 /// Return 0 on success, -1 on error
5854 
5856 {
5857  if (fPlayer) {
5858  if (qry > 0) {
5859  TString ref;
5860  if (GetQueryReference(qry, ref) == 0) {
5861  return Finalize(ref, force);
5862  } else {
5863  Info("Finalize", "query #%d not found", qry);
5864  }
5865  } else {
5866  // The last query
5867  return Finalize("", force);
5868  }
5869  }
5870  return -1;
5871 }
5872 
5873 ////////////////////////////////////////////////////////////////////////////////
5874 /// Finalize query with reference ref.
5875 /// If force, force retrieval if the query is found in the local list
5876 /// but has already been finalized (default kFALSE).
5877 /// If ref = 0, finalize current query.
5878 /// Return 0 on success, -1 on error
5879 
5880 Long64_t TProof::Finalize(const char *ref, Bool_t force)
5881 {
5882  if (fPlayer) {
5883  // Get the pointer to the query
5884  TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5885  : GetQueryResult();
5887  TString xref(ref);
5888  if (!qr) {
5889  if (!xref.IsNull()) {
5890  retrieve = kTRUE;
5891  }
5892  } else {
5893  if (qr->IsFinalized()) {
5894  if (force) {
5895  retrieve = kTRUE;
5896  } else {
5897  Info("Finalize","query already finalized:"
5898  " use Finalize(<qry>,kTRUE) to force new retrieval");
5899  qr = 0;
5900  }
5901  } else {
5902  retrieve = kTRUE;
5903  xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5904  }
5905  }
5906  if (retrieve) {
5907  Retrieve(xref.Data());
5908  qr = fPlayer->GetQueryResult(xref.Data());
5909  }
5910  if (qr)
5911  return fPlayer->Finalize(qr);
5912  }
5913  return -1;
5914 }
5915 
5916 ////////////////////////////////////////////////////////////////////////////////
5917 /// Send retrieve request for the qry-th query in fQueries.
5918 /// If path is defined save it to path.
5919 
5920 Int_t TProof::Retrieve(Int_t qry, const char *path)
5921 {
5922  if (qry > 0) {
5923  TString ref;
5924  if (GetQueryReference(qry, ref) == 0)
5925  return Retrieve(ref, path);
5926  else
5927  Info("Retrieve", "query #%d not found", qry);
5928  } else {
5929  Info("Retrieve","positive argument required - do nothing");
5930  }
5931  return -1;
5932 }
5933 
5934 ////////////////////////////////////////////////////////////////////////////////
5935 /// Send retrieve request for the query specified by ref.
5936 /// If path is defined save it to path.
5937 /// Generic method working for all queries known by the server.
5938 
5939 Int_t TProof::Retrieve(const char *ref, const char *path)
5940 {
5941  if (ref) {
5943  m << TString(ref);
5944  Broadcast(m, kActive);
5946 
5947  // Archive it locally, if required
5948  if (path) {
5949 
5950  // Get pointer to query
5951  TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5952 
5953  if (qr) {
5954 
5955  TFile *farc = TFile::Open(path,"UPDATE");
5956  if (!farc || (farc && !(farc->IsOpen()))) {
5957  Info("Retrieve", "archive file cannot be open (%s)", path);
5958  return 0;
5959  }
5960  farc->cd();
5961 
5962  // Update query status
5963  qr->SetArchived(path);
5964 
5965  // Write to file
5966  qr->Write();
5967 
5968  farc->Close();
5969  SafeDelete(farc);
5970 
5971  } else {
5972  Info("Retrieve", "query not found after retrieve");
5973  return -1;
5974  }
5975  }
5976 
5977  return 0;
5978  }
5979  return -1;
5980 }
5981 
5982 ////////////////////////////////////////////////////////////////////////////////
5983 /// Send remove request for the qry-th query in fQueries.
5984 
5986 {
5987  if (qry > 0) {
5988  TString ref;
5989  if (GetQueryReference(qry, ref) == 0)
5990  return Remove(ref, all);
5991  else
5992  Info("Remove", "query #%d not found", qry);
5993  } else {
5994  Info("Remove","positive argument required - do nothing");
5995  }
5996  return -1;
5997 }
5998 
5999 ////////////////////////////////////////////////////////////////////////////////
6000 /// Send remove request for the query specified by ref.
6001 /// If all = TRUE remove also local copies of the query, if any.
6002 /// Generic method working for all queries known by the server.
6003 /// This method can be also used to reset the list of queries
6004 /// waiting to be processed: for that purpose use ref == "cleanupqueue".
6005 
6006 Int_t TProof::Remove(const char *ref, Bool_t all)
6007 {
6008  if (all) {
6009  // Remove also local copies, if any
6010  if (fPlayer)
6011  fPlayer->RemoveQueryResult(ref);
6012  }
6013 
6014  if (IsLite()) return 0;
6015 
6016  if (ref) {
6018  m << TString(ref);
6019  Broadcast(m, kActive);
6021  return 0;
6022  }
6023  return -1;
6024 }
6025 
6026 ////////////////////////////////////////////////////////////////////////////////
6027 /// Send archive request for the qry-th query in fQueries.
6028 
6029 Int_t TProof::Archive(Int_t qry, const char *path)
6030 {
6031  if (qry > 0) {
6032  TString ref;
6033  if (GetQueryReference(qry, ref) == 0)
6034  return Archive(ref, path);
6035  else
6036  Info("Archive", "query #%d not found", qry);
6037  } else {
6038  Info("Archive","positive argument required - do nothing");
6039  }
6040  return -1;
6041 }
6042 
6043 ////////////////////////////////////////////////////////////////////////////////
6044 /// Send archive request for the query specified by ref.
6045 /// Generic method working for all queries known by the server.
6046 /// If ref == "Default", path is understood as a default path for
6047 /// archiving.
6048 
6049 Int_t TProof::Archive(const char *ref, const char *path)
6050 {
6051  if (ref) {
6053  m << TString(ref) << TString(path);
6054  Broadcast(m, kActive);
6056  return 0;
6057  }
6058  return -1;
6059 }
6060 
6061 ////////////////////////////////////////////////////////////////////////////////
6062 /// Send cleanup request for the session specified by tag.
6063 
6064 Int_t TProof::CleanupSession(const char *sessiontag)
6065 {
6066  if (sessiontag) {
6068  m << TString(sessiontag);
6069  Broadcast(m, kActive);
6071  return 0;
6072  }
6073  return -1;
6074 }
6075 
6076 ////////////////////////////////////////////////////////////////////////////////
6077 /// Change query running mode to the one specified by 'mode'.
6078 
6080 {
6081  fQueryMode = mode;
6082 
6083  if (gDebug > 0)
6084  Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6085  "Sync" : "Async");
6086 }
6087 
6088 ////////////////////////////////////////////////////////////////////////////////
6089 /// Find out the query mode based on the current setting and 'mode'.
6090 
6092 {
6093  EQueryMode qmode = fQueryMode;
6094 
6095  if (mode && (strlen(mode) > 0)) {
6096  TString m(mode);
6097  m.ToUpper();
6098  if (m.Contains("ASYN")) {
6099  qmode = kAsync;
6100  } else if (m.Contains("SYNC")) {
6101  qmode = kSync;
6102  }
6103  }
6104 
6105  if (gDebug > 0)
6106  Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6107  "Sync" : "Async");
6108 
6109  return qmode;
6110 }
6111 
6112 ////////////////////////////////////////////////////////////////////////////////
6113 /// Execute the specified drawing action on a data set (TDSet).
6114 /// Event- or Entry-lists should be set in the data set object using
6115 /// TDSet::SetEntryList.
6116 /// Returns -1 in case of error or number of selected events otherwise.
6117 
6118 Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6119  const char *selection, Option_t *option,
6121 {
6122  if (!IsValid() || !fPlayer) return -1;
6123 
6124  // Make sure that asynchronous processing is not active
6125  if (!IsIdle()) {
6126  Info("DrawSelect","not idle, asynchronous Draw not supported");
6127  return -1;
6128  }
6129  TString opt(option);
6130  Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6131  if (idx != kNPOS)
6132  opt.Replace(idx,4,"");
6133 
6134  return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6135 }
6136 
6137 ////////////////////////////////////////////////////////////////////////////////
6138 /// Execute the specified drawing action on a data set which is stored on the
6139 /// master with name 'dsetname'.
6140 /// The syntax for dsetname is name[#[dir/]objname], e.g.
6141 /// "mydset" analysis of the first tree in the top dir of the dataset
6142 /// named "mydset"
6143 /// "mydset#T" analysis tree "T" in the top dir of the dataset
6144 /// named "mydset"
6145 /// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6146 /// named "mydset"
6147 /// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6148 /// dataset named "mydset"
6149 /// The last argument 'enl' specifies an entry- or event-list to be used as
6150 /// event selection.
6151 /// The return value is -1 in case of error and TSelector::GetStatus() in
6152 /// in case of success.
6153 
6154 Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6155  const char *selection, Option_t *option,
6157 {
6158  if (fProtocol < 13) {
6159  Info("Process", "processing 'by name' not supported by the server");
6160  return -1;
6161  }
6162 
6163  TString name(dsetname);
6164  TString obj;
6165  TString dir = "/";
6166  Int_t idxc = name.Index("#");
6167  if (idxc != kNPOS) {
6168  Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6169  if (idxs != kNPOS) {
6170  obj = name(idxs+1, name.Length());
6171  dir = name(idxc+1, name.Length());
6172  dir.Remove(dir.Index("/") + 1);
6173  name.Remove(idxc);
6174  } else {
6175  obj = name(idxc+1, name.Length());
6176  name.Remove(idxc);
6177  }
6178  } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6179  // protection against using ':' instead of '#'
6180  Error("DrawSelect", "bad name syntax (%s): please use"
6181  " a '#' after the dataset name", dsetname);
6182  return -1;
6183  }
6184 
6185  TDSet *dset = new TDSet(name, obj, dir);
6186  // Set entry-list, if required
6187  dset->SetEntryList(enl);
6188  Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6189  delete dset;
6190  return retval;
6191 }
6192 
6193 ////////////////////////////////////////////////////////////////////////////////
6194 /// Send STOPPROCESS message to master and workers.
6195 
6196 void TProof::StopProcess(Bool_t abort, Int_t timeout)
6197 {
6198  PDB(kGlobal,2)
6199  Info("StopProcess","enter %d", abort);
6200 
6201  if (!IsValid())
6202  return;
6203 
6204  // Flag that we have been stopped
6206  SetRunStatus(rst);
6207 
6208  if (fPlayer)
6209  fPlayer->StopProcess(abort, timeout);
6210 
6211  // Stop any blocking 'Collect' request; on masters we do this only if
6212  // aborting; when stopping, we still need to receive the results
6213  if (TestBit(TProof::kIsClient) || abort)
6215 
6216  if (fSlaves->GetSize() == 0)
6217  return;
6218 
6219  // Notify the remote counterpart
6220  TSlave *sl;
6221  TIter next(fSlaves);
6222  while ((sl = (TSlave *)next()))
6223  if (sl->IsValid())
6224  // Ask slave to progate the stop/abort request
6225  sl->StopProcess(abort, timeout);
6226 }
6227 
6228 ////////////////////////////////////////////////////////////////////////////////
6229 /// Signal to disable related switches
6230 
6232 {
6233  Emit("DisableGoAsyn()");
6234 }
6235 
6236 ////////////////////////////////////////////////////////////////////////////////
6237 /// Send GOASYNC message to the master.
6238 
6240 {
6241  if (!IsValid()) return;
6242 
6243  if (GetRemoteProtocol() < 22) {
6244  Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6245  return;
6246  }
6247 
6248  if (fSync && !IsIdle()) {
6250  Broadcast(m);
6251  } else {
6252  Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6253  }
6254 }
6255 
6256 ////////////////////////////////////////////////////////////////////////////////
6257 /// Receive the log file of the slave with socket s.
6258 
6260 {
6261  const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6262  char buf[kMAXBUF];
6263 
6264  // If macro saving is enabled prepare macro
6268  }
6269 
6270  // Append messages to active logging unit
6271  Int_t fdout = -1;
6272  if (!fLogToWindowOnly) {
6273  fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6274  if (fdout < 0) {
6275  Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6276  " will not log msgs", fdout);
6277  return;
6278  }
6279  lseek(fdout, (off_t) 0, SEEK_END);
6280  }
6281 
6282  Int_t left, rec, r;
6283  Long_t filesize = 0;
6284 
6285  while (filesize < size) {
6286  left = Int_t(size - filesize);
6287  if (left >= kMAXBUF)
6288  left = kMAXBUF-1;
6289  rec = s->RecvRaw(&buf, left);
6290  filesize = (rec > 0) ? (filesize + rec) : filesize;
6291  if (!fLogToWindowOnly && !fSaveLogToMacro) {
6292  if (rec > 0) {
6293 
6294  char *p = buf;
6295  r = rec;
6296  while (r) {
6297  Int_t w;
6298 
6299  w = write(fdout, p, r);
6300 
6301  if (w < 0) {
6302  SysError("RecvLogFile", "error writing to unit: %d", fdout);
6303  break;
6304  }
6305  r -= w;
6306  p += w;
6307  }
6308  } else if (rec < 0) {
6309  Error("RecvLogFile", "error during receiving log file");
6310  break;
6311  }
6312  }
6313  if (rec > 0) {
6314  buf[rec] = 0;
6315  EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6316  // If macro saving is enabled add to TMacro
6317  if (fSaveLogToMacro) fMacroLog.AddLine(buf);
6318  }
6319  }
6320 
6321  // If idle restore logs to main session window
6322  if (fRedirLog && IsIdle() && !TestBit(TProof::kIsMaster))
6323  fRedirLog = kFALSE;
6324 }
6325 
6326 ////////////////////////////////////////////////////////////////////////////////
6327 /// Notify locally 'msg' to the appropriate units (file, stdout, window)
6328 /// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6329 
6330 void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6331 {
6332  // Must have somenthing to notify
6333  Int_t len = 0;
6334  if (!msg || (len = strlen(msg)) <= 0)
6335  return;
6336 
6337  // Get suffix length if any
6338  Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6339 
6340  // Append messages to active logging unit
6341  Int_t fdout = -1;
6342  if (!fLogToWindowOnly) {
6343  fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6344  if (fdout < 0) {
6345  Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6346  " will not notify msgs", fdout);
6347  return;
6348  }
6349  lseek(fdout, (off_t) 0, SEEK_END);
6350  }
6351 
6352  if (!fLogToWindowOnly) {
6353  // Write to output unit (stdout or a log file)
6354  if (len > 0) {
6355  char *p = (char *)msg;
6356  Int_t r = len;
6357  while (r) {
6358  Int_t w = write(fdout, p, r);
6359  if (w < 0) {
6360  SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6361  break;
6362  }
6363  r -= w;
6364  p += w;
6365  }
6366  // Add a suffix, if requested
6367  if (lsfx > 0)
6368  if (write(fdout, sfx, lsfx) != lsfx)
6369  SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6370  }
6371  }
6372  if (len > 0) {
6373  // Publish the message to the separate window (if the latter is missing
6374  // the message will just get lost)
6375  EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6376  }
6377 
6378  // If idle restore logs to main session window
6379  if (fRedirLog && IsIdle())
6380  fRedirLog = kFALSE;
6381 }
6382 
6383 ////////////////////////////////////////////////////////////////////////////////
6384 /// Log a message into the appropriate window by emitting a signal.
6385 
6386 void TProof::LogMessage(const char *msg, Bool_t all)
6387 {
6388  PDB(kGlobal,1)
6389  Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6390  all ? "true" : "false");
6391 
6392  if (gROOT->IsBatch()) {
6393  PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6394  return;
6395  }
6396 
6397  if (msg)
6398  EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6399 
6400  // Re-position at the beginning of the file, if requested.
6401  // This is used by the dialog when it re-opens the log window to
6402  // provide all the session messages
6403  if (all)
6404  lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6405 
6406  const Int_t kMAXBUF = 32768;
6407  char buf[kMAXBUF];
6408  Int_t len;
6409  do {
6410  while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6411  TSystem::GetErrno() == EINTR)
6413 
6414  if (len < 0) {
6415  Error("LogMessage", "error reading log file");
6416  break;
6417  }
6418 
6419  if (len > 0) {
6420  buf[len] = 0;
6421  EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6422  }
6423 
6424  } while (len > 0);
6425 }
6426 
6427 ////////////////////////////////////////////////////////////////////////////////
6428 /// Send to all active slaves servers the current slave group size
6429 /// and their unique id. Returns number of active slaves.
6430 /// Returns -1 in case of error.
6431 
6433 {
6434  if (!IsValid()) return -1;
6435  if (TestBit(TProof::kIsClient)) return 0;
6436  if (!fSendGroupView) return 0;
6438 
6439  TIter next(fActiveSlaves);
6440  TSlave *sl;
6441 
6442  int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6443  char str[32];
6444 
6445  while ((sl = (TSlave *)next())) {
6446  snprintf(str, 32, "%d %d", cnt, size);
6447  if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6448  MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6449  bad++;
6450  } else
6451  cnt++;
6452  }
6453 
6454  // Send the group view again in case there was a change in the
6455  // group size due to a bad slave
6456 
6457  if (bad) SendGroupView();
6458 
6459  return GetNumberOfActiveSlaves();
6460 }
6461 
6462 ////////////////////////////////////////////////////////////////////////////////
6463 /// Static method to extract the filename (if any) form a CINT command.
6464 /// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6465 /// appliable.
6466 
6467 Bool_t TProof::GetFileInCmd(const char *cmd, TString &fn)
6468 {
6469  TString s = cmd;
6470  s = s.Strip(TString::kBoth);
6471 
6472  if (s.Length() > 0 &&
6473  (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6474  TString file = s(2, s.Length());
6475  TString acm, arg, io;
6476  fn = gSystem->SplitAclicMode(file, acm, arg, io);
6477  if (!fn.IsNull())
6478  return kTRUE;
6479  }
6480 
6481  // Not found
6482  return kFALSE;
6483 }
6484 
6485 ////////////////////////////////////////////////////////////////////////////////
6486 /// Send command to be executed on the PROOF master and/or slaves.
6487 /// If plusMaster is kTRUE then exeucte on slaves and master too.
6488 /// Command can be any legal command line command. Commands like
6489 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6490 /// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6491 /// succes.
6492 
6493 Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6494 {
6495  return Exec(cmd, kActive, plusMaster);
6496 }
6497 
6498 ////////////////////////////////////////////////////////////////////////////////
6499 /// Send command to be executed on the PROOF master and/or slaves.
6500 /// Command can be any legal command line command. Commands like
6501 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6502 /// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6503 /// succes.
6504 
6505 Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6506 {
6507  if (!IsValid()) return -1;
6508 
6509  TString s = cmd;
6510  s = s.Strip(TString::kBoth);
6511 
6512  if (!s.Length()) return 0;
6513 
6514  // check for macro file and make sure the file is available on all slaves
6515  TString filename;
6516  if (TProof::GetFileInCmd(s.Data(), filename)) {
6517  char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6518  if (fn) {
6519  if (GetNumberOfUniqueSlaves() > 0) {
6520  if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6521  Error("Exec", "file %s could not be transfered", fn);
6522  delete [] fn;
6523  return -1;
6524  }
6525  } else {
6526  TString scmd = s(0,3) + fn;
6527  Int_t n = SendCommand(scmd, list);
6528  delete [] fn;
6529  return n;
6530  }
6531  } else {
6532  Error("Exec", "macro %s not found", filename.Data());
6533  return -1;
6534  }
6535  delete [] fn;
6536  }
6537 
6538  if (plusMaster) {
6539  if (IsLite()) {
6540  gROOT->ProcessLine(cmd);
6541  } else {
6542  DeactivateWorker("*");
6543  Int_t res = SendCommand(cmd, list);
6544  ActivateWorker("restore");
6545  if (res < 0)
6546  return res;
6547  }
6548  }
6549  return SendCommand(cmd, list);
6550 }
6551 
6552 ////////////////////////////////////////////////////////////////////////////////
6553 /// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6554 /// Command can be any legal command line command. Commands like
6555 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6556 /// to the PROOF cluster.
6557 /// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6558 /// TMacro, accessible via TMacro::GetMacroLog();
6559 /// Returns -1 in case of error, >=0 in case of succes.
6560 
6561 Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6562 {
6563  if (!IsValid()) return -1;
6564 
6565  TString s = cmd;
6566  s = s.Strip(TString::kBoth);
6567 
6568  if (!s.Length()) return 0;
6569 
6570  Int_t res = 0;
6571  if (IsLite()) {
6572  gROOT->ProcessLine(cmd);
6573  } else {
6574  Bool_t oldRedirLog = fRedirLog;
6575  fRedirLog = kTRUE;
6576  // Deactivate all workers
6577  DeactivateWorker("*");
6578  fRedirLog = kFALSE;
6579  // Reactivate the target ones, if needed
6580  if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6581  // Honour log-to-macro-saving settings
6582  Bool_t oldSaveLog = fSaveLogToMacro;
6583  fSaveLogToMacro = logtomacro;
6584  res = SendCommand(cmd, kActive);
6585  fSaveLogToMacro = oldSaveLog;
6586  fRedirLog = kTRUE;
6587  ActivateWorker("restore");
6588  fRedirLog = oldRedirLog;
6589  }
6590  // Done
6591  return res;
6592 }
6593 
6594 ////////////////////////////////////////////////////////////////////////////////
6595 /// Send command to be executed on the PROOF master and/or slaves.
6596 /// Command can be any legal command line command, however commands
6597 /// like ".x file.C" or ".L file.C" will not cause the file.C to be
6598 /// transfered to the PROOF cluster. In that case use TProof::Exec().
6599 /// Returns the status send by the remote server as part of the
6600 /// kPROOF_LOGDONE message. Typically this is the return code of the
6601 /// command on the remote side. Returns -1 in case of error.
6602 
6603 Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6604 {
6605  if (!IsValid()) return -1;
6606 
6607  Broadcast(cmd, kMESS_CINT, list);
6608  Collect(list);
6609 
6610  return fStatus;
6611 }
6612 
6613 ////////////////////////////////////////////////////////////////////////////////
6614 /// Get value of environment variable 'env' on node 'ord'
6615 
6616 TString TProof::Getenv(const char *env, const char *ord)
6617 {
6618  // The command to be executed
6619  TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6620  if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6621  // Get the line
6622  TObjString *os = fMacroLog.GetLineWith("const char");
6623  if (os) {
6624  TString info;
6625  Ssiz_t from = 0;
6626  os->GetString().Tokenize(info, from, "\"");
6627  os->GetString().Tokenize(info, from, "\"");
6628  if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6629  return info;
6630  }
6631  return TString("");
6632 }
6633 
6634 ////////////////////////////////////////////////////////////////////////////////
6635 /// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6636 
6637 Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6638 {
6639  // The command to be executed
6640  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6641  // Exectute the command saving the logs to macro
6642  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6643  // Get the line
6644  TObjString *os = fMacroLog.GetLineWith("const char");
6645  Int_t rc = -1;
6646  if (os) {
6647  Ssiz_t fst = os->GetString().First('\"');
6648  Ssiz_t lst = os->GetString().Last('\"');
6649  TString info = os->GetString()(fst+1, lst-fst-1);
6650  if (info.IsDigit()) {
6651  env = info.Atoi();
6652  rc = 0;
6653  if (gDebug > 0)
6654  Printf("%s: %d", rcenv, env);
6655  }
6656  }
6657  return rc;
6658 }
6659 
6660 ////////////////////////////////////////////////////////////////////////////////
6661 /// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6662 
6663 Int_t TProof::GetRC(const char *rcenv, Double_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.IsFloat()) {
6677  env = info.Atof();
6678  rc = 0;
6679  if (gDebug > 0)
6680  Printf("%s: %f", rcenv, env);
6681  }
6682  }
6683  return rc;
6684 }
6685 
6686 ////////////////////////////////////////////////////////////////////////////////
6687 /// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6688 
6689 Int_t TProof::GetRC(const char *rcenv, TString &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  env = os->GetString()(fst+1, lst-fst-1);
6702  rc = 0;
6703  if (gDebug > 0)
6704  Printf("%s: %s", rcenv, env.Data());
6705  }
6706  return rc;
6707 }
6708 
6709 ////////////////////////////////////////////////////////////////////////////////
6710 /// Transfer the current state of the master to the active slave servers.
6711 /// The current state includes: the current working directory, etc.
6712 /// Returns the number of active slaves. Returns -1 in case of error.
6713 
6715 {
6716  if (!IsValid()) return -1;
6717 
6718  // Go to the new directory, reset the interpreter environment and
6719  // tell slave to delete all objects from its new current directory.
6720  Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6721 
6722  return GetParallel();
6723 }
6724 
6725 ////////////////////////////////////////////////////////////////////////////////
6726 /// Transfer the current state of the master to the active slave servers.
6727 /// The current state includes: the current working directory, etc.
6728 /// Returns the number of active slaves. Returns -1 in case of error.
6729 
6731 {
6732  if (!IsValid()) return -1;
6733 
6734  // Go to the new directory, reset the interpreter environment and
6735  // tell slave to delete all objects from its new current directory.
6736  Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6737 
6738  return GetParallel();
6739 }
6740 
6741 ////////////////////////////////////////////////////////////////////////////////
6742 /// Transfer the initial (i.e. current) state of the master to all
6743 /// slave servers. Currently the initial state includes: log level.
6744 /// Returns the number of active slaves. Returns -1 in case of error.
6745 
6747 {
6748  if (!IsValid()) return -1;
6749 
6751 
6752  return GetNumberOfActiveSlaves();
6753 }
6754 
6755 ////////////////////////////////////////////////////////////////////////////////
6756 /// Check if a file needs to be send to the slave. Use the following
6757 /// algorithm:
6758 /// - check if file appears in file map
6759 /// - if yes, get file's modtime and check against time in map,
6760 /// if modtime not same get md5 and compare against md5 in map,
6761 /// if not same return kTRUE.
6762 /// - if no, get file's md5 and modtime and store in file map, ask
6763 /// slave if file exists with specific md5, if yes return kFALSE,
6764 /// if no return kTRUE.
6765 /// The options 'cpopt' define if to copy things from cache to sandbox and what.
6766 /// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6767 /// must be set in cpopt; the default is copy everything.
6768 /// Returns kTRUE in case file needs to be send, returns kFALSE in case
6769 /// file is already on remote node.
6770 
6771 Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6772 {
6773  Bool_t sendto = kFALSE;
6774 
6775  // create worker based filename
6776  TString sn = slave->GetName();
6777  sn += ":";
6778  sn += slave->GetOrdinal();
6779  sn += ":";
6780  sn += gSystem->BaseName(file);
6781 
6782  // check if file is in map
6783  FileMap_t::const_iterator it;
6784  if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6785  // file in map
6786  MD5Mod_t md = (*it).second;
6787  if (md.fModtime != modtime) {
6788  TMD5 *md5 = TMD5::FileChecksum(file);
6789  if (md5) {
6790  if ((*md5) != md.fMD5) {
6791  sendto = kTRUE;
6792  md.fMD5 = *md5;
6793  md.fModtime = modtime;
6794  fFileMap[sn] = md;
6795  // When on the master, the master and/or slaves may share
6796  // their file systems and cache. Therefore always make a
6797  // check for the file. If the file already exists with the
6798  // expected md5 the kPROOF_CHECKFILE command will cause the
6799  // file to be copied from cache to slave sandbox.
6800  if (TestBit(TProof::kIsMaster)) {
6801  sendto = kFALSE;
6802  TMessage mess(kPROOF_CHECKFILE);
6803  mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6804  slave->GetSocket()->Send(mess);
6805 
6806  fCheckFileStatus = 0;
6808  sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6809  }
6810  }
6811  delete md5;
6812  } else {
6813  Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6814  return kFALSE;
6815  }
6816  }
6817  } else {
6818  // file not in map
6819  TMD5 *md5 = TMD5::FileChecksum(file);
6820  MD5Mod_t md;
6821  if (md5) {
6822  md.fMD5 = *md5;
6823  md.fModtime = modtime;
6824  fFileMap[sn] = md;
6825  delete md5;
6826  } else {
6827  Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6828  return kFALSE;
6829  }
6830  TMessage mess(kPROOF_CHECKFILE);
6831  mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6832  slave->GetSocket()->Send(mess);
6833 
6834  fCheckFileStatus = 0;
6836  sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6837  }
6838 
6839  return sendto;
6840 }
6841 
6842 ////////////////////////////////////////////////////////////////////////////////
6843 /// Send a file to master or slave servers. Returns number of slaves
6844 /// the file was sent to, maybe 0 in case master and slaves have the same
6845 /// file system image, -1 in case of error.
6846 /// If defined, send to worker 'wrk' only.
6847 /// If defined, the full path of the remote path will be rfile.
6848 /// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6849 /// (to copy to the cache on a different name use rfile = "cache:newname").
6850 /// The mask 'opt' is an or of ESendFileOpt:
6851 ///
6852 /// kAscii (0x0) if set true ascii file transfer is used
6853 /// kBinary (0x1) if set true binary file transfer is used
6854 /// kForce (0x2) if not set an attempt is done to find out
6855 /// whether the file really needs to be downloaded
6856 /// (a valid copy may already exist in the cache
6857 /// from a previous run); the bit is set by
6858 /// UploadPackage, since the check is done elsewhere.
6859 /// kForward (0x4) if set, ask server to forward the file to slave
6860 /// or submaster (meaningless for slave servers).
6861 /// kCpBin (0x8) Retrieve from the cache the binaries associated
6862 /// with the file
6863 /// kCp (0x10) Retrieve the files from the cache
6864 ///
6865 
6866 Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6867 {
6868  if (!IsValid()) return -1;
6869 
6870  // Use the active slaves list ...
6871  TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6872  // ... or the specified slave, if any
6873  if (wrk) {
6874  slaves = new TList();
6875  slaves->Add(wrk);
6876  }
6877 
6878  if (slaves->GetSize() == 0) return 0;
6879 
6880 #ifndef R__WIN32
6881  Int_t fd = open(file, O_RDONLY);
6882 #else
6883  Int_t fd = open(file, O_RDONLY | O_BINARY);
6884 #endif
6885  if (fd < 0) {
6886  SysError("SendFile", "cannot open file %s", file);
6887  return -1;
6888  }
6889 
6890  // Get info about the file
6891  Long64_t size = -1;
6892  Long_t id, flags, modtime = 0;
6893  if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6894  Error("SendFile", "cannot stat file %s", file);
6895  close(fd);
6896  return -1;
6897  }
6898  if (size == 0) {
6899  Error("SendFile", "empty file %s", file);
6900  close(fd);
6901  return -1;
6902  }
6903 
6904  // Decode options
6905  Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6906  Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6907  Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6908 
6909  // Copy options
6910  Int_t cpopt = 0;
6911  if ((opt & kCp)) cpopt |= kCp;
6912  if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6913 
6914  const Int_t kMAXBUF = 32768; //16384 //65536;
6915  char buf[kMAXBUF];
6916  Int_t nsl = 0;
6917 
6918  TIter next(slaves);
6919  TSlave *sl;
6920  TString fnam(rfile);
6921  if (fnam == "cache") {
6922  fnam += TString::Format(":%s", gSystem->BaseName(file));
6923  } else if (fnam.IsNull()) {
6924  fnam = gSystem->BaseName(file);
6925  }
6926  // List on which we will collect the results
6927  fStatus = 0;
6928  while ((sl = (TSlave *)next())) {
6929  if (!sl->IsValid())
6930  continue;
6931 
6932  Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6933  // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6934  // is false. Masters might still need to send the file to newly added
6935  // slaves.
6936  PDB(kPackage,2) {
6937  const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6938  Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6939  file, sl->GetName(), sl->GetOrdinal(), sendto);
6940  }
6941  if (sl->fSlaveType == TSlave::kSlave && !sendto)
6942  continue;
6943  // The value of 'size' is used as flag remotely, so we need to
6944  // reset it to 0 if we are not going to send the file
6945  Long64_t siz = sendto ? size : 0;
6946  snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6947  if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6948  MarkBad(sl, "could not send kPROOF_SENDFILE request");
6949  continue;
6950  }
6951 
6952  if (sendto) {
6953 
6954  lseek(fd, 0, SEEK_SET);
6955 
6956  Int_t len;
6957  do {
6958  while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6960 
6961  if (len < 0) {
6962  SysError("SendFile", "error reading from file %s", file);
6964  close(fd);
6965  return -1;
6966  }
6967 
6968  if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6969  SysError("SendFile", "error writing to slave %s:%s (now offline)",
6970  sl->GetName(), sl->GetOrdinal());
6971  MarkBad(sl, "sendraw failure");
6972  sl = 0;
6973  break;
6974  }
6975 
6976  } while (len > 0);
6977 
6978  nsl++;
6979  }
6980  // Wait for the operation to be done
6981  if (sl)
6983  }
6984 
6985  close(fd);
6986 
6987  // Cleanup temporary list, if any
6988  if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
6989  SafeDelete(slaves);
6990 
6991  // We return failure is at least one unique worker failed
6992  return (fStatus != 0) ? -1 : nsl;
6993 }
6994 
6995 ////////////////////////////////////////////////////////////////////////////////
6996 /// Sends an object to master and workers and expect them to send back a
6997 /// message with the output of its TObject::Print(). Returns -1 on error, the
6998 /// number of workers that received the objects on success.
6999 
7001 {
7002  if (!IsValid() || !obj) return -1;
7003  TMessage mess(kPROOF_ECHO);
7004  mess.WriteObject(obj);
7005  return Broadcast(mess);
7006 }
7007 
7008 ////////////////////////////////////////////////////////////////////////////////
7009 /// Sends a string to master and workers and expect them to echo it back to
7010 /// the client via a message. It is a special case of the generic Echo()
7011 /// that works with TObjects. Returns -1 on error, the number of workers that
7012 /// received the message on success.
7013 
7014 Int_t TProof::Echo(const char *str)
7015 {
7016  TObjString *os = new TObjString(str);
7017  Int_t rv = Echo(os);
7018  delete os;
7019  return rv;
7020 }
7021 
7022 ////////////////////////////////////////////////////////////////////////////////
7023 /// Send object to master or slave servers. Returns number of slaves object
7024 /// was sent to, -1 in case of error.
7025 
7027 {
7028  if (!IsValid() || !obj) return -1;
7029 
7030  TMessage mess(kMESS_OBJECT);
7031 
7032  mess.WriteObject(obj);
7033  return Broadcast(mess, list);
7034 }
7035 
7036 ////////////////////////////////////////////////////////////////////////////////
7037 /// Send print command to master server. Returns number of slaves message
7038 /// was sent to. Returns -1 in case of error.
7039 
7041 {
7042  if (!IsValid()) return -1;
7043 
7044  Broadcast(option, kPROOF_PRINT, kActive);
7045  return Collect(kActive, fCollectTimeout);
7046 }
7047 
7048 ////////////////////////////////////////////////////////////////////////////////
7049 /// Set server logging level.
7050 
7052 {
7053  char str[32];
7054  fLogLevel = level;
7055  gProofDebugLevel = level;
7057  snprintf(str, 32, "%d %u", level, mask);
7059 }
7060 
7061 ////////////////////////////////////////////////////////////////////////////////
7062 /// Switch ON/OFF the real-time logging facility. When this option is
7063 /// ON, log messages from processing are sent back as they come, instead of
7064 /// being sent back at the end in one go. This may help debugging or monitoring
7065 /// in some cases, but, depending on the amount of log, it may have significant
7066 /// consequencies on the load over the network, so it must be used with care.
7067 
7069 {
7070  if (IsValid()) {
7072  mess << on;
7073  Broadcast(mess);
7074  } else {
7075  Warning("SetRealTimeLog","session is invalid - do nothing");
7076  }
7077 }
7078 
7079 ////////////////////////////////////////////////////////////////////////////////
7080 /// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7081 /// selection is done (if nodes is less than the available nodes).
7082 /// Returns the number of parallel slaves. Returns -1 in case of error.
7083 
7085 {
7086  if (!IsValid()) return -1;
7087 
7088  if (TestBit(TProof::kIsMaster)) {
7089  if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7090  return SendCurrentState();
7091  } else {
7092  if (nodes < 0) {
7093  PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7094  } else {
7095  PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7096  nodes == 1 ? "" : "s");
7097  }
7098  TMessage mess(kPROOF_PARALLEL);
7099  mess << nodes << random;
7100  Broadcast(mess);
7102  Int_t n = GetParallel();
7103  PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7104  return n;
7105  }
7106 }
7107 
7108 ////////////////////////////////////////////////////////////////////////////////
7109 /// Tell PROOF how many slaves to use in parallel. Returns the number of
7110 /// parallel slaves. Returns -1 in case of error.
7111 
7113 {
7114  // If delayed startup reset settings, if required
7115  if (fDynamicStartup && nodes < 0) {
7116  if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7117  }
7118 
7119  Int_t n = SetParallelSilent(nodes, random);
7120  if (TestBit(TProof::kIsClient)) {
7121  if (n < 1) {
7122  Printf("PROOF set to sequential mode");
7123  } else {
7124  TString subfix = (n == 1) ? "" : "s";
7125  if (random)
7126  subfix += ", randomly selected";
7127  Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7128  }
7129  } else if (fDynamicStartup && nodes >= 0) {
7130  if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7131  gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7132  }
7133  return n;
7134 }
7135 
7136 ////////////////////////////////////////////////////////////////////////////////
7137 /// Add nWorkersToAdd workers to current list of workers. This function is
7138 /// works on the master only, and only when an analysis is ongoing. A message
7139 /// is sent back to the client when we go "more" parallel.
7140 /// Returns -1 on error, number of total (not added!) workers on success.
7141 
7143 {
7144  if (!IsValid() || !IsMaster() || IsIdle()) {
7145  Error("GoMoreParallel", "can't invoke here -- should not happen!");
7146  return -1;
7147  }
7148  if (!gProofServ && !IsLite()) {
7149  Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7150  return -1;
7151  }
7152 
7153  TSlave *sl = 0x0;
7154  TIter next( fSlaves );
7155  Int_t nAddedWorkers = 0;
7156 
7157  while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7158  (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7159 
7160  // If worker is of an invalid type, break everything: it should not happen!
7161  if ((sl->GetSlaveType() != TSlave::kSlave) &&
7162  (sl->GetSlaveType() != TSlave::kMaster)) {
7163  Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7164  sl->GetName(), sl->GetOrdinal());
7165  R__ASSERT(0);
7166  }
7167 
7168  // Skip current worker if it is not a good candidate
7169  if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7170  (strcmp("IGNORE", sl->GetImage()) == 0)) {
7171  PDB(kGlobal, 2)
7172  Info("GoMoreParallel", "Worker %s:%s won't be considered",
7173  sl->GetName(), sl->GetOrdinal());
7174  continue;
7175  }
7176 
7177  // Worker is good but it is already active: skip it
7178  if (fActiveSlaves->FindObject(sl)) {
7179  Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7180  sl->GetName(), sl->GetOrdinal());
7181  continue;
7182  }
7183 
7184  //
7185  // From here on: worker is a good candidate
7186  //
7187 
7188  if (sl->GetSlaveType() == TSlave::kSlave) {
7190  fActiveSlaves->Add(sl);
7191  fInactiveSlaves->Remove(sl);
7192  fActiveMonitor->Add(sl->GetSocket());
7193  nAddedWorkers++;
7194  PDB(kGlobal, 2)
7195  Info("GoMoreParallel", "Worker %s:%s marked as active!",
7196  sl->GetName(), sl->GetOrdinal());
7197  }
7198  else {
7199  // Can't add masters dynamically: this should not happen!
7200  Error("GoMoreParallel", "Dynamic addition of master is not supported");
7201  R__ASSERT(0);
7202  }
7203 
7204  } // end loop over all slaves
7205 
7206  // Get slave status (will set the slaves fWorkDir correctly)
7207  PDB(kGlobal, 3)
7208  Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7209  AskStatistics();
7210 
7211  // Find active slaves with unique image
7212  PDB(kGlobal, 3)
7213  Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7214  FindUniqueSlaves();
7215 
7216  // Send new group-view to slaves
7217  PDB(kGlobal, 3)
7218  Info("GoMoreParallel", "Will invoke SendGroupView()");
7219  SendGroupView();
7220 
7221  PDB(kGlobal, 3)
7222  Info("GoMoreParallel", "Will invoke GetParallel()");
7223  Int_t nTotalWorkers = GetParallel();
7224 
7225  // Notify the client that we've got more workers, and print info on
7226  // Master's log as well
7227  TString s;
7228  s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7229  nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7230  nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7232  Info("GoMoreParallel", "%s", s.Data());
7233 
7234  return nTotalWorkers;
7235 }
7236 
7237 ////////////////////////////////////////////////////////////////////////////////
7238 /// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7239 /// list is sorted by slave performace the active list will contain first
7240 /// the most performant nodes. Returns the number of active slaves.
7241 /// If random is TRUE, and nodes is less than the number of available workers,
7242 /// a random selection is done.
7243 /// Returns -1 in case of error.
7244 
7246 {
7247  if (!IsValid()) return -1;
7248 
7249  fActiveSlaves->Clear();
7251 
7252  // Prepare the list of candidates first.
7253  // Algorithm depends on random option.
7254  TSlave *sl = 0;
7255  TList *wlst = new TList;
7256  TIter nxt(fSlaves);
7258  while ((sl = (TSlave *)nxt())) {
7259  if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7260  if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7261  if ((sl->GetSlaveType() != TSlave::kSlave) &&
7262  (sl->GetSlaveType() != TSlave::kMaster)) {
7263  Error("GoParallel", "TSlave is neither Master nor Slave");
7264  R__ASSERT(0);
7265  }
7266  // Good candidate
7267  wlst->Add(sl);
7268  // Set it inactive
7269  fInactiveSlaves->Add(sl);
7271  }
7272  }
7273  Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7274  int cnt = 0;
7276  while (cnt < nwrks) {
7277  // Random choice, if requested
7278  if (random) {
7279  Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7280  sl = (TSlave *) wlst->At(iwrk);
7281  } else {
7282  // The first available
7283  sl = (TSlave *) wlst->First();
7284  }
7285  if (!sl) {
7286  Error("GoParallel", "attaching to candidate!");
7287  break;
7288  }
7289  // Remove from the list
7290  wlst->Remove(sl);
7291 
7292  Int_t slavenodes = 0;
7293  if (sl->GetSlaveType() == TSlave::kSlave) {
7295  fActiveSlaves->Add(sl);
7296  fInactiveSlaves->Remove(sl);
7297  fActiveMonitor->Add(sl->GetSocket());
7298  slavenodes = 1;
7299  } else if (sl->GetSlaveType() == TSlave::kMaster) {
7300  fEndMaster = kFALSE;
7301  TMessage mess(kPROOF_PARALLEL);
7302  if (!attach) {
7303  Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7304  mess << nn;
7305  } else {
7306  // To get the number of slaves
7307  mess.SetWhat(kPROOF_LOGFILE);
7308  mess << -1 << -1;
7309  }
7310  if (sl->GetSocket()->Send(mess) == -1) {
7311  MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7312  slavenodes = 0;
7313  } else {
7314  Collect(sl, fCollectTimeout);
7315  if (sl->IsValid()) {
7317  fActiveSlaves->Add(sl);
7318  fInactiveSlaves->Remove(sl);
7319  fActiveMonitor->Add(sl->GetSocket());
7320  if (sl->GetParallel() > 0) {
7321  slavenodes = sl->GetParallel();
7322  } else {
7323  // Sequential mode: the master acts as a worker
7324  slavenodes = 1;
7325  }
7326  } else {
7327  MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7328  slavenodes = 0;
7329  }
7330  }
7331  }
7332  // 'slavenodes' may be different than 1 in multimaster setups
7333  cnt += slavenodes;
7334  }
7335 
7336  // Cleanup list
7337  wlst->SetOwner(0);
7338  SafeDelete(wlst);
7339 
7340  // Get slave status (will set the slaves fWorkDir correctly)
7341  AskStatistics();
7342 
7343  // Find active slaves with unique image
7344  FindUniqueSlaves();
7345 
7346  // Send new group-view to slaves
7347  if (!attach)
7348  SendGroupView();
7349 
7350  Int_t n = GetParallel();
7351 
7352  if (TestBit(TProof::kIsClient)) {
7353  if (n < 1)
7354  printf("PROOF set to sequential mode\n");
7355  else
7356  printf("PROOF set to parallel mode (%d worker%s)\n",
7357  n, n == 1 ? "" : "s");
7358  }
7359 
7360  PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7361  return n;
7362 }
7363 
7364 ////////////////////////////////////////////////////////////////////////////////
7365 /// List contents of the data directory in the sandbox.
7366 /// This is the place where files produced by the client queries are kept
7367 
7369 {
7370  if (!IsValid() || !fManager) return;
7371 
7372  // This is run via the manager
7373  fManager->Find("~/data", "-type f", "all");
7374 }
7375 
7376 ////////////////////////////////////////////////////////////////////////////////
7377 /// Remove files for the data directory.
7378 /// The option 'what' can take the values:
7379 /// kPurge remove all files and directories under '~/data'
7380 /// kUnregistered remove only files not in registered datasets (default)
7381 /// kDataset remove files belonging to dataset 'dsname'
7382 /// User is prompt for confirmation, unless kForceClear is ORed with the option
7383 
7384 void TProof::ClearData(UInt_t what, const char *dsname)
7385 {
7386  if (!IsValid() || !fManager) return;
7387 
7388  // Check whether we need to prompt
7389  TString prompt, a("Y");
7390  Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7391  Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7392 
7393  // If all just send the request
7394  if ((what & TProof::kPurge)) {
7395  // Prompt, if requested
7396  if (doask && !Prompt("Do you really want to remove all data files")) return;
7397  if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7398  Warning("ClearData", "problems purging data directory");
7399  return;
7400  } else if ((what & TProof::kDataset)) {
7401  // We must have got a name
7402  if (!dsname || strlen(dsname) <= 0) {
7403  Error("ClearData", "dataset name mandatory when removing a full dataset");
7404  return;
7405  }
7406  // Check if the dataset is registered
7407  if (!ExistsDataSet(dsname)) {
7408  Error("ClearData", "dataset '%s' does not exists", dsname);
7409  return;
7410  }
7411  // Get the file content
7412  TFileCollection *fc = GetDataSet(dsname);
7413  if (!fc) {
7414  Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7415  return;
7416  }
7417  // Prompt, if requested
7418  TString pmpt = TString::Format("Do you really want to remove all data files"
7419  " of dataset '%s'", dsname);
7420  if (doask && !Prompt(pmpt.Data())) return;
7421 
7422  // Loop through the files
7423  Bool_t rmds = kTRUE;
7424  TIter nxf(fc->GetList());
7425  TFileInfo *fi = 0;
7426  Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7427  while ((fi = (TFileInfo *) nxf())) {
7428  // Fill the host info
7429  TString host, file;
7430  // Take info from the current url
7431  if (!(fi->GetFirstUrl())) {
7432  Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7433  fi->GetName());
7434  continue;
7435  }
7436  TUrl uf(*(fi->GetFirstUrl()));
7437  file = uf.GetFile();
7438  host = uf.GetHost();
7439  // Now search for any "file:" url
7440  Int_t nurl = fi->GetNUrls();
7441  fi->ResetUrl();
7442  TUrl *up = 0;
7443  while (nurl-- && fi->NextUrl()) {
7444  up = fi->GetCurrentUrl();
7445  if (!strcmp(up->GetProtocol(), "file")) {
7446  TString opt(up->GetOptions());
7447  if (opt.BeginsWith("node=")) {
7448  host=opt;
7449  host.ReplaceAll("node=","");
7450  file = up->GetFile();
7451  break;
7452  }
7453  }
7454  }
7455  // Issue a remove request now
7456  if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7457  Error("ClearData", "problems removing '%s'", file.Data());
7458  // Some files not removed: keep the meta info about this dataset
7459  rmds = kFALSE;
7460  }
7461  rfiles++;
7462  ClearDataProgress(rfiles, nfiles);
7463  }
7464  fprintf(stderr, "\n");
7465  if (rmds) {
7466  // All files were removed successfully: remove also the dataset meta info
7467  RemoveDataSet(dsname);
7468  }
7469  } else if (what & TProof::kUnregistered) {
7470 
7471  // Get the existing files
7472  TString outtmp("ProofClearData_");
7473  FILE *ftmp = gSystem->TempFileName(outtmp);
7474  if (!ftmp) {
7475  Error("ClearData", "cannot create temp file for logs");
7476  return;
7477  }
7478  fclose(ftmp);
7480  gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7481  ShowData();
7482  gSystem->RedirectOutput(0, 0, &h);
7483  // Parse the output file now
7484  std::ifstream in;
7485  in.open(outtmp.Data());
7486  if (!in.is_open()) {
7487  Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7488  gSystem->Unlink(outtmp);
7489  return;
7490  }
7491  // Go through
7492  Int_t nfiles = 0;
7493  TMap *afmap = new TMap;
7494  TString line, host, file;
7495  Int_t from = 0;
7496  while (in.good()) {
7497  line.ReadLine(in);
7498  if (line.IsNull()) continue;
7499  while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7500  from = 0;
7501  host = "";
7502  if (!line.Tokenize(host, from, "| ")) continue;
7503  file = "";
7504  if (!line.Tokenize(file, from, "| ")) continue;
7505  if (!host.IsNull() && !file.IsNull()) {
7506  TList *fl = (TList *) afmap->GetValue(host.Data());
7507  if (!fl) {
7508  fl = new TList();
7509  fl->SetName(host);
7510  afmap->Add(new TObjString(host), fl);
7511  }
7512  fl->Add(new TObjString(file));
7513  nfiles++;
7514  PDB(kDataset,2)
7515  Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7516  } else {
7517  Warning("ClearData", "found incomplete line: '%s'", line.Data());
7518  }
7519  }
7520  // Close and remove the file
7521  in.close();
7522  gSystem->Unlink(outtmp);
7523 
7524  // Get registered data files
7525  TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7526  TMap *fcmap = GetDataSets(sel);
7527  if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7528  PDB(kDataset,1)
7529  Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7530  SafeDelete(fcmap);
7531  }
7532 
7533  // Go thorugh and prepare the lists per node
7534  TString opt;
7535  TObjString *os = 0;
7536  if (fcmap) {
7537  TIter nxfc(fcmap);
7538  while ((os = (TObjString *) nxfc())) {
7539  TFileCollection *fc = 0;
7540  if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7541  TFileInfo *fi = 0;
7542  TIter nxfi(fc->GetList());
7543  while ((fi = (TFileInfo *) nxfi())) {
7544  // Get special "file:" url
7545  fi->ResetUrl();
7546  Int_t nurl = fi->GetNUrls();
7547  TUrl *up = 0;
7548  while (nurl-- && fi->NextUrl()) {
7549  up = fi->GetCurrentUrl();
7550  if (!strcmp(up->GetProtocol(), "file")) {
7551  opt = up->GetOptions();
7552  if (opt.BeginsWith("node=")) {
7553  host=opt;
7554  host.ReplaceAll("node=","");
7555  file = up->GetFile();
7556  PDB(kDataset,2)
7557  Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7558  // Remove this from the full list, if there
7559  TList *fl = (TList *) afmap->GetValue(host.Data());
7560  if (fl) {
7561  TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7562  if (fn) {
7563  fl->Remove(fn);
7564  SafeDelete(fn);
7565  nfiles--;
7566  } else {
7567  Warning("ClearData",
7568  "registered file '%s' not found in the full list!",
7569  file.Data());
7570  }
7571  }
7572  break;
7573  }
7574  }
7575  }
7576  }
7577  }
7578  }
7579  // Clean up the the received map
7580  if (fcmap) fcmap->SetOwner(kTRUE);
7581  SafeDelete(fcmap);
7582  }
7583  // List of the files to be removed
7584  Info("ClearData", "%d unregistered files to be removed:", nfiles);
7585  afmap->Print();
7586  // Prompt, if requested
7587  TString pmpt = TString::Format("Do you really want to remove all %d"
7588  " unregistered data files", nfiles);
7589  if (doask && !Prompt(pmpt.Data())) return;
7590 
7591  // Remove one by one; we may implement a bloc remove in the future
7592  Int_t rfiles = 0;
7593  TIter nxls(afmap);
7594  while ((os = (TObjString *) nxls())) {
7595  TList *fl = 0;
7596  if ((fl = (TList *) afmap->GetValue(os))) {
7597  TIter nxf(fl);
7598  TObjString *fn = 0;
7599  while ((fn = (TObjString *) nxf())) {
7600  // Issue a remove request now
7601  if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7602  Error("ClearData", "problems removing '%s' on host '%s'",
7603  fn->GetName(), os->GetName());
7604  }
7605  rfiles++;
7606  ClearDataProgress(rfiles, nfiles);
7607  }
7608  }
7609  }
7610  fprintf(stderr, "\n");
7611  // Final cleanup
7612  afmap->SetOwner(kTRUE);
7613  SafeDelete(afmap);
7614  }
7615 }
7616 
7617 ////////////////////////////////////////////////////////////////////////////////
7618 /// Prompt the question 'p' requiring an answer y,Y,n,N
7619 /// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7620 
7621 Bool_t TProof::Prompt(const char *p)
7622 {
7623  TString pp(p);
7624  if (!pp.Contains("?")) pp += "?";
7625  if (!pp.Contains("[y/N]")) pp += " [y/N]";
7626  TString a = Getline(pp.Data());
7627  if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7628  Printf("Please answer y, Y, n or N");
7629  // Unclear answer: assume negative
7630  return kFALSE;
7631  } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7632  // Explicitly Negative answer
7633  return kFALSE;
7634  }
7635  // Explicitly Positive answer
7636  return kTRUE;
7637 }
7638 
7639 ////////////////////////////////////////////////////////////////////////////////
7640 /// Progress bar for clear data
7641 
7643 {
7644  fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7645  for (Int_t l = 0; l < 20; l++) {
7646  if (r > 0 && t > 0) {
7647  if (l < 20*r/t)
7648  fprintf(stderr, "=");
7649  else if (l == 20*r/t)
7650  fprintf(stderr, ">");
7651  else if (l > 20*r/t)
7652  fprintf(stderr, ".");
7653  } else
7654  fprintf(stderr, "=");
7655  }
7656  fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7657 }
7658 
7659 ////////////////////////////////////////////////////////////////////////////////
7660 /// List contents of file cache. If all is true show all caches also on
7661 /// slaves. If everything is ok all caches are to be the same.
7662 
7664 {
7665  if (!IsValid()) return;
7666 
7667  TMessage mess(kPROOF_CACHE);
7668  mess << Int_t(kShowCache) << all;
7669  Broadcast(mess, kUnique);
7670 
7671  if (all) {
7672  TMessage mess2(kPROOF_CACHE);
7673  mess2 << Int_t(kShowSubCache) << all;
7674  Broadcast(mess2, fNonUniqueMasters);
7675 
7677  } else {
7679  }
7680 }
7681 
7682 ////////////////////////////////////////////////////////////////////////////////
7683 /// Remove file from all file caches. If file is 0 or "" or "*", remove all
7684 /// the files
7685 
7686 void TProof::ClearCache(const char *file)
7687 {
7688  if (!IsValid()) return;
7689 
7690  TMessage mess(kPROOF_CACHE);
7691  mess << Int_t(kClearCache) << TString(file);
7692  Broadcast(mess, kUnique);
7693 
7694  TMessage mess2(kPROOF_CACHE);
7695  mess2 << Int_t(kClearSubCache) << TString(file);
7696  Broadcast(mess2, fNonUniqueMasters);
7697 
7699 
7700  // clear file map so files get send again to remote nodes
7701  fFileMap.clear();
7702 }
7703 
7704 ////////////////////////////////////////////////////////////////////////////////
7705 /// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7706 
7707 void TProof::SystemCmd(const char *cmd, Int_t fdout)
7708 {
7709  if (fdout < 0) {
7710  // Exec directly the command
7711  gSystem->Exec(cmd);
7712  } else {
7713  // Exec via a pipe
7714  FILE *fin = gSystem->OpenPipe(cmd, "r");
7715  if (fin) {
7716  // Now we go
7717  char line[2048];
7718  while (fgets(line, 2048, fin)) {
7719  Int_t r = strlen(line);
7720  if (r > 0) {
7721  if (write(fdout, line, r) < 0) {
7722  ::Warning("TProof::SystemCmd",
7723  "errno %d writing to file descriptor %d",
7724  TSystem::GetErrno(), fdout);
7725  }
7726  } else {
7727  // Done
7728  break;
7729  }
7730  }
7731  gSystem->ClosePipe(fin);
7732  }
7733  }
7734 }
7735 
7736 ////////////////////////////////////////////////////////////////////////////////
7737 /// List contents of package directory. If all is true show all package
7738 /// directories also on slaves. If everything is ok all package directories
7739 /// should be the same. If redir is kTRUE the result is redirected to the log
7740 /// file (option available for internal actions).
7741 
7743 {
7744  if (!IsValid()) return;
7745 
7746  Bool_t oldredir = fRedirLog;
7747  if (redirlog) fRedirLog = kTRUE;
7748 
7749  // Active logging unit
7750  FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7751  if (!fout) {
7752  Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7753  " will not log msgs", fout);
7754  return;
7755  }
7756  lseek(fileno(fout), (off_t) 0, SEEK_END);
7757 
7758  if (TestBit(TProof::kIsClient)) {
7759  fPackMgr->Show();
7760  }
7761 
7762  // Nothing more to do if we are a Lite-session
7763  if (IsLite()) {
7764  fRedirLog = oldredir;
7765  return;
7766  }
7767 
7768  TMessage mess(kPROOF_CACHE);
7769  mess << Int_t(kShowPackages) << all;
7770  Broadcast(mess, kUnique);
7771 
7772  if (all) {
7773  TMessage mess2(kPROOF_CACHE);
7774  mess2 << Int_t(kShowSubPackages) << all;
7775  Broadcast(mess2, fNonUniqueMasters);
7776 
7778  } else {
7780  }
7781  // Restore logging option
7782  fRedirLog = oldredir;
7783 }
7784 
7785 ////////////////////////////////////////////////////////////////////////////////
7786 /// List which packages are enabled. If all is true show enabled packages
7787 /// for all active slaves. If everything is ok all active slaves should
7788 /// have the same packages enabled.
7789 
7791 {
7792  if (!IsValid()) return;
7793 
7794  if (TestBit(TProof::kIsClient)) {
7795  fPackMgr->ShowEnabled(TString::Format("*** Enabled packages on client on %s\n",
7796  gSystem->HostName()));
7797  }
7798 
7799  // Nothing more to do if we are a Lite-session
7800  if (IsLite()) return;
7801 
7802  TMessage mess(kPROOF_CACHE);
7803  mess << Int_t(kShowEnabledPackages) << all;
7804  Broadcast(mess);
7806 }
7807 
7808 ////////////////////////////////////////////////////////////////////////////////
7809 /// Remove all packages.
7810 /// Returns 0 in case of success and -1 in case of error.
7811 
7813 {
7814  if (!IsValid()) return -1;
7815 
7816  if (UnloadPackages() == -1)
7817  return -1;
7818 
7819  if (DisablePackages() == -1)
7820  return -1;
7821 
7822  return fStatus;
7823 }
7824 
7825 ////////////////////////////////////////////////////////////////////////////////
7826 /// Remove a specific package.
7827 /// Returns 0 in case of success and -1 in case of error.
7828 
7829 Int_t TProof::ClearPackage(const char *package)
7830 {
7831  if (!IsValid()) return -1;
7832 
7833  if (!package || !package[0]) {
7834  Error("ClearPackage", "need to specify a package name");
7835  return -1;
7836  }
7837 
7838  // if name, erroneously, is a par pathname strip off .par and path
7839  TString pac = package;
7840  if (pac.EndsWith(".par"))
7841  pac.Remove(pac.Length()-4);
7842  pac = gSystem->BaseName(pac);
7843 
7844  if (UnloadPackage(pac) == -1)
7845  return -1;
7846 
7847  if (DisablePackage(pac) == -1)
7848  return -1;
7849 
7850  return fStatus;
7851 }
7852 
7853 ////////////////////////////////////////////////////////////////////////////////
7854 /// Remove a specific package.
7855 /// Returns 0 in case of success and -1 in case of error.
7856 
7858 {
7859  if (!IsValid()) return -1;
7860 
7861  if (!pack || strlen(pack) <= 0) {
7862  Error("DisablePackage", "need to specify a package name");
7863  return -1;
7864  }
7865 
7866  // if name, erroneously, is a par pathname strip off .par and path
7867  TString pac = pack;
7868  if (pac.EndsWith(".par"))
7869  pac.Remove(pac.Length()-4);
7870  pac = gSystem->BaseName(pac);
7871 
7872  if (fPackMgr->Remove(pack) < 0)
7873  Warning("DisablePackage", "problem removing locally package '%s'", pack);
7874 
7875  // Nothing more to do if we are a Lite-session
7876  if (IsLite()) return 0;
7877 
7878  Int_t st = -1;
7879  Bool_t done = kFALSE;
7880  if (fManager) {
7881  // Try to do it via XROOTD (new way)
7882  TString path;
7883  path.Form("~/packages/%s", pack);
7884  if (fManager->Rm(path, "-rf", "all") != -1) {
7885  path.Append(".par");
7886  if (fManager->Rm(path, "-f", "all") != -1) {
7887  done = kTRUE;
7888  st = 0;
7889  }
7890  }
7891  }
7892  if (!done) {
7893  // Try via TProofServ (old way)
7894  TMessage mess(kPROOF_CACHE);
7895  mess << Int_t(kDisablePackage) << pac;
7896  Broadcast(mess, kUnique);
7897 
7898  TMessage mess2(kPROOF_CACHE);
7899  mess2 << Int_t(kDisableSubPackage) << pac;
7900  Broadcast(mess2, fNonUniqueMasters);
7901 
7903  st = fStatus;
7904  }
7905 
7906  // Done
7907  return st;
7908 }
7909 
7910 ////////////////////////////////////////////////////////////////////////////////
7911 /// Remove all packages.
7912 /// Returns 0 in case of success and -1 in case of error.
7913 
7915 {
7916  if (!IsValid()) return -1;
7917 
7918  // remove all packages on client
7919  if (fPackMgr->Remove(nullptr) < 0)
7920  Warning("DisablePackages", "problem removing packages locally");
7921 
7922  // Nothing more to do if we are a Lite-session
7923  if (IsLite()) return 0;
7924 
7925  Int_t st = -1;
7926  Bool_t done = kFALSE;
7927  if (fManager) {
7928  // Try to do it via XROOTD (new way)
7929  if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
7930  done = kTRUE;
7931  st = 0;
7932  }
7933  }
7934  if (!done) {
7935 
7936  TMessage mess(kPROOF_CACHE);
7937  mess << Int_t(kDisablePackages);
7938  Broadcast(mess, kUnique);
7939 
7940  TMessage mess2(kPROOF_CACHE);
7941  mess2 << Int_t(kDisableSubPackages);
7942  Broadcast(mess2, fNonUniqueMasters);
7943 
7945  st = fStatus;
7946  }
7947 
7948  // Done
7949  return st;
7950 }
7951 
7952 ////////////////////////////////////////////////////////////////////////////////
7953 /// Build specified package. Executes the PROOF-INF/BUILD.sh
7954 /// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
7955 /// then submit build command to slaves, but don't wait
7956 /// for results. If opt is kCollectBuildResults then collect result
7957 /// from slaves. To be used on the master.
7958 /// If opt = kBuildAll (default) then submit and wait for results
7959 /// (to be used on the client).
7960 /// Returns 0 in case of success and -1 in case of error.
7961 
7962 Int_t TProof::BuildPackage(const char *package,
7963  EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
7964 {
7965  if (!IsValid()) return -1;
7966 
7967  if (!package || !package[0]) {
7968  Error("BuildPackage", "need to specify a package name");
7969  return -1;
7970  }
7971 
7972  // if name, erroneously, is a par pathname strip off .par and path
7973  TString pac = package;
7974  if (pac.EndsWith(".par"))
7975  pac.Remove(pac.Length()-4);
7976  pac = gSystem->BaseName(pac);
7977 
7978  Bool_t buildOnClient = kTRUE;
7979  if (opt == kDontBuildOnClient) {
7980  buildOnClient = kFALSE;
7981  opt = kBuildAll;
7982  }
7983  // Prepare the local package
7984  TString pdir;
7985  Int_t st = 0;
7986 
7987  if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
7988  if (workers) {
7989  TMessage mess(kPROOF_CACHE);
7990  mess << Int_t(kBuildPackage) << pac << chkveropt;
7991  Broadcast(mess, workers);
7992 
7993  } else {
7994  TMessage mess(kPROOF_CACHE);
7995  mess << Int_t(kBuildPackage) << pac << chkveropt;
7996  Broadcast(mess, kUnique);
7997 
7998  TMessage mess2(kPROOF_CACHE);
7999  mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8000  Broadcast(mess2, fNonUniqueMasters);
8001  }
8002  }
8003 
8004  if (opt >= kBuildAll) {
8005  // by first forwarding the build commands to the master and slaves
8006  // and only then building locally we build in parallel
8007  if (buildOnClient) {
8008  st = fPackMgr->Build(pac, chkveropt);
8009  }
8010 
8011 
8012  fStatus = 0;
8013  if (!IsLite() || !buildOnClient) {
8014 
8015  // On the master, workers that fail are deactivated
8016  // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8017  if (workers) {
8018 // Collect(workers, -1, -1, deactivateOnFailure);
8019  Collect(workers);
8020  } else {
8022  }
8023  }
8024 
8025  if (fStatus < 0 || st < 0)
8026  return -1;
8027  }
8028 
8029  return 0;
8030 }
8031 
8032 ////////////////////////////////////////////////////////////////////////////////
8033 /// Load specified package. Executes the PROOF-INF/SETUP.C script
8034 /// on all active nodes. If notOnClient = true, don't load package
8035 /// on the client. The default is to load the package also on the client.
8036 /// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8037 /// The objects in the list must be streamable; the SETUP macro will be executed
8038 /// like this: SETUP.C(loadopts).
8039 /// Returns 0 in case of success and -1 in case of error.
8040 
8041 Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8042  TList *loadopts, TList *workers)
8043 {
8044  if (!IsValid()) return -1;
8045 
8046  if (!package || !package[0]) {
8047  Error("LoadPackage", "need to specify a package name");
8048  return -1;
8049  }
8050 
8051  // if name, erroneously, is a par pathname strip off .par and path
8052  TString pac = package;
8053  if (pac.EndsWith(".par"))
8054  pac.Remove(pac.Length()-4);
8055  pac = gSystem->BaseName(pac);
8056 
8057  if (!notOnClient && TestBit(TProof::kIsClient))
8058  if (fPackMgr->Load(package, loadopts) == -1) return -1;
8059 
8060  TMessage mess(kPROOF_CACHE);
8061  mess << Int_t(kLoadPackage) << pac;
8062  if (loadopts) mess << loadopts;
8063 
8064  // On the master, workers that fail are deactivated
8065  Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8066 
8067  Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8068 
8069  if (workers) {
8070  PDB(kPackage, 3)
8071  Info("LoadPackage", "Sending load message to selected workers only");
8072  Broadcast(mess, workers);
8073  if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8074  } else {
8075  Broadcast(mess);
8076  Collect(kActive, -1, -1, deactivateOnFailure);
8077  }
8078 
8079  return fStatus;
8080 }
8081 
8082 ////////////////////////////////////////////////////////////////////////////////
8083 /// Unload specified package.
8084 /// Returns 0 in case of success and -1 in case of error.
8085 
8086 Int_t TProof::UnloadPackage(const char *package)
8087 {
8088  if (!IsValid()) return -1;
8089 
8090  if (!package || !package[0]) {
8091  Error("UnloadPackage", "need to specify a package name");
8092  return -1;
8093  }
8094 
8095  // if name, erroneously, is a par pathname strip off .par and path
8096  TString pac = package;
8097  if (pac.EndsWith(".par"))
8098  pac.Remove(pac.Length()-4);
8099  pac = gSystem->BaseName(pac);
8100 
8101  if (fPackMgr->Unload(package) < 0)
8102  Warning("UnloadPackage", "unable to remove symlink to %s", package);
8103 
8104  // Nothing more to do if we are a Lite-session
8105  if (IsLite()) return 0;
8106 
8107  TMessage mess(kPROOF_CACHE);
8108  mess << Int_t(kUnloadPackage) << pac;
8109  Broadcast(mess);
8110  Collect();
8111 
8112  return fStatus;
8113 }
8114 
8115 ////////////////////////////////////////////////////////////////////////////////
8116 /// Unload all packages.
8117 /// Returns 0 in case of success and -1 in case of error.
8118 
8120 {
8121  if (!IsValid()) return -1;
8122 
8123  if (TestBit(TProof::kIsClient)) {
8124  if (fPackMgr->Unload(0) < 0) return -1;
8125  }
8126 
8127  // Nothing more to do if we are a Lite-session
8128  if (IsLite()) return 0;
8129 
8130  TMessage mess(kPROOF_CACHE);
8131  mess << Int_t(kUnloadPackages);
8132  Broadcast(mess);
8133  Collect();
8134 
8135  return fStatus;
8136 }
8137 
8138 ////////////////////////////////////////////////////////////////////////////////
8139 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8140 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8141 /// In case notOnClient = true, don't enable the package on the client.
8142 /// The default is to enable packages also on the client.
8143 /// If specified, enables packages only on the specified workers.
8144 /// Returns 0 in case of success and -1 in case of error.
8145 /// Provided for backward compatibility.
8146 
8147 Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8148  TList *workers)
8149 {
8150  return EnablePackage(package, (TList *)0, notOnClient, workers);
8151 }
8152 
8153 ////////////////////////////////////////////////////////////////////////////////
8154 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8155 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8156 /// In case notOnClient = true, don't enable the package on the client.
8157 /// The default is to enable packages also on the client.
8158 /// It is is possible to specify options for the loading step via 'loadopts';
8159 /// the string will be passed passed as argument to SETUP.
8160 /// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8161 /// plugin version checking during building: possible choices are:
8162 /// off no check; failure may occur at loading
8163 /// on check ROOT version [default]
8164 /// svn check ROOT version and Git commit SHA1.
8165 /// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8166 /// If specified, enables packages only on the specified workers.
8167 /// Returns 0 in case of success and -1 in case of error.
8168 
8169 Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8170  Bool_t notOnClient, TList *workers)
8171 {
8172  TList *optls = 0;
8173  if (loadopts && strlen(loadopts)) {
8174  if (fProtocol > 28) {
8175  TObjString *os = new TObjString(loadopts);
8176  // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8177  os->String().ReplaceAll("checkversion=", "chkv=");
8178  Ssiz_t fcv = kNPOS, lcv = kNPOS;
8179  if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8180  TRegexp re("[; |]");
8181  if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8182  lcv = os->String().Length();
8183  }
8184  TString ocv = os->String()(fcv, lcv - fcv);
8185  Int_t cvopt = -1;
8186  if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8187  cvopt = (Int_t) TPackMgr::kDontCheck;
8188  else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8189  cvopt = (Int_t) TPackMgr::kCheckROOT;
8190  else
8191  Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8192  if (cvopt > -1) {
8193  if (gDebug > 0)
8194  Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8195  optls = new TList;
8196  optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8197  // Remove the special option from; we leave a separator if there were two (one before and one after)
8198  if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8199  if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8200  os->String().ReplaceAll(ocv.Data(), "");
8201  }
8202  }
8203  if (!os->String().IsNull()) {
8204  if (!optls) optls = new TList;
8205  optls->Add(new TObjString(os->String().Data()));
8206  }
8207  if (optls) optls->SetOwner(kTRUE);
8208  } else {
8209  // Notify
8210  Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8211  }
8212  }
8213  // Run
8214  Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8215  // Clean up
8216  SafeDelete(optls);
8217  // Done
8218  return rc;
8219 }
8220 
8221 ////////////////////////////////////////////////////////////////////////////////
8222 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8223 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8224 /// In case notOnClient = true, don't enable the package on the client.
8225 /// The default is to enable packages also on the client.
8226 /// It is is possible to specify a list of objects to be passed to the SETUP
8227 /// functions via 'loadopts'; the objects must be streamable.
8228 /// Returns 0 in case of success and -1 in case of error.
8229 
8230 Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8231  Bool_t notOnClient, TList *workers)
8232 {
8233  if (!IsValid()) return -1;
8234 
8235  if (!package || !package[0]) {
8236  Error("EnablePackage", "need to specify a package name");
8237  return -1;
8238  }
8239 
8240  // if name, erroneously, is a par pathname strip off .par and path
8241  TString pac = package;
8242  if (pac.EndsWith(".par"))
8243  pac.Remove(pac.Length()-4);
8244  pac = gSystem->BaseName(pac);
8245 
8247  if (notOnClient)
8248  opt = kDontBuildOnClient;
8249 
8250  // Get check version option; user settings have priority
8251  Int_t chkveropt = TPackMgr::kCheckROOT;
8252  TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8253  if (!ocv.IsNull()) {
8254  if (ocv == "off" || ocv == "0")
8255  chkveropt = (Int_t) TPackMgr::kDontCheck;
8256  else if (ocv == "on" || ocv == "1")
8257  chkveropt = (Int_t) TPackMgr::kCheckROOT;
8258  else
8259  Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8260  }
8261  if (loadopts) {
8262  TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8263  if (pcv) {
8264  chkveropt = pcv->GetVal();
8265  loadopts->Remove(pcv);
8266  delete pcv;
8267  }
8268  }
8269  if (gDebug > 0)
8270  Info("EnablePackage", "using check version option: %d", chkveropt);
8271 
8272  if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8273  return -1;
8274 
8275  TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8276  if (optls && fProtocol <= 28) {
8277  Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8278  optls = 0;
8279  }
8280 
8281  if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8282  return -1;
8283 
8284  // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8288  }
8290  TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8291  : new TPair(new TObjString(pac), 0);
8293  }
8294 
8295  return 0;
8296 }
8297 
8298 ////////////////////////////////////////////////////////////////////////////////
8299 /// Download a PROOF archive (PAR file) from the master package repository.
8300 /// The PAR file is downloaded in the current directory or in the directory
8301 /// specified by 'dstdir'. If a package with the same name already exists
8302 /// at destination, a check on the MD5 sum is done and the user warned or
8303 /// prompted for action, depending is the file is equal or different.
8304 /// Returns 0 in case of success and -1 in case of error.
8305 
8306 Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8307 {
8308  if (!fManager || !(fManager->IsValid())) {
8309  Error("DownloadPackage", "the manager is undefined!");
8310  return -1;
8311  }
8312 
8313  // Create the default source and destination paths
8314  TString parname(gSystem->BaseName(pack)), src, dst;
8315  if (!parname.EndsWith(".par")) parname += ".par";
8316  src.Form("packages/%s", parname.Data());
8317  if (!dstdir || strlen(dstdir) <= 0) {
8318  dst.Form("./%s", parname.Data());
8319  } else {
8320  // Check the destination directory
8321  FileStat_t st;
8322  if (gSystem->GetPathInfo(dstdir, st) != 0) {
8323  // Directory does not exit: create it
8324  if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8325  Error("DownloadPackage",
8326  "could not create the destination directory '%s' (errno: %d)",
8327  dstdir, TSystem::GetErrno());
8328  return -1;
8329  }
8330  } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8331  Error("DownloadPackage",
8332  "destination path '%s' exist but is not a directory!", dstdir);
8333  return -1;
8334  }
8335  dst.Form("%s/%s", dstdir, parname.Data());
8336  }
8337 
8338  // Make sure the source file exists
8339  FileStat_t stsrc;
8340  RedirectHandle_t rh;
8341  if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8342  Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8343  Int_t rc = fManager->Stat(src, stsrc);
8344  if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8345  Warning("DownloadPackage", "problems restoring output");
8346  if (rc != 0) {
8347  // Check if there is another possible source
8349  TMacro *mp = GetLastLog();
8350  if (mp) {
8351  // Look for global directories
8352  Bool_t isGlobal = kFALSE;
8353  TIter nxl(mp->GetListOfLines());
8354  TObjString *os = 0;
8355  TString globaldir;
8356  while ((os = (TObjString *) nxl())) {
8357  TString s(os->GetName());
8358  if (s.Contains("*** Global Package cache")) {
8359  // Get the directory
8360  s.Remove(0, s.Last(':') + 1);
8361  s.Remove(s.Last(' '));
8362  globaldir = s;
8363  isGlobal = kTRUE;
8364  } else if (s.Contains("*** Package cache")) {
8365  isGlobal = kFALSE;
8366  globaldir = "";
8367  }
8368  // Check for the package
8369  if (isGlobal && s.Contains(parname)) {
8370  src.Form("%s/%s", globaldir.Data(), parname.Data());
8371  break;
8372  }
8373  }
8374  // Cleanup
8375  delete mp;
8376  }
8377  }
8378 
8379  // Do it via the manager
8380  if (fManager->GetFile(src, dst, "silent") != 0) {
8381  Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8382  pack, src.Data(), dst.Data());
8383  return -1;
8384  } else {
8385  Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8386  pack, dst.Data());
8387  }
8388  // Done
8389  return 0;
8390 }
8391 
8392 ////////////////////////////////////////////////////////////////////////////////
8393 /// Upload a PROOF archive (PAR file). A PAR file is a compressed
8394 /// tar file with one special additional directory, PROOF-INF
8395 /// (blatantly copied from Java's jar format). It must have the extension
8396 /// .par. A PAR file can be directly a binary or a source with a build
8397 /// procedure. In the PROOF-INF directory there can be a build script:
8398 /// BUILD.sh to be called to build the package, in case of a binary PAR
8399 /// file don't specify a build script or make it a no-op. Then there is
8400 /// SETUP.C which sets the right environment variables to use the package,
8401 /// like LD_LIBRARY_PATH, etc.
8402 /// The 'opt' allows to specify whether the .PAR should be just unpacked
8403 /// in the existing dir (opt = kUntar, default) or a remove of the existing
8404 /// directory should be executed (opt = kRemoveOld), so triggering a full
8405 /// re-build. The option if effective only for PROOF protocol > 8 .
8406 /// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8407 /// an alternative global directory for global usage. This may require special
8408 /// privileges.
8409 /// If download is kTRUE and the package is not found locally, then it is downloaded
8410 /// from the master repository.
8411 /// Returns 0 in case of success and -1 in case of error.
8412 
8414  TList *workers)
8415 {
8416  if (!IsValid()) return -1;
8417 
8418  // Remote PAR ?
8419  TFile::EFileType ft = TFile::GetType(pack);
8420  Bool_t remotepar = (ft == TFile::kWeb || ft == TFile::kNet) ? kTRUE : kFALSE;
8421 
8422  TString par(pack), base, name;
8423  if (par.EndsWith(".par")) {
8424  base = gSystem->BaseName(par);
8425  name = base(0, base.Length() - strlen(".par"));
8426  } else {
8427  name = gSystem->BaseName(par);
8428  base.Form("%s.par", name.Data());
8429  par += ".par";
8430  }
8431 
8432  // Default location is the local working dir; then the package dir
8433  gSystem->ExpandPathName(par);
8434  if (gSystem->AccessPathName(par, kReadPermission)) {
8435  Int_t xrc = -1;
8436  if (!remotepar) xrc = TPackMgr::FindParPath(fPackMgr, name, par);
8437  if (xrc == 0) {
8438  // Package is in the global dirs
8439  if (gDebug > 0)
8440  Info("UploadPackage", "global package found (%s): no upload needed",
8441  par.Data());
8442  return 0;
8443  } else if (xrc < 0) {
8444  Error("UploadPackage", "PAR file '%s' not found", par.Data());
8445  return -1;
8446  }
8447  }
8448 
8449  // Strategy:
8450  // On the client:
8451  // get md5 of package and check if it is different
8452  // from the one stored in the local package directory. If it is lock
8453  // the package directory and copy the package, unlock the directory.
8454  // On the masters:
8455  // get md5 of package and check if it is different from the
8456  // one stored on the remote node. If it is different lock the remote
8457  // package directory and use TFTP or SendFile to ftp the package to the
8458  // remote node, unlock the directory.
8459 
8460 
8461  if (TestBit(TProof::kIsClient)) {
8462  Bool_t rmold = (opt == TProof::kRemoveOld) ? kTRUE : kFALSE;
8463  if (fPackMgr->Install(par, rmold) < 0) {
8464  Error("UploadPackage", "installing '%s' failed", gSystem->BaseName(par));
8465  return -1;
8466  }
8467  }
8468 
8469  // Nothing more to do if we are a Lite-session
8470  if (IsLite()) return 0;
8471 
8472  TMD5 *md5 = fPackMgr->ReadMD5(name);
8473 
8474  TString smsg;
8475  if (remotepar && GetRemoteProtocol() > 36) {
8476  smsg.Form("+%s", par.Data());
8477  } else {
8478  smsg.Form("+%s", base.Data());
8479  }
8480 
8481  TMessage mess(kPROOF_CHECKFILE);
8482  mess << smsg << (*md5);
8483  TMessage mess2(kPROOF_CHECKFILE);
8484  smsg.Replace(0, 1, "-");
8485  mess2 << smsg << (*md5);
8486  TMessage mess3(kPROOF_CHECKFILE);
8487  smsg.Replace(0, 1, "=");
8488  mess3 << smsg << (*md5);
8489 
8490  delete md5;
8491 
8492  if (fProtocol > 8) {
8493  // Send also the option
8494  mess << (UInt_t) opt;
8495  mess2 << (UInt_t) opt;
8496  mess3 << (UInt_t) opt;
8497  }
8498 
8499  // Loop over all slaves with unique fs image, or to a selected
8500  // list of workers, if specified
8501  if (!workers)
8502  workers = fUniqueSlaves;
8503  TIter next(workers);
8504  TSlave *sl = 0;
8505  while ((sl = (TSlave *) next())) {
8506  if (!sl->IsValid())
8507  continue;
8508 
8509  sl->GetSocket()->Send(mess);
8510 
8511  fCheckFileStatus = 0;
8513  if (fCheckFileStatus == 0) {
8514 
8515  if (fProtocol > 5) {
8516  // remote directory is locked, upload file over the open channel
8517  smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
8518  if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
8519  Error("UploadPackage", "%s: problems uploading file %s",
8520  sl->GetOrdinal(), par.Data());
8521  return -1;
8522  }
8523  } else {
8524  // old servers receive it via TFTP
8525  TFTP ftp(TString("root://")+sl->GetName(), 1);
8526  if (!ftp.IsZombie()) {
8527  smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
8528  ftp.cd(smsg.Data());
8529  ftp.put(par, base.Data());
8530  }
8531  }
8532 
8533  // install package and unlock dir
8534  sl->GetSocket()->Send(mess2);
8535  fCheckFileStatus = 0;
8537  if (fCheckFileStatus == 0) {
8538  Error("UploadPackage", "%s: unpacking of package %s failed",
8539  sl->GetOrdinal(), base.Data());
8540  return -1;
8541  }
8542  }
8543  }
8544 
8545  // loop over all other master nodes
8546  TIter nextmaster(fNonUniqueMasters);
8547  TSlave *ma;
8548  while ((ma = (TSlave *) nextmaster())) {
8549  if (!ma->IsValid())
8550  continue;
8551 
8552  ma->GetSocket()->Send(mess3);
8553 
8554  fCheckFileStatus = 0;
8556  if (fCheckFileStatus == 0) {
8557  // error -> package should have been found
8558  Error("UploadPackage", "package %s did not exist on submaster %s",
8559  base.Data(), ma->GetOrdinal());
8560  return -1;
8561  }
8562  }
8563 
8564  return 0;
8565 }
8566 
8567 
8568 ////////////////////////////////////////////////////////////////////////////////
8569 /// Make sure that the directory path contained by macro is in the macro path
8570 
8571 void TProof::AssertMacroPath(const char *macro)
8572 {
8573  static TString macrop(gROOT->GetMacroPath());
8574  if (macro && strlen(macro) > 0) {
8575  TString dirn(gSystem->DirName(macro));
8576  if (!macrop.Contains(dirn)) {
8577  macrop += TString::Format("%s:", dirn.Data());
8578  gROOT->SetMacroPath(macrop);
8579  }
8580  }
8581 }
8582 
8583 
8584 ////////////////////////////////////////////////////////////////////////////////
8585 /// Load the specified macro on master, workers and, if notOnClient is
8586 /// kFALSE, on the client. The macro file is uploaded if new or updated.
8587 /// Additional files to be uploaded (or updated, if needed) can be specified
8588 /// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
8589 /// If existing in the same directory, a header basename(macro).h or .hh, is also
8590 /// uploaded.
8591 /// The default is to load the macro also on the client; notOnClient can be used
8592 /// to avoid loading on the client.
8593 /// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
8594 /// only, and collection is not done; if uniqueWorkers is kFALSE, collection
8595 /// from the previous request is done, and broadcasting + collection from the
8596 /// other workers is done.
8597 /// The wrks arg can be used on the master to limit the set of workers.
8598 /// Returns 0 in case of success and -1 in case of error.
8599 
8600 Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
8601  TList *wrks)
8602 {
8603  if (!IsValid()) return -1;
8604 
8605  if (!macro || !macro[0]) {
8606  Error("Load", "need to specify a macro name");
8607  return -1;
8608  }
8609 
8610  // Make sure the path is in the macro path
8611  TProof::AssertMacroPath(macro);
8612 
8613  if (TestBit(TProof::kIsClient) && !wrks) {
8614 
8615  // Extract the file implementation name first
8616  TString addsname, implname = macro;
8617  Ssiz_t icom = implname.Index(",");
8618  if (icom != kNPOS) {
8619  addsname = implname(icom + 1, implname.Length());
8620  implname.Remove(icom);
8621  }
8622  TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
8623  TString bmsg(basemacro), acmode, args, io;
8624  implname = gSystem->SplitAclicMode(implname, acmode, args, io);
8625 
8626  // Macro names must have a standard format
8627  Int_t dot = implname.Last('.');
8628  if (dot == kNPOS) {
8629  Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
8630  return -1;
8631  }
8632 
8633  // Is there any associated header file
8634  Bool_t hasHeader = kTRUE;
8635  TString headname = implname;
8636  headname.Remove(dot);
8637  headname += ".h";
8638  if (gSystem->AccessPathName(headname, kReadPermission)) {
8639  TString h = headname;
8640  headname.Remove(dot);
8641  headname += ".hh";
8642  if (gSystem->AccessPathName(headname, kReadPermission)) {
8643  hasHeader = kFALSE;
8644  if (gDebug > 0)
8645  Info("Load", "no associated header file found: tried: %s %s",
8646  h.Data(), headname.Data());
8647  }
8648  }
8649 
8650  // Is there any additional file ?
8651  TString addincs;
8652  TList addfiles;
8653  if (!addsname.IsNull()) {
8654  TString fn;
8655  Int_t from = 0;
8656  while (addsname.Tokenize(fn, from, ",")) {
8658  Error("Load", "additional file '%s' not found", fn.Data());
8659  return -1;
8660  }
8661  // Create the additional include statement
8662  if (!notOnClient) {
8663  TString dirn(gSystem->DirName(fn));
8664  if (addincs.IsNull()) {
8665  addincs.Form("-I%s", dirn.Data());
8666  } else if (!addincs.Contains(dirn)) {
8667  addincs += TString::Format(" -I%s", dirn.Data());
8668  }
8669  }
8670  // Remember these files ...
8671  addfiles.Add(new TObjString(fn));
8672  }
8673  }
8674 
8675  // Send files now; the md5 check is run here; see SendFile for more
8676  // details.
8677  if (SendFile(implname, kAscii | kForward , "cache") == -1) {
8678  Error("Load", "problems sending implementation file %s", implname.Data());
8679  return -1;
8680  }
8681  if (hasHeader)
8682  if (SendFile(headname, kAscii | kForward , "cache") == -1) {
8683  Error("Load", "problems sending header file %s", headname.Data());
8684  return -1;
8685  }
8686  // Additional files
8687  if (addfiles.GetSize() > 0) {
8688  TIter nxfn(&addfiles);
8689  TObjString *os = 0;
8690  while ((os = (TObjString *) nxfn())) {
8691  // These files need to be available everywhere, cache and sandbox
8692  if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
8693  Error("Load", "problems sending additional file %s", os->GetName());
8694  return -1;
8695  }
8696  // Add the base names to the message broadcasted
8697  bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
8698  }
8699  addfiles.SetOwner(kTRUE);
8700  }
8701 
8702  // The files are now on the workers: now we send the loading request
8703  TMessage mess(kPROOF_CACHE);
8704  if (GetRemoteProtocol() < 34) {
8705  mess << Int_t(kLoadMacro) << basemacro;
8706  // This may be needed
8707  AddIncludePath("../../cache");
8708  } else {
8709  mess << Int_t(kLoadMacro) << bmsg;
8710  }
8711  Broadcast(mess, kActive);
8712 
8713  // Load locally, if required
8714  if (!notOnClient) {
8715  // Mofify the include path
8716  TString oldincs = gSystem->GetIncludePath();
8717  if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
8718 
8719  // By first forwarding the load command to the master and workers
8720  // and only then loading locally we load/build in parallel
8721  gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
8722 
8723  // Restore include path
8724  if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
8725 
8726  // Update the macro path
8728  TString np(gSystem->DirName(macro));
8729  if (!np.IsNull()) {
8730  np += ":";
8731  if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
8732  Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
8733  mp.Insert(ip, np);
8734  TROOT::SetMacroPath(mp);
8735  if (gDebug > 0)
8736  Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
8737  }
8738  }
8739  }
8740 
8741  // Wait for master and workers to be done
8742  Collect(kActive);
8743 
8744  if (IsLite()) {
8745  PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8746  if (!fLoadedMacros) {
8747  fLoadedMacros = new TList();
8749  }
8750  // if wrks is specified the macro should already be loaded on the master.
8751  fLoadedMacros->Add(new TObjString(macro));
8752  }
8753 
8754  } else {
8755  // On master
8756 
8757  // The files are now on the workers: now we send the loading request first
8758  // to the unique workers, so that the eventual compilation occurs only once.
8759  TString basemacro = gSystem->BaseName(macro);
8760  TMessage mess(kPROOF_CACHE);
8761 
8762  if (uniqueWorkers) {
8763  mess << Int_t(kLoadMacro) << basemacro;
8764  if (wrks) {
8765  Broadcast(mess, wrks);
8766  Collect(wrks);
8767  } else {
8768  Broadcast(mess, kUnique);
8769  }
8770  } else {
8771  // Wait for the result of the previous sending
8772  Collect(kUnique);
8773 
8774  // We then send a tuned loading request to the other workers
8775  TList others;
8776  TSlave *wrk = 0;
8777  TIter nxw(fActiveSlaves);
8778  while ((wrk = (TSlave *)nxw())) {
8779  if (!fUniqueSlaves->FindObject(wrk)) {
8780  others.Add(wrk);
8781  }
8782  }
8783 
8784  // Do not force compilation, if it was requested
8785  Int_t ld = basemacro.Last('.');
8786  if (ld != kNPOS) {
8787  Int_t lpp = basemacro.Index("++", ld);
8788  if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
8789  }
8790  mess << Int_t(kLoadMacro) << basemacro;
8791  Broadcast(mess, &others);
8792  Collect(&others);
8793  }
8794 
8795  PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8796  if (!fLoadedMacros) {
8797  fLoadedMacros = new TList();
8799  }
8800  // if wrks is specified the macro should already be loaded on the master.
8801  if (!wrks)
8802  fLoadedMacros->Add(new TObjString(macro));
8803  }
8804 
8805  // Done
8806  return 0;
8807 }
8808 
8809 ////////////////////////////////////////////////////////////////////////////////
8810 /// Add 'libpath' to the lib path search.
8811 /// Multiple paths can be specified at once separating them with a comma or
8812 /// a blank.
8813 /// Return 0 on success, -1 otherwise
8814 
8815 Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
8816  Bool_t doCollect)
8817 {
8818  if ((!libpath || !libpath[0])) {
8819  if (gDebug > 0)
8820  Info("AddDynamicPath", "list is empty - nothing to do");
8821  return 0;
8822  }
8823 
8824  // Do it also on clients, if required
8825  if (onClient)
8826  HandleLibIncPath("lib", kTRUE, libpath);
8827 
8829  m << TString("lib") << (Bool_t)kTRUE;
8830 
8831  // Add paths
8832  if (libpath && strlen(libpath)) {
8833  m << TString(libpath);
8834  } else {
8835  m << TString("-");
8836  }
8837 
8838  // Tell the server to send back or not
8839  m << (Int_t)doCollect;
8840 
8841  // Forward the request
8842  if (wrks) {
8843  Broadcast(m, wrks);
8844  if (doCollect)
8845  Collect(wrks, fCollectTimeout);
8846  } else {
8847  Broadcast(m);
8849  }
8850 
8851  return 0;
8852 }
8853 
8854 ////////////////////////////////////////////////////////////////////////////////
8855 /// Add 'incpath' to the inc path search.
8856 /// Multiple paths can be specified at once separating them with a comma or
8857 /// a blank.
8858 /// Return 0 on success, -1 otherwise
8859 
8860 Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
8861  Bool_t doCollect)
8862 {
8863  if ((!incpath || !incpath[0])) {
8864  if (gDebug > 0)
8865  Info("AddIncludePath", "list is empty - nothing to do");
8866  return 0;
8867  }
8868 
8869  // Do it also on clients, if required
8870  if (onClient)
8871  HandleLibIncPath("inc", kTRUE, incpath);
8872 
8874  m << TString("inc") << (Bool_t)kTRUE;
8875 
8876  // Add paths
8877  if (incpath && strlen(incpath)) {
8878  m << TString(incpath);
8879  } else {
8880  m << TString("-");
8881  }
8882 
8883  // Tell the server to send back or not
8884  m << (Int_t)doCollect;
8885 
8886  // Forward the request
8887  if (wrks) {
8888  Broadcast(m, wrks);
8889  if (doCollect)
8890  Collect(wrks, fCollectTimeout);
8891  } else {
8892  Broadcast(m);
8894  }
8895 
8896  return 0;
8897 }
8898 
8899 ////////////////////////////////////////////////////////////////////////////////
8900 /// Remove 'libpath' from the lib path search.
8901 /// Multiple paths can be specified at once separating them with a comma or
8902 /// a blank.
8903 /// Return 0 on success, -1 otherwise
8904 
8905 Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
8906 {
8907  if ((!libpath || !libpath[0])) {
8908  if (gDebug > 0)
8909  Info("RemoveDynamicPath", "list is empty - nothing to do");
8910  return 0;
8911  }
8912 
8913  // Do it also on clients, if required
8914  if (onClient)
8915  HandleLibIncPath("lib", kFALSE, libpath);
8916 
8918  m << TString("lib") <<(Bool_t)kFALSE;
8919 
8920  // Add paths
8921  if (libpath && strlen(libpath))
8922  m << TString(libpath);
8923  else
8924  m << TString("-");
8925 
8926  // Forward the request
8927  Broadcast(m);
8929 
8930  return 0;
8931 }
8932 
8933 ////////////////////////////////////////////////////////////////////////////////
8934 /// Remove 'incpath' from the inc path search.
8935 /// Multiple paths can be specified at once separating them with a comma or
8936 /// a blank.
8937 /// Return 0 on success, -1 otherwise
8938 
8939 Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
8940 {
8941  if ((!incpath || !incpath[0])) {
8942  if (gDebug > 0)
8943  Info("RemoveIncludePath", "list is empty - nothing to do");
8944  return 0;
8945  }
8946 
8947  // Do it also on clients, if required
8948  if (onClient)
8949  HandleLibIncPath("in", kFALSE, incpath);
8950 
8952  m << TString("inc") << (Bool_t)kFALSE;
8953 
8954  // Add paths
8955  if (incpath && strlen(incpath))
8956  m << TString(incpath);
8957  else
8958  m << TString("-");
8959 
8960  // Forward the request
8961  Broadcast(m);
8963 
8964  return 0;
8965 }
8966 
8967 ////////////////////////////////////////////////////////////////////////////////
8968 /// Handle lib, inc search paths modification request
8969 
8970 void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
8971 {
8972  TString type(what);
8973  TString path(dirs);
8974 
8975  // Check type of action
8976  if ((type != "lib") && (type != "inc")) {
8977  Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
8978  return;
8979  }
8980 
8981  // Separators can be either commas or blanks
8982  path.ReplaceAll(","," ");
8983 
8984  // Decompose lists
8985  TObjArray *op = 0;
8986  if (path.Length() > 0 && path != "-") {
8987  if (!(op = path.Tokenize(" "))) {
8988  Warning("HandleLibIncPath","decomposing path %s", path.Data());
8989  return;
8990  }
8991  }
8992 
8993  if (add) {
8994 
8995  if (type == "lib") {
8996 
8997  // Add libs
8998  TIter nxl(op, kIterBackward);
8999  TObjString *lib = 0;
9000  while ((lib = (TObjString *) nxl())) {
9001  // Expand path
9002  TString xlib = lib->GetName();
9003  gSystem->ExpandPathName(xlib);
9004  // Add to the dynamic lib search path if it exists and can be read
9005  if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9006  TString newlibpath = gSystem->GetDynamicPath();
9007  // In the first position after the working dir
9008  Int_t pos = 0;
9009  if (newlibpath.BeginsWith(".:"))
9010  pos = 2;
9011  if (newlibpath.Index(xlib) == kNPOS) {
9012  newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9013  gSystem->SetDynamicPath(newlibpath);
9014  }
9015  } else {
9016  if (gDebug > 0)
9017  Info("HandleLibIncPath",
9018  "libpath %s does not exist or cannot be read - not added", xlib.Data());
9019  }
9020  }
9021 
9022  } else {
9023 
9024  // Add incs
9025  TIter nxi(op);
9026  TObjString *inc = 0;
9027  while ((inc = (TObjString *) nxi())) {
9028  // Expand path
9029  TString xinc = inc->GetName();
9030  gSystem->ExpandPathName(xinc);
9031  // Add to the dynamic lib search path if it exists and can be read
9032  if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9033  TString curincpath = gSystem->GetIncludePath();
9034  if (curincpath.Index(xinc) == kNPOS)
9035  gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9036  } else
9037  if (gDebug > 0)
9038  Info("HandleLibIncPath",
9039  "incpath %s does not exist or cannot be read - not added", xinc.Data());
9040  }
9041  }
9042 
9043 
9044  } else {
9045 
9046  if (type == "lib") {
9047 
9048  // Remove libs
9049  TIter nxl(op);
9050  TObjString *lib = 0;
9051  while ((lib = (TObjString *) nxl())) {
9052  // Expand path
9053  TString xlib = lib->GetName();
9054  gSystem->ExpandPathName(xlib);
9055  // Remove from the dynamic lib search path
9056  TString newlibpath = gSystem->GetDynamicPath();
9057  newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9058  gSystem->SetDynamicPath(newlibpath);
9059  }
9060 
9061  } else {
9062 
9063  // Remove incs
9064  TIter nxi(op);
9065  TObjString *inc = 0;
9066  while ((inc = (TObjString *) nxi())) {
9067  TString newincpath = gSystem->GetIncludePath();
9068  newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9069  // Remove the interpreter path (added anyhow internally)
9070  newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9071  gSystem->SetIncludePath(newincpath);
9072  }
9073  }
9074  }
9075 }
9076 
9077 ////////////////////////////////////////////////////////////////////////////////
9078 /// Get from the master the list of names of the packages available.
9079 
9081 {
9082  if (!IsValid())
9083  return (TList *)0;
9084 
9085  TMessage mess(kPROOF_CACHE);
9086  mess << Int_t(kListPackages);
9087  Broadcast(mess);
9089 
9090  return fAvailablePackages;
9091 }
9092 
9093 ////////////////////////////////////////////////////////////////////////////////
9094 /// Get from the master the list of names of the packages enabled.
9095 
9097 {
9098  if (!IsValid())
9099  return (TList *)0;
9100 
9101  TMessage mess(kPROOF_CACHE);
9102  mess << Int_t(kListEnabledPackages);
9103  Broadcast(mess);
9105 
9106  return fEnabledPackages;
9107 }
9108 
9109 ////////////////////////////////////////////////////////////////////////////////
9110 /// Print a progress bar on stderr. Used in batch mode.
9111 
9113  Float_t procTime, Long64_t bytesread)
9114 {
9115  if (fPrintProgress) {
9116  Bool_t redirlog = fRedirLog;
9117  fRedirLog = kFALSE;
9118  // Call the external function
9119  (*fPrintProgress)(total, processed, procTime, bytesread);
9120  fRedirLog = redirlog;
9121  return;
9122  }
9123 
9124  fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9125 
9126  for (int l = 0; l < 20; l++) {
9127  if (total > 0) {
9128  if (l < 20*processed/total)
9129  fprintf(stderr, "=");
9130  else if (l == 20*processed/total)
9131  fprintf(stderr, ">");
9132  else if (l > 20*processed/total)
9133  fprintf(stderr, ".");
9134  } else
9135  fprintf(stderr, "=");
9136  }
9137  Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9138  Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9139  TString sunit("B/s");
9140  if (evtrti > 0.) {
9141  Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9142  if (mbsrti > 0.) {
9143  const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9144  if (mbsrti >= toG) {
9145  mbsrti /= toG;
9146  sunit = "GB/s";
9147  } else if (mbsrti >= toM) {
9148  mbsrti /= toM;
9149  sunit = "MB/s";
9150  } else if (mbsrti >= toK) {
9151  mbsrti /= toK;
9152  sunit = "kB/s";
9153  }
9154  fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9155  (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9156  } else {
9157  fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9158  (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9159  }
9160  } else {
9161  fprintf(stderr, "| %.02f %%\r",
9162  (total ? ((100.0*processed)/total) : 100.0));
9163  }
9164  if (processed >= total) {
9165  fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9166  }
9167 }
9168 
9169 ////////////////////////////////////////////////////////////////////////////////
9170 /// Get query progress information. Connect a slot to this signal
9171 /// to track progress.
9172 
9174 {
9175  if (fPrintProgress) {
9176  // Call the external function
9177  return (*fPrintProgress)(total, processed, -1., -1);
9178  }
9179 
9180  PDB(kGlobal,1)
9181  Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9182 
9183  if (gROOT->IsBatch()) {
9184  // Simple progress bar
9185  if (total > 0)
9186  PrintProgress(total, processed);
9187  } else {
9188  EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9189  }
9190 }
9191 
9192 ////////////////////////////////////////////////////////////////////////////////
9193 /// Get query progress information. Connect a slot to this signal
9194 /// to track progress.
9195 
9196 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
9197  Float_t initTime, Float_t procTime,
9198  Float_t evtrti, Float_t mbrti)
9199 {
9200  PDB(kGlobal,1)
9201  Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9202  initTime, procTime, evtrti, mbrti);
9203 
9204  if (gROOT->IsBatch()) {
9205  // Simple progress bar
9206  if (total > 0)
9207  PrintProgress(total, processed, procTime, bytesread);
9208  } else {
9209  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9210  7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9211  }
9212 }
9213 
9214 ////////////////////////////////////////////////////////////////////////////////
9215 /// Get query progress information. Connect a slot to this signal
9216 /// to track progress.
9217 
9218 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
9219  Float_t initTime, Float_t procTime,
9220  Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9221 {
9222  PDB(kGlobal,1)
9223  Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9224  initTime, procTime, evtrti, mbrti, actw, eses);
9225 
9226  if (gROOT->IsBatch()) {
9227  // Simple progress bar
9228  if (total > 0)
9229  PrintProgress(total, processed, procTime, bytesread);
9230  } else {
9231  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9232  10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9233  }
9234 }
9235 
9236 ////////////////////////////////////////////////////////////////////////////////
9237 /// Get list of feedback objects. Connect a slot to this signal
9238 /// to monitor the feedback object.
9239 
9241 {
9242  PDB(kGlobal,1)
9243  Info("Feedback","%d objects", objs->GetSize());
9244  PDB(kFeedback,1) {
9245  Info("Feedback","%d objects", objs->GetSize());
9246  objs->ls();
9247  }
9248 
9249  Emit("Feedback(TList *objs)", (Long_t) objs);
9250 }
9251 
9252 ////////////////////////////////////////////////////////////////////////////////
9253 /// Close progress dialog.
9254 
9256 {
9257  PDB(kGlobal,1)
9258  Info("CloseProgressDialog",
9259  "called: have progress dialog: %d", fProgressDialogStarted);
9260 
9261  // Nothing to do if not there
9263  return;
9264 
9265  Emit("CloseProgressDialog()");
9266 }
9267 
9268 ////////////////////////////////////////////////////////////////////////////////
9269 /// Reset progress dialog.
9270 
9271 void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9272  Long64_t ent)
9273 {
9274  PDB(kGlobal,1)
9275  Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9276 
9277  EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9278  4, sel, sz, fst, ent);
9279 }
9280 
9281 ////////////////////////////////////////////////////////////////////////////////
9282 /// Send startup message.
9283 
9284 void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9285 {
9286  PDB(kGlobal,1)
9287  Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9288 
9289  EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9290  4, msg, st, done, total);
9291 }
9292 
9293 ////////////////////////////////////////////////////////////////////////////////
9294 /// Send dataset preparation status.
9295 
9296 void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9297 {
9298  PDB(kGlobal,1)
9299  Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9300 
9301  EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9302  4, msg, st, done, total);
9303 }
9304 
9305 ////////////////////////////////////////////////////////////////////////////////
9306 /// Send or notify data set status
9307 
9308 void TProof::SendDataSetStatus(const char *action, UInt_t done,
9309  UInt_t tot, Bool_t st)
9310 {
9311  if (IsLite()) {
9312  if (tot) {
9313  TString type = "files";
9314  Int_t frac = (Int_t) (done*100.)/tot;
9315  char msg[512] = {0};
9316  if (frac >= 100) {
9317  snprintf(msg, 512, "%s: OK (%d %s) \n",
9318  action,tot, type.Data());
9319  } else {
9320  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9321  action, done, tot, frac);
9322  }
9323  if (fSync)
9324  fprintf(stderr,"%s", msg);
9325  else
9326  NotifyLogMsg(msg, 0);
9327  }
9328  return;
9329  }
9330 
9331  if (TestBit(TProof::kIsMaster)) {
9333  mess << TString(action) << tot << done << st;
9334  gProofServ->GetSocket()->Send(mess);
9335  }
9336 }
9337 
9338 ////////////////////////////////////////////////////////////////////////////////
9339 /// Notify availability of a query result.
9340 
9341 void TProof::QueryResultReady(const char *ref)
9342 {
9343  PDB(kGlobal,1)
9344  Info("QueryResultReady","ref: %s", ref);
9345 
9346  Emit("QueryResultReady(const char*)",ref);
9347 }
9348 
9349 ////////////////////////////////////////////////////////////////////////////////
9350 /// Validate a TDSet.
9351 
9353 {
9354  if (dset->ElementsValid()) return;
9355 
9356  TList nodes;
9357  nodes.SetOwner();
9358 
9359  TList slholder;
9360  slholder.SetOwner();
9361  TList elemholder;
9362  elemholder.SetOwner();
9363 
9364  // build nodelist with slaves and elements
9365  TIter nextSlave(GetListOfActiveSlaves());
9366  while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9367  TList *sllist = 0;
9368  TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9369  if (!p) {
9370  sllist = new TList;
9371  sllist->SetName(sl->GetName());
9372  slholder.Add(sllist);
9373  TList *elemlist = new TList;
9374  elemlist->SetName(TString(sl->GetName())+"_elem");
9375  elemholder.Add(elemlist);
9376  nodes.Add(new TPair(sllist, elemlist));
9377  } else {
9378  sllist = dynamic_cast<TList*>(p->Key());
9379  }
9380  if (sllist) sllist->Add(sl);
9381  }
9382 
9383  // add local elements to nodes
9384  TList nonLocal; // list of nonlocal elements
9385  // make two iterations - first add local elements - then distribute nonlocals
9386  for (Int_t i = 0; i < 2; i++) {
9387  Bool_t local = i>0?kFALSE:kTRUE;
9388  TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9389  while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9390  if (elem->GetValid()) continue;
9391  TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9392  if (p) {
9393  TList *eli = dynamic_cast<TList*>(p->Value());
9394  TList *sli = dynamic_cast<TList*>(p->Key());
9395  if (eli && sli) {
9396  eli->Add(elem);
9397 
9398  // order list by elements/slave
9399  TPair *p2 = p;
9400  Bool_t stop = kFALSE;
9401  while (!stop) {
9402  TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9403  if (p3) {
9404  TList *p3v = dynamic_cast<TList*>(p3->Value());
9405  TList *p3k = dynamic_cast<TList*>(p3->Key());
9406  if (p3v && p3k) {
9407  Int_t nelem = p3v->GetSize();
9408  Int_t nsl = p3k->GetSize();
9409  if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
9410  else stop = kTRUE;
9411  }
9412  } else {
9413  stop = kTRUE;
9414  }
9415  }
9416 
9417  if (p2!=p) {
9418  nodes.Remove(p->Key());
9419  nodes.AddAfter(p2->Key(), p);
9420  }
9421  } else {
9422  Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
9423  continue;
9424  }
9425 
9426  } else {
9427  if (local) {
9428  nonLocal.Add(elem);
9429  } else {
9430  Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
9431  }
9432  }
9433  }
9434  }
9435 
9436  // send to slaves
9437  TList usedslaves;
9438  TIter nextNode(&nodes);
9439  SetDSet(dset); // set dset to be validated in Collect()
9440  while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
9441  TList *slaves = dynamic_cast<TList*>(node->Key());
9442  TList *setelements = dynamic_cast<TList*>(node->Value());
9443  if (!slaves || !setelements) continue;
9444  // distribute elements over the slaves
9445  Int_t nslaves = slaves->GetSize();
9446  Int_t nelements = setelements->GetSize();
9447  for (Int_t i=0; i<nslaves; i++) {
9448 
9449  TDSet copyset(dset->GetType(), dset->GetObjName(),
9450  dset->GetDirectory());
9451  for (Int_t j = (i*nelements)/nslaves;
9452  j < ((i+1)*nelements)/nslaves;
9453  j++) {
9454  TDSetElement *elem =
9455  dynamic_cast<TDSetElement*>(setelements->At(j));
9456  if (elem) {
9457  copyset.Add(elem->GetFileName(), elem->GetObjName(),
9458  elem->GetDirectory(), elem->GetFirst(),
9459  elem->GetNum(), elem->GetMsd());
9460  }
9461  }
9462 
9463  if (copyset.GetListOfElements()->GetSize()>0) {
9465  mesg << &copyset;
9466 
9467  TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
9468  if (sl) {
9469  PDB(kGlobal,1) Info("ValidateDSet",
9470  "Sending TDSet with %d elements to slave %s"
9471  " to be validated",
9472  copyset.GetListOfElements()->GetSize(),
9473  sl->GetOrdinal());
9474  sl->GetSocket()->Send(mesg);
9475  usedslaves.Add(sl);
9476  }
9477  }
9478  }
9479  }
9480 
9481  PDB(kGlobal,1)
9482  Info("ValidateDSet","Calling Collect");
9483  Collect(&usedslaves);
9484  SetDSet(0);
9485 }
9486 
9487 ////////////////////////////////////////////////////////////////////////////////
9488 /// Add data objects that might be needed during the processing of
9489 /// the selector (see Process()). This object can be very large, so they
9490 /// are distributed in an optimized way using a dedicated file.
9491 /// If push is TRUE the input data are sent over even if no apparent change
9492 /// occured to the list.
9493 
9495 {
9496  if (obj) {
9497  if (!fInputData) fInputData = new TList;
9498  if (!fInputData->FindObject(obj)) {
9499  fInputData->Add(obj);
9501  }
9502  }
9503  if (push) SetBit(TProof::kNewInputData);
9504 }
9505 
9506 ////////////////////////////////////////////////////////////////////////////////
9507 /// Remove obj form the input data list; if obj is null (default), clear the
9508 /// input data info.
9509 
9511 {
9512  if (!obj) {
9513  if (fInputData) {
9516  }
9518 
9519  // Also remove any info about input data in the input list
9520  TObject *o = 0;
9521  TList *in = GetInputList();
9522  while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9523  in->Remove(o);
9524  while ((o = GetInputList()->FindObject("PROOF_InputData")))
9525  in->Remove(o);
9526 
9527  // ... and reset the file
9528  fInputDataFile = "";
9530 
9531  } else if (fInputData) {
9532  Int_t sz = fInputData->GetSize();
9533  while (fInputData->FindObject(obj))
9534  fInputData->Remove(obj);
9535  // Flag for update, if anything changed
9536  if (sz != fInputData->GetSize())
9538  }
9539 }
9540 
9541 ////////////////////////////////////////////////////////////////////////////////
9542 /// Remove obj 'name' form the input data list;
9543 
9544 void TProof::ClearInputData(const char *name)
9545 {
9546  TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
9547  if (obj) ClearInputData(obj);
9548 }
9549 
9550 ////////////////////////////////////////////////////////////////////////////////
9551 /// Set the file to be used to optimally distribute the input data objects.
9552 /// If the file exists the object in the file are added to those in the
9553 /// fInputData list. If the file path is null, a default file will be created
9554 /// at the moment of sending the processing request with the content of
9555 /// the fInputData list. See also SendInputDataFile.
9556 
9557 void TProof::SetInputDataFile(const char *datafile)
9558 {
9559  if (datafile && strlen(datafile) > 0) {
9560  if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
9562  fInputDataFile = datafile;
9563  } else {
9564  if (!fInputDataFile.IsNull())
9566  fInputDataFile = "";
9567  }
9568  // Make sure that the chosen file is readable
9571  fInputDataFile = "";
9572  }
9573 }
9574 
9575 ////////////////////////////////////////////////////////////////////////////////
9576 /// Send the input data objects to the master; the objects are taken from the
9577 /// dedicated list and / or the specified file.
9578 /// If the fInputData is empty the specified file is sent over.
9579 /// If there is no specified file, a file named "inputdata.root" is created locally
9580 /// with the content of fInputData and sent over to the master.
9581 /// If both fInputData and the specified file are not empty, a copy of the file
9582 /// is made locally and augmented with the content of fInputData.
9583 
9585 {
9586  // Prepare the file
9587  TString dataFile;
9588  PrepareInputDataFile(dataFile);
9589 
9590  // Send it, if not empty
9591  if (dataFile.Length() > 0) {
9592 
9593  Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
9594  BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
9595 
9596  // Set the name in the input list
9597  TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
9598  AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
9599  }
9600 }
9601 
9602 ////////////////////////////////////////////////////////////////////////////////
9603 /// Prepare the file with the input data objects to be sent the master; the
9604 /// objects are taken from the dedicated list and / or the specified file.
9605 /// If the fInputData is empty the specified file is sent over.
9606 /// If there is no specified file, a file named "inputdata.root" is created locally
9607 /// with the content of fInputData and sent over to the master.
9608 /// If both fInputData and the specified file are not empty, a copy of the file
9609 /// is made locally and augmented with the content of fInputData.
9610 
9612 {
9613  // Save info about new data for usage in this call;
9615  // Next time we need some change
9617 
9618  // Check the list
9619  Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
9620  // Check the file
9621  Bool_t file_ok = kFALSE;
9624  // It must contain something
9626  if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
9627  file_ok = kTRUE;
9628  }
9629 
9630  // Remove any info about input data in the input list
9631  TObject *o = 0;
9632  TList *in = GetInputList();
9633  while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9634  in->Remove(o);
9635  while ((o = GetInputList()->FindObject("PROOF_InputData")))
9636  in->Remove(o);
9637 
9638  // We must have something to send
9639  dataFile = "";
9640  if (!list_ok && !file_ok) return;
9641 
9642  // Three cases:
9643  if (file_ok && !list_ok) {
9644  // Just send the file
9645  dataFile = fInputDataFile;
9646  } else if (!file_ok && list_ok) {
9648  // Nothing to do, if no new data
9649  if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
9650  // Create the file first
9651  TFile *f = TFile::Open(fInputDataFile, "RECREATE");
9652  if (f) {
9653  f->cd();
9654  TIter next(fInputData);
9655  TObject *obj;
9656  while ((obj = next())) {
9657  obj->Write(0, TObject::kSingleKey, 0);
9658  }
9659  f->Close();
9660  SafeDelete(f);
9661  } else {
9662  Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
9663  return;
9664  }
9665  dataFile = fInputDataFile;
9666  } else if (file_ok && list_ok) {
9667  dataFile = kPROOF_InputDataFile;
9668  // Create the file if not existing or there are new data
9669  if (newdata || gSystem->AccessPathName(dataFile)) {
9670  // Cleanup previous file if obsolete
9671  if (!gSystem->AccessPathName(dataFile))
9672  gSystem->Unlink(dataFile);
9673  if (dataFile != fInputDataFile) {
9674  // Make a local copy first
9675  if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
9676  Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
9677  return;
9678  }
9679  }
9680  // Add the input data list
9681  TFile *f = TFile::Open(dataFile, "UPDATE");
9682  if (f) {
9683  f->cd();
9684  TIter next(fInputData);
9685  TObject *obj = 0;
9686  while ((obj = next())) {
9687  obj->Write(0, TObject::kSingleKey, 0);
9688  }
9689  f->Close();
9690  SafeDelete(f);
9691  } else {
9692  Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
9693  return;
9694  }
9695  }
9696  }
9697 
9698  // Done
9699  return;
9700 }
9701 
9702 ////////////////////////////////////////////////////////////////////////////////
9703 /// Add objects that might be needed during the processing of
9704 /// the selector (see Process()).
9705 
9707 {
9708  if (fPlayer) fPlayer->AddInput(obj);
9709 }
9710 
9711 ////////////////////////////////////////////////////////////////////////////////
9712 /// Clear input object list.
9713 
9715 {
9716  if (fPlayer) fPlayer->ClearInput();
9717 
9718  // the system feedback list is always in the input list
9720 }
9721 
9722 ////////////////////////////////////////////////////////////////////////////////
9723 /// Get input list.
9724 
9726 {
9727  return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
9728 }
9729 
9730 ////////////////////////////////////////////////////////////////////////////////
9731 /// Get specified object that has been produced during the processing
9732 /// (see Process()).
9733 
9735 {
9736 
9738  // Can be called by MarkBad on the master before the player is initialized
9739  return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
9740 
9741  // This checks also associated output files
9742  return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
9743 }
9744 
9745 ////////////////////////////////////////////////////////////////////////////////
9746 /// Find object 'name' in list 'out' or in the files specified in there
9747 
9749 {
9750  TObject *o = 0;
9751  if (!name || (name && strlen(name) <= 0) ||
9752  !out || (out && out->GetSize() <= 0)) return o;
9753  if ((o = out->FindObject(name))) return o;
9754 
9755  // For the time being we always check for all the files; this may require
9756  // some caching
9757  TProofOutputFile *pf = 0;
9758  TIter nxo(out);
9759  while ((o = nxo())) {
9760  if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
9761  TFile *f = 0;
9762  if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
9763  TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
9764  f = TFile::Open(fn.Data());
9765  if (!f || (f && f->IsZombie())) {
9766  ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
9767  }
9768  }
9769  if (f && (o = f->Get(name))) return o;
9770  }
9771  }
9772 
9773  // Done, unsuccessfully
9774  return o;
9775 }
9776 
9777 ////////////////////////////////////////////////////////////////////////////////
9778 /// Get list with all object created during processing (see Process()).
9779 
9781 {
9782  if (fOutputList.GetSize() > 0) return &fOutputList;
9783  if (fPlayer) {
9785  return &fOutputList;
9786  }
9787  return (TList *)0;
9788 }
9789 
9790 ////////////////////////////////////////////////////////////////////////////////
9791 /// Set input list parameter. If the parameter is already
9792 /// set it will be set to the new value.
9793 
9794 void TProof::SetParameter(const char *par, const char *value)
9795 {
9796  if (!fPlayer) {
9797  Warning("SetParameter", "player undefined! Ignoring");
9798  return;
9799  }
9800 
9801  TList *il = fPlayer->GetInputList();
9802  TObject *item = il->FindObject(par);
9803  if (item) {
9804  il->Remove(item);
9805  delete item;
9806  }
9807  il->Add(new TNamed(par, value));
9808 }
9809 
9810 ////////////////////////////////////////////////////////////////////////////////
9811 /// Set an input list parameter.
9812 
9813 void TProof::SetParameter(const char *par, Int_t value)
9814 {
9815  if (!fPlayer) {
9816  Warning("SetParameter", "player undefined! Ignoring");
9817  return;
9818  }
9819 
9820  TList *il = fPlayer->GetInputList();
9821  TObject *item = il->FindObject(par);
9822  if (item) {
9823  il->Remove(item);
9824  delete item;
9825  }
9826  il->Add(new TParameter<Int_t>(par, value));
9827 }
9828 
9829 ////////////////////////////////////////////////////////////////////////////////
9830 /// Set an input list parameter.
9831 
9832 void TProof::SetParameter(const char *par, Long_t value)
9833 {
9834  if (!fPlayer) {
9835  Warning("SetParameter", "player undefined! Ignoring");
9836  return;
9837  }
9838 
9839  TList *il = fPlayer->GetInputList();
9840  TObject *item = il->FindObject(par);
9841  if (item) {
9842  il->Remove(item);
9843  delete item;
9844  }
9845  il->Add(new TParameter<Long_t>(par, value));
9846 }
9847 
9848 ////////////////////////////////////////////////////////////////////////////////
9849 /// Set an input list parameter.
9850 
9851 void TProof::SetParameter(const char *par, Long64_t value)
9852 {
9853  if (!fPlayer) {
9854  Warning("SetParameter", "player undefined! Ignoring");
9855  return;
9856  }
9857 
9858  TList *il = fPlayer->GetInputList();
9859  TObject *item = il->FindObject(par);
9860  if (item) {
9861  il->Remove(item);
9862  delete item;
9863  }
9864  il->Add(new TParameter<Long64_t>(par, value));
9865 }
9866 
9867 ////////////////////////////////////////////////////////////////////////////////
9868 /// Set an input list parameter.
9869 
9870 void TProof::SetParameter(const char *par, Double_t value)
9871 {
9872  if (!fPlayer) {
9873  Warning("SetParameter", "player undefined! Ignoring");
9874  return;
9875  }
9876 
9877  TList *il = fPlayer->GetInputList();
9878  TObject *item = il->FindObject(par);
9879  if (item) {
9880  il->Remove(item);
9881  delete item;
9882  }
9883  il->Add(new TParameter<Double_t>(par, value));
9884 }
9885 
9886 ////////////////////////////////////////////////////////////////////////////////
9887 /// Get specified parameter. A parameter set via SetParameter() is either
9888 /// a TParameter or a TNamed or 0 in case par is not defined.
9889 
9890 TObject *TProof::GetParameter(const char *par) const
9891 {
9892  if (!fPlayer) {
9893  Warning("GetParameter", "player undefined! Ignoring");
9894  return (TObject *)0;
9895  }
9896 
9897  TList *il = fPlayer->GetInputList();
9898  return il->FindObject(par);
9899 }
9900 
9901 ////////////////////////////////////////////////////////////////////////////////
9902 /// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
9903 /// or exact name (e.g. PROOF_MaxSlavesPerNode).
9904 
9905 void TProof::DeleteParameters(const char *wildcard)
9906 {
9907  if (!fPlayer) return;
9908 
9909  if (!wildcard) wildcard = "";
9910  TRegexp re(wildcard, kTRUE);
9911  Int_t nch = strlen(wildcard);
9912 
9913  TList *il = fPlayer->GetInputList();
9914  if (il) {
9915  TObject *p = 0;
9916  TIter next(il);
9917  while ((p = next())) {
9918  TString s = p->GetName();
9919  if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9920  il->Remove(p);
9921  delete p;
9922  }
9923  }
9924 }
9925 
9926 ////////////////////////////////////////////////////////////////////////////////
9927 /// Show the input list parameters specified by the wildcard.
9928 /// Default is the special PROOF control parameters (PROOF_*).
9929 
9930 void TProof::ShowParameters(const char *wildcard) const
9931 {
9932  if (!fPlayer) return;
9933 
9934  if (!wildcard) wildcard = "";
9935  TRegexp re(wildcard, kTRUE);
9936  Int_t nch = strlen(wildcard);
9937 
9938  TList *il = fPlayer->GetInputList();
9939  TObject *p;
9940  TIter next(il);
9941  while ((p = next())) {
9942  TString s = p->GetName();
9943  if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9944  if (p->IsA() == TNamed::Class()) {
9945  Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9946  } else if (p->IsA() == TParameter<Long_t>::Class()) {
9947  Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
9948  } else if (p->IsA() == TParameter<Long64_t>::Class()) {
9949  Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
9950  } else if (p->IsA() == TParameter<Double_t>::Class()) {
9951  Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
9952  } else {
9953  Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9954  }
9955  }
9956 }
9957 
9958 ////////////////////////////////////////////////////////////////////////////////
9959 /// Add object to feedback list.
9960 
9961 void TProof::AddFeedback(const char *name)
9962 {
9963  PDB(kFeedback, 3)
9964  Info("AddFeedback", "Adding object \"%s\" to feedback", name);
9965  if (fFeedback->FindObject(name) == 0)
9966  fFeedback->Add(new TObjString(name));
9967 }
9968 
9969 ////////////////////////////////////////////////////////////////////////////////
9970 /// Remove object from feedback list.
9971 
9972 void TProof::RemoveFeedback(const char *name)
9973 {
9974  TObject *obj = fFeedback->FindObject(name);
9975  if (obj != 0) {
9976  fFeedback->Remove(obj);
9977  delete obj;
9978  }
9979 }
9980 
9981 ////////////////////////////////////////////////////////////////////////////////
9982 /// Clear feedback list.
9983 
9985 {
9986  fFeedback->Delete();
9987 }
9988 
9989 ////////////////////////////////////////////////////////////////////////////////
9990 /// Show items in feedback list.
9991 
9993 {
9994  if (fFeedback->GetSize() == 0) {
9995  Info("","no feedback requested");
9996  return;
9997  }
9998 
9999  fFeedback->Print();
10000 }
10001 
10002 ////////////////////////////////////////////////////////////////////////////////
10003 /// Return feedback list.
10004 
10006 {
10007  return fFeedback;
10008 }
10009 
10010 ////////////////////////////////////////////////////////////////////////////////
10011 /// Creates a tree header (a tree with nonexisting files) object for
10012 /// the DataSet.
10013 
10015 {
10017  TSlave *sl = (TSlave*) l->First();
10018  if (sl == 0) {
10019  Error("GetTreeHeader", "No connection");
10020  return 0;
10021  }
10022 
10023  TSocket *soc = sl->GetSocket();
10025 
10026  msg << dset;
10027 
10028  soc->Send(msg);
10029 
10030  TMessage *reply;
10031  Int_t d = -1;
10032  if (fProtocol >= 20) {
10034  reply = (TMessage *) fRecvMessages->First();
10035  } else {
10036  d = soc->Recv(reply);
10037  }
10038  if (!reply) {
10039  Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10040  return 0;
10041  }
10042 
10043  TString s1;
10044  TTree *t = 0;
10045  (*reply) >> s1;
10046  if (s1 == "Success")
10047  (*reply) >> t;
10048 
10049  PDB(kGlobal, 1) {
10050  if (t) {
10051  Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10052  s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10053  } else {
10054  Info("GetTreeHeader", "tree header retrieval failed");
10055  }
10056  }
10057  delete reply;
10058 
10059  return t;
10060 }
10061 
10062 ////////////////////////////////////////////////////////////////////////////////
10063 /// Draw feedback creation proxy. When accessed via TProof avoids
10064 /// link dependency on libProofPlayer.
10065 
10067 {
10068  return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10069 }
10070 
10071 ////////////////////////////////////////////////////////////////////////////////
10072 /// Set draw feedback option.
10073 
10075 {
10076  if (fPlayer) fPlayer->SetDrawFeedbackOption(f, opt);
10077 }
10078 
10079 ////////////////////////////////////////////////////////////////////////////////
10080 /// Delete draw feedback object.
10081 
10083 {
10085 }
10086 
10087 ////////////////////////////////////////////////////////////////////////////////
10088 /// FIXME: to be written
10089 
10091 {
10092  return 0;
10093 /*
10094  TMessage msg(kPROOF_GETOUTPUTLIST);
10095  TList* slaves = fActiveSlaves;
10096  Broadcast(msg, slaves);
10097  TMonitor mon;
10098  TList* outputList = new TList();
10099 
10100  TIter si(slaves);
10101  TSlave *slave;
10102  while ((slave = (TSlave*)si.Next()) != 0) {
10103  PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10104  slave->GetSocket(), slave->GetName());
10105  mon.Add(slave->GetSocket());
10106  }
10107  mon.ActivateAll();
10108  ((TProof*)gProof)->DeActivateAsyncInput();
10109  ((TProof*)gProof)->fCurrentMonitor = &mon;
10110 
10111  while (mon.GetActive() != 0) {
10112  TSocket *sock = mon.Select();
10113  if (!sock) {
10114  Error("GetOutputList","TMonitor::.Select failed!");
10115  break;
10116  }
10117  mon.DeActivate(sock);
10118  TMessage *reply;
10119  if (sock->Recv(reply) <= 0) {
10120  MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10121 // Error("GetOutputList","Recv failed! for slave-%d (%s)",
10122 // slave->GetOrdinal(), slave->GetName());
10123  continue;
10124  }
10125  if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10126 // Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10127 // slave->GetOrdinal(), slave->GetName());
10128  MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10129  continue;
10130  }
10131  TList* l;
10132 
10133  (*reply) >> l;
10134  TIter next(l);
10135  TNamed *n;
10136  while ( (n = dynamic_cast<TNamed*> (next())) ) {
10137  if (!outputList->FindObject(n->GetName()))
10138  outputList->Add(n);
10139  }
10140  delete reply;
10141  }
10142  ((TProof*)gProof)->fCurrentMonitor = 0;
10143 
10144  return outputList;
10145 */
10146 }
10147 
10148 ////////////////////////////////////////////////////////////////////////////////
10149 /// Build the PROOF's structure in the browser.
10150 
10152 {
10153  b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10154  b->Add(&fMaster, fMaster.Class(), "fMaster");
10155  b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10156  b->Add(fChains, fChains->Class(), "fChains");
10157 
10158  if (fPlayer) {
10159  b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10160  if (fPlayer->GetOutputList())
10161  b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10162  if (fPlayer->GetListOfResults())
10164  fPlayer->GetListOfResults()->Class(), "ListOfResults");
10165  }
10166 }
10167 
10168 ////////////////////////////////////////////////////////////////////////////////
10169 /// Set a new PROOF player.
10170 
10172 {
10173  if (fPlayer)
10174  delete fPlayer;
10175  fPlayer = player;
10176 };
10177 
10178 ////////////////////////////////////////////////////////////////////////////////
10179 /// Construct a TProofPlayer object. The player string specifies which
10180 /// player should be created: remote, slave, sm (supermaster) or base.
10181 /// Default is remote. Socket is needed in case a slave player is created.
10182 
10184 {
10185  if (!player)
10186  player = "remote";
10187 
10188  SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10189  return GetPlayer();
10190 }
10191 
10192 ////////////////////////////////////////////////////////////////////////////////
10193 /// Add chain to data set
10194 
10196 {
10197  fChains->Add(chain);
10198 }
10199 
10200 ////////////////////////////////////////////////////////////////////////////////
10201 /// Remove chain from data set
10202 
10204 {
10205  fChains->Remove(chain);
10206 }
10207 
10208 ////////////////////////////////////////////////////////////////////////////////
10209 /// Ask for remote logs in the range [start, end]. If start == -1 all the
10210 /// messages not yet received are sent back.
10211 
10212 void TProof::GetLog(Int_t start, Int_t end)
10213 {
10214  if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10215 
10216  TMessage msg(kPROOF_LOGFILE);
10217 
10218  msg << start << end;
10219 
10220  Broadcast(msg, kActive);
10222 }
10223 
10224 ////////////////////////////////////////////////////////////////////////////////
10225 /// Fill a TMacro with the log lines since the last reading (fLogFileR)
10226 /// Return (TMacro *)0 if no line was logged.
10227 /// The returned TMacro must be deleted by the caller.
10228 
10230 {
10231  TMacro *maclog = 0;
10232 
10233  // Save present offset
10234  off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10235  if (nowlog < 0) {
10236  SysError("GetLastLog",
10237  "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10238  return maclog;
10239  }
10240 
10241  // Get extremes
10242  off_t startlog = nowlog;
10243  off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10244  if (endlog < 0) {
10245  SysError("GetLastLog",
10246  "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10247  return maclog;
10248  }
10249 
10250  // Perhaps nothing to log
10251  UInt_t tolog = (UInt_t)(endlog - startlog);
10252  if (tolog <= 0) return maclog;
10253 
10254  // Set starting point
10255  if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10256  SysError("GetLastLog",
10257  "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10258  return maclog;
10259  }
10260 
10261  // Create the output object
10262  maclog = new TMacro;
10263 
10264  // Now we go
10265  char line[2048];
10266  Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10267  while (fgets(line, wanted, fLogFileR)) {
10268  Int_t r = strlen(line);
10269  if (r > 0) {
10270  if (line[r-1] == '\n') line[r-1] = '\0';
10271  maclog->AddLine(line);
10272  } else {
10273  // Done
10274  break;
10275  }
10276  tolog -= r;
10277  wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10278  }
10279 
10280  // Restore original pointer
10281  if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10282  Warning("GetLastLog",
10283  "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10284  }
10285 
10286  // Done
10287  return maclog;
10288 }
10289 
10290 ////////////////////////////////////////////////////////////////////////////////
10291 /// Display log of query pq into the log window frame
10292 
10294 {
10295  if (!pq) return;
10296 
10297  TList *lines = pq->GetLogFile()->GetListOfLines();
10298  if (lines) {
10299  TIter nxl(lines);
10300  TObjString *l = 0;
10301  while ((l = (TObjString *)nxl()))
10302  EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10303  }
10304 }
10305 
10306 ////////////////////////////////////////////////////////////////////////////////
10307 /// Display on screen the content of the temporary log file for query
10308 /// in reference
10309 
10310 void TProof::ShowLog(const char *queryref)
10311 {
10312  // Make sure we have all info (GetListOfQueries retrieves the
10313  // head info only)
10314  Retrieve(queryref);
10315 
10316  if (fPlayer) {
10317  if (queryref) {
10318  if (fPlayer->GetListOfResults()) {
10319  TIter nxq(fPlayer->GetListOfResults());
10320  TQueryResult *qr = 0;
10321  while ((qr = (TQueryResult *) nxq()))
10322  if (strstr(queryref, qr->GetTitle()) &&
10323  strstr(queryref, qr->GetName()))
10324  break;
10325  if (qr) {
10326  PutLog(qr);
10327  return;
10328  }
10329 
10330  }
10331  }
10332  }
10333 }
10334 
10335 ////////////////////////////////////////////////////////////////////////////////
10336 /// Display on screen the content of the temporary log file.
10337 /// If qry == -2 show messages from the last (current) query.
10338 /// If qry == -1 all the messages not yet displayed are shown (default).
10339 /// If qry == 0, all the messages in the file are shown.
10340 /// If qry > 0, only the messages related to query 'qry' are shown.
10341 /// For qry != -1 the original file offset is restored at the end
10342 
10344 {
10345  // Save present offset
10346  off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10347  if (nowlog < 0) {
10348  SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10349  return;
10350  }
10351 
10352  // Get extremes
10353  off_t startlog = nowlog;
10354  off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10355  if (endlog < 0) {
10356  SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10357  return;
10358  }
10359 
10360  lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10361  if (qry == 0) {
10362  startlog = 0;
10363  lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10364  } else if (qry != -1) {
10365 
10366  TQueryResult *pq = 0;
10367  if (qry == -2) {
10368  // Pickup the last one
10369  pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10370  if (!pq) {
10371  GetListOfQueries();
10372  if (fQueries)
10373  pq = (TQueryResult *)(fQueries->Last());
10374  }
10375  } else if (qry > 0) {
10376  TList *queries = GetQueryResults();
10377  if (queries) {
10378  TIter nxq(queries);
10379  while ((pq = (TQueryResult *)nxq()))
10380  if (qry == pq->GetSeqNum())
10381  break;
10382  }
10383  if (!pq) {
10384  queries = GetListOfQueries();
10385  TIter nxq(queries);
10386  while ((pq = (TQueryResult *)nxq()))
10387  if (qry == pq->GetSeqNum())
10388  break;
10389  }
10390  }
10391  if (pq) {
10392  PutLog(pq);
10393  return;
10394  } else {
10395  if (gDebug > 0)
10396  Info("ShowLog","query %d not found in list", qry);
10397  qry = -1;
10398  }
10399  }
10400 
10401  // Number of bytes to log
10402  UInt_t tolog = (UInt_t)(endlog - startlog);
10403 
10404  // Perhaps nothing
10405  if (tolog <= 0) {
10406  // Set starting point
10407  lseek(fileno(fLogFileR), startlog, SEEK_SET);
10408  }
10409 
10410  // Now we go
10411  Int_t np = 0;
10412  char line[2048];
10413  Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10414  while (fgets(line, wanted, fLogFileR)) {
10415 
10416  Int_t r = strlen(line);
10417  if (!SendingLogToWindow()) {
10418  if (line[r-1] != '\n') line[r-1] = '\n';
10419  if (r > 0) {
10420  char *p = line;
10421  while (r) {
10422  Int_t w = write(fileno(stdout), p, r);
10423  if (w < 0) {
10424  SysError("ShowLog", "error writing to stdout");
10425  break;
10426  }
10427  r -= w;
10428  p += w;
10429  }
10430  }
10431  tolog -= strlen(line);
10432  np++;
10433 
10434  // Ask if more is wanted
10435  if (!(np%10)) {
10436  const char *opt = Getline("More (y/n)? [y]");
10437  if (opt[0] == 'n')
10438  break;
10439  }
10440 
10441  // We may be over
10442  if (tolog <= 0)
10443  break;
10444 
10445  // Update wanted bytes
10446  wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10447  } else {
10448  // Log to window
10449  if (line[r-1] == '\n') line[r-1] = 0;
10450  LogMessage(line, kFALSE);
10451  }
10452  }
10453  if (!SendingLogToWindow()) {
10454  // Avoid screwing up the prompt
10455  if (write(fileno(stdout), "\n", 1) != 1)
10456  SysError("ShowLog", "error writing to stdout");
10457  }
10458 
10459  // Restore original pointer
10460  if (qry > -1)
10461  lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10462 }
10463 
10464 ////////////////////////////////////////////////////////////////////////////////
10465 /// Set session with 'id' the default one. If 'id' is not found in the list,
10466 /// the current session is set as default
10467 
10469 {
10470  if (GetManager()) {
10471  TProofDesc *d = GetManager()->GetProofDesc(id);
10472  if (d) {
10473  if (d->GetProof()) {
10474  gProof = d->GetProof();
10475  return;
10476  }
10477  }
10478 
10479  // Id not found or undefined: set as default this session
10480  gProof = this;
10481  }
10482 
10483  return;
10484 }
10485 
10486 ////////////////////////////////////////////////////////////////////////////////
10487 /// Detach this instance to its proofserv.
10488 /// If opt is 'S' or 's' the remote server is shutdown
10489 
10491 {
10492  // Nothing to do if not in contact with proofserv
10493  if (!IsValid()) return;
10494 
10495  // Get worker and socket instances
10496  TSlave *sl = (TSlave *) fActiveSlaves->First();
10497  TSocket *s = 0;
10498  if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
10499  Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
10500  return;
10501  }
10502 
10503  Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
10504 
10505  // If processing, try to stop processing first
10506  if (shutdown && !IsIdle()) {
10507  // Remove pending requests
10508  Remove("cleanupqueue");
10509  // Do not wait for ever, but al least 20 seconds
10510  Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
10511  timeout = (timeout > 20) ? timeout : 20;
10512  // Send stop signal
10513  StopProcess(kFALSE, (Long_t) (timeout / 2));
10514  // Receive results
10515  Collect(kActive, timeout);
10516  }
10517 
10518  // Avoid spurious messages: deactivate new inputs ...
10520 
10521  // ... and discard existing ones
10522  sl->FlushSocket();
10523 
10524  // Close session (we always close the connection)
10525  Close(opt);
10526 
10527  // Close the progress dialog, if any
10530 
10531  // Update info in the table of our manager, if any
10532  if (GetManager() && GetManager()->QuerySessions("L")) {
10533  TIter nxd(GetManager()->QuerySessions("L"));
10534  TProofDesc *d = 0;
10535  while ((d = (TProofDesc *)nxd())) {
10536  if (d->GetProof() == this) {
10537  d->SetProof(0);
10538  GetManager()->QuerySessions("L")->Remove(d);
10539  break;
10540  }
10541  }
10542  }
10543 
10544  // Invalidate this instance
10545  fValid = kFALSE;
10546 
10547  return;
10548 }
10549 
10550 ////////////////////////////////////////////////////////////////////////////////
10551 /// Set an alias for this session. If reconnection is supported, the alias
10552 /// will be communicated to the remote coordinator so that it can be recovered
10553 /// when reconnecting
10554 
10555 void TProof::SetAlias(const char *alias)
10556 {
10557  // Set it locally
10558  TNamed::SetTitle(alias);
10560  // Set the name at the same value
10561  TNamed::SetName(alias);
10562 
10563  // Nothing to do if not in contact with coordinator
10564  if (!IsValid()) return;
10565 
10566  if (!IsProofd() && TestBit(TProof::kIsClient)) {
10567  TSlave *sl = (TSlave *) fActiveSlaves->First();
10568  if (sl)
10569  sl->SetAlias(alias);
10570  }
10571 
10572  return;
10573 }
10574 
10575 ////////////////////////////////////////////////////////////////////////////////
10576 /// *** This function is deprecated and will disappear in future versions ***
10577 /// *** It is just a wrapper around TFile::Cp.
10578 /// *** Please use TProofMgr::UploadFiles.
10579 ///
10580 /// Upload a set of files and save the list of files by name dataSetName.
10581 /// The 'files' argument is a list of TFileInfo objects describing the files
10582 /// as first url.
10583 /// The mask 'opt' is a combination of EUploadOpt:
10584 /// kAppend (0x1) if set true files will be appended to
10585 /// the dataset existing by given name
10586 /// kOverwriteDataSet (0x2) if dataset with given name exited it
10587 /// would be overwritten
10588 /// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10589 /// kOverwriteAllFiles (0x8) overwrite all files that may exist
10590 /// kOverwriteNoFiles (0x10) overwrite none
10591 /// kAskUser (0x0) ask user before overwriteng dataset/files
10592 /// The default value is kAskUser.
10593 /// The user will be asked to confirm overwriting dataset or files unless
10594 /// specified opt provides the answer!
10595 /// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10596 /// skippedFiles argument. The function will add to this list TFileInfo
10597 /// objects describing all files that existed on the cluster and were
10598 /// not uploaded.
10599 ///
10600 /// Communication Summary
10601 /// Client Master
10602 /// |------------>DataSetName----------->|
10603 /// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
10604 /// (*)|-------> call RegisterDataSet ------->|
10605 /// (*) - optional
10606 
10607 Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
10608 {
10609  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10610 
10611  return -1;
10612 }
10613 
10614 ////////////////////////////////////////////////////////////////////////////////
10615 /// *** This function is deprecated and will disappear in future versions ***
10616 /// *** It is just a wrapper around TFile::Cp.
10617 /// *** Please use TProofMgr::UploadFiles.
10618 ///
10619 /// Upload a set of files and save the list of files by name dataSetName.
10620 /// The mask 'opt' is a combination of EUploadOpt:
10621 /// kAppend (0x1) if set true files will be appended to
10622 /// the dataset existing by given name
10623 /// kOverwriteDataSet (0x2) if dataset with given name exited it
10624 /// would be overwritten
10625 /// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10626 /// kOverwriteAllFiles (0x8) overwrite all files that may exist
10627 /// kOverwriteNoFiles (0x10) overwrite none
10628 /// kAskUser (0x0) ask user before overwriteng dataset/files
10629 /// The default value is kAskUser.
10630 /// The user will be asked to confirm overwriting dataset or files unless
10631 /// specified opt provides the answer!
10632 /// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10633 /// skippedFiles argument. The function will add to this list TFileInfo
10634 /// objects describing all files that existed on the cluster and were
10635 /// not uploaded.
10636 ///
10637 
10638 Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
10639 {
10640  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10641 
10642  return -1;
10643 }
10644 
10645 ////////////////////////////////////////////////////////////////////////////////
10646 /// *** This function is deprecated and will disappear in future versions ***
10647 /// *** It is just a wrapper around TFile::Cp.
10648 /// *** Please use TProofMgr::UploadFiles.
10649 ///
10650 /// Upload files listed in "file" to PROOF cluster.
10651 /// Where file = name of file containing list of files and
10652 /// dataset = dataset name and opt is a combination of EUploadOpt bits.
10653 /// Each file description (line) can include wildcards.
10654 /// Check TFileInfo compatibility
10655 
10656 Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
10657 {
10658  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10659 
10660  // Done
10661  return -1;
10662 }
10663 
10664 ////////////////////////////////////////////////////////////////////////////////
10665 /// Register the 'dataSet' on the cluster under the current
10666 /// user, group and the given 'dataSetName'.
10667 /// If a dataset with the same name already exists the action fails unless 'opts'
10668 /// contains 'O', in which case the old dataset is overwritten, or contains 'U',
10669 /// in which case 'newDataSet' is added to the existing dataset (duplications are
10670 /// ignored, if any).
10671 /// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
10672 /// is configured to allow so). By default the dataset is not verified.
10673 /// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
10674 /// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
10675 /// If 'opts' contains 'S' validation would be run serially (meaningful only if
10676 /// validation is required).
10677 /// Returns kTRUE on success.
10678 
10679 Bool_t TProof::RegisterDataSet(const char *dataSetName,
10680  TFileCollection *dataSet, const char *optStr)
10681 {
10682  // Check TFileInfo compatibility
10683  if (fProtocol < 17) {
10684  Info("RegisterDataSet",
10685  "functionality not available: the server does not have dataset support");
10686  return kFALSE;
10687  }
10688 
10689  if (!dataSetName || strlen(dataSetName) <= 0) {
10690  Info("RegisterDataSet", "specifying a dataset name is mandatory");
10691  return kFALSE;
10692  }
10693 
10694  Bool_t parallelverify = kFALSE;
10695  TString sopt(optStr);
10696  if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
10697  // We do verification in parallel later on; just register for now
10698  parallelverify = kTRUE;
10699  sopt.ReplaceAll("V", "");
10700  }
10701  // This would screw up things remotely, make sure is not there
10702  sopt.ReplaceAll("S", "");
10703 
10704  TMessage mess(kPROOF_DATASETS);
10705  mess << Int_t(kRegisterDataSet);
10706  mess << TString(dataSetName);
10707  mess << sopt;
10708  mess.WriteObject(dataSet);
10709  Broadcast(mess);
10710 
10711  Bool_t result = kTRUE;
10712  Collect();
10713  if (fStatus != 0) {
10714  Error("RegisterDataSet", "dataset was not saved");
10715  result = kFALSE;
10716  return result;
10717  }
10718 
10719  // If old server or not verifying in parallel we are done
10720  if (!parallelverify) return result;
10721 
10722  // If we are here it means that we will verify in parallel
10723  sopt += "V";
10724  if (VerifyDataSet(dataSetName, sopt) < 0){
10725  Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
10726  return kFALSE;
10727  }
10728 
10729  // We are done
10730  return kTRUE;
10731 }
10732 
10733 ////////////////////////////////////////////////////////////////////////////////
10734 /// Set/Change the name of the default tree. The tree name may contain
10735 /// subdir specification in the form "subdir/name".
10736 /// Returns 0 on success, -1 otherwise.
10737 
10738 Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
10739 {
10740  // Check TFileInfo compatibility
10741  if (fProtocol < 23) {
10742  Info("SetDataSetTreeName", "functionality not supported by the server");
10743  return -1;
10744  }
10745 
10746  if (!dataset || strlen(dataset) <= 0) {
10747  Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
10748  return -1;
10749  }
10750 
10751  if (!treename || strlen(treename) <= 0) {
10752  Info("SetDataSetTreeName", "specifying a tree name is mandatory");
10753  return -1;
10754  }
10755 
10756  TUri uri(dataset);
10757  TString fragment(treename);
10758  if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
10759  uri.SetFragment(fragment);
10760 
10761  TMessage mess(kPROOF_DATASETS);
10762  mess << Int_t(kSetDefaultTreeName);
10763  mess << uri.GetUri();
10764  Broadcast(mess);
10765 
10766  Collect();
10767  if (fStatus != 0) {
10768  Error("SetDataSetTreeName", "some error occured: default tree name not changed");
10769  return -1;
10770  }
10771  return 0;
10772 }
10773 
10774 ////////////////////////////////////////////////////////////////////////////////
10775 /// Lists all datasets that match given uri.
10776 /// The 'optStr' can contain a comma-separated list of servers for which the
10777 /// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
10778 /// only the global information in the TFileCollection is retrieved; useful to only
10779 /// get the list of available datasets.
10780 
10781 TMap *TProof::GetDataSets(const char *uri, const char *optStr)
10782 {
10783  if (fProtocol < 15) {
10784  Info("GetDataSets",
10785  "functionality not available: the server does not have dataset support");
10786  return 0;
10787  }
10788  if (fProtocol < 31 && strstr(optStr, ":lite:"))
10789  Warning("GetDataSets", "'lite' option not supported by the server");
10790 
10791  TMessage mess(kPROOF_DATASETS);
10792  mess << Int_t(kGetDataSets);
10793  mess << TString(uri ? uri : "");
10794  mess << TString(optStr ? optStr : "");
10795  Broadcast(mess);
10797 
10798  TMap *dataSetMap = 0;
10799  if (fStatus != 0) {
10800  Error("GetDataSets", "error receiving datasets information");
10801  } else {
10802  // Look in the list
10803  TMessage *retMess = (TMessage *) fRecvMessages->First();
10804  if (retMess && retMess->What() == kMESS_OK) {
10805  if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
10806  Error("GetDataSets", "error receiving datasets");
10807  } else
10808  Error("GetDataSets", "message not found or wrong type (%p)", retMess);
10809  }
10810 
10811  return dataSetMap;
10812 }
10813 
10814 ////////////////////////////////////////////////////////////////////////////////
10815 /// Shows datasets in locations that match the uri.
10816 /// By default shows the user's datasets and global ones
10817 
10818 void TProof::ShowDataSets(const char *uri, const char* optStr)
10819 {
10820  if (fProtocol < 15) {
10821  Info("ShowDataSets",
10822  "functionality not available: the server does not have dataset support");
10823  return;
10824  }
10825 
10826  TMessage mess(kPROOF_DATASETS);
10827  mess << Int_t(kShowDataSets);
10828  mess << TString(uri ? uri : "");
10829  mess << TString(optStr ? optStr : "");
10830  Broadcast(mess);
10831 
10833  if (fStatus != 0)
10834  Error("ShowDataSets", "error receiving datasets information");
10835 }
10836 
10837 ////////////////////////////////////////////////////////////////////////////////
10838 /// Returns kTRUE if 'dataset' exists, kFALSE otherwise
10839 
10840 Bool_t TProof::ExistsDataSet(const char *dataset)
10841 {
10842  if (fProtocol < 15) {
10843  Info("ExistsDataSet", "functionality not available: the server has an"
10844  " incompatible version of TFileInfo");
10845  return kFALSE;
10846  }
10847 
10848  if (!dataset || strlen(dataset) <= 0) {
10849  Error("ExistsDataSet", "dataset name missing");
10850  return kFALSE;
10851  }
10852 
10854  msg << Int_t(kCheckDataSetName) << TString(dataset);
10855  Broadcast(msg);
10857  if (fStatus == -1) {
10858  // The dataset exists
10859  return kTRUE;
10860  }
10861  // The dataset does not exists
10862  return kFALSE;
10863 }
10864 
10865 ////////////////////////////////////////////////////////////////////////////////
10866 /// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
10867 
10868 void TProof::ClearDataSetCache(const char *dataset)
10869 {
10870  if (fProtocol < 28) {
10871  Info("ClearDataSetCache", "functionality not available on server");
10872  return;
10873  }
10874 
10876  msg << Int_t(kCache) << TString(dataset) << TString("clear");
10877  Broadcast(msg);
10879  // Done
10880  return;
10881 }
10882 
10883 ////////////////////////////////////////////////////////////////////////////////
10884 /// Display the content of the dataset cache, if any (matching 'dataset', if defined).
10885 
10886 void TProof::ShowDataSetCache(const char *dataset)
10887 {
10888  if (fProtocol < 28) {
10889  Info("ShowDataSetCache", "functionality not available on server");
10890  return;
10891  }
10892 
10894  msg << Int_t(kCache) << TString(dataset) << TString("show");
10895  Broadcast(msg);
10897  // Done
10898  return;
10899 }
10900 
10901 ////////////////////////////////////////////////////////////////////////////////
10902 /// Get a list of TFileInfo objects describing the files of the specified
10903 /// dataset.
10904 /// To get the short version (containing only the global meta information)
10905 /// specify optStr = "S:" or optStr = "short:".
10906 /// To get the sub-dataset of files located on a given server(s) specify
10907 /// the list of servers (comma-separated) in the 'optStr' field.
10908 
10909 TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10910 {
10911  if (fProtocol < 15) {
10912  Info("GetDataSet", "functionality not available: the server has an"
10913  " incompatible version of TFileInfo");
10914  return 0;
10915  }
10916 
10917  if (!uri || strlen(uri) <= 0) {
10918  Info("GetDataSet", "specifying a dataset name is mandatory");
10919  return 0;
10920  }
10921 
10922  TMessage nameMess(kPROOF_DATASETS);
10923  nameMess << Int_t(kGetDataSet);
10924  nameMess << TString(uri);
10925  nameMess << TString(optStr ? optStr: "");
10926  if (Broadcast(nameMess) < 0)
10927  Error("GetDataSet", "sending request failed");
10928 
10930  TFileCollection *fileList = 0;
10931  if (fStatus != 0) {
10932  Error("GetDataSet", "error receiving datasets information");
10933  } else {
10934  // Look in the list
10935  TMessage *retMess = (TMessage *) fRecvMessages->First();
10936  if (retMess && retMess->What() == kMESS_OK) {
10937  if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10938  Error("GetDataSet", "error reading list of files");
10939  } else
10940  Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10941  }
10942 
10943  return fileList;
10944 }
10945 
10946 ////////////////////////////////////////////////////////////////////////////////
10947 /// display meta-info for given dataset usi
10948 
10949 void TProof::ShowDataSet(const char *uri, const char* opt)
10950 {
10951  TFileCollection *fileList = 0;
10952  if ((fileList = GetDataSet(uri))) {
10953  fileList->Print(opt);
10954  delete fileList;
10955  } else
10956  Warning("ShowDataSet","no such dataset: %s", uri);
10957 }
10958 
10959 ////////////////////////////////////////////////////////////////////////////////
10960 /// Remove the specified dataset from the PROOF cluster.
10961 /// Files are not deleted.
10962 
10963 Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10964 {
10965  TMessage nameMess(kPROOF_DATASETS);
10966  nameMess << Int_t(kRemoveDataSet);
10967  nameMess << TString(uri?uri:"");
10968  nameMess << TString(optStr?optStr:"");
10969  if (Broadcast(nameMess) < 0)
10970  Error("RemoveDataSet", "sending request failed");
10972 
10973  if (fStatus != 0)
10974  return -1;
10975  else
10976  return 0;
10977 }
10978 
10979 ////////////////////////////////////////////////////////////////////////////////
10980 /// Find datasets, returns in a TList all found datasets.
10981 
10982 TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
10983 {
10984  Error ("FindDataSets", "not yet implemented");
10985  return (TList *) 0;
10986 }
10987 
10988 ////////////////////////////////////////////////////////////////////////////////
10989 /// Allows users to request staging of a particular dataset. Requests are
10990 /// saved in a special dataset repository and must be honored by the endpoint.
10991 
10993 {
10994  if (fProtocol < 35) {
10995  Error("RequestStagingDataSet",
10996  "functionality not supported by the server");
10997  return kFALSE;
10998  }
10999 
11000  TMessage mess(kPROOF_DATASETS);
11001  mess << Int_t(kRequestStaging);
11002  mess << TString(dataset);
11003  Broadcast(mess);
11004 
11005  Collect();
11006  if (fStatus != 0) {
11007  Error("RequestStagingDataSet", "staging request was unsuccessful");
11008  return kFALSE;
11009  }
11010 
11011  return kTRUE;
11012 }
11013 
11014 ////////////////////////////////////////////////////////////////////////////////
11015 /// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11016 /// failure. Dataset not found equals to a failure.
11017 
11019 {
11020  if (fProtocol < 36) {
11021  Error("CancelStagingDataSet",
11022  "functionality not supported by the server");
11023  return kFALSE;
11024  }
11025 
11026  TMessage mess(kPROOF_DATASETS);
11027  mess << Int_t(kCancelStaging);
11028  mess << TString(dataset);
11029  Broadcast(mess);
11030 
11031  Collect();
11032  if (fStatus != 0) {
11033  Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11034  return kFALSE;
11035  }
11036 
11037  return kTRUE;
11038 }
11039 
11040 ////////////////////////////////////////////////////////////////////////////////
11041 /// Obtains a TFileCollection showing the staging status of the specified
11042 /// dataset. A valid dataset manager and dataset staging requests repository
11043 /// must be present on the endpoint.
11044 
11046 {
11047  if (fProtocol < 35) {
11048  Error("GetStagingStatusDataSet",
11049  "functionality not supported by the server");
11050  return NULL;
11051  }
11052 
11053  TMessage nameMess(kPROOF_DATASETS);
11054  nameMess << Int_t(kStagingStatus);
11055  nameMess << TString(dataset);
11056  if (Broadcast(nameMess) < 0) {
11057  Error("GetStagingStatusDataSet", "sending request failed");
11058  return NULL;
11059  }
11060 
11062  TFileCollection *fc = NULL;
11063 
11064  if (fStatus < 0) {
11065  Error("GetStagingStatusDataSet", "problem processing the request");
11066  }
11067  else if (fStatus == 0) {
11068  TMessage *retMess = (TMessage *)fRecvMessages->First();
11069  if (retMess && (retMess->What() == kMESS_OK)) {
11070  fc = (TFileCollection *)(
11071  retMess->ReadObject(TFileCollection::Class()) );
11072  if (!fc)
11073  Error("GetStagingStatusDataSet", "error reading list of files");
11074  }
11075  else {
11076  Error("GetStagingStatusDataSet",
11077  "response message not found or wrong type (%p)", retMess);
11078  }
11079  }
11080  //else {}
11081 
11082  return fc;
11083 }
11084 
11085 ////////////////////////////////////////////////////////////////////////////////
11086 /// Like GetStagingStatusDataSet, but displays results immediately.
11087 
11088 void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11089 {
11091  if (fc) {
11092  fc->Print(opt);
11093  delete fc;
11094  }
11095 }
11096 
11097 ////////////////////////////////////////////////////////////////////////////////
11098 /// Verify if all files in the specified dataset are available.
11099 /// Print a list and return the number of missing files.
11100 /// Returns -1 in case of error.
11101 
11102 Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11103 {
11104  if (fProtocol < 15) {
11105  Info("VerifyDataSet", "functionality not available: the server has an"
11106  " incompatible version of TFileInfo");
11107  return -1;
11108  }
11109 
11110  // Sanity check
11111  if (!uri || (uri && strlen(uri) <= 0)) {
11112  Error("VerifyDataSet", "dataset name is is mandatory");
11113  return -1;
11114  }
11115 
11116  Int_t nmissingfiles = 0;
11117 
11118  TString sopt(optStr);
11119  if (fProtocol < 34 || sopt.Contains("S")) {
11120  sopt.ReplaceAll("S", "");
11121  Info("VerifyDataSet", "Master-only verification");
11122  TMessage nameMess(kPROOF_DATASETS);
11123  nameMess << Int_t(kVerifyDataSet);
11124  nameMess << TString(uri);
11125  nameMess << sopt;
11126  Broadcast(nameMess);
11127 
11129 
11130  if (fStatus < 0) {
11131  Info("VerifyDataSet", "no such dataset %s", uri);
11132  return -1;
11133  } else
11134  nmissingfiles = fStatus;
11135  return nmissingfiles;
11136  }
11137 
11138  // Request for parallel verification: can only be done if we have workers
11139  if (!IsParallel() && !fDynamicStartup) {
11140  Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11141  Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11142  return -1;
11143  }
11144 
11145  // Do parallel verification
11146  return VerifyDataSetParallel(uri, optStr);
11147 }
11148 
11149 ////////////////////////////////////////////////////////////////////////////////
11150 /// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11151 /// TProofLite::VerifyDataSet
11152 
11153 Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11154 {
11155  Int_t nmissingfiles = 0;
11156 
11157  // Let PROOF master prepare node-files map
11158  SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11159 
11160  // Use TPacketizerFile
11161  TString oldpack;
11162  if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11163  SetParameter("PROOF_Packetizer", "TPacketizerFile");
11164 
11165  // Add dataset name
11166  SetParameter("PROOF_VerifyDataSet", uri);
11167  // Add options
11168  SetParameter("PROOF_VerifyDataSetOption", optStr);
11169  SetParameter("PROOF_SavePartialResults", (Int_t)0);
11170  Int_t oldifiip = -1;
11171  if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11172  SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11173 
11174  // TO DO : figure out mss and stageoption
11175  const char* mss="";
11176  SetParameter("PROOF_MSS", mss);
11177  const char* stageoption="";
11178  SetParameter("PROOF_StageOption", stageoption);
11179 
11180  // Process verification in parallel
11181  Process("TSelVerifyDataSet", (Long64_t) 1);
11182 
11183  // Restore packetizer
11184  if (!oldpack.IsNull())
11185  SetParameter("PROOF_Packetizer", oldpack);
11186  else
11187  DeleteParameters("PROOF_Packetizer");
11188 
11189  // Delete or restore parameters
11190  DeleteParameters("PROOF_FilesToProcess");
11191  DeleteParameters("PROOF_VerifyDataSet");
11192  DeleteParameters("PROOF_VerifyDataSetOption");
11193  DeleteParameters("PROOF_MSS");
11194  DeleteParameters("PROOF_StageOption");
11195  if (oldifiip > -1) {
11196  SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11197  } else {
11198  DeleteParameters("PROOF_IncludeFileInfoInPacket");
11199  }
11200  DeleteParameters("PROOF_SavePartialResults");
11201 
11202  // Merge outputs
11203  Int_t nopened = 0;
11204  Int_t ntouched = 0;
11205  Bool_t changed_ds = kFALSE;
11206 
11207  TIter nxtout(GetOutputList());
11208  TObject* obj;
11209  TList *lfiindout = new TList;
11210  while ((obj = nxtout())) {
11211  TList *l = dynamic_cast<TList *>(obj);
11212  if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11213  TIter nxt(l);
11214  TFileInfo *fiindout = 0;
11215  while ((fiindout = (TFileInfo*) nxt())) {
11216  lfiindout->Add(fiindout);
11217  }
11218  }
11219  // Add up number of disppeared files
11220  TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11221  if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11222  nmissingfiles += pdisappeared->GetVal();
11223  }
11224  TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11225  if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11226  nopened += pnopened->GetVal();
11227  }
11228  TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11229  if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11230  ntouched += pntouched->GetVal();
11231  }
11232  TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11233  if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11234  if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11235  }
11236  }
11237 
11238  Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11239  " # missing files = %d)",
11240  uri, changed_ds, nopened, ntouched, nmissingfiles);
11241  // Done
11242  return nmissingfiles;
11243 }
11244 
11245 ////////////////////////////////////////////////////////////////////////////////
11246 /// returns a map of the quotas of all groups
11247 
11248 TMap *TProof::GetDataSetQuota(const char* optStr)
11249 {
11250  if (IsLite()) {
11251  Info("UploadDataSet", "Lite-session: functionality not implemented");
11252  return (TMap *)0;
11253  }
11254 
11255  TMessage mess(kPROOF_DATASETS);
11256  mess << Int_t(kGetQuota);
11257  mess << TString(optStr?optStr:"");
11258  Broadcast(mess);
11259 
11261  TMap *groupQuotaMap = 0;
11262  if (fStatus < 0) {
11263  Info("GetDataSetQuota", "could not receive quota");
11264  } else {
11265  // Look in the list
11266  TMessage *retMess = (TMessage *) fRecvMessages->First();
11267  if (retMess && retMess->What() == kMESS_OK) {
11268  if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11269  Error("GetDataSetQuota", "error getting quotas");
11270  } else
11271  Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11272  }
11273 
11274  return groupQuotaMap;
11275 }
11276 
11277 ////////////////////////////////////////////////////////////////////////////////
11278 /// shows the quota and usage of all groups
11279 /// if opt contains "U" shows also distribution of usage on user-level
11280 
11282 {
11283  if (fProtocol < 15) {
11284  Info("ShowDataSetQuota",
11285  "functionality not available: the server does not have dataset support");
11286  return;
11287  }
11288 
11289  if (IsLite()) {
11290  Info("UploadDataSet", "Lite-session: functionality not implemented");
11291  return;
11292  }
11293 
11294  TMessage mess(kPROOF_DATASETS);
11295  mess << Int_t(kShowQuota);
11296  mess << TString(opt?opt:"");
11297  Broadcast(mess);
11298 
11299  Collect();
11300  if (fStatus != 0)
11301  Error("ShowDataSetQuota", "error receiving quota information");
11302 }
11303 
11304 ////////////////////////////////////////////////////////////////////////////////
11305 /// If in active in a monitor set ready state
11306 
11308 {
11309  if (fCurrentMonitor)
11311 }
11312 
11313 ////////////////////////////////////////////////////////////////////////////////
11314 /// Make sure that the worker identified by the ordinal number 'ord' is
11315 /// in the active list. The request will be forwarded to the master
11316 /// in direct contact with the worker. If needed, this master will move
11317 /// the worker from the inactive to the active list and rebuild the list
11318 /// of unique workers.
11319 /// Use ord = "*" to activate all inactive workers.
11320 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11321 /// status of which will be modified at once.
11322 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11323 /// or the number of workers with status change (on master; 0 on client).
11324 
11325 Int_t TProof::ActivateWorker(const char *ord, Bool_t save)
11326 {
11327  return ModifyWorkerLists(ord, kTRUE, save);
11328 }
11329 
11330 ////////////////////////////////////////////////////////////////////////////////
11331 /// Remove the worker identified by the ordinal number 'ord' from the
11332 /// the active list. The request will be forwarded to the master
11333 /// in direct contact with the worker. If needed, this master will move
11334 /// the worker from the active to the inactive list and rebuild the list
11335 /// of unique workers.
11336 /// Use ord = "*" to deactivate all active workers.
11337 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11338 /// status of which will be modified at once.
11339 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11340 /// or the number of workers with status change (on master; 0 on client).
11341 
11342 Int_t TProof::DeactivateWorker(const char *ord, Bool_t save)
11343 {
11344  return ModifyWorkerLists(ord, kFALSE, save);
11345 }
11346 
11347 ////////////////////////////////////////////////////////////////////////////////
11348 /// Modify the worker active/inactive list by making the worker identified by
11349 /// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11350 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11351 /// status of which will be modified at once.
11352 /// If needed, the request will be forwarded to the master in direct contact
11353 /// with the worker. The end-master will move the worker from one list to the
11354 /// other active and rebuild the list of unique active workers.
11355 /// Use ord = "*" to deactivate all active workers.
11356 /// If save is TRUE the current active list is saved before any modification is
11357 /// done; re-running with ord = "restore" restores the saved list
11358 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11359 /// or the number of workers with status change (on master; 0 on client).
11360 
11361 Int_t TProof::ModifyWorkerLists(const char *ord, Bool_t add, Bool_t save)
11362 {
11363  // Make sure the input make sense
11364  if (!ord || strlen(ord) <= 0) {
11365  Info("ModifyWorkerLists",
11366  "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11367  return -1;
11368  }
11369  if (gDebug > 0)
11370  Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11371 
11372  Int_t nwc = 0;
11373  Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11374  if (IsEndMaster()) {
11375  if (restoring) {
11376  // We are asked to restore the previous settings
11377  nwc = RestoreActiveList();
11378  } else {
11379  if (save) SaveActiveList();
11380  }
11381  }
11382 
11383  Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11384 
11385  // Check if this is for us
11387  if (!allord &&
11388  strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11389  return 0;
11390  }
11391 
11392  Bool_t fw = kTRUE; // Whether to forward one step down
11393  Bool_t rs = kFALSE; // Whether to rescan for unique workers
11394 
11395  // Appropriate list pointing
11396  TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11397  TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11398 
11399  if (IsEndMaster() && !restoring) {
11400  // Create the hash list of ordinal numbers
11401  THashList *ords = 0;
11402  if (!allord) {
11403  ords = new THashList();
11404  const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
11405  TString oo(ord), o;
11406  Int_t from = 0;
11407  while(oo.Tokenize(o, from, ","))
11408  if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
11409  }
11410  // We do not need to send forward
11411  fw = kFALSE;
11412  // Look for the worker in the initial list
11413  TObject *os = 0;
11414  TSlave *wrk = 0;
11415  if (in->GetSize() > 0) {
11416  TIter nxw(in);
11417  while ((wrk = (TSlave *) nxw())) {
11418  os = 0;
11419  if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
11420  // Add it to the final list
11421  if (!out->FindObject(wrk)) {
11422  out->Add(wrk);
11423  if (add)
11424  fActiveMonitor->Add(wrk->GetSocket());
11425  }
11426  // Remove it from the initial list
11427  in->Remove(wrk);
11428  if (!add) {
11429  fActiveMonitor->Remove(wrk->GetSocket());
11431  } else
11432  wrk->SetStatus(TSlave::kActive);
11433  // Count
11434  nwc++;
11435  // Nothing to forward (ord is unique)
11436  fw = kFALSE;
11437  // Rescan for unique workers (active list modified)
11438  rs = kTRUE;
11439  // We may be done, if not option 'all'
11440  if (!allord && ords) {
11441  if (os) ords->Remove(os);
11442  if (ords->GetSize() == 0) break;
11443  SafeDelete(os);
11444  }
11445  }
11446  }
11447  }
11448  // If some worker not found, notify it if at the end
11449  if (!fw && ords && ords->GetSize() > 0) {
11450  TString oo;
11451  TIter nxo(ords);
11452  while ((os = nxo())) {
11453  TIter nxw(out);
11454  while ((wrk = (TSlave *) nxw()))
11455  if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
11456  if (!wrk) {
11457  if (!oo.IsNull()) oo += ",";
11458  oo += os->GetName();
11459  }
11460  }
11461  if (!oo.IsNull()) {
11462  Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
11463  nwc = -2;
11464  }
11465  }
11466  // Cleanup hash list
11467  if (ords) {
11468  ords->Delete();
11469  SafeDelete(ords);
11470  }
11471  }
11472 
11473  // Rescan for unique workers
11474  if (rs)
11475  FindUniqueSlaves();
11476 
11477  // Forward the request one step down, if needed
11478  Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
11479  if (fw) {
11480  if (fProtocol > 32) {
11482  mess << action << TString(ord);
11483  Broadcast(mess);
11485  if (fStatus != 0) {
11486  nwc = (fStatus < nwc) ? fStatus : nwc;
11487  if (fStatus == -2) {
11488  if (gDebug > 0)
11489  Warning("ModifyWorkerLists", "request not completely full filled");
11490  } else {
11491  Error("ModifyWorkerLists", "request failed");
11492  }
11493  }
11494  } else {
11495  TString oo(ord), o;
11496  if (oo.Contains(","))
11497  Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
11498  Int_t from = 0;
11499  while(oo.Tokenize(o, from, ",")) {
11501  mess << action << o;
11502  Broadcast(mess);
11504  }
11505  }
11506  }
11507  // Done
11508  return nwc;
11509 }
11510 
11511 ////////////////////////////////////////////////////////////////////////////////
11512 /// Save current list of active workers
11513 
11515 {
11517  if (fInactiveSlaves->GetSize() == 0) {
11518  fActiveSlavesSaved = "*";
11519  } else {
11520  TIter nxw(fActiveSlaves);
11521  TSlave *wk = 0;
11522  while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
11523  }
11524 }
11525 
11526 ////////////////////////////////////////////////////////////////////////////////
11527 /// Restore saved list of active workers
11528 
11530 {
11531  // Clear the current active list
11532  DeactivateWorker("*", kFALSE);
11533  // Restore the previous active list
11534  if (!fActiveSlavesSaved.IsNull())
11536 
11537  return 0;
11538 }
11539 
11540 ////////////////////////////////////////////////////////////////////////////////
11541 /// Start a PROOF session on a specific cluster. If cluster is 0 (the
11542 /// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
11543 /// If cluster is "lite://" we start a PROOF-lite session.
11544 /// If cluster is "" (empty string) then we connect to the cluster specified
11545 /// by 'Proof.LocalDefault', defaulting to "lite://".
11546 /// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
11547 /// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
11548 /// Via conffile a specific PROOF config file in the confir directory can be specified.
11549 /// Use loglevel to set the default loging level for debugging.
11550 /// The appropriate instance of TProofMgr is created, if not
11551 /// yet existing. The instantiated TProof object is returned.
11552 /// Use TProof::cd() to switch between PROOF sessions.
11553 /// For more info on PROOF see the TProof ctor.
11554 
11555 TProof *TProof::Open(const char *cluster, const char *conffile,
11556  const char *confdir, Int_t loglevel)
11557 {
11558  const char *pn = "TProof::Open";
11559 
11560  // Make sure libProof and dependents are loaded and TProof can be created,
11561  // dependents are loaded via the information in the [system].rootmap file
11562  if (!cluster) {
11563 
11564  TPluginManager *pm = gROOT->GetPluginManager();
11565  if (!pm) {
11566  ::Error(pn, "plugin manager not found");
11567  return 0;
11568  }
11569 
11570  if (gROOT->IsBatch()) {
11571  ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
11572  return 0;
11573  }
11574  // start PROOF Session Viewer
11575  TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
11576  if (!sv) {
11577  ::Error(pn, "no plugin found for TSessionViewer");
11578  return 0;
11579  }
11580  if (sv->LoadPlugin() == -1) {
11581  ::Error(pn, "plugin for TSessionViewer could not be loaded");
11582  return 0;
11583  }
11584  sv->ExecPlugin(0);
11585  return 0;
11586 
11587  } else {
11588 
11589  TString clst(cluster);
11590 
11591  // Check for PoD cluster
11592  if (PoDCheckUrl( &clst ) < 0) return 0;
11593 
11594  if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
11595  if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
11596 
11597  // Parse input URL
11598  TUrl u(clst);
11599 
11600  // *** GG, 060711: this does not seem to work any more (at XrdClient level)
11601  // *** to be investigated (it is not really needed; static tunnels work).
11602  // Dynamic tunnel:
11603  // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
11604  TString opts(u.GetOptions());
11605  if (!opts.IsNull()) {
11606  Int_t it = opts.Index("tunnel=");
11607  if (it != kNPOS) {
11608  TString sport = opts(it + strlen("tunnel="), opts.Length());
11609  TString host("127.0.0.1");
11610  Int_t port = -1;
11611  Int_t ic = sport.Index(":");
11612  if (ic != kNPOS) {
11613  // Isolate the host
11614  host = sport(0, ic);
11615  sport.Remove(0, ic + 1);
11616  }
11617  if (!sport.IsDigit()) {
11618  // Remove the non digit part
11619  TRegexp re("[^0-9]");
11620  Int_t ind = sport.Index(re);
11621  if (ind != kNPOS)
11622  sport.Remove(ind);
11623  }
11624  // Set the port
11625  if (sport.IsDigit())
11626  port = sport.Atoi();
11627  if (port > 0) {
11628  // Set the relevant variables
11629  ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
11630  gEnv->SetValue("XNet.SOCKS4Host", host);
11631  gEnv->SetValue("XNet.SOCKS4Port", port);
11632  } else {
11633  // Warn parsing problems
11634  ::Warning("TProof::Open",
11635  "problems parsing tunnelling info from options: %s", opts.Data());
11636  }
11637  }
11638  }
11639 
11640  // Find out if we are required to attach to a specific session
11641  Int_t locid = -1;
11642  Bool_t create = kFALSE;
11643  if (opts.Length() > 0) {
11644  if (opts.BeginsWith("N",TString::kIgnoreCase)) {
11645  create = kTRUE;
11646  opts.Remove(0,1);
11647  u.SetOptions(opts);
11648  } else if (opts.IsDigit()) {
11649  locid = opts.Atoi();
11650  }
11651  }
11652 
11653  // Attach-to or create the appropriate manager
11654  TProofMgr *mgr = TProofMgr::Create(u.GetUrl());
11655 
11656  TProof *proof = 0;
11657  if (mgr && mgr->IsValid()) {
11658 
11659  // If XProofd we always attempt an attach first (unless
11660  // explicitly not requested).
11661  Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
11662  if (attach) {
11663  TProofDesc *d = 0;
11664  if (locid < 0)
11665  // Get the list of sessions
11666  d = (TProofDesc *) mgr->QuerySessions("")->First();
11667  else
11668  d = (TProofDesc *) mgr->GetProofDesc(locid);
11669  if (d) {
11670  proof = (TProof*) mgr->AttachSession(d);
11671  if (!proof || !proof->IsValid()) {
11672  if (locid)
11673  ::Error(pn, "new session could not be attached");
11674  SafeDelete(proof);
11675  }
11676  }
11677  }
11678 
11679  // start the PROOF session
11680  if (!proof) {
11681  proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
11682  if (!proof || !proof->IsValid()) {
11683  ::Error(pn, "new session could not be created");
11684  SafeDelete(proof);
11685  }
11686  }
11687  }
11688  return proof;
11689  }
11690 }
11691 
11692 ////////////////////////////////////////////////////////////////////////////////
11693 /// Get instance of the effective manager for 'url'
11694 /// Return 0 on failure.
11695 
11696 TProofMgr *TProof::Mgr(const char *url)
11697 {
11698  if (!url)
11699  return (TProofMgr *)0;
11700 
11701  // Attach or create the relevant instance
11702  return TProofMgr::Create(url);
11703 }
11704 
11705 ////////////////////////////////////////////////////////////////////////////////
11706 /// Wrapper around TProofMgr::Reset(...).
11707 
11708 void TProof::Reset(const char *url, Bool_t hard)
11709 {
11710  if (url) {
11711  TProofMgr *mgr = TProof::Mgr(url);
11712  if (mgr && mgr->IsValid())
11713  mgr->Reset(hard);
11714  else
11715  ::Error("TProof::Reset",
11716  "unable to initialize a valid manager instance");
11717  }
11718 }
11719 
11720 ////////////////////////////////////////////////////////////////////////////////
11721 /// Get environemnt variables.
11722 
11724 {
11725  return fgProofEnvList;
11726 }
11727 
11728 ////////////////////////////////////////////////////////////////////////////////
11729 /// Add an variable to the list of environment variables passed to proofserv
11730 /// on the master and slaves
11731 
11732 void TProof::AddEnvVar(const char *name, const char *value)
11733 {
11734  if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
11735 
11736  if (fgProofEnvList == 0) {
11737  // initialize the list if needed
11738  fgProofEnvList = new TList;
11740  } else {
11741  // replace old entries with the same name
11742  TObject *o = fgProofEnvList->FindObject(name);
11743  if (o != 0) {
11744  fgProofEnvList->Remove(o);
11745  }
11746  }
11747  fgProofEnvList->Add(new TNamed(name, value));
11748 }
11749 
11750 ////////////////////////////////////////////////////////////////////////////////
11751 /// Remove an variable from the list of environment variables passed to proofserv
11752 /// on the master and slaves
11753 
11754 void TProof::DelEnvVar(const char *name)
11755 {
11756  if (fgProofEnvList == 0) return;
11757 
11758  TObject *o = fgProofEnvList->FindObject(name);
11759  if (o != 0) {
11760  fgProofEnvList->Remove(o);
11761  }
11762 }
11763 
11764 ////////////////////////////////////////////////////////////////////////////////
11765 /// Clear the list of environment variables passed to proofserv
11766 /// on the master and slaves
11767 
11769 {
11770  if (fgProofEnvList == 0) return;
11771 
11773 }
11774 
11775 ////////////////////////////////////////////////////////////////////////////////
11776 /// Save information about the worker set in the file .workers in the working
11777 /// dir. Called each time there is a change in the worker setup, e.g. by
11778 /// TProof::MarkBad().
11779 
11781 {
11782  // We must be masters
11784  return;
11785 
11786  // We must have a server defined
11787  if (!gProofServ) {
11788  Error("SaveWorkerInfo","gProofServ undefined");
11789  return;
11790  }
11791 
11792  // The relevant lists must be defined
11793  if (!fSlaves && !fBadSlaves) {
11794  Warning("SaveWorkerInfo","all relevant worker lists is undefined");
11795  return;
11796  }
11797 
11798  // Create or truncate the file first
11799  TString fnwrk = TString::Format("%s/.workers",
11801  FILE *fwrk = fopen(fnwrk.Data(),"w");
11802  if (!fwrk) {
11803  Error("SaveWorkerInfo",
11804  "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
11805  return;
11806  }
11807 
11808  // Do we need to register an additional line for another log?
11809  TString addlogext;
11810  TString addLogTag;
11811  if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
11812  addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
11813  TPMERegexp reLogTag("^__(.*)__\\.log"); // $
11814  if (reLogTag.Match(addlogext) == 2) {
11815  addLogTag = reLogTag[1];
11816  }
11817  else {
11818  addLogTag = "+++";
11819  }
11820  if (gDebug > 0)
11821  Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
11822  }
11823 
11824  // Used to eliminate datetime and PID from workdir to obtain log file name
11825  TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
11826 
11827  // Loop over the list of workers (active is any worker not flagged as bad)
11828  TIter nxa(fSlaves);
11829  TSlave *wrk = 0;
11830  TString logfile;
11831  while ((wrk = (TSlave *) nxa())) {
11832  Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
11833  logfile = wrk->GetWorkDir();
11834  if (re.Match(logfile) == 2) logfile = re[1];
11835  else continue; // invalid (should not happen)
11836  // Write out record for this worker
11837  fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
11838  wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11839  wrk->GetOrdinal(), logfile.Data());
11840  // Additional line, if required
11841  if (addlogext.Length() > 0) {
11842  fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
11843  wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11844  wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
11845  }
11846 
11847  }
11848 
11849  // Loop also over the list of bad workers (if they failed to startup they are not in
11850  // the overall list
11851  TIter nxb(fBadSlaves);
11852  while ((wrk = (TSlave *) nxb())) {
11853  logfile = wrk->GetWorkDir();
11854  if (re.Match(logfile) == 2) logfile = re[1];
11855  else continue; // invalid (should not happen)
11856  if (!fSlaves->FindObject(wrk)) {
11857  // Write out record for this worker
11858  fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
11859  wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
11860  wrk->GetOrdinal(), logfile.Data());
11861  }
11862  }
11863 
11864  // Eventually loop over the list of gracefully terminated workers: we'll get
11865  // logfiles from those workers as well. They'll be shown with a special
11866  // status of "2"
11868  TSlaveInfo *sli;
11869  while (( sli = (TSlaveInfo *)nxt() )) {
11870  logfile = sli->GetDataDir();
11871  if (re.Match(logfile) == 2) logfile = re[1];
11872  else continue; // invalid (should not happen)
11873  fprintf(fwrk, "%s 2 %s %s.log\n",
11874  sli->GetName(), sli->GetOrdinal(), logfile.Data());
11875  // Additional line, if required
11876  if (addlogext.Length() > 0) {
11877  fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
11878  sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
11879  logfile.Data(), addlogext.Data());
11880  }
11881  }
11882 
11883  // Close file
11884  fclose(fwrk);
11885 
11886  // We are done
11887  return;
11888 }
11889 
11890 ////////////////////////////////////////////////////////////////////////////////
11891 /// Get the value from the specified parameter from the specified collection.
11892 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11893 /// or value type does not match), 0 otherwise.
11894 
11895 Int_t TProof::GetParameter(TCollection *c, const char *par, TString &value)
11896 {
11897  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11898  if (obj) {
11899  TNamed *p = dynamic_cast<TNamed*>(obj);
11900  if (p) {
11901  value = p->GetTitle();
11902  return 0;
11903  }
11904  }
11905  return -1;
11906 
11907 }
11908 
11909 ////////////////////////////////////////////////////////////////////////////////
11910 /// Get the value from the specified parameter from the specified collection.
11911 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11912 /// or value type does not match), 0 otherwise.
11913 
11914 Int_t TProof::GetParameter(TCollection *c, const char *par, Int_t &value)
11915 {
11916  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11917  if (obj) {
11918  TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
11919  if (p) {
11920  value = p->GetVal();
11921  return 0;
11922  }
11923  }
11924  return -1;
11925 }
11926 
11927 ////////////////////////////////////////////////////////////////////////////////
11928 /// Get the value from the specified parameter from the specified collection.
11929 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11930 /// or value type does not match), 0 otherwise.
11931 
11932 Int_t TProof::GetParameter(TCollection *c, const char *par, Long_t &value)
11933 {
11934  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11935  if (obj) {
11936  TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
11937  if (p) {
11938  value = p->GetVal();
11939  return 0;
11940  }
11941  }
11942  return -1;
11943 }
11944 
11945 ////////////////////////////////////////////////////////////////////////////////
11946 /// Get the value from the specified parameter from the specified collection.
11947 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11948 /// or value type does not match), 0 otherwise.
11949 
11951 {
11952  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11953  if (obj) {
11954  TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
11955  if (p) {
11956  value = p->GetVal();
11957  return 0;
11958  }
11959  }
11960  return -1;
11961 }
11962 
11963 ////////////////////////////////////////////////////////////////////////////////
11964 /// Get the value from the specified parameter from the specified collection.
11965 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11966 /// or value type does not match), 0 otherwise.
11967 
11969 {
11970  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11971  if (obj) {
11972  TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
11973  if (p) {
11974  value = p->GetVal();
11975  return 0;
11976  }
11977  }
11978  return -1;
11979 }
11980 
11981 ////////////////////////////////////////////////////////////////////////////////
11982 /// Make sure that dataset is in the form to be processed. This may mean
11983 /// retrieving the relevant info from the dataset manager or from the
11984 /// attached input list.
11985 /// Returns 0 on success, -1 on error
11986 
11988  TDataSetManager *mgr, TString &emsg)
11989 {
11990  emsg = "";
11991 
11992  // We must have something to process
11993  if (!dset || !input || !mgr) {
11994  emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
11995  return -1;
11996  }
11997 
11998  TList *datasets = new TList;
11999  TFileCollection *dataset = 0;
12000  TString lookupopt;
12001  TString dsname(dset->GetName());
12002 
12003  // First extract the "entry list" part on the global name, if any
12004  TString dsns(dsname), enlname;
12005  Ssiz_t eli = dsns.Index("?enl=");
12006  if (eli != kNPOS) {
12007  enlname = dsns(eli + strlen("?enl="), dsns.Length());
12008  dsns.Remove(eli, dsns.Length()-eli);
12009  }
12010 
12011  // The dataset maybe in the form of a TFileCollection in the input list
12012  if (dsname.BeginsWith("TFileCollection:")) {
12013  // Isolate the real name
12014  dsname.ReplaceAll("TFileCollection:", "");
12015  // Get the object
12016  dataset = (TFileCollection *) input->FindObject(dsname);
12017  if (!dataset) {
12018  emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12019  return -1;
12020  }
12021  // Remove from everywhere
12022  input->RecursiveRemove(dataset);
12023  // Add it to the local list
12024  datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12025  // Make sure we lookup everything (unless the client or the administrator
12026  // required something else)
12027  if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12028  lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12029  input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12030  }
12031  }
12032 
12033  // This is the name we parse for additional specifications, such directory
12034  // and object name; for multiple datasets we assume that the directory and
12035  // and object name are the same for all datasets
12036  TString dsnparse;
12037  // The received message included an empty dataset, with only the name
12038  // defined: assume that a dataset, stored on the PROOF master by that
12039  // name, should be processed.
12040  if (!dataset) {
12041 
12042  TFileCollection *fc = nullptr;
12043 
12044  // Check if the entry list and dataset name are valid. If they have spaces,
12045  // commas, or pipes, they are not considered as valid and we revert to the
12046  // "multiple datasets" case
12047  TRegexp rg("[, |]");
12048  Bool_t validEnl = (enlname.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12049  Bool_t validSdsn = (dsns.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12050 
12051  if (validEnl && validSdsn && (( fc = mgr->GetDataSet(dsns) ))) {
12052 
12053  //
12054  // String corresponds to ONE dataset only
12055  //
12056 
12057  TIter nxfi(fc->GetList());
12058  TFileInfo *fi;
12059  while (( fi = (TFileInfo *)nxfi() ))
12060  fi->SetTitle(dsns.Data());
12061  dataset = fc;
12062  dsnparse = dsns; // without entry list
12063 
12064  // Adds the entry list (or empty string if not specified)
12065  datasets->Add( new TPair(dataset, new TObjString( enlname.Data() )) );
12066 
12067  } else {
12068 
12069  //
12070  // String does NOT correspond to one dataset: check if many datasets
12071  // were specified instead
12072  //
12073 
12074  dsns = dsname.Data();
12075  TString dsn1;
12076  Int_t from1 = 0;
12077  while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12078  TString dsn2;
12079  Int_t from2 = 0;
12080  while (dsn1.Tokenize(dsn2, from2, "|")) {
12081  enlname = "";
12082  Int_t ienl = dsn2.Index("?enl=");
12083  if (ienl != kNPOS) {
12084  enlname = dsn2(ienl + 5, dsn2.Length());
12085  dsn2.Remove(ienl);
12086  }
12087  if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12088  // Save dataset name in TFileInfo's title to use it in TDset
12089  TIter nxfi(fc->GetList());
12090  TFileInfo *fi;
12091  while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12092  dsnparse = dsn2;
12093  if (!dataset) {
12094  // This is our dataset
12095  dataset = fc;
12096  } else {
12097  // Add it to the dataset
12098  dataset->Add(fc);
12099  SafeDelete(fc);
12100  }
12101  }
12102  }
12103  // The dataset name(s) in the first element
12104  if (dataset) {
12105  if (dataset->GetList()->First())
12106  ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12107  // Add it to the local list
12108  datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12109  }
12110  // Reset the pointer
12111  dataset = 0;
12112  }
12113 
12114  }
12115 
12116  //
12117  // At this point the dataset(s) to be processed, if any, are found in the
12118  // "datasets" variable
12119  //
12120 
12121  if (!datasets || datasets->GetSize() <= 0) {
12122  emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12123  return -1;
12124  } else {
12125  // Make 'dataset' to point to the first one in the list
12126  if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12127  emsg.Form("dataset pointer is null: corruption? - aborting");
12128  return -1;
12129  }
12130  }
12131  // Apply the lookup option requested by the client or the administartor
12132  // (by default we trust the information in the dataset)
12133  if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12134  lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12135  input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12136  }
12137  } else {
12138  // We were given a named, single, TFileCollection
12139  dsnparse = dsname;
12140  }
12141 
12142  // Logic for the subdir/obj names: try first to see if the dataset name contains
12143  // some info; if not check the settings in the TDSet object itself; if still empty
12144  // check the default tree name / path in the TFileCollection object; if still empty
12145  // use the default as the flow will determine
12146  TString dsTree;
12147  // Get the [subdir/]tree, if any
12148  mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12149  if (dsTree.IsNull()) {
12150  // Use what we have in the original dataset; we need this to locate the
12151  // meta data information
12152  dsTree += dset->GetDirectory();
12153  dsTree += dset->GetObjName();
12154  }
12155  if (!dsTree.IsNull() && dsTree != "/") {
12156  TString tree(dsTree);
12157  Int_t idx = tree.Index("/");
12158  if (idx != kNPOS) {
12159  TString dir = tree(0, idx+1);
12160  tree.Remove(0, idx);
12161  dset->SetDirectory(dir);
12162  }
12163  dset->SetObjName(tree);
12164  } else {
12165  // Use the default obj name from the TFileCollection
12166  dsTree = dataset->GetDefaultTreeName();
12167  }
12168 
12169  // Pass dataset server mapping instructions, if any
12170  TList *srvmapsref = TDataSetManager::GetDataSetSrvMaps();
12171  TList *srvmapslist = srvmapsref;
12172  TString srvmaps;
12173  if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12174  srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12175  if (gProofServ) {
12176  TString msg;
12177  if (srvmapsref && !srvmapslist) {
12178  msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12179  } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12180  msg.Form("+++ Info: dataset server mapping(s) modified by user");
12181  } else if (!srvmapsref && srvmapslist) {
12182  msg.Form("+++ Info: dataset server mapping(s) added by user");
12183  }
12185  }
12186  }
12187 
12188  // Flag multi-datasets
12189  if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12190  // Loop over the list of datasets
12191  TList *listOfMissingFiles = new TList;
12192  TEntryList *entrylist = 0;
12193  TPair *pair = 0;
12194  TIter nxds(datasets);
12195  while ((pair = (TPair *) nxds())) {
12196  // File Collection
12197  dataset = (TFileCollection *) pair->Key();
12198  // Entry list, if any
12199  TEntryList *enl = 0;
12200  TObjString *os = (TObjString *) pair->Value();
12201  if (strlen(os->GetName())) {
12202  if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12203  if (gProofServ)
12205  " entry list %s not found", os->GetName()));
12206  }
12207  if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12208  if (gProofServ)
12210  " no sub-lists in entry-list!"));
12211  }
12212  }
12213  TList *missingFiles = new TList;
12214  TSeqCollection* files = dataset->GetList();
12215  if (gDebug > 0) files->Print();
12216  Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12217  if (dset->TestBit(TDSet::kMultiDSet)) {
12218  TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12219  ds->SetSrvMaps(srvmapslist);
12220  if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12221  emsg.Form("error integrating dataset %s", dataset->GetName());
12222  continue;
12223  }
12224  // Add the TDSet object to the multi-dataset
12225  dset->Add(ds);
12226  // Add entry list if any
12227  if (enl) ds->SetEntryList(enl);
12228  } else {
12229  dset->SetSrvMaps(srvmapslist);
12230  if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12231  emsg.Form("error integrating dataset %s", dataset->GetName());
12232  continue;
12233  }
12234  if (enl) entrylist = enl;
12235  }
12236  if (missingFiles) {
12237  // The missing files objects have to be removed from the dataset
12238  // before delete.
12239  TIter next(missingFiles);
12240  TObject *file;
12241  while ((file = next())) {
12242  dataset->GetList()->Remove(file);
12243  listOfMissingFiles->Add(file);
12244  }
12245  missingFiles->SetOwner(kFALSE);
12246  missingFiles->Clear();
12247  }
12248  SafeDelete(missingFiles);
12249  }
12250  // Cleanup; we need to do this because pairs do no delete their content
12251  nxds.Reset();
12252  while ((pair = (TPair *) nxds())) {
12253  if (pair->Key()) delete pair->Key();
12254  if (pair->Value()) delete pair->Value();
12255  }
12256  datasets->SetOwner(kTRUE);
12257  SafeDelete(datasets);
12258 
12259  // Cleanup the server mapping list, if created by the user
12260  if (srvmapslist && srvmapslist != srvmapsref) {
12261  srvmapslist->SetOwner(kTRUE);
12262  SafeDelete(srvmapslist);
12263  }
12264 
12265  // Set the global entrylist, if required
12266  if (entrylist) dset->SetEntryList(entrylist);
12267 
12268  // Make sure it will be sent back merged with other similar lists created
12269  // during processing; this list will be transferred by the player to the
12270  // output list, once the latter has been created (see TProofPlayerRemote::Process)
12271  if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12272  listOfMissingFiles->SetName("MissingFiles");
12273  input->Add(listOfMissingFiles);
12274  }
12275 
12276  // Done
12277  return 0;
12278 }
12279 
12280 ////////////////////////////////////////////////////////////////////////////////
12281 /// Save input data file from 'cachedir' into the sandbox or create a the file
12282 /// with input data objects
12283 
12284 Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12285 {
12286  TList *input = 0;
12287 
12288  // We must have got something to process
12289  if (!qr || !(input = qr->GetInputList()) ||
12290  !cachedir || strlen(cachedir) <= 0) return 0;
12291 
12292  // There must be some input data or input data file
12293  TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12294  TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12295  if (!data && !inputdata) return 0;
12296  // Default dstination filename
12297  if (!data)
12298  input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12299 
12300  TString dstname(data->GetTitle()), srcname;
12301  Bool_t fromcache = kFALSE;
12302  if (dstname.BeginsWith("cache:")) {
12303  fromcache = kTRUE;
12304  dstname.ReplaceAll("cache:", "");
12305  srcname.Form("%s/%s", cachedir, dstname.Data());
12306  if (gSystem->AccessPathName(srcname)) {
12307  emsg.Form("input data file not found in cache (%s)", srcname.Data());
12308  return -1;
12309  }
12310  }
12311 
12312  // If from cache, just move the cache file
12313  if (fromcache) {
12314  if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12315  emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12316  return -1;
12317  }
12318  } else {
12319  // Create the file
12320  if (inputdata && inputdata->GetSize() > 0) {
12321  TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12322  if (f) {
12323  f->cd();
12324  inputdata->Write();
12325  f->Close();
12326  delete f;
12327  } else {
12328  emsg.Form("could not create %s", dstname.Data());
12329  return -1;
12330  }
12331  } else {
12332  emsg.Form("no input data!");
12333  return -1;
12334  }
12335  }
12336  ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12337 
12338  // Save the file name and clean up the data list
12339  data->SetTitle(dstname);
12340  if (inputdata) {
12341  input->Remove(inputdata);
12342  inputdata->SetOwner();
12343  delete inputdata;
12344  }
12345 
12346  // Done
12347  return 0;
12348 }
12349 
12350 ////////////////////////////////////////////////////////////////////////////////
12351 /// Send the input data file to the workers
12352 
12354 {
12355  TList *input = 0;
12356 
12357  // We must have got something to process
12358  if (!qr || !(input = qr->GetInputList())) return 0;
12359 
12360  // There must be some input data or input data file
12361  TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12362  if (!inputdata) return 0;
12363 
12364  TString fname(inputdata->GetTitle());
12365  if (gSystem->AccessPathName(fname)) {
12366  emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12367  return -1;
12368  }
12369 
12370  // PROOF session must available
12371  if (!p || !p->IsValid()) {
12372  emsg.Form("TProof object undefined or invalid: protocol error!");
12373  return -1;
12374  }
12375 
12376  // Send to unique workers and submasters
12377  p->BroadcastFile(fname, TProof::kBinary, "cache");
12378 
12379  // Done
12380  return 0;
12381 }
12382 
12383 ////////////////////////////////////////////////////////////////////////////////
12384 /// Get the input data from the file defined in the input list
12385 
12386 Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12387 {
12388  // We must have got something to process
12389  if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12390 
12391  // There must be some input data or input data file
12392  TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12393  if (!inputdata) return 0;
12394 
12395  TString fname;
12396  fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12397  if (gSystem->AccessPathName(fname)) {
12398  emsg.Form("input data file not found in cache (%s)", fname.Data());
12399  return -1;
12400  }
12401 
12402  // List of added objects (for proper cleaning ...)
12403  TList *added = new TList;
12404  added->SetName("PROOF_InputObjsFromFile");
12405  // Read the input data into the input list
12406  TFile *f = TFile::Open(fname.Data());
12407  if (f) {
12408  TList *keys = (TList *) f->GetListOfKeys();
12409  if (!keys) {
12410  emsg.Form("could not get list of object keys from file");
12411  return -1;
12412  }
12413  TIter nxk(keys);
12414  TKey *k = 0;
12415  while ((k = (TKey *)nxk())) {
12416  TObject *o = f->Get(k->GetName());
12417  if (o) {
12418  input->Add(o);
12419  added->Add(o);
12420  }
12421  }
12422  // Add the file as last one
12423  if (added->GetSize() > 0) {
12424  added->Add(f);
12425  input->Add(added);
12426  } else {
12427  // Cleanup the file now
12428  f->Close();
12429  delete f;
12430  }
12431  } else {
12432  emsg.Form("could not open %s", fname.Data());
12433  return -1;
12434  }
12435 
12436  // Done
12437  return 0;
12438 }
12439 
12440 ////////////////////////////////////////////////////////////////////////////////
12441 /// Start the log viewer window usign the plugin manager
12442 
12443 void TProof::LogViewer(const char *url, Int_t idx)
12444 {
12445  if (!gROOT->IsBatch()) {
12446  // Get the handler, if not yet done
12447  if (!fgLogViewer) {
12448  if ((fgLogViewer =
12449  gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
12450  if (fgLogViewer->LoadPlugin() == -1) {
12451  fgLogViewer = 0;
12452  ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
12453  return;
12454  }
12455  }
12456  }
12457  if (fgLogViewer) {
12458  // Execute the plug-in
12459  TString u = (url && strlen(url) <= 0) ? "lite" : url;
12460  fgLogViewer->ExecPlugin(2, u.Data(), idx);
12461  }
12462  } else {
12463  if (url && strlen(url) > 0) {
12464  ::Info("TProof::LogViewer",
12465  "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
12466  } else if (url && strlen(url) <= 0) {
12467  ::Info("TProof::LogViewer",
12468  "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
12469  } else {
12470  ::Info("TProof::LogViewer",
12471  "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
12472  }
12473  }
12474  // Done
12475  return;
12476 }
12477 
12478 ////////////////////////////////////////////////////////////////////////////////
12479 /// Enable/Disable the graphic progress dialog.
12480 /// By default the dialog is enabled
12481 
12483 {
12484  if (on)
12486  else
12488 }
12489 
12490 ////////////////////////////////////////////////////////////////////////////////
12491 /// Show information about missing files during query described by 'qr' or the
12492 /// last query if qr is null (default).
12493 /// A short summary is printed in the end.
12494 
12496 {
12497  TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12498  if (!xqr) {
12499  Warning("ShowMissingFiles", "no (last) query found: do nothing");
12500  return;
12501  }
12502 
12503  // Get the list, if any
12504  TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12505  if (!missing) {
12506  Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12507  return;
12508  }
12509 
12510  Int_t nmf = 0, ncf = 0;
12511  Long64_t msz = 0, mszzip = 0, mev = 0;
12512  // Scan the list
12513  TFileInfo *fi = 0;
12514  TIter nxf(missing);
12515  while ((fi = (TFileInfo *) nxf())) {
12516  char status = 'M';
12517  if (fi->TestBit(TFileInfo::kCorrupted)) {
12518  ncf++;
12519  status = 'C';
12520  } else {
12521  nmf++;
12522  }
12523  TFileInfoMeta *im = fi->GetMetaData();
12524  if (im) {
12525  if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
12526  if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
12527  mev += im->GetEntries();
12528  Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
12529  } else {
12530  Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
12531  }
12532  }
12533 
12534  // Final notification
12535  if (msz <= 0) msz = -1;
12536  if (mszzip <= 0) mszzip = -1;
12537  Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
12538  if (msz > 0. || mszzip > 0.) {
12539  Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12540  " about %.2f%% of the total (%lld bytes, %lld zipped)",
12541  nmf, ncf, mev, xf * 100., msz, mszzip);
12542  } else {
12543  Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12544  " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
12545  }
12546 }
12547 
12548 ////////////////////////////////////////////////////////////////////////////////
12549 /// Get a TFileCollection with the files missing in the query described by 'qr'
12550 /// or the last query if qr is null (default).
12551 /// Return a null pointer if none were found, for whatever reason.
12552 /// The caller is responsible for the returned object.
12553 
12555 {
12556  TFileCollection *fc = 0;
12557 
12558  TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12559  if (!xqr) {
12560  Warning("GetMissingFiles", "no (last) query found: do nothing");
12561  return fc;
12562  }
12563 
12564  // Get the list, if any
12565  TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12566  if (!missing) {
12567  if (gDebug > 0)
12568  Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12569  return fc;
12570  }
12571 
12572  // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
12573  TString fcname("unknown");
12574  TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
12575  if (ds) {
12576  fcname.Form("%s.m0", ds->GetName());
12577  Int_t j = 1;
12578  while (gDirectory->FindObject(fcname) && j < 1000)
12579  fcname.Form("%s.m%d", ds->GetName(), j++);
12580  }
12581  fc = new TFileCollection(fcname, "Missing Files");
12582  if (ds) fc->SetDefaultTreeName(ds->GetObjName());
12583  // Scan the list
12584  TFileInfo *fi = 0;
12585  TIter nxf(missing);
12586  while ((fi = (TFileInfo *) nxf())) {
12587  fc->Add((TFileInfo *) fi->Clone());
12588  }
12589  fc->Update();
12590  // Done
12591  return fc;
12592 }
12593 
12594 ////////////////////////////////////////////////////////////////////////////////
12595 /// Enable/Disable saving of the performance tree
12596 
12597 void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
12598 {
12599  if (pf && strlen(pf) > 0) {
12600  fPerfTree = pf;
12601  SetParameter("PROOF_StatsHist", "");
12602  SetParameter("PROOF_StatsTrace", "");
12603  if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
12604  Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
12605  } else {
12606  fPerfTree = "";
12607  DeleteParameters("PROOF_StatsHist");
12608  DeleteParameters("PROOF_StatsTrace");
12609  DeleteParameters("PROOF_SlaveStatsTrace");
12610  Info("SetPerfTree", "saving of the performance tree disabled");
12611  }
12612 }
12613 
12614 ////////////////////////////////////////////////////////////////////////////////
12615 /// Save performance information from TPerfStats to file 'pf'.
12616 /// If 'ref' is defined, do it for query 'ref'.
12617 /// Return 0 on sucecss, -1 in case of any error
12618 
12619 Int_t TProof::SavePerfTree(const char *pf, const char *ref)
12620 {
12621  if (!IsValid()) {
12622  Error("SafePerfTree", "this TProof instance is invalid!");
12623  return -1;
12624  }
12625 
12626  TList *outls = GetOutputList();
12627  TString sref;
12628  if (ref && strlen(ref) > 0) {
12629  if (!fPlayer) {
12630  Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
12631  return -1;
12632  }
12633  TQueryResult *qr = fPlayer->GetQueryResult(ref);
12634  if (!qr) {
12635  Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
12636  return -1;
12637  }
12638  outls = qr->GetOutputList();
12639  sref.Form(" for requested query '%s'", ref);
12640  }
12641  if (!outls || (outls && outls->GetSize() <= 0)) {
12642  Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
12643  return -1;
12644  }
12645 
12646  TString fn = fPerfTree;
12647  if (pf && strlen(pf)) fn = pf;
12648  if (fn.IsNull()) fn = "perftree.root";
12649 
12650  TFile f(fn, "RECREATE");
12651  if (f.IsZombie()) {
12652  Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
12653  } else {
12654  f.cd();
12655  TIter nxo(outls);
12656  TObject* obj = 0;
12657  while ((obj = nxo())) {
12658  TString objname(obj->GetName());
12659  if (objname.BeginsWith("PROOF_")) {
12660  // Must list the objects since other PROOF_ objects exist
12661  // besides timing objects
12662  if (objname == "PROOF_PerfStats" ||
12663  objname == "PROOF_PacketsHist" ||
12664  objname == "PROOF_EventsHist" ||
12665  objname == "PROOF_NodeHist" ||
12666  objname == "PROOF_LatencyHist" ||
12667  objname == "PROOF_ProcTimeHist" ||
12668  objname == "PROOF_CpuTimeHist")
12669  obj->Write();
12670  }
12671  }
12672  f.Close();
12673  }
12674  Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
12675 
12676  // Done
12677  return 0;
12678 }
static Int_t FindParPath(TPackMgr *packmgr, const char *pack, TString &par)
Get the full path to PAR, looking also in the global dirs.
Definition: TPackMgr.cxx:933
Int_t GetSlaveType() const
Definition: TSlave.h:139
virtual TQueryResult * GetQueryResult(const char *ref)=0
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:261
Int_t GetStatus() const
Definition: TSlave.h:140
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:9494
virtual void DeleteDrawFeedback(TDrawFeedback *f)=0
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
TList * GetOutputList()
Definition: TQueryResult.h:131
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition: TProof.cxx:3077
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:932
static void AssertMacroPath(const char *macro)
Make sure that the directory path contained by macro is in the macro path.
Definition: TProof.cxx:8571
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:894
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition: TProof.cxx:7368
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:785
Long64_t GetEntries() const
Definition: TQueryResult.h:122
virtual Int_t AddProcessed(TSlave *, TProofProgressStatus *, Double_t, TList **)
void AddFeedback(const char *name)
Add object to feedback list.
Definition: TProof.cxx:9961
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command &#39;cmd&#39;. If fdout > -1, append the output to fdout.
Definition: TProof.cxx:7707
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:1276
TList * GetListOfLines() const
Definition: TMacro.h:51
void RecvLogFile(TSocket *s, Int_t size)
Receive the log file of the slave with socket s.
Definition: TProof.cxx:6259
void Interrupt(EUrgent type, ESlaves list=kActive)
Send interrupt to master or slave servers.
Definition: TProof.cxx:2254
void SetSessionTag(const char *st)
Definition: TSlave.h:161
virtual Int_t SendGroupPriority(const char *, Int_t)
Definition: TSlave.h:110
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition: TProof.cxx:9173
const Long64_t kPROOF_DynWrkPollInt_s
Definition: TProof.h:138
TList * GetListOfBadSlaves() const
Definition: TProof.h:657
TMD5 * ReadMD5(const char *pack)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition: TPackMgr.cxx:708
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:949
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition: TProof.cxx:10555
virtual TList * GetInputList() const =0
The PROOF package manager contains tools to manage packages.
Definition: TPackMgr.h:37
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual Bool_t IsValid() const
Definition: TSocket.h:151
virtual void AddOutput(TList *out)=0
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:715
An array of TObjects.
Definition: TObjArray.h:37
TString fPerfTree
Definition: TProof.h:557
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8119
float xmin
Definition: THbookFile.cxx:93
const char * GetName() const
Returns name of object.
Definition: TMap.h:116
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition: TProof.cxx:4382
const char * GetName() const
Returns name of object.
Definition: TProof.h:231
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition: TProof.cxx:1965
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2055
void SetPort(Int_t port)
Definition: TUrl.h:91
virtual TFileCollection * GetStagingStatusDataSet(const char *dataset)
Obtains a TFileCollection showing the staging status of the specified dataset.
Definition: TProof.cxx:11045
Long64_t GetBytesRead() const
Definition: TProof.h:929
static Bool_t GetFileInCmd(const char *cmd, TString &fn)
Static method to extract the filename (if any) form a CINT command.
Definition: TProof.cxx:6467
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:110
Bool_t fIsWaiting
Definition: TProof.h:508
Bool_t R_ISLNK(Int_t mode)
Definition: TSystem.h:120
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7812
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3798
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
TMonitor * fAllUniqueMonitor
Definition: TProof.h:486
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:4493
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
virtual void AddInput(TObject *inp)=0
const char * GetDefaultTreeName() const
Returns the tree set with SetDefaultTreeName if set Returns the name of the first tree in the meta da...
long long Long64_t
Definition: RtypesCore.h:69
Int_t fBusSpeed
Definition: TSystem.h:157
void Activate(TList *slaves=0)
Activate slave server list.
Definition: TProof.cxx:2367
static constexpr double pi
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition: TProof.cxx:10203
auto * m
Definition: textangle.C:8
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if &#39;dataset&#39; exists, kFALSE otherwise.
Definition: TProof.cxx:10840
Int_t fPhysRam
Definition: TSystem.h:159
static double p3(double t, double a, double b, double c, double d)
virtual ~TProof()
Clean up PROOF environment.
Definition: TProof.cxx:649
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:9611
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:53
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition: TProof.cxx:8147
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:7384
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition: TProof.cxx:12597
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:869
virtual Bool_t RegisterDataSet(const char *name, TFileCollection *dataset, const char *optStr="")
Register the &#39;dataSet&#39; on the cluster under the current user, group and the given &#39;dataSetName&#39;...
Definition: TProof.cxx:10679
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:6118
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:474
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition: TUrl.cxx:520
void SetRealTimeLog(Bool_t on=kTRUE)
Switch ON/OFF the real-time logging facility.
Definition: TProof.cxx:7068
TString fConfDir
Definition: TProof.h:569
EUrgent
Definition: TProof.h:393
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:370
Int_t GetPort() const
Definition: TProof.h:912
TLine * line
Int_t fOtherQueries
Definition: TProof.h:523
virtual void FlushSocket()
Definition: TSlave.h:105
Collectable string class.
Definition: TObjString.h:28
float Float_t
Definition: RtypesCore.h:53
Int_t fWorkersToMerge
Definition: TProof.h:551
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10183
Float_t fCpuTime
Definition: TProof.h:490
const char Option_t
Definition: RtypesCore.h:62
const char * GetHostName() const
Definition: TInetAddress.h:71
Bool_t fSync
Definition: TProof.h:506
void SetPrepTime(Float_t preptime)
Definition: TQueryResult.h:97
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:4138
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 &#39;mon&#39;. ...
Definition: TProof.cxx:2386
Int_t GetParallel() const
Definition: TSlave.h:141
virtual Int_t Reconnect()
Definition: TSocket.h:157
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition: TProof.cxx:11307
void SetPasswd(const char *pw)
Definition: TUrl.h:86
TList * fWrksOutputReady
Definition: TProof.h:559
virtual void SetMaxDrawQueries(Int_t max)=0
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition: TProof.cxx:1638
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:527
TString fOS
Definition: TSystem.h:152
virtual void ShowDataSetCache(const char *dataset=0)
Display the content of the dataset cache, if any (matching &#39;dataset&#39;, if defined).
Definition: TProof.cxx:10886
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
This class represents a WWW compatible URL.
Definition: TUrl.h:35
Long64_t fBytesRead
Definition: TSlave.h:92
Bool_t fMergersSet
Definition: TProof.h:548
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition: TProof.cxx:1512
TList * GetWorkers()
Definition: TProof.h:272
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:1374
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:248
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:10171
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:9890
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition: TProof.cxx:1869
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:822
const char * GetProtocol() const
Definition: TUrl.h:67
This class implements a data set to be used for PROOF processing.
Definition: TDSet.h:153
const char * GetGroup() const
Definition: TProofServ.h:242
TList * GetOutputNames()
FIXME: to be written.
Definition: TProof.cxx:10090
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:1037
void ShowParameters(const char *wildcard="PROOF_*") const
Show the input list parameters specified by the wildcard.
Definition: TProof.cxx:9930
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
void TerminateWorker(TSlave *wrk)
Ask an active worker &#39;wrk&#39; to terminate, i.e. to shutdown.
Definition: TProof.cxx:4668
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TSlave * GetMerger()
Definition: TProof.h:274
Int_t Unload(const char *pack)
Method to unload a package.
Definition: TPackMgr.cxx:411
virtual TList * GetLists() const
Definition: TEntryList.h:73
TProof * GetProof() const
Definition: TProofMgr.h:164
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:688
virtual void FindUniqueSlaves()
Add to the fUniqueSlave list the active slaves that have a unique (user) file system image...
Definition: TProof.cxx:1890
void Interrupt()
Definition: TMonitor.h:71
Int_t FindNextFreeMerger()
Return a merger, which is both active and still accepts some workers to be assigned to it...
Definition: TProof.cxx:4276
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:9794
virtual void StoreFeedback(TObject *slave, TList *out)=0
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
Definition: TFileInfo.cxx:260
The PROOF manager interacts with the PROOF server coordinator to create or destroy a PROOF session...
Definition: TProofMgr.h:43
void SetROOTVersion(const char *rv)
Definition: TSlave.h:159
TSocket * GetSocket() const
Definition: TProofServ.h:257
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1766
const char *const kPROOF_WorkDir
Definition: TProof.h:124
static const TList * GetEnvVars()
Get environemnt variables.
Definition: TProof.cxx:11723
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:47
virtual EExitStatus GetExitStatus() const =0
virtual void Add()
Add signal handler to system signal handler list.
virtual Int_t GetEntries() const
Definition: TCollection.h:177
const char * GetMsd() const
Definition: TSlave.h:142
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition: TFile.cxx:1670
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:10909
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:689
TList * fAllUniqueSlaves
Definition: TProof.h:482
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:9780
void SetArchCompiler(const char *ac)
Definition: TSlave.h:158
TObject * GetInputObject(const char *classname) const
Return first instance of class &#39;classname&#39; in the input list.
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:540
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7857
TString fImage
Definition: TProof.h:570
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1113
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:31
const char * GetName() const
Returns name of object.
Definition: TParameter.h:68
TFileCollection * GetMissingFiles(TQueryResult *qr=0)
Get a TFileCollection with the files missing in the query described by &#39;qr&#39; or the last query if qr i...
Definition: TProof.cxx:12554
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
Int_t GetPerfIndex() const
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
#define R__ASSERT(e)
Definition: TError.h:96
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:207
const char * GetOrdinal() const
Definition: TProof.h:232
#define gROOT
Definition: TROOT.h:410
TString fLogFileName
Definition: TProof.h:511
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor&#39;s active list.
Definition: TMonitor.cxx:168
Long64_t GetFirst() const
Definition: TDSet.h:112
virtual void StopProcess(Bool_t abort, Int_t timeout)
Sent stop/abort request to PROOF server.
Definition: TSlave.cxx:630
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:31
Int_t LoadPlugin()
Load the plugin library for this handler.
TList * GetListOfSlaves() const
Definition: TProof.h:654
#define O_BINARY
Definition: civetweb.c:652
virtual void SetCurrentQuery(TQueryResult *q)=0
const char * GetOrdinal() const
Definition: TSlave.h:131
TList * fQueries
Definition: TProof.h:522
Basic string class.
Definition: TString.h:131
virtual void Touch()
Definition: TSlave.h:165
virtual void Add()
Add file event handler to system file handler list.
virtual void Progress(Long64_t total, Long64_t processed)=0
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition: TProof.cxx:1956
void SetDSet(TDSet *dset)
Definition: TProof.h:737
virtual void SetInterruptHandler(Bool_t)
Definition: TSlave.h:156
Int_t GetClientProtocol() const
Definition: TProof.h:914
TString fGroup
Definition: TProof.h:468
TString fDataDir
Definition: TProof.h:219
#define f(i)
Definition: RSha256.hxx:104
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition: TProof.cxx:11780
int Int_t
Definition: RtypesCore.h:41
Int_t Load(const char *pack, TList *optls=0)
Method to load a package taking an option list Return -1 on error, 0 otherwise.
Definition: TPackMgr.cxx:220
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1004
bool Bool_t
Definition: RtypesCore.h:59
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition: TProof.cxx:9972
TList * fUniqueSlaves
Definition: TProof.h:481
virtual Bool_t JoinProcess(TList *workers)=0
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition: TProof.cxx:12482
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition: TProof.cxx:6386
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:605
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by &#39;mode&#39;.
Definition: TProof.cxx:6079
Bool_t IsMaster() const
Definition: TProof.h:936
void SetUser(const char *user)
Definition: TUrl.h:85
TList * fWaitingSlaves
Definition: TProof.h:521
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition: TProof.cxx:2453
#define gInterpreter
Definition: TInterpreter.h:527
const char * GetOptions() const
Definition: TUrl.h:74
const TString & GetImage() const
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1522
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:10343
This class represents a RFC 3986 compatible URI.
Definition: TUri.h:35
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition: TProof.cxx:2093
TFileHandler * GetInputHandler() const
Definition: TSlave.h:144
Definition: TFTP.h:34
const char * GetConfFile() const
Definition: TProof.h:905
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:670
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
Int_t GetSeqNum() const
Definition: TQueryResult.h:115
const char * GetName() const
Returns name of object.
Definition: TSlave.h:124
static TPluginHandler * fgLogViewer
Definition: TProof.h:561
TString & Prepend(const char *cs)
Definition: TString.h:656
R__EXTERN TApplication * gApplication
Definition: TApplication.h:165
Bool_t Contains(const char *name) const
Definition: TCollection.h:169
TString fHostName
Definition: TProof.h:217
Float_t fRealTime
Definition: TProof.h:489
void EmitVA(const char *signal_name, Int_t, const T &... params)
Emit a signal with a varying number of arguments.
Definition: TQObject.h:101
Bool_t Notify()
Handle input.
Definition: TProof.cxx:166
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 &#39;ord&#39; ac...
Definition: TProof.cxx:11361
void Show(const char *title=0)
Show available packages.
Definition: TPackMgr.cxx:548
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
Bool_t IsTopMaster() const
Definition: TProofServ.h:295
TMacro * GetLogFile() const
Definition: TQueryResult.h:126
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:262
TString fModel
Definition: TSystem.h:153
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition: TProof.cxx:10293
Long64_t GetEntries() const
void CloseProgressDialog()
Close progress dialog.
Definition: TProof.cxx:9255
Int_t GetNumberOfQueries()
Number of queries processed by this session.
Definition: TProof.cxx:2083
Int_t AddIncludePath(const char *incpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add &#39;incpath&#39; to the inc path search.
Definition: TProof.cxx:8860
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
const char * GetDataPoolUrl() const
Definition: TProof.h:1043
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)
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:644
TDSet * fDSet
Definition: TProof.h:503
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7686
void DisableGoAsyn()
Signal to disable related switches.
Definition: TProof.cxx:6231
TList * fInputData
Definition: TProof.h:535
Int_t SendObject(const TObject *obj, ESlaves list=kActive)
Send object to master or slave servers.
Definition: TProof.cxx:7026
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6730
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:2545
void Reset(Int_t n=-1)
Definition: TProof.h:312
TList * GetListOfElements() const
Definition: TDSet.h:231
TVirtualProofPlayer * fPlayer
Definition: TProof.h:494
void SetProof(TProof *p)
Definition: TProofMgr.h:179
void Reset()
Definition: TCollection.h:252
Iterator of linked list.
Definition: TList.h:197
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:469
Bool_t IsLite() const
Definition: TProof.h:933
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:904
const char * GetOutputFileName() const
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:387
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
EQueryMode
Definition: TProof.h:349
Long64_t GetEntries() const
Definition: TFileInfo.h:139
const char * GetImage() const
Definition: TSlave.h:125
virtual void DiscardSession(TProof *p)
Discard TProofDesc of session &#39;p&#39; from the internal list.
Definition: TProofMgr.cxx:366
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2743
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:268
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for &#39;url&#39; Return 0 on failure.
Definition: TProof.cxx:11696
EUploadPackageOpt
Definition: TProof.h:366
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:3976
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:736
Int_t Length() const
Definition: TBuffer.h:96
const char * GetFileName() const
Int_t fMode
Definition: TSystem.h:128
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:4874
Bool_t fMasterServ
Definition: TProof.h:566
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove &#39;incpath&#39; from the inc path search.
Definition: TProof.cxx:8939
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 &#39;pf&#39;.
Definition: TProof.cxx:12619
Bool_t fFinalizationRunning
Definition: TProof.h:554
const char * GetFile() const
Definition: TUrl.h:72
const char * GetConfDir() const
Definition: TProof.h:904
Int_t Install(const char *par, Bool_t rmold=kFALSE)
Install package from par (unpack the file in the directory); par can be an URL for remote retrieval...
Definition: TPackMgr.cxx:766
TSignalHandler * fIntHandler
Definition: TProof.h:491
Manages an element of a TDSet.
Definition: TDSet.h:66
Int_t fDrawQueries
Definition: TProof.h:524
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
TString fDataPoolUrl
Definition: TProof.h:585
void AddMergedObjects(Int_t objects)
Definition: TProof.h:282
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:625
TList * GetListOfEnabled() const
Get list of enabled packages Returns a pointer to a TList object, transferring ownership to the calle...
Definition: TPackMgr.cxx:644
TList * fChains
Definition: TProof.h:496
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3352
Bool_t SendingLogToWindow() const
Definition: TProof.h:1016
const char * GetHost() const
Definition: TUrl.h:70
virtual TVirtualPacketizer * GetPacketizer() const
Int_t Update(Long64_t avgsize=-1)
Update accumulated information about the elements of the collection (e.g.
TPluginHandler * fProgressDialog
Definition: TProof.h:492
TList * fBadSlaves
Definition: TProof.h:574
virtual TList * GetOutputList() const =0
Int_t fLastAssignedMerger
Definition: TProof.h:552
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1357
Sequenceable collection abstract base class.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
Bool_t fSendGroupView
list returned by kPROOF_GETSLAVEINFO
Definition: TProof.h:474
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:77
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition: TProof.cxx:11018
virtual Bool_t IsValid() const
Definition: TSlave.h:150
const char * Export(Bool_t &changed)
Definition: TProof.h:304
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4775
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition: TProof.cxx:6196
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:301
Long64_t GetNum() const
Definition: TDSet.h:114
virtual Bool_t IsProofd() const
Definition: TProofMgr.h:76
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:2286
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:1473
void UpdateDialog()
Final update of the progress dialog.
Definition: TProof.cxx:4325
#define PDB(mask, level)
Definition: TProofDebug.h:56
Int_t GetPerfIdx() const
Definition: TSlave.h:132
virtual Bool_t IsLite() const
Definition: TProofMgr.h:75
void Class()
Definition: Class.C:29
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
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:1831
TSocket * GetSocket() const
Definition: TSlave.h:134
Int_t GetNUrls() const
Definition: TFileInfo.h:74
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
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:7051
virtual TDSetElement * GetNextPacket(TSlave *slave, TMessage *r)=0
Int_t DownloadPackage(const char *par, const char *dstdir=0)
Download a PROOF archive (PAR file) from the master package repository.
Definition: TProof.cxx:8306
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
Int_t GetLogLevel() const
Definition: TProof.h:916
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition: TProof.cxx:4395
virtual void ReleaseWorker(const char *)
Definition: TProofServ.h:305
virtual void ShowCache(Bool_t all=kFALSE)
List contents of file cache.
Definition: TProof.cxx:7663
Int_t fRedirectNext
Definition: TProof.h:555
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=0)
Resolve the file type as a function of the protocol field in &#39;name&#39;.
Definition: TFile.cxx:4691
virtual Int_t Rm(const char *, const char *=0, const char *=0)
Run &#39;rm&#39; on &#39;what&#39;. Locally it is just a call to TSystem::Unlink .
Definition: TProofMgr.cxx:1065
Bool_t IsEndMaster() const
Definition: TProof.h:664
void ShowEnabled(const char *title=0)
Show enabled packages.
Definition: TPackMgr.cxx:662
const char *const kPROOF_WorkerIdleTO
Definition: TProof.h:135
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1768
Int_t fParallel
Definition: TSlave.h:97
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriory.
Definition: TMessage.cxx:220
void SetInputDataFile(const char *datafile)
Set the file to be used to optimally distribute the input data objects.
Definition: TProof.cxx:9557
const char * GetGroup() const
Definition: TProof.h:907
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition: TProof.cxx:10949
static double p2(double t, double a, double b, double c)
Bool_t IsSync() const
Definition: TProof.h:669
static TList * GetDataSetSrvMaps()
Static getter for server mapping list.
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1638
virtual UInt_t Integer(UInt_t imax)
Returns a random integer on [ 0, imax-1 ].
Definition: TRandom.cxx:341
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:2647
static void LogViewer(const char *url=0, Int_t sessionidx=0)
Start the log viewer window usign the plugin manager.
Definition: TProof.cxx:12443
const char * GetDirectory() const
Return directory where to look for object.
Definition: TDSet.cxx:253
void Deactivate()
Definition: TProof.h:287
void ResetMergePrg()
Reset the merge progress notificator.
Definition: TProof.cxx:2443
A sorted doubly linked list.
Definition: TSortedList.h:28
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition: TProof.cxx:10781
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition: TProof.cxx:7142
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:745
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition: TProof.cxx:10818
TString fConfFile
Definition: TProof.h:568
virtual void AddEventsProcessed(Long64_t ev)=0
TString & Append(const char *cs)
Definition: TString.h:559
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2152
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition: TProof.cxx:2942
ESlaveStatus fStatus
Definition: TProof.h:222
const char * GetSessionTag() const
Definition: TProof.h:909
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1574
TString fOrdinal
Definition: TSlave.h:86
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:1853
void Validate()
Validate the TDSet by opening files.
Definition: TDSet.cxx:1590
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition: TProof.cxx:7642
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to &#39;id&#39;.
Definition: TProofMgr.cxx:324
const char * GetProofWorkDir() const
Definition: TSlave.h:126
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by &#39;ref&#39;...
Definition: TProof.cxx:2126
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:11555
Int_t GetPort() const
Definition: TInetAddress.h:73
const char * GetDir(Bool_t raw=kFALSE) const
TList * fSlaves
Definition: TProof.h:572
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:487
Int_t fNotIdle
Definition: TProof.h:505
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:10607
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1458
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition: TSlave.cxx:511
XFontStruct * id
Definition: TGX11.cxx:108
TList * GetEnabledPackages() const
Definition: TProof.h:735
void SetDirectory(const char *dir)
Set/change directory.
Definition: TDSet.cxx:1041
const Bool_t kSortDescending
Definition: TList.h:38
friend class TProofInputHandler
Definition: TProof.h:324
const char * GetDataDir() const
Definition: TProof.h:229
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2320
TList * fInactiveSlaves
Definition: TProof.h:480
void SetSrvMaps(TList *srvmaps=0)
Set (or unset) the list for mapping servers coordinate for files.
Definition: TDSet.cxx:1172
Bool_t IsRetrieve() const
A container class for query results.
Definition: TQueryResult.h:36
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition: TProof.cxx:2117
Int_t ActivateWorker(const char *ord, Bool_t save=kTRUE)
Make sure that the worker identified by the ordinal number &#39;ord&#39; is in the active list...
Definition: TProof.cxx:11325
PrintProgress_t fPrintProgress
Definition: TProof.h:540
Int_t fCollectTimeout
Definition: TProof.h:583
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo&#39;s. In case of error return 0.
Definition: TProof.cxx:2299
Long_t fModtime
Definition: TProof.h:499
virtual void Close(Option_t *opt="")
Close slave socket.
Definition: TSlave.cxx:277
TObject * Value() const
Definition: TMap.h:121
void Error(const char *location, const char *msgfmt,...)
TProofMergePrg fMergePrg
Definition: TProof.h:519
static TList * fgProofEnvList
Definition: TProof.h:545
void HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
Handle lib, inc search paths modification request.
Definition: TProof.cxx:8970
Float_t GetRealTime() const
Definition: TProof.h:930
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2066
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
void SetManager(TProofMgr *mgr)
Set manager and schedule its destruction after this for clean operations.
Definition: TProof.cxx:1285
static Int_t PoDCheckUrl(TString *_cluster)
This a private API function.
Definition: TProof.cxx:344
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual Int_t GetFile(const char *, const char *, const char *=0)
Definition: TProofMgr.h:122
std::recursive_mutex fCloseMutex
Definition: TProof.h:542
void SetTermTime(Float_t termtime)
Definition: TQueryResult.h:100
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:113
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning...
Definition: TProof.cxx:1031
Int_t Compare(const TObject *obj) const
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:180
Bool_t fIsPollingWorkers
Definition: TProof.h:475
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition: TProof.cxx:510
virtual void ClearInput()=0
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition: TProof.cxx:1974
void AddInput(TObject *obj)
Add obj to the input list.
A doubly linked list.
Definition: TList.h:44
const char * GetObjName() const
Definition: TDSet.h:120
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:533
const char * GetUser() const
Definition: TUrl.h:68
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition: TProof.cxx:6064
Bool_t fRedirLog
Definition: TProof.h:510
const char * pwd()
Definition: TSystem.h:405
void AddChain(TChain *chain)
Add chain to data set.
Definition: TProof.cxx:10195
TMonitor * fUniqueMonitor
Definition: TProof.h:485
void SetMergedWorker()
Increase number of already merged workers by 1.
Definition: TProof.cxx:295
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
Definition: TFileInfo.cxx:424
const char *const kPROOF_ConfFile
Definition: TProof.h:122
Int_t GetPort() const
Definition: TSlave.h:130
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition: TProof.cxx:11529
const char * GetName() const
Returns name of object.
Definition: TObjString.h:39
Int_t fL2Cache
Definition: TSystem.h:158
FileMap_t fFileMap
Definition: TProof.h:502
void cd(Int_t id=-1)
Set session with &#39;id&#39; the default one.
Definition: TProof.cxx:10468
Bool_t ElementsValid()
Check if all elements are valid.
Definition: TDSet.cxx:1556
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition: TProof.cxx:5985
Long64_t GetZipBytes() const
Definition: TFileInfo.h:144
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8413
TMonitor * fAllMonitor
Definition: TProof.h:575
virtual void AddQueryResult(TQueryResult *q)=0
void SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
Int_t Archive(Int_t query, const char *url)
Send archive request for the qry-th query in fQueries.
Definition: TProof.cxx:6029
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
void InitMembers()
Default initializations.
Definition: TProof.cxx:524
Named parameter, streamable and storable.
Definition: TParameter.h:37
const TString & GetString() const
Definition: TObjString.h:47
friend class TProofInterruptHandler
Definition: TProof.h:325
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition: TProof.cxx:11708
EFileType
File type.
Definition: TFile.h:186
Int_t Build(const char *pack, Int_t opt=TPackMgr::kCheckROOT)
Method to build a package.
Definition: TPackMgr.cxx:87
TString fUser
Definition: TSystem.h:142
float ymax
Definition: THbookFile.cxx:93
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3782
Int_t fLogLevel
Definition: TProof.h:469
TProofMgr * fManager
Definition: TProof.h:587
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition: TProof.cxx:10082
virtual void Find(const char *="~/", const char *=0, const char *=0)
Definition: TProofMgr.h:113
const char *const kPROOF_TerminateWorker
Definition: TProof.h:134
TList * fActiveSlaves
Definition: TProof.h:477
void QueryResultReady(const char *ref)
Notify availability of a query result.
Definition: TProof.cxx:9341
const TString GetUri() const
Returns the whole URI - an implementation of chapter 5.3 component recomposition. ...
Definition: TUri.cxx:140
Bool_t fSaveLogToMacro
Definition: TProof.h:516
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:9308
Bool_t fValid
Definition: TProof.h:464
Bool_t fDataReady
Definition: TProof.h:576
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:321
void DecreaseNWrks()
Definition: TProof.h:309
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1622
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:155
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
const TString & GetNodeName() const
ROOT::R::TRInterface & r
Definition: Object.C:4
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4754
Int_t DisablePackages()
Remove all packages.
Definition: TProof.cxx:7914
Bool_t fIsLink
Definition: TSystem.h:133
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition: TProof.cxx:10992
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
TString fWorkDir
Definition: TProof.h:467
write collection with single key
Definition: TObject.h:87
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition: TSlave.cxx:494
void Print(Option_t *option="") const
Print slave info.
Definition: TProof.cxx:222
ERunStatus fRunStatus
Definition: TProof.h:507
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition: TProof.cxx:5829
auto * a
Definition: textangle.C:12
const char * GetSessionDir() const
Definition: TProofServ.h:247
TString fWorkDir
Definition: TSlave.h:82
TObject * Key() const
Definition: TMap.h:120
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:11281
TMonitor * fCurrentMonitor
Definition: TProof.h:487
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:2521
Int_t Add(TFileInfo *info)
Add TFileInfo to the collection.
Int_t GetNWrks() const
Long_t ExecPlugin(int nargs, const T &... params)
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
virtual void SetInitTime()=0
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7742
const char *const kPROOF_ConfDir
Definition: TProof.h:123
void SaveActiveList()
Save current list of active workers.
Definition: TProof.cxx:11514
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
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.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
Int_t fSeqNum
Definition: TProof.h:526
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1779
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:378
Collection abstract base class.
Definition: TCollection.h:63
void SetActive(Bool_t=kTRUE)
Definition: TProof.h:988
Int_t BuildPackage(const char *package, EBuildPackageOpt opt=kBuildAll, Int_t chkveropt=TPackMgr::kCheckROOT, TList *workers=0)
Build specified package.
Definition: TProof.cxx:7962
virtual void ClearDataSetCache(const char *dataset=0)
Clear the content of the dataset cache, if any (matching &#39;dataset&#39;, if defined).
Definition: TProof.cxx:10868
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition: TProof.cxx:2106
virtual Int_t VerifyDataSet(const char *dataset, const char *optStr="")
Verify if all files in the specified dataset are available.
Definition: TProof.cxx:11102
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2264
TList * fSlaveInfo
Definition: TProof.h:473
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition: TMonitor.cxx:498
unsigned int UInt_t
Definition: RtypesCore.h:42
TList * GetInputList()
Definition: TQueryResult.h:120
TMacro fMacroLog
Definition: TProof.h:517
Int_t GetPort()
Definition: TProof.h:275
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:405
TObject * GetOutput(const char *name)
Get specified object that has been produced during the processing (see Process()).
Definition: TProof.cxx:9734
Class to steer the merging of files produced on the workers.
Bool_t IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
See if the data is ready to be analyzed.
Definition: TProof.cxx:2218
void IncreaseIdx()
Definition: TProof.h:311
This class implements a plugin library manager.
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1081
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:7000
virtual Int_t Stat(const char *, FileStat_t &, const char *=0)
Definition: TProofMgr.h:120
#define s1(x)
Definition: RSha256.hxx:91
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:11732
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:11768
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:6771
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:498
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:327
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:5275
Bool_t fProgressDialogStarted
Definition: TProof.h:493
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:661
const Int_t kPROOF_Protocol
Definition: TProof.h:120
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition: TProof.cxx:6432
float xmax
Definition: THbookFile.cxx:93
TStopwatch fQuerySTW
Definition: TProof.h:593
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
Bool_t fMergersByHost
Definition: TProof.h:549
TString fInputDataFile
Definition: TProof.h:536
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:6505
TPackMgr * GetPackMgr() const
Definition: TProofServ.h:249
void SetStatus(ESlaveStatus stat)
Definition: TProof.h:234
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1575
FILE * fLogFileR
Definition: TProof.h:513
void SetName(const char *name)
Definition: TCollection.h:204
Int_t fProtocol
Definition: TProof.h:571
const char * GetUrl()
Definition: TProof.h:911
Bool_t IsEqual(const TObject *obj) const
Used to compare slaveinfos by ordinal.
Definition: TProof.cxx:208
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:6866
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
TList * GetEnabledPackages() const
Definition: TProofServ.h:267
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition: TProof.cxx:4230
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:9112
Bool_t fLogToWindowOnly
Definition: TProof.h:514
TString & String()
Definition: TObjString.h:49
void ReleaseMonitor(TMonitor *mon)
Release the used monitor to be used, making sure to delete newly created monitors.
Definition: TProof.cxx:2632
static constexpr double nm
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1630
TList * fFeedback
Definition: TProof.h:495
Bool_t IsIdle() const
Definition: TProof.h:940
virtual void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE)
Write object to I/O buffer.
Definition: TBufferIO.cxx:530
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition: TProof.cxx:9296
void AddInput(TObject *obj)
Add objects that might be needed during the processing of the selector (see Process()).
Definition: TProof.cxx:9706
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:679
TString fMsd
Definition: TProof.h:218
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9352
Float_t fPrepTime
Definition: TProof.h:594
virtual TObjLink * FirstLink() const
Definition: TList.h:108
#define h(i)
Definition: RSha256.hxx:106
#define Printf
Definition: TGeoToOCC.h:18
const TString & GetMsd() const
TList * fRunningDSets
Definition: TProof.h:581
const TString & GetOrdinal() const
const Bool_t kFALSE
Definition: RtypesCore.h:88
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition: TProof.cxx:10229
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition: TProof.cxx:11153
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove &#39;libpath&#39; from the lib path search.
Definition: TProof.cxx:8905
Bool_t fDynamicStartup
Definition: TProof.h:589
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:442
void GoAsynchronous()
Send GOASYNC message to the master.
Definition: TProof.cxx:6239
virtual void RemoveQueryResult(const char *ref)=0
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition: TSlave.cxx:656
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:9510
UInt_t What() const
Definition: TMessage.h:74
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6603
static unsigned int total
Int_t AssertPath(const char *path, Bool_t writable)
Make sure that &#39;path&#39; exists; if &#39;writable&#39; is kTRUE, make also sure that the path is writable...
Definition: TProof.cxx:1253
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:1688
#define SafeDelete(p)
Definition: RConfig.h:529
Int_t LoadPackage(const char *package, Bool_t notOnClient=kFALSE, TList *loadopts=0, TList *workers=0)
Load specified package.
Definition: TProof.cxx:8041
void SetHost(const char *host)
Definition: TUrl.h:87
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
long Long_t
Definition: RtypesCore.h:50
int Ssiz_t
Definition: RtypesCore.h:63
The packetizer is a load balancing object created for each query.
TList * GetInputList()
Get input list.
Definition: TProof.cxx:9725
TString fName
Definition: TSlave.h:79
void NotifyLogMsg(const char *msg, const char *sfx="\)
Notify locally &#39;msg&#39; to the appropriate units (file, stdout, window) If defined, &#39;sfx&#39; is added after...
Definition: TProof.cxx:6330
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:1482
#define d(i)
Definition: RSha256.hxx:102
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition: TProof.cxx:4909
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition: TProof.cxx:328
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:550
Bool_t fEndMaster
Definition: TProof.h:530
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2172
void Close(Option_t *option="")
Close all open slave servers.
Definition: TProof.cxx:1776
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3872
void SetFeedback(TString &opt, TString &optfb, Int_t action)
Extract from opt in optfb information about wanted feedback settings.
Definition: TProof.cxx:5204
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1418
TProof * gProof
Definition: TProof.cxx:105
void SetDefaultTreeName(const char *treeName)
#define ClassImp(name)
Definition: Rtypes.h:359
const char *const kPROOF_InputDataFile
Definition: TProof.h:136
void ShowFeedback() const
Show items in feedback list.
Definition: TProof.cxx:9992
TDrawFeedback * CreateDrawFeedback()
Draw feedback creation proxy.
Definition: TProof.cxx:10066
virtual Long64_t GetEventsProcessed() const =0
Bool_t IsProofd() const
Definition: TProof.h:934
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:265
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:716
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:9905
Int_t SetParallelSilent(Int_t nodes, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7084
Long64_t fBytesRead
Definition: TProof.h:488
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:7245
Int_t fMergersCount
Definition: TProof.h:550
TSignalHandler * GetSignalHandler() const
Definition: TApplication.h:106
void SetObjName(const char *objname)
Set/change object name.
Definition: TDSet.cxx:1026
double Double_t
Definition: RtypesCore.h:55
virtual const char * HostName()
Return the system&#39;s host name.
Definition: TSystem.cxx:311
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:876
ESlaves
Definition: TProof.h:564
virtual void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)=0
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:12386
void ClearInput()
Clear input object list.
Definition: TProof.cxx:9714
Bool_t IsFinalized() const
Definition: TQueryResult.h:145
const char * GetMaster() const
Definition: TProof.h:903
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition: TDSet.cxx:1894
TList * fEnabledPackages
Definition: TProof.h:580
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and &#39;mode&#39;.
Definition: TProof.cxx:6091
virtual void Remove()
Remove signal handler from system signal handler list.
void Feedback(TList *objs)
Get list of feedback objects.
Definition: TProof.cxx:9240
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2282
TList * fNonUniqueMasters
Definition: TProof.h:483
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TFile.cxx:1298
TList * fRecvMessages
Definition: TProof.h:472
TString fCpuType
Definition: TSystem.h:154
TNamed()
Definition: TNamed.h:36
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition: TProof.cxx:1992
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:9584
TList * fEnabledPackagesOnCluster
Definition: TProof.h:533
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition: TProof.h:316
virtual Bool_t IsValid() const
Definition: TProofMgr.h:77
static RooMathCoreReg dummy
void Detach(Option_t *opt="")
Detach this instance to its proofserv.
Definition: TProof.cxx:10490
int nentries
Definition: THbookFile.cxx:89
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
void SetNWrks(Int_t n)
Definition: TProof.h:313
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
static constexpr double s
EBuildPackageOpt
Definition: TProof.h:453
#define R__LOCKGUARD(mutex)
virtual TQueryResult * GetCurrentQuery() const =0
void SetRunStatus(ERunStatus rst)
Definition: TProof.h:672
const char * GetFileName() const
Definition: TDSet.h:111
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition: TPackMgr.cxx:871
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition: TProof.cxx:10014
Int_t BufferSize() const
Definition: TBuffer.h:94
const char * GetWorkDir() const
Definition: TSlave.h:127
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:406
void ShowMissingFiles(TQueryResult *qr=0)
Show information about missing files during query described by &#39;qr&#39; or the last query if qr is null (...
Definition: TProof.cxx:12495
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:399
Int_t GetSandbox(TString &sb, Bool_t assert=kFALSE, const char *rc=0)
Set the sandbox path from &#39; Proof.Sandbox&#39; or the alternative var &#39;rc&#39;.
Definition: TProof.cxx:1004
void ShowQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2143
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1304
Float_t fRealTime
Definition: TSlave.h:93
const char * GetType() const
Definition: TDSet.h:228
void SetArchived(const char *archfile)
Set (or update) query in archived state.
void ResetUrl()
Definition: TFileInfo.h:68
virtual void Remove()
Remove file event handler from system file handler list.
Int_t GetPort() const
Definition: TUrl.h:81
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job...
Definition: TProof.cxx:320
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition: TProof.cxx:5855
EQueryMode fQueryMode
Definition: TProof.h:588
Bool_t IsNull() const
Definition: TString.h:402
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex &#39;this&#39; was created with.
Definition: TPRegexp.cxx:708
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:247
Bool_t IsTty() const
Definition: TProof.h:938
TString fImage
Definition: TSlave.h:80
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable &#39;env&#39; on node &#39;ord&#39;.
Definition: TProof.cxx:6616
Int_t UnloadPackage(const char *package)
Unload specified package.
Definition: TProof.cxx:8086
FILE * fLogFileW
Definition: TProof.h:512
Mother of all ROOT objects.
Definition: TObject.h:37
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:144
Long64_t GetTotBytes() const
Definition: TFileInfo.h:143
Int_t fStatus
Definition: TSlave.h:96
Bool_t IsWorker() const
char Char_t
Definition: RtypesCore.h:29
TPackMgr * fPackMgr
Definition: TProof.h:532
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
TSelector * fSelector
Definition: TProof.h:591
void CleanGDirectory(TList *ol)
Remove links to objects in list &#39;ol&#39; from gDirectory.
Definition: TProof.cxx:3018
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition: TProof.cxx:9096
TString fActiveSlavesSaved
Definition: TProof.h:478
const char * GetImage() const
Definition: TProofServ.h:244
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:1052
Float_t GetCpuTime() const
Definition: TProof.h:931
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7790
Int_t GetRC(const char *RCenv, Int_t &env, const char *ord="0")
Get into &#39;env&#39; the value of integer RC env variable &#39;rcenv&#39; on node &#39;ord&#39;.
Definition: TProof.cxx:6637
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:116
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition: TROOT.cxx:2769
R__EXTERN TProofServ * gProofServ
Definition: TProofServ.h:347
const TString & GetWorkDir() const
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:10656
virtual void Add(TObject *obj)
Definition: TList.h:87
auto * l
Definition: textangle.C:4
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
Definition: TProofMgr.cxx:228
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:97
Class that contains a list of TFileInfo&#39;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:760
TMap * GetDataSetQuota(const char *optStr="")
returns a map of the quotas of all groups
Definition: TProof.cxx:11248
Definition: file.py:1
Utility class to draw objects in the feedback list during queries.
Definition: TDrawFeedback.h:35
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition: TProof.cxx:4408
TProofOutputList fOutputList
Definition: TProof.h:538
const char * GetWorkDir() const
Definition: TProofServ.h:243
SysInfo_t GetSysInfo() const
Definition: TProof.h:233
virtual TList * GetListOfKeys() const
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition: TProof.cxx:4716
const char * GetMsd() const
Definition: TDSet.h:117
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:54
static char fgCr[4]
Definition: TProof.h:300
Int_t fSessionID
Definition: TProof.h:528
A chain is a collection of files containing TTree objects.
Definition: TChain.h:33
void SetOptions(const char *opt)
Definition: TUrl.h:90
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2000
const char * GetImage() const
Definition: TProof.h:910
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
Int_t fCpuSpeed
Definition: TSystem.h:156
Int_t GetRemoteProtocol() const
Definition: TProof.h:913
static Int_t SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
Save input data file from &#39;cachedir&#39; into the sandbox or create a the file with input data objects...
Definition: TProof.cxx:12284
#define snprintf
Definition: civetweb.c:1351
const char * GetUser() const
Definition: TSlave.h:128
static TList * ParseDataSetSrvMaps(const TString &srvmaps)
Create a server mapping list from the content of &#39;srvmaps&#39; Return the list (owned by the caller) or 0...
Int_t fStatus
Definition: TProof.h:470
void ClearFeedback()
Clear feedback list.
Definition: TProof.cxx:9984
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7112
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1321
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition: TProof.cxx:306
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
#define c(i)
Definition: RSha256.hxx:101
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
Int_t Remove(const char *pack=0, Bool_t dolock=kTRUE)
Remove package &#39;pack&#39; If &#39;pack&#39; is null or empty all packages are cleared.
Definition: TPackMgr.cxx:593
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1896
Float_t fCpuTime
Definition: TSlave.h:94
Int_t AddDynamicPath(const char *libpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add &#39;libpath&#39; to the lib path search.
Definition: TProof.cxx:8815
void Reset()
Definition: TStopwatch.h:52
static constexpr double pc
TInetAddress GetInetAddress() const
Definition: TSocket.h:132
Bool_t IsParallel() const
Definition: TProof.h:939
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition: TProof.cxx:9080
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:4039
const char * GetUser() const
Definition: TProof.h:906
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:1962
virtual Int_t AddOutputObject(TObject *obj)=0
Bool_t IsActive()
Definition: TProof.h:288
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1738
TList * fAvailablePackages
Definition: TProof.h:579
A TTree object has a header with a name and a title.
Definition: TTree.h:70
Int_t fCheckFileStatus
Definition: TProof.h:471
const AParamType & GetVal() const
Definition: TParameter.h:69
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition: TProof.cxx:10074
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:284
#define gDirectory
Definition: TDirectory.h:213
Long64_t fTotalBytes
Definition: TProof.h:578
Bool_t IsWaiting() const
Definition: TProof.h:941
Class describing a generic file including meta information.
Definition: TFileInfo.h:38
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:165
Int_t SendInitialState()
Transfer the initial (i.e.
Definition: TProof.cxx:6746
const char * GetName() const
Returns name of object.
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition: TProof.cxx:5920
void ResetBit(UInt_t f)
Definition: TObject.h:171
TProofMgr::EServType fServType
Definition: TProof.h:586
Bool_t IsValid() const
Definition: TProof.h:937
void AttachList(TList *alist)
Attach to list &#39;alist&#39;.
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1254
virtual void ActivateAll()
Activate all de-activated sockets.
Definition: TMonitor.cxx:268
Abstract interface for the PROOF player.
TList * fTerminatedSlaveInfos
Definition: TProof.h:573
Definition: first.py:1
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:2429
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition: TProof.cxx:2013
TProof * fProof
Definition: TProof.h:201
TList * FindDataSets(const char *searchString, const char *optStr="")
Find datasets, returns in a TList all found datasets.
Definition: TProof.cxx:10982
Bool_t Prompt(const char *p)
Prompt the question &#39;p&#39; requiring an answer y,Y,n,N Return kTRUE is the answer was y or Y...
Definition: TProof.cxx:7621
Double_t Sqrt(Double_t x)
Definition: TMath.h:690
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition: TProof.cxx:11088
TList * fLoadedMacros
Definition: TProof.h:544
virtual Int_t RemoveDataSet(const char *dataset, const char *optStr="")
Remove the specified dataset from the PROOF cluster.
Definition: TProof.cxx:10963
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition: TProof.cxx:4306
const Bool_t kIterBackward
Definition: TCollection.h:41
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
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
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:8600
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Class describing a PROOF worker server.
Definition: TSlave.h:46
const char * GetUser() const
Definition: TProofServ.h:241
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:10738
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:33
const char * GetObjName() const
Definition: TDSet.h:229
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:902
Long64_t fBytesReady
Definition: TProof.h:577
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition: TProof.cxx:10212
void ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst, Long64_t ent)
Reset progress dialog.
Definition: TProof.cxx:9271
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7829
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual ~TMergerInfo()
Destructor.
Definition: TProof.cxx:284
Int_t SendPrint(Option_t *option="")
Send print command to master server.
Definition: TProof.cxx:7040
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
TString fMaster
Definition: TProof.h:466
Bool_t fTty
Definition: TProof.h:465
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition: TProof.cxx:9284
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:25
Int_t DeactivateWorker(const char *ord, Bool_t save=kTRUE)
Remove the worker identified by the ordinal number &#39;ord&#39; from the the active list.
Definition: TProof.cxx:11342
TList * fMergers
Definition: TProof.h:553
TList * GetListOfActiveSlaves() const
Definition: TProof.h:723
TUrl fUrl
Definition: TProof.h:567
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:712
ESlaveType fSlaveType
Definition: TSlave.h:95
const char * GetOrdinal() const
Definition: TProofServ.h:253
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:11754
TMonitor * fActiveMonitor
Definition: TProof.h:484
TString fProofWorkDir
Definition: TSlave.h:81
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
Bool_t Notify()
TProof interrupt handler.
Definition: TProof.cxx:119
TSocket * fSocket
Definition: TProof.h:200
TList * GetFeedbackList() const
Return feedback list.
Definition: TProof.cxx:10005
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition: TProof.cxx:1983
void Browse(TBrowser *b)
Build the PROOF&#39;s structure in the browser.
Definition: TProof.cxx:10151
char name[80]
Definition: TGX11.cxx:109
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition: TMacro.cxx:139
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 * cnt
Definition: TXMLSetup.cxx:74
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual const char * GetName() const
Return name of this collection.
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition: TProof.cxx:3032
virtual TDrawFeedback * CreateDrawFeedback(TProof *p)=0
Long64_t fLastPollWorkers_s
Definition: TProof.h:476
void ResetInterrupt()
Definition: TMonitor.h:72
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:4074
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:2588
Int_t fMaxDrawQueries
Definition: TProof.h:525
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
const char * GetPrefix() const
Definition: TProofServ.h:276
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition: TProof.cxx:12353
const char * GetDirectory() const
Definition: TDSet.h:230
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition: TProof.cxx:3986
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:917
void IncreaseNWrks()
Definition: TProof.h:310
const char * Data() const
Definition: TString.h:364
void SetOrdinal(const char *ord)
Definition: TProof.h:236
const char *const kPROOF_PackDir
Definition: TProof.h:126
Int_t GetPort() const
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:11987
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition: TProof.cxx:4426