ROOT  6.06/09
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 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TProof //
15 // //
16 // This class controls a Parallel ROOT Facility, PROOF, cluster. //
17 // It fires the worker servers, it keeps track of how many workers are //
18 // running, it keeps track of the workers running status, it broadcasts //
19 // messages to all workers, it collects results, etc. //
20 // //
21 //////////////////////////////////////////////////////////////////////////
22 
23 #include <stdlib.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #ifdef WIN32
27 # include <io.h>
28 # include <sys/stat.h>
29 # include <sys/types.h>
30 # include "snprintf.h"
31 #else
32 # include <unistd.h>
33 #endif
34 #include <vector>
35 
36 #include "RConfigure.h"
37 #include "Riostream.h"
38 #include "Getline.h"
39 #include "TBrowser.h"
40 #include "TChain.h"
41 #include "TCondor.h"
42 #include "TDSet.h"
43 #include "TError.h"
44 #include "TEnv.h"
45 #include "TEntryList.h"
46 #include "TEventList.h"
47 #include "TFile.h"
48 #include "TFileInfo.h"
49 #include "TFunction.h"
50 #include "TFTP.h"
51 #include "THashList.h"
52 #include "TInterpreter.h"
53 #include "TKey.h"
54 #include "TMap.h"
55 #include "TMath.h"
56 #include "TMessage.h"
57 #include "TMethodArg.h"
58 #include "TMethodCall.h"
59 #include "TMonitor.h"
60 #include "TMutex.h"
61 #include "TObjArray.h"
62 #include "TObjString.h"
63 #include "TParameter.h"
64 #include "TProof.h"
65 #include "TProofNodeInfo.h"
66 #include "TProofOutputFile.h"
67 #include "TVirtualProofPlayer.h"
68 #include "TVirtualPacketizer.h"
69 #include "TProofServ.h"
70 #include "TPluginManager.h"
71 #include "TQueryResult.h"
72 #include "TRandom.h"
73 #include "TRegexp.h"
74 #include "TROOT.h"
75 #include "TSlave.h"
76 #include "TSocket.h"
77 #include "TSortedList.h"
78 #include "TSystem.h"
79 #include "TTree.h"
80 #include "TUrl.h"
81 #include "TFileCollection.h"
82 #include "TDataSetManager.h"
83 #include "TDataSetManagerFile.h"
84 #include "TMacro.h"
85 #include "TSelector.h"
86 #include "TPRegexp.h"
87 
88 TProof *gProof = 0;
89 
90 // Rotating indicator
91 char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
92 
93 TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
94 TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
95 
97 
98 //----- PROOF Interrupt signal handler -----------------------------------------
99 ////////////////////////////////////////////////////////////////////////////////
100 /// TProof interrupt handler.
101 
103 {
104  if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
105 
106  // Cannot ask the user : abort any remote processing
107  fProof->StopProcess(kTRUE);
108 
109  } else {
110  // Real stop or request to switch to asynchronous?
111  const char *a = 0;
112  if (fProof->GetRemoteProtocol() < 22) {
113  a = Getline("\nSwitch to asynchronous mode not supported remotely:"
114  "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
115  } else {
116  a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
117  " any other key to continue: ");
118  }
119  if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
120 
121  Info("Notify","Processing interrupt signal ... %c", a[0]);
122 
123  // Stop or abort any remote processing
124  Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
125  fProof->StopProcess(abort);
126 
127  } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
128  // Stop any remote processing
129  fProof->GoAsynchronous();
130  }
131  }
132 
133  return kTRUE;
134 }
135 
136 //----- Input handler for messages from TProofServ -----------------------------
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Constructor
139 
141  : TFileHandler(s->GetDescriptor(),1),
142  fSocket(s), fProof(p)
143 {
144 }
145 
146 ////////////////////////////////////////////////////////////////////////////////
147 /// Handle input
148 
150 {
152  return kTRUE;
153 }
154 
155 
156 //------------------------------------------------------------------------------
157 
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// Used to sort slaveinfos by ordinal.
162 
163 Int_t TSlaveInfo::Compare(const TObject *obj) const
164 {
165  if (!obj) return 1;
166 
167  const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
168 
169  if (!si) return fOrdinal.CompareTo(obj->GetName());
170 
171  const char *myord = GetOrdinal();
172  const char *otherord = si->GetOrdinal();
173  while (myord && otherord) {
174  Int_t myval = atoi(myord);
175  Int_t otherval = atoi(otherord);
176  if (myval < otherval) return 1;
177  if (myval > otherval) return -1;
178  myord = strchr(myord, '.');
179  if (myord) myord++;
180  otherord = strchr(otherord, '.');
181  if (otherord) otherord++;
182  }
183  if (myord) return -1;
184  if (otherord) return 1;
185  return 0;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Used to compare slaveinfos by ordinal.
190 
192 {
193  if (!obj) return kFALSE;
194  const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
195  if (!si) return kFALSE;
196  return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// Print slave info. If opt = "active" print only the active
201 /// slaves, if opt="notactive" print only the not active slaves,
202 /// if opt = "bad" print only the bad slaves, else
203 /// print all slaves.
204 
205 void TSlaveInfo::Print(Option_t *opt) const
206 {
207  TString stat = fStatus == kActive ? "active" :
208  fStatus == kBad ? "bad" :
209  "not active";
210 
211  Bool_t newfmt = kFALSE;
212  TString oo(opt);
213  if (oo.Contains("N")) {
214  newfmt = kTRUE;
215  oo.ReplaceAll("N","");
216  }
217  if (oo == "active" && fStatus != kActive) return;
218  if (oo == "notactive" && fStatus != kNotActive) return;
219  if (oo == "bad" && fStatus != kBad) return;
220 
221  if (newfmt) {
222  TString msd, si, datadir;
223  if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
224  if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
225  if (fSysInfo.fCpus > 0) {
226  si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
228  } else {
229  si.Form("| %s", fHostName.Data());
230  }
231  Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
232 
233  } else {
234  TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
235 
236  std::cout << "Slave: " << fOrdinal
237  << " hostname: " << fHostName
238  << " msd: " << msd
239  << " perf index: " << fPerfIndex
240  << " " << stat
241  << std::endl;
242  }
243 }
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 /// Setter for fSysInfo
247 
249 {
250  fSysInfo.fOS = si.fOS; // OS
251  fSysInfo.fModel = si.fModel; // computer model
252  fSysInfo.fCpuType = si.fCpuType; // type of cpu
253  fSysInfo.fCpus = si.fCpus; // number of cpus
254  fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
255  fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
256  fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
257  fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
258 }
259 
261 
262 //------------------------------------------------------------------------------
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// Destructor
266 
267 TMergerInfo::~TMergerInfo()
268 {
269  // Just delete the list, the objects are owned by other list
270  if (fWorkers) {
271  fWorkers->SetOwner(kFALSE);
272  SafeDelete(fWorkers);
273  }
274 }
275 ////////////////////////////////////////////////////////////////////////////////
276 /// Increase number of already merged workers by 1
277 
279 {
280  if (AreAllWorkersMerged())
281  Error("SetMergedWorker", "all workers have been already merged before!");
282  else
283  fMergedWorkers++;
284 }
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// Add new worker to the list of workers to be merged by this merger
288 
290 {
291  if (!fWorkers)
292  fWorkers = new TList();
293  if (fWorkersToMerge == fWorkers->GetSize()) {
294  Error("AddWorker", "all workers have been already assigned to this merger");
295  return;
296  }
297  fWorkers->Add(sl);
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Return if merger has already merged all workers, i.e. if it has finished its merging job
302 
304 {
305  return (fWorkersToMerge == fMergedWorkers);
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Return if the determined number of workers has been already assigned to this merger
310 
312 {
313  if (!fWorkers)
314  return kFALSE;
315 
316  return (fWorkers->GetSize() == fWorkersToMerge);
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// This a private API function.
321 /// It checks whether the connection string contains a PoD cluster protocol.
322 /// If it does, then the connection string will be changed to reflect
323 /// a real PROOF connection string for a PROOF cluster managed by PoD.
324 /// PoD: http://pod.gsi.de .
325 /// Return -1 if the PoD request failed; return 0 otherwise.
326 
327 static Int_t PoDCheckUrl(TString *_cluster)
328 {
329  if ( !_cluster )
330  return 0;
331 
332  // trim spaces from both sides of the string
333  *_cluster = _cluster->Strip( TString::kBoth );
334  // PoD protocol string
335  const TString pod_prot("pod");
336 
337  // URL test
338  // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
339  TUrl url( _cluster->Data() );
340  if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
341  return 0;
342 
343  // PoD cluster is used
344  // call pod-info in a batch mode (-b).
345  // pod-info will find either a local PoD cluster or
346  // a remote one, manged by pod-remote.
347  *_cluster = gSystem->GetFromPipe("pod-info -c -b");
348  if( 0 == _cluster->Length() ) {
349  Error("PoDCheckUrl", "PoD server is not running");
350  return -1;
351  }
352  return 0;
353 }
354 
355 ////////////////////////////////////////////////////////////////////////////////
356 /// Create a PROOF environment. Starting PROOF involves either connecting
357 /// to a master server, which in turn will start a set of slave servers, or
358 /// directly starting as master server (if master = ""). Masterurl is of
359 /// the form: [proof[s]://]host[:port]. Conffile is the name of the config
360 /// file describing the remote PROOF cluster (this argument alows you to
361 /// describe different cluster configurations).
362 /// The default is proof.conf. Confdir is the directory where the config
363 /// file and other PROOF related files are (like motd and noproof files).
364 /// Loglevel is the log level (default = 1). User specified custom config
365 /// files will be first looked for in $HOME/.conffile.
366 
367 TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
368  Int_t loglevel, const char *alias, TProofMgr *mgr)
369  : fUrl(masterurl)
370 {
371  // Default initializations
372  InitMembers();
373 
374  // This may be needed during init
375  fManager = mgr;
376 
377  // Default server type
379 
380  // Default query mode
381  fQueryMode = kSync;
382 
383  // Parse the main URL, adjusting the missing fields and setting the relevant
384  // bits
387 
388  // Protocol and Host
389  if (!masterurl || strlen(masterurl) <= 0) {
390  fUrl.SetProtocol("proof");
391  fUrl.SetHost("__master__");
392  } else if (!(strstr(masterurl, "://"))) {
393  fUrl.SetProtocol("proof");
394  }
395  // Port
396  if (fUrl.GetPort() == TUrl(" ").GetPort())
397  fUrl.SetPort(TUrl("proof:// ").GetPort());
398 
399  // Make sure to store the FQDN, so to get a solid reference for subsequent checks
400  if (!strcmp(fUrl.GetHost(), "__master__"))
401  fMaster = fUrl.GetHost();
402  else if (!strlen(fUrl.GetHost()))
403  fMaster = gSystem->GetHostByName(gSystem->HostName()).GetHostName();
404  else
405  fMaster = gSystem->GetHostByName(fUrl.GetHost()).GetHostName();
406 
407  // Server type
408  if (strlen(fUrl.GetOptions()) > 0) {
409  TString opts(fUrl.GetOptions());
410  if (!(strncmp(fUrl.GetOptions(),"std",3))) {
412  opts.Remove(0,3);
413  fUrl.SetOptions(opts.Data());
414  } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
416  opts.Remove(0,4);
417  fUrl.SetOptions(opts.Data());
418  }
419  }
420 
421  // Instance type
425  if (fMaster == "__master__") {
426  fMasterServ = kTRUE;
429  } else if (fMaster == "prooflite") {
430  // Client and master are merged
431  fMasterServ = kTRUE;
433  }
434  // Flag that we are a client
436  if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
437 
438  Init(masterurl, conffile, confdir, loglevel, alias);
439 
440  // If the user was not set, get it from the master
441  if (strlen(fUrl.GetUser()) <= 0) {
442  TString usr, emsg;
443  if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
444  TObjString *os = fMacroLog.GetLineWith("const char");
445  if (os) {
446  Ssiz_t fst = os->GetString().First('\"');
447  Ssiz_t lst = os->GetString().Last('\"');
448  usr = os->GetString()(fst+1, lst-fst-1);
449  } else {
450  emsg = "could not find 'const char *' string in macro log";
451  }
452  } else {
453  emsg = "could not retrieve user info";
454  }
455  if (!emsg.IsNull()) {
456  // Get user logon name
458  if (pw) {
459  usr = pw->fUser;
460  delete pw;
461  }
462  Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
463  }
464  // Set the user name in the main URL
465  fUrl.SetUser(usr.Data());
466  }
467 
468  // If called by a manager, make sure it stays in last position
469  // for cleaning
470  if (mgr) {
472  gROOT->GetListOfSockets()->Remove(mgr);
473  gROOT->GetListOfSockets()->Add(mgr);
474  }
475 
476  // Old-style server type: we add this to the list and set the global pointer
478  if (!gROOT->GetListOfProofs()->FindObject(this))
479  gROOT->GetListOfProofs()->Add(this);
480 
481  // Still needed by the packetizers: needs to be changed
482  gProof = this;
483 }
484 
485 ////////////////////////////////////////////////////////////////////////////////
486 /// Protected constructor to be used by classes deriving from TProof
487 /// (they have to call Init themselves and override StartSlaves
488 /// appropriately).
489 ///
490 /// This constructor simply closes any previous gProof and sets gProof
491 /// to this instance.
492 
493 TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
494 {
495  // Default initializations
496  InitMembers();
497 
498  if (!gROOT->GetListOfProofs()->FindObject(this))
499  gROOT->GetListOfProofs()->Add(this);
500 
501  gProof = this;
502 }
503 
504 ////////////////////////////////////////////////////////////////////////////////
505 /// Default initializations
506 
508 {
509  fValid = kFALSE;
510  fTty = kFALSE;
511  fRecvMessages = 0;
512  fSlaveInfo = 0;
516  fLastPollWorkers_s = -1;
517  fActiveSlaves = 0;
518  fInactiveSlaves = 0;
519  fUniqueSlaves = 0;
520  fAllUniqueSlaves = 0;
521  fNonUniqueMasters = 0;
522  fActiveMonitor = 0;
523  fUniqueMonitor = 0;
524  fAllUniqueMonitor = 0;
525  fCurrentMonitor = 0;
526  fBytesRead = 0;
527  fRealTime = 0;
528  fCpuTime = 0;
529  fIntHandler = 0;
530  fProgressDialog = 0;
533  fPlayer = 0;
534  fFeedback = 0;
535  fChains = 0;
536  fDSet = 0;
537  fNotIdle = 0;
538  fSync = kTRUE;
540  fIsWaiting = kFALSE;
541  fRedirLog = kFALSE;
542  fLogFileW = 0;
543  fLogFileR = 0;
546  fMacroLog.SetName("ProofLogMacro");
547 
548  fWaitingSlaves = 0;
549  fQueries = 0;
550  fOtherQueries = 0;
551  fDrawQueries = 0;
552  fMaxDrawQueries = 1;
553  fSeqNum = 0;
554 
555  fSessionID = -1;
556  fEndMaster = kFALSE;
557 
559  fPackageLock = 0;
562 
563  fInputData = 0;
564 
565  fPrintProgress = 0;
566 
567  fLoadedMacros = 0;
568 
569  fProtocol = -1;
570  fSlaves = 0;
572  fBadSlaves = 0;
573  fAllMonitor = 0;
574  fDataReady = kFALSE;
575  fBytesReady = 0;
576  fTotalBytes = 0;
577  fAvailablePackages = 0;
578  fEnabledPackages = 0;
579  fRunningDSets = 0;
580 
581  fCollectTimeout = -1;
582 
583  fManager = 0;
584  fQueryMode = kSync;
586 
587  fCloseMutex = 0;
588 
591  fMergers = 0;
592  fMergersCount = -1;
594  fWorkersToMerge = 0;
596 
597  fPerfTree = "";
598 
599  fWrksOutputReady = 0;
600 
601  fSelector = 0;
602 
603  fPrepTime = 0.;
604 
605  // Check if the user defined a list of environment variables to send over:
606  // include them into the dedicated list
607  if (gSystem->Getenv("PROOF_ENVVARS")) {
608  TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
609  Int_t from = 0;
610  while (envs.Tokenize(env, from, ",")) {
611  if (!env.IsNull()) {
612  if (!gSystem->Getenv(env)) {
613  Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
614  } else {
615  if (!envsfound.IsNull()) envsfound += ",";
616  envsfound += env;
617  TProof::DelEnvVar(env);
618  TProof::AddEnvVar(env, gSystem->Getenv(env));
619  }
620  }
621  }
622  if (envsfound.IsNull()) {
623  Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
624  } else {
625  Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
626  }
627  }
628 
629  // Done
630  return;
631 }
632 
633 ////////////////////////////////////////////////////////////////////////////////
634 /// Clean up PROOF environment.
635 
637 {
638  if (fChains) {
639  while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
640  // remove "chain" from list
641  chain->SetProof(0);
642  RemoveChain(chain);
643  }
644  }
645 
646  // remove links to packages enabled on the client
647  if (TestBit(TProof::kIsClient)) {
648  // iterate over all packages
649  TIter nextpackage(fEnabledPackagesOnClient);
650  while (TObjString *package = dynamic_cast<TObjString*>(nextpackage())) {
651  FileStat_t stat;
652  if (gSystem->GetPathInfo(package->String(), stat) == 0) {
653  // check if symlink, if so unlink
654  // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
655  // existing file or to a directory, but if fIsLink is true the symlink exists
656  if (stat.fIsLink)
657  gSystem->Unlink(package->String());
658  }
659  }
660  }
661 
662  Close();
691  if (fWrksOutputReady) {
693  delete fWrksOutputReady;
694  }
695 
696  // remove file with redirected logs
697  if (TestBit(TProof::kIsClient)) {
698  if (fLogFileR)
699  fclose(fLogFileR);
700  if (fLogFileW)
701  fclose(fLogFileW);
702  if (fLogFileName.Length() > 0)
704  }
705 
706  // Remove for the global list
707  gROOT->GetListOfProofs()->Remove(this);
708  // ... and from the manager list
709  if (fManager && fManager->IsValid())
710  fManager->DiscardSession(this);
711 
712  if (gProof && gProof == this) {
713  // Set previous as default
714  TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
715  while ((gProof = (TProof *)pvp())) {
716  if (gProof->InheritsFrom(TProof::Class()))
717  break;
718  }
719  }
720 
721  // For those interested in our destruction ...
722  Emit("~TProof()");
723  Emit("CloseWindow()");
724 }
725 
726 ////////////////////////////////////////////////////////////////////////////////
727 /// Start the PROOF environment. Starting PROOF involves either connecting
728 /// to a master server, which in turn will start a set of slave servers, or
729 /// directly starting as master server (if master = ""). For a description
730 /// of the arguments see the TProof ctor. Returns the number of started
731 /// master or slave servers, returns 0 in case of error, in which case
732 /// fValid remains false.
733 
734 Int_t TProof::Init(const char *, const char *conffile,
735  const char *confdir, Int_t loglevel, const char *alias)
736 {
738 
739  fValid = kFALSE;
740 
741  // Connected to terminal?
742  fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
743 
744  // If in attach mode, options is filled with additional info
745  Bool_t attach = kFALSE;
746  if (strlen(fUrl.GetOptions()) > 0) {
747  attach = kTRUE;
748  // A flag from the GUI
749  TString opts = fUrl.GetOptions();
750  if (opts.Contains("GUI")) {
752  opts.Remove(opts.Index("GUI"));
753  fUrl.SetOptions(opts);
754  }
755  }
756 
757  if (TestBit(TProof::kIsMaster)) {
758  // Fill default conf file and conf dir
759  if (!conffile || !conffile[0])
761  if (!confdir || !confdir[0])
763  // The group; the client receives it in the kPROOF_SESSIONTAG message
765  } else {
766  fConfDir = confdir;
767  fConfFile = conffile;
768  }
769 
770  // Analysise the conffile field
771  if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
773 
775  fLogLevel = loglevel;
778  fImage = fMasterServ ? "" : "<local>";
779  fIntHandler = 0;
780  fStatus = 0;
781  fRecvMessages = new TList;
783  fSlaveInfo = 0;
784  fChains = new TList;
785  fAvailablePackages = 0;
786  fEnabledPackages = 0;
787  fRunningDSets = 0;
789  fInputData = 0;
791  fPrintProgress = 0;
792 
795 
796  // Timeout for some collect actions
797  fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
798 
799  // Should the workers be started dynamically; default: no
800  fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
801 
802  // Default entry point for the data pool is the master
804  fDataPoolUrl.Form("root://%s", fMaster.Data());
805  else
806  fDataPoolUrl = "";
807 
808  fProgressDialog = 0;
810 
811  // Default alias is the master name
812  TString al = (alias) ? alias : fMaster.Data();
813  SetAlias(al);
814 
815  // Client logging of messages from the master and slaves
816  fRedirLog = kFALSE;
817  if (TestBit(TProof::kIsClient)) {
818  fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
819  if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
820  Error("Init", "could not create temporary logfile");
821  if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
822  Error("Init", "could not open temp logfile for reading");
823  }
825 
826  // Status of cluster
827  fNotIdle = 0;
828  // Query type
829  fSync = (attach) ? kFALSE : kTRUE;
830  // Not enqueued
831  fIsWaiting = kFALSE;
832 
833  // Counters
834  fBytesRead = 0;
835  fRealTime = 0;
836  fCpuTime = 0;
837 
838  // List of queries
839  fQueries = 0;
840  fOtherQueries = 0;
841  fDrawQueries = 0;
842  fMaxDrawQueries = 1;
843  fSeqNum = 0;
844 
845  // Remote ID of the session
846  fSessionID = -1;
847 
848  // Part of active query
849  fWaitingSlaves = 0;
850 
851  // Make remote PROOF player
852  fPlayer = 0;
853  MakePlayer();
854 
855  fFeedback = new TList;
856  fFeedback->SetOwner();
857  fFeedback->SetName("FeedbackList");
859 
860  // sort slaves by descending performance index
862  fActiveSlaves = new TList;
863  fInactiveSlaves = new TList;
864  fUniqueSlaves = new TList;
865  fAllUniqueSlaves = new TList;
866  fNonUniqueMasters = new TList;
867  fBadSlaves = new TList;
868  fAllMonitor = new TMonitor;
869  fActiveMonitor = new TMonitor;
870  fUniqueMonitor = new TMonitor;
872  fCurrentMonitor = 0;
873 
876 
877  fPackageLock = 0;
879  fLoadedMacros = 0;
881 
882  // Enable optimized sending of streamer infos to use embedded backward/forward
883  // compatibility support between different ROOT versions and different versions of
884  // users classes
885  Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
886  if (enableSchemaEvolution) {
888  } else {
889  Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
890  }
891 
892  if (IsMaster()) {
893  // to make UploadPackage() method work on the master as well.
895  } else {
896 
897  TString sandbox;
898  if (GetSandbox(sandbox, kTRUE) != 0) {
899  Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
900  return 0;
901  }
902 
903  // Package Dir
904  fPackageDir = gEnv->GetValue("Proof.PackageDir", "");
905  if (fPackageDir.IsNull())
906  fPackageDir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
907  if (AssertPath(fPackageDir, kTRUE) != 0) {
908  Error("Init", "failure asserting directory %s", fPackageDir.Data());
909  return 0;
910  }
911  }
912 
913  if (!IsMaster()) {
914  // List of directories where to look for global packages
915  TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
916  if (globpack.Length() > 0) {
917  Int_t ng = 0;
918  Int_t from = 0;
919  TString ldir;
920  while (globpack.Tokenize(ldir, from, ":")) {
922  if (gSystem->AccessPathName(ldir, kReadPermission)) {
923  Warning("Init", "directory for global packages %s does not"
924  " exist or is not readable", ldir.Data());
925  } else {
926  // Add to the list, key will be "G<ng>", i.e. "G0", "G1", ...
927  TString key = TString::Format("G%d", ng++);
928  if (!fGlobalPackageDirList) {
931  }
932  fGlobalPackageDirList->Add(new TNamed(key,ldir));
933  }
934  }
935  }
936 
937  TString lockpath(fPackageDir);
938  lockpath.ReplaceAll("/", "%");
939  lockpath.Insert(0, TString::Format("%s/%s",
941  fPackageLock = new TProofLockPath(lockpath.Data());
942 
944  fEnabledPackagesOnClient->SetOwner();
945  }
946 
947  // Master may want dynamic startup
948  if (fDynamicStartup) {
949  if (!IsMaster()) {
950  // If on client - start the master
951  if (!StartSlaves(attach))
952  return 0;
953  }
954  } else {
955 
956  // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
957  // result retrieving, ...)
958  Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
959  if (!IsMaster() || !masterOnly) {
960  // Start slaves (the old, static, per-session way)
961  if (!StartSlaves(attach))
962  return 0;
963  // Client: Is Master in dynamic startup mode?
964  if (!IsMaster()) {
965  Int_t dyn;
966  GetRC("Proof.DynamicStartup", dyn);
967  if (dyn != 0) fDynamicStartup = kTRUE;
968  }
969  }
970  }
971  // we are now properly initialized
972  fValid = kTRUE;
973 
974  // De-activate monitor (will be activated in Collect)
976 
977  // By default go into parallel mode
978  Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
979  TNamed *n = 0;
980  if (TProof::GetEnvVars() &&
981  (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
982  TString s(n->GetTitle());
983  if (s.IsDigit()) nwrk = s.Atoi();
984  }
985  GoParallel(nwrk, attach);
986 
987  // Send relevant initial state to slaves
988  if (!attach)
990  else if (!IsIdle())
991  // redirect log
992  fRedirLog = kTRUE;
993 
994  // Done at this point, the alias will be communicated to the coordinator, if any
996  SetAlias(al);
997 
998  SetActive(kFALSE);
999 
1000  if (IsValid()) {
1001 
1002  // Activate input handler
1004 
1006  gROOT->GetListOfSockets()->Add(this);
1007  }
1008 
1009  AskParallel();
1010 
1011  return fActiveSlaves->GetSize();
1012 }
1013 
1014 ////////////////////////////////////////////////////////////////////////////////
1015 /// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1016 /// Use the existing setting or the default if nothing is found.
1017 /// If 'assert' is kTRUE, make also sure that the path exists.
1018 /// Return 0 on success, -1 on failure
1019 
1021 {
1022  // Get it from 'rc', if defined
1023  if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1024  // Or use the default 'rc'
1025  if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1026  // If nothing found , use the default
1027  if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1028  // Expand special settings
1029  if (sb == ".") {
1030  sb = gSystem->pwd();
1031  } else if (sb == "..") {
1032  sb = gSystem->DirName(gSystem->pwd());
1033  }
1034  gSystem->ExpandPathName(sb);
1035 
1036  // Assert the path, if required
1037  if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1038  // Done
1039  return 0;
1040 }
1041 
1042 ////////////////////////////////////////////////////////////////////////////////
1043 /// The config file field may contain special instructions which need to be
1044 /// parsed at the beginning, e.g. for debug runs with valgrind.
1045 /// Several options can be given separated by a ','
1046 
1047 void TProof::ParseConfigField(const char *config)
1048 {
1049  TString sconf(config), opt;
1050  Ssiz_t from = 0;
1051  Bool_t cpuPin = kFALSE;
1052 
1053  // Analysise the field
1054  const char *cq = (IsLite()) ? "\"" : "";
1055  while (sconf.Tokenize(opt, from, ",")) {
1056  if (opt.IsNull()) continue;
1057 
1058  if (opt.BeginsWith("valgrind")) {
1059  // Any existing valgrind setting? User can give full settings, which we fully respect,
1060  // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1061  // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1062  // will add option "--time-stamp --leak-check=full" to our default options
1063  TString mst, top, sub, wrk, all;
1064  TList *envs = fgProofEnvList;
1065  TNamed *n = 0;
1066  if (envs) {
1067  if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1068  all = n->GetTitle();
1069  if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1070  mst = n->GetTitle();
1071  if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1072  top = n->GetTitle();
1073  if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1074  sub = n->GetTitle();
1075  if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1076  wrk = n->GetTitle();
1077  }
1078  if (all != "" && mst == "") mst = all;
1079  if (all != "" && top == "") top = all;
1080  if (all != "" && sub == "") sub = all;
1081  if (all != "" && wrk == "") wrk = all;
1082  if (all != "" && all.BeginsWith("valgrind_opts:")) {
1083  // The field is used to add an option Reset the setting
1084  Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1085  " must be set again for next run , if any");
1086  TProof::DelEnvVar("PROOF_WRAPPERCMD");
1087  }
1088  TString var, cmd;
1089  cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1090  TString mstlab("NO"), wrklab("NO");
1091  Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1092  !opt.Contains("topmaster") && !opt.Contains("submaster")))
1093  ? kTRUE : kFALSE;
1094  if (doMaster) {
1095  if (!IsLite()) {
1096  // Check if we have to add a var
1097  if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1098  mst.ReplaceAll("valgrind_opts:","");
1099  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1100  TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1101  mstlab = "YES";
1102  } else if (mst != "") {
1103  mstlab = "YES";
1104  }
1105  } else {
1106  if (opt.Contains("master")) {
1107  Warning("ParseConfigField",
1108  "master valgrinding does not make sense for PROOF-Lite: ignoring");
1109  opt.ReplaceAll("master", "");
1110  if (!opt.Contains("workers")) return;
1111  }
1112  if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1113  }
1114  }
1115  if (opt.Contains("topmaster")) {
1116  // Check if we have to add a var
1117  if (top == "" || top.BeginsWith("valgrind_opts:")) {
1118  top.ReplaceAll("valgrind_opts:","");
1119  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1120  TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1121  mstlab = "YES";
1122  } else if (top != "") {
1123  mstlab = "YES";
1124  }
1125  }
1126  if (opt.Contains("submaster")) {
1127  // Check if we have to add a var
1128  if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1129  sub.ReplaceAll("valgrind_opts:","");
1130  var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1131  TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1132  mstlab = "YES";
1133  } else if (sub != "") {
1134  mstlab = "YES";
1135  }
1136  }
1137  if (opt.Contains("=workers") || opt.Contains("+workers")) {
1138  // Check if we have to add a var
1139  if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1140  wrk.ReplaceAll("valgrind_opts:","");
1141  var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1142  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1143  TString nwrks("2");
1144  Int_t inw = opt.Index('#');
1145  if (inw != kNPOS) {
1146  nwrks = opt(inw+1, opt.Length());
1147  if (!nwrks.IsDigit()) nwrks = "2";
1148  }
1149  // Set the relevant variables
1150  if (!IsLite()) {
1151  TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1152  } else {
1153  gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1154  }
1155  wrklab = nwrks;
1156  // Register the additional worker log in the session file
1157  // (for the master this is done automatically)
1158  TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1159  } else if (wrk != "") {
1160  wrklab = "ALL";
1161  }
1162  }
1163  // Increase the relevant timeouts
1164  if (!IsLite()) {
1165  TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1166  gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1167  } else {
1168  gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1169  }
1170  // Warn for slowness
1171  Printf(" ");
1172  if (!IsLite()) {
1173  Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1174  } else {
1175  Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1176  }
1177  Printf(" ---> Please be patient: startup may be VERY slow ...");
1178  Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1179  Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1180  Printf(" ");
1181 
1182  } else if (opt.BeginsWith("igprof-pp")) {
1183 
1184  // IgProf profiling on master and worker. PROOF does not set the
1185  // environment for you: proper environment variables (like PATH and
1186  // LD_LIBRARY_PATH) should be set externally
1187 
1188  Printf("*** Requested IgProf performance profiling ***");
1189  TString addLogExt = "__igprof.pp__.log";
1190  TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1191  TString tmp;
1192 
1193  if (IsLite()) {
1194  addLogFmt.Append("\"");
1195  addLogFmt.Prepend("\"");
1196  }
1197 
1198  tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1199  TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1200 
1201  tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1202  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1203 
1204  TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1205 
1206  } else if (opt.BeginsWith("cpupin=")) {
1207  // Enable CPU pinning. Takes as argument the list of processor IDs
1208  // that will be used in order. Processor IDs are numbered from 0,
1209  // use likwid to see how they are organized. A possible parameter
1210  // format would be:
1211  //
1212  // cpupin=3+4+0+9+10+22+7
1213  //
1214  // Only the specified processor IDs will be used in a round-robin
1215  // fashion, dealing with the fact that you can request more workers
1216  // than the number of processor IDs you have specified.
1217  //
1218  // To use all available processors in their order:
1219  //
1220  // cpupin=*
1221 
1222  opt.Remove(0, 7);
1223 
1224  // Remove any char which is neither a number nor a plus '+'
1225  for (Ssiz_t i=0; i<opt.Length(); i++) {
1226  Char_t c = opt[i];
1227  if ((c != '+') && ((c < '0') || (c > '9')))
1228  opt[i] = '_';
1229  }
1230  opt.ReplaceAll("_", "");
1231  TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1232  cpuPin = kTRUE;
1233  } else if (opt.BeginsWith("workers=")) {
1234 
1235  // Request for a given number of workers (within the max) or worker
1236  // startup combination:
1237  // workers=5 start max 5 workers (or less, if less are assigned)
1238  // workers=2x start max 2 workers per node (or less, if less are assigned)
1239  opt.ReplaceAll("workers=","");
1240  TProof::AddEnvVar("PROOF_NWORKERS", opt);
1241  }
1242  }
1243 
1244  // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1245  #ifdef R__LINUX
1246  if (IsLite() && cpuPin) {
1247  Printf("*** Requested CPU pinning ***");
1248  const TList *ev = GetEnvVars();
1249  const char *pinCmd = "taskset -c <cpupin>";
1250  TString val;
1251  TNamed *p;
1252  if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1253  val = p->GetTitle();
1254  val.Insert(val.Length()-1, " ");
1255  val.Insert(val.Length()-1, pinCmd);
1256  }
1257  else {
1258  val.Form("\"%s\"", pinCmd);
1259  }
1260  TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1261  }
1262  #endif
1263 }
1264 
1265 ////////////////////////////////////////////////////////////////////////////////
1266 /// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1267 /// that the path is writable
1268 
1269 Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1270 {
1271  if (!inpath || strlen(inpath) <= 0) {
1272  Error("AssertPath", "undefined input path");
1273  return -1;
1274  }
1275 
1276  TString path(inpath);
1277  gSystem->ExpandPathName(path);
1278 
1279  if (gSystem->AccessPathName(path, kFileExists)) {
1280  if (gSystem->mkdir(path, kTRUE) != 0) {
1281  Error("AssertPath", "could not create path %s", path.Data());
1282  return -1;
1283  }
1284  }
1285  // It must be writable
1286  if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1287  if (gSystem->Chmod(path, 0666) != 0) {
1288  Error("AssertPath", "could not make path %s writable", path.Data());
1289  return -1;
1290  }
1291  }
1292 
1293  // Done
1294  return 0;
1295 }
1296 
1297 ////////////////////////////////////////////////////////////////////////////////
1298 /// Set manager and schedule its destruction after this for clean
1299 /// operations.
1300 
1302 {
1303  fManager = mgr;
1304 
1305  if (mgr) {
1307  gROOT->GetListOfSockets()->Remove(mgr);
1308  gROOT->GetListOfSockets()->Add(mgr);
1309  }
1310 }
1311 
1312 ////////////////////////////////////////////////////////////////////////////////
1313 /// Works on the master node only.
1314 /// It starts workers on the machines in workerList and sets the paths,
1315 /// packages and macros as on the master.
1316 /// It is a subbstitute for StartSlaves(...)
1317 /// The code is mostly the master part of StartSlaves,
1318 /// with the parallel startup removed.
1319 
1321 {
1322  if (!IsMaster()) {
1323  Error("AddWorkers", "AddWorkers can only be called on the master!");
1324  return -1;
1325  }
1326 
1327  if (!workerList || !(workerList->GetSize())) {
1328  Error("AddWorkers", "empty list of workers!");
1329  return -2;
1330  }
1331 
1332  // Code taken from master part of StartSlaves with the parllel part removed
1333 
1334  fImage = gProofServ->GetImage();
1335  if (fImage.IsNull())
1336  fImage.Form("%s:%s", TUrl(gSystem->HostName()).GetHostFQDN(), gProofServ->GetWorkDir());
1337 
1338  // Get all workers
1339  UInt_t nSlaves = workerList->GetSize();
1340  UInt_t nSlavesDone = 0;
1341  Int_t ord = 0;
1342 
1343  // Loop over all new workers and start them (if we had already workers it means we are
1344  // increasing parallelism or that is not the first time we are called)
1345  Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1346 
1347  // A list of TSlave objects for workers that are being added
1348  TList *addedWorkers = new TList();
1349  if (!addedWorkers) {
1350  // This is needed to silence Coverity ...
1351  Error("AddWorkers", "cannot create new list for the workers to be added");
1352  return -2;
1353  }
1354  addedWorkers->SetOwner(kFALSE);
1355  TListIter next(workerList);
1356  TObject *to;
1357  TProofNodeInfo *worker;
1358  TSlaveInfo *dummysi = new TSlaveInfo();
1359  while ((to = next())) {
1360  // Get the next worker from the list
1361  worker = (TProofNodeInfo *)to;
1362 
1363  // Read back worker node info
1364  const Char_t *image = worker->GetImage().Data();
1365  const Char_t *workdir = worker->GetWorkDir().Data();
1366  Int_t perfidx = worker->GetPerfIndex();
1367  Int_t sport = worker->GetPort();
1368  if (sport == -1)
1369  sport = fUrl.GetPort();
1370 
1371  // Create worker server
1372  TString fullord;
1373  if (worker->GetOrdinal().Length() > 0) {
1374  fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1375  } else {
1376  fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1377  }
1378 
1379  // Remove worker from the list of workers terminated gracefully
1380  dummysi->SetOrdinal(fullord);
1381  TSlaveInfo *rmsi = (TSlaveInfo *)fTerminatedSlaveInfos->Remove(dummysi);
1382  if (rmsi) SafeDelete(rmsi);
1383 
1384  // Create worker server
1385  TString wn(worker->GetNodeName());
1386  if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1387  TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1388  // Add group info in the password firdl, if any
1389  if (strlen(gProofServ->GetGroup()) > 0) {
1390  // Set also the user, otherwise the password is not exported
1391  if (strlen(u.GetUser()) <= 0)
1392  u.SetUser(gProofServ->GetUser());
1394  }
1395  TSlave *slave = 0;
1396  if (worker->IsWorker()) {
1397  slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1398  } else {
1399  slave = CreateSubmaster(u.GetUrl(), fullord,
1400  image, worker->GetMsd(), worker->GetNWrks());
1401  }
1402 
1403  // Add to global list (we will add to the monitor list after
1404  // finalizing the server startup)
1405  Bool_t slaveOk = kTRUE;
1406  fSlaves->Add(slave);
1407  if (slave->IsValid()) {
1408  addedWorkers->Add(slave);
1409  } else {
1410  slaveOk = kFALSE;
1411  fBadSlaves->Add(slave);
1412  Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1413  }
1414 
1415  PDB(kGlobal,3)
1416  Info("AddWorkers", "worker on host %s created"
1417  " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1418 
1419  // Notify opening of connection
1420  nSlavesDone++;
1422  m << TString("Opening connections to workers") << nSlaves
1423  << nSlavesDone << slaveOk;
1424  gProofServ->GetSocket()->Send(m);
1425 
1426  ord++;
1427  } //end of the worker loop
1428  SafeDelete(dummysi);
1429 
1430  // Cleanup
1431  SafeDelete(workerList);
1432 
1433  nSlavesDone = 0;
1434 
1435  // Here we finalize the server startup: in this way the bulk
1436  // of remote operations are almost parallelized
1437  TIter nxsl(addedWorkers);
1438  TSlave *sl = 0;
1439  while ((sl = (TSlave *) nxsl())) {
1440 
1441  // Finalize setup of the server
1442  if (sl->IsValid())
1443  sl->SetupServ(TSlave::kSlave, 0);
1444 
1445  // Monitor good slaves
1446  Bool_t slaveOk = kTRUE;
1447  if (sl->IsValid()) {
1448  fAllMonitor->Add(sl->GetSocket());
1449  PDB(kGlobal,3)
1450  Info("AddWorkers", "worker on host %s finalized"
1451  " and added to list", sl->GetOrdinal());
1452  } else {
1453  slaveOk = kFALSE;
1454  fBadSlaves->Add(sl);
1455  }
1456 
1457  // Notify end of startup operations
1458  nSlavesDone++;
1460  m << TString("Setting up worker servers") << nSlaves
1461  << nSlavesDone << slaveOk;
1462  gProofServ->GetSocket()->Send(m);
1463  }
1464 
1465  // Now set new state on the added workers (on all workers for simplicity)
1466  // use fEnabledPackages, fLoadedMacros,
1467  // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1468  // no need to load packages that are only loaded and not enabled (dyn mode)
1469  Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1470  TNamed *n = 0;
1471  if (TProof::GetEnvVars() &&
1472  (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1473  TString s(n->GetTitle());
1474  if (s.IsDigit()) nwrk = s.Atoi();
1475  }
1476 
1477  if (fDynamicStartup && goMoreParallel) {
1478 
1479  PDB(kGlobal, 3)
1480  Info("AddWorkers", "will invoke GoMoreParallel()");
1481  Int_t nw = GoMoreParallel(nwrk);
1482  PDB(kGlobal, 3)
1483  Info("AddWorkers", "GoMoreParallel()=%d", nw);
1484 
1485  }
1486  else {
1487  // Not in Dynamic Workers mode
1488  PDB(kGlobal, 3)
1489  Info("AddWorkers", "will invoke GoParallel()");
1490  GoParallel(nwrk, kFALSE, 0);
1491  }
1492 
1493  // Set worker processing environment
1494  SetupWorkersEnv(addedWorkers, goMoreParallel);
1495 
1496  // Update list of current workers
1497  PDB(kGlobal, 3)
1498  Info("AddWorkers", "will invoke SaveWorkerInfo()");
1499  SaveWorkerInfo();
1500 
1501  // Inform the client that the number of workers has changed
1502  if (fDynamicStartup && gProofServ) {
1503  PDB(kGlobal, 3)
1504  Info("AddWorkers", "will invoke SendParallel()");
1506 
1507  if (goMoreParallel && fPlayer) {
1508  // In case we are adding workers dynamically to an existing process, we
1509  // should invoke a special player's Process() to set only added workers
1510  // to the proper state
1511  PDB(kGlobal, 3)
1512  Info("AddWorkers", "will send the PROCESS message to selected workers");
1513  fPlayer->JoinProcess(addedWorkers);
1514  // Update merger counters (new workers are not yet active)
1515  fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1516  }
1517  }
1518 
1519  // Cleanup
1520  delete addedWorkers;
1521 
1522  return 0;
1523 }
1524 
1525 ////////////////////////////////////////////////////////////////////////////////
1526 /// Set up packages, loaded macros, include and lib paths ...
1527 
1528 void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1529 {
1530  // Packages
1532  if (packs->GetSize() > 0) {
1533  TIter nxp(packs);
1534  TPair *pck = 0;
1535  while ((pck = (TPair *) nxp())) {
1536  // Upload and Enable methods are intelligent and avoid
1537  // re-uploading or re-enabling of a package to a node that has it.
1538  if (fDynamicStartup && increasingWorkers) {
1539  // Upload only on added workers
1540  PDB(kGlobal, 3)
1541  Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1542  if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1543  EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1544  } else {
1545  PDB(kGlobal, 3)
1546  Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1547  if (UploadPackage(pck->GetName()) >= 0)
1548  EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1549  }
1550  }
1551  }
1552 
1553  // Loaded macros
1554  if (fLoadedMacros) {
1555  TIter nxp(fLoadedMacros);
1556  TObjString *os = 0;
1557  while ((os = (TObjString *) nxp())) {
1558  PDB(kGlobal, 3) {
1559  Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1560  Printf("Loading a macro : %s", os->GetName());
1561  }
1562  Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1563  }
1564  }
1565 
1566  // Dynamic path
1567  TString dyn = gSystem->GetDynamicPath();
1568  dyn.ReplaceAll(":", " ");
1569  dyn.ReplaceAll("\"", " ");
1570  PDB(kGlobal, 3)
1571  Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1572  AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1573 
1574  // Include path
1575  TString inc = gSystem->GetIncludePath();
1576  inc.ReplaceAll("-I", " ");
1577  inc.ReplaceAll("\"", " ");
1578  PDB(kGlobal, 3)
1579  Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1580  AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1581 
1582  // Done
1583  return;
1584 }
1585 
1586 ////////////////////////////////////////////////////////////////////////////////
1587 /// Used for shuting down the workres after a query is finished.
1588 /// Sends each of the workers from the workerList, a kPROOF_STOP message.
1589 /// If the workerList == 0, shutdown all the workers.
1590 
1592 {
1593  if (!IsMaster()) {
1594  Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1595  return -1;
1596  }
1597 
1598  fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1599 
1600  if (!workerList) {
1601  // shutdown all the workers
1602  TIter nxsl(fSlaves);
1603  TSlave *sl = 0;
1604  while ((sl = (TSlave *) nxsl())) {
1605  // Shut down the worker assumig that it is not processing
1606  TerminateWorker(sl);
1607  }
1608 
1609  } else {
1610  if (!(workerList->GetSize())) {
1611  Error("RemoveWorkers", "The list of workers should not be empty!");
1612  return -2;
1613  }
1614 
1615  // Loop over all the workers and stop them
1616  TListIter next(workerList);
1617  TObject *to;
1618  TProofNodeInfo *worker;
1619  while ((to = next())) {
1620  TSlave *sl = 0;
1621  if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1622  // Get the next worker from the list
1623  worker = (TProofNodeInfo *)to;
1624  TIter nxsl(fSlaves);
1625  while ((sl = (TSlave *) nxsl())) {
1626  // Shut down the worker assumig that it is not processing
1627  if (sl->GetName() == worker->GetNodeName())
1628  break;
1629  }
1630  } else if (to->InheritsFrom(TSlave::Class())) {
1631  sl = (TSlave *) to;
1632  } else {
1633  Warning("RemoveWorkers","unknown object type: %s - it should be"
1634  " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1635  }
1636  // Shut down the worker assumig that it is not processing
1637  if (sl) {
1638  if (gDebug > 0)
1639  Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1640  TerminateWorker(sl);
1641  }
1642  }
1643  }
1644 
1645  // Update also the master counter
1646  if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1647 
1648  return 0;
1649 }
1650 
1651 ////////////////////////////////////////////////////////////////////////////////
1652 /// Start up PROOF slaves.
1653 
1655 {
1656  // If this is a master server, find the config file and start slave
1657  // servers as specified in the config file
1658  if (TestBit(TProof::kIsMaster)) {
1659 
1660  Int_t pc = 0;
1661  TList *workerList = new TList;
1662  // Get list of workers
1663  if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1664  TString emsg("no resource currently available for this session: please retry later");
1665  if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1666  gProofServ->SendAsynMessage(emsg.Data());
1667  return kFALSE;
1668  }
1669  // Setup the workers
1670  if (AddWorkers(workerList) < 0)
1671  return kFALSE;
1672 
1673  } else {
1674 
1675  // create master server
1676  Printf("Starting master: opening connection ...");
1677  TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1678 
1679  if (slave->IsValid()) {
1680 
1681  // Notify
1682  fprintf(stderr,"Starting master:"
1683  " connection open: setting up server ... \r");
1684  StartupMessage("Connection to master opened", kTRUE, 1, 1);
1685 
1686  if (!attach) {
1687 
1688  // Set worker interrupt handler
1689  slave->SetInterruptHandler(kTRUE);
1690 
1691  // Finalize setup of the server
1693 
1694  if (slave->IsValid()) {
1695 
1696  // Notify
1697  Printf("Starting master: OK ");
1698  StartupMessage("Master started", kTRUE, 1, 1);
1699 
1700  // check protocol compatibility
1701  // protocol 1 is not supported anymore
1702  if (fProtocol == 1) {
1703  Error("StartSlaves",
1704  "client and remote protocols not compatible (%d and %d)",
1706  slave->Close("S");
1707  delete slave;
1708  return kFALSE;
1709  }
1710 
1711  fSlaves->Add(slave);
1712  fAllMonitor->Add(slave->GetSocket());
1713 
1714  // Unset worker interrupt handler
1715  slave->SetInterruptHandler(kFALSE);
1716 
1717  // Set interrupt PROOF handler from now on
1718  fIntHandler = new TProofInterruptHandler(this);
1719 
1720  // Give-up after 5 minutes
1721  Int_t rc = Collect(slave, 300);
1722  Int_t slStatus = slave->GetStatus();
1723  if (slStatus == -99 || slStatus == -98 || rc == 0) {
1724  fSlaves->Remove(slave);
1725  fAllMonitor->Remove(slave->GetSocket());
1726  if (slStatus == -99)
1727  Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1728  else if (slStatus == -98)
1729  Error("StartSlaves", "could not setup output redirection on master");
1730  else
1731  Error("StartSlaves", "setting up master");
1732  slave->Close("S");
1733  delete slave;
1734  return 0;
1735  }
1736 
1737  if (!slave->IsValid()) {
1738  fSlaves->Remove(slave);
1739  fAllMonitor->Remove(slave->GetSocket());
1740  slave->Close("S");
1741  delete slave;
1742  Error("StartSlaves",
1743  "failed to setup connection with PROOF master server");
1744  return kFALSE;
1745  }
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  } else {
1754  // Notify
1755  Printf("Starting master: failure");
1756  }
1757  } else {
1758 
1759  // Notify
1760  Printf("Starting master: OK ");
1761  StartupMessage("Master attached", kTRUE, 1, 1);
1762 
1763  if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1764  if ((fProgressDialog =
1765  gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1766  if (fProgressDialog->LoadPlugin() == -1)
1767  fProgressDialog = 0;
1768  }
1769 
1770  fSlaves->Add(slave);
1771  fIntHandler = new TProofInterruptHandler(this);
1772  }
1773 
1774  } else {
1775  delete slave;
1776  // Notify only if verbosity is on: most likely the failure has already been notified
1777  if (gDebug > 0)
1778  Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1779  return kFALSE;
1780  }
1781  }
1782 
1783  return kTRUE;
1784 }
1785 
1786 ////////////////////////////////////////////////////////////////////////////////
1787 /// Close all open slave servers.
1788 /// Client can decide to shutdown the remote session by passing option is 'S'
1789 /// or 's'. Default for clients is detach, if supported. Masters always
1790 /// shutdown the remote counterpart.
1791 
1793 {
1795 
1796  fValid = kFALSE;
1797  if (fSlaves) {
1798  if (fIntHandler)
1799  fIntHandler->Remove();
1800 
1801  TIter nxs(fSlaves);
1802  TSlave *sl = 0;
1803  while ((sl = (TSlave *)nxs()))
1804  sl->Close(opt);
1805 
1806  fActiveSlaves->Clear("nodelete");
1807  fUniqueSlaves->Clear("nodelete");
1808  fAllUniqueSlaves->Clear("nodelete");
1809  fNonUniqueMasters->Clear("nodelete");
1810  fBadSlaves->Clear("nodelete");
1811  fInactiveSlaves->Clear("nodelete");
1812  fSlaves->Delete();
1813  }
1814  }
1815 
1816  {
1818  gROOT->GetListOfSockets()->Remove(this);
1819 
1820  if (fChains) {
1821  while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1822  // remove "chain" from list
1823  chain->SetProof(0);
1824  RemoveChain(chain);
1825  }
1826  }
1827 
1828  if (IsProofd()) {
1829 
1830  gROOT->GetListOfProofs()->Remove(this);
1831  if (gProof && gProof == this) {
1832  // Set previous proofd-related as default
1833  TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1834  while ((gProof = (TProof *)pvp())) {
1835  if (gProof->IsProofd())
1836  break;
1837  }
1838  }
1839  }
1840  }
1841 }
1842 
1843 ////////////////////////////////////////////////////////////////////////////////
1844 /// Create a new TSlave of type TSlave::kSlave.
1845 /// Note: creation of TSlave is private with TProof as a friend.
1846 /// Derived classes must use this function to create slaves.
1847 
1848 TSlave *TProof::CreateSlave(const char *url, const char *ord,
1849  Int_t perf, const char *image, const char *workdir)
1850 {
1851  TSlave* sl = TSlave::Create(url, ord, perf, image,
1852  this, TSlave::kSlave, workdir, 0);
1853 
1854  if (sl->IsValid()) {
1855  sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1856  // must set fParallel to 1 for slaves since they do not
1857  // report their fParallel with a LOG_DONE message
1858  sl->fParallel = 1;
1859  }
1860 
1861  return sl;
1862 }
1863 
1864 
1865 ////////////////////////////////////////////////////////////////////////////////
1866 /// Create a new TSlave of type TSlave::kMaster.
1867 /// Note: creation of TSlave is private with TProof as a friend.
1868 /// Derived classes must use this function to create slaves.
1869 
1870 TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1871  const char *image, const char *msd, Int_t nwk)
1872 {
1873  TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1874  TSlave::kMaster, 0, msd, nwk);
1875 
1876  if (sl->IsValid()) {
1877  sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1878  }
1879 
1880  return sl;
1881 }
1882 
1883 ////////////////////////////////////////////////////////////////////////////////
1884 /// Find slave that has TSocket s. Returns 0 in case slave is not found.
1885 
1887 {
1888  TSlave *sl;
1889  TIter next(fSlaves);
1890 
1891  while ((sl = (TSlave *)next())) {
1892  if (sl->IsValid() && sl->GetSocket() == s)
1893  return sl;
1894  }
1895  return 0;
1896 }
1897 
1898 ////////////////////////////////////////////////////////////////////////////////
1899 /// Add to the fUniqueSlave list the active slaves that have a unique
1900 /// (user) file system image. This information is used to transfer files
1901 /// only once to nodes that share a file system (an image). Submasters
1902 /// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1903 /// list. That list is used to trigger the transferring of files to
1904 /// the submaster's unique slaves without the need to transfer the file
1905 /// to the submaster.
1906 
1908 {
1909  fUniqueSlaves->Clear();
1914 
1916 
1917  while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1918  if (fImage == sl->fImage) {
1919  if (sl->GetSlaveType() == TSlave::kMaster) {
1920  fNonUniqueMasters->Add(sl);
1921  fAllUniqueSlaves->Add(sl);
1922  fAllUniqueMonitor->Add(sl->GetSocket());
1923  }
1924  continue;
1925  }
1926 
1927  TIter next2(fUniqueSlaves);
1928  TSlave *replace_slave = 0;
1929  Bool_t add = kTRUE;
1930  while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1931  if (sl->fImage == sl2->fImage) {
1932  add = kFALSE;
1933  if (sl->GetSlaveType() == TSlave::kMaster) {
1934  if (sl2->GetSlaveType() == TSlave::kSlave) {
1935  // give preference to master
1936  replace_slave = sl2;
1937  add = kTRUE;
1938  } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1939  fNonUniqueMasters->Add(sl);
1940  fAllUniqueSlaves->Add(sl);
1941  fAllUniqueMonitor->Add(sl->GetSocket());
1942  } else {
1943  Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1944  R__ASSERT(0);
1945  }
1946  }
1947  break;
1948  }
1949  }
1950 
1951  if (add) {
1952  fUniqueSlaves->Add(sl);
1953  fAllUniqueSlaves->Add(sl);
1954  fUniqueMonitor->Add(sl->GetSocket());
1955  fAllUniqueMonitor->Add(sl->GetSocket());
1956  if (replace_slave) {
1957  fUniqueSlaves->Remove(replace_slave);
1958  fAllUniqueSlaves->Remove(replace_slave);
1959  fUniqueMonitor->Remove(replace_slave->GetSocket());
1960  fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1961  }
1962  }
1963  }
1964 
1965  // will be actiavted in Collect()
1968 }
1969 
1970 ////////////////////////////////////////////////////////////////////////////////
1971 /// Return number of slaves as described in the config file.
1972 
1974 {
1975  return fSlaves->GetSize();
1976 }
1977 
1978 ////////////////////////////////////////////////////////////////////////////////
1979 /// Return number of active slaves, i.e. slaves that are valid and in
1980 /// the current computing group.
1981 
1983 {
1984  return fActiveSlaves->GetSize();
1985 }
1986 
1987 ////////////////////////////////////////////////////////////////////////////////
1988 /// Return number of inactive slaves, i.e. slaves that are valid but not in
1989 /// the current computing group.
1990 
1992 {
1993  return fInactiveSlaves->GetSize();
1994 }
1995 
1996 ////////////////////////////////////////////////////////////////////////////////
1997 /// Return number of unique slaves, i.e. active slaves that have each a
1998 /// unique different user files system.
1999 
2001 {
2002  return fUniqueSlaves->GetSize();
2003 }
2004 
2005 ////////////////////////////////////////////////////////////////////////////////
2006 /// Return number of bad slaves. This are slaves that we in the config
2007 /// file, but refused to startup or that died during the PROOF session.
2008 
2010 {
2011  return fBadSlaves->GetSize();
2012 }
2013 
2014 ////////////////////////////////////////////////////////////////////////////////
2015 /// Ask the for the statistics of the slaves.
2016 
2018 {
2019  if (!IsValid()) return;
2020 
2023 }
2024 
2025 ////////////////////////////////////////////////////////////////////////////////
2026 /// Get statistics about CPU time, real time and bytes read.
2027 /// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2028 /// and GetBytesRead()
2029 
2031 {
2032  if (fProtocol > 27) {
2033  // This returns the correct result
2034  AskStatistics();
2035  } else {
2036  // AskStatistics is buggy: parse the output of Print()
2037  RedirectHandle_t rh;
2038  gSystem->RedirectOutput(fLogFileName, "a", &rh);
2039  Print();
2040  gSystem->RedirectOutput(0, 0, &rh);
2041  TMacro *mp = GetLastLog();
2042  if (mp) {
2043  // Look for global directories
2044  TIter nxl(mp->GetListOfLines());
2045  TObjString *os = 0;
2046  while ((os = (TObjString *) nxl())) {
2047  TString s(os->GetName());
2048  if (s.Contains("Total MB's processed:")) {
2049  s.ReplaceAll("Total MB's processed:", "");
2050  if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2051  } else if (s.Contains("Total real time used (s):")) {
2052  s.ReplaceAll("Total real time used (s):", "");
2053  if (s.IsFloat()) fRealTime = s.Atof();
2054  } else if (s.Contains("Total CPU time used (s):")) {
2055  s.ReplaceAll("Total CPU time used (s):", "");
2056  if (s.IsFloat()) fCpuTime = s.Atof();
2057  }
2058  }
2059  delete mp;
2060  }
2061  }
2062 
2063  if (verbose) {
2064  Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2065  GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2066  }
2067 }
2068 
2069 ////////////////////////////////////////////////////////////////////////////////
2070 /// Ask the for the number of parallel slaves.
2071 
2073 {
2074  if (!IsValid()) return;
2075 
2078 }
2079 
2080 ////////////////////////////////////////////////////////////////////////////////
2081 /// Ask the master for the list of queries.
2082 
2084 {
2085  if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2086 
2087  Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2089  m << all;
2090  Broadcast(m, kActive);
2092 
2093  // This should have been filled by now
2094  return fQueries;
2095 }
2096 
2097 ////////////////////////////////////////////////////////////////////////////////
2098 /// Number of queries processed by this session
2099 
2101 {
2102  if (fQueries)
2103  return fQueries->GetSize() - fOtherQueries;
2104  return 0;
2105 }
2106 
2107 ////////////////////////////////////////////////////////////////////////////////
2108 /// Set max number of draw queries whose results are saved
2109 
2111 {
2112  if (max > 0) {
2113  if (fPlayer)
2114  fPlayer->SetMaxDrawQueries(max);
2115  fMaxDrawQueries = max;
2116  }
2117 }
2118 
2119 ////////////////////////////////////////////////////////////////////////////////
2120 /// Get max number of queries whose full results are kept in the
2121 /// remote sandbox
2122 
2124 {
2126  m << kFALSE;
2127  Broadcast(m, kActive);
2129 }
2130 
2131 ////////////////////////////////////////////////////////////////////////////////
2132 /// Return pointer to the list of query results in the player
2133 
2135 {
2136  return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2137 }
2138 
2139 ////////////////////////////////////////////////////////////////////////////////
2140 /// Return pointer to the full TQueryResult instance owned by the player
2141 /// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2142 
2144 {
2145  return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2146 }
2147 
2148 ////////////////////////////////////////////////////////////////////////////////
2149 /// Ask the master for the list of queries.
2150 /// Options:
2151 /// "A" show information about all the queries known to the
2152 /// server, i.e. even those processed by other sessions
2153 /// "L" show only information about queries locally available
2154 /// i.e. already retrieved. If "L" is specified, "A" is
2155 /// ignored.
2156 /// "F" show all details available about queries
2157 /// "H" print help menu
2158 /// Default ""
2159 
2161 {
2162  Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2163  if (help) {
2164 
2165  // Help
2166 
2167  Printf("+++");
2168  Printf("+++ Options: \"A\" show all queries known to server");
2169  Printf("+++ \"L\" show retrieved queries");
2170  Printf("+++ \"F\" full listing of query info");
2171  Printf("+++ \"H\" print this menu");
2172  Printf("+++");
2173  Printf("+++ (case insensitive)");
2174  Printf("+++");
2175  Printf("+++ Use Retrieve(<#>) to retrieve the full"
2176  " query results from the master");
2177  Printf("+++ e.g. Retrieve(8)");
2178 
2179  Printf("+++");
2180 
2181  return;
2182  }
2183 
2184  if (!IsValid()) return;
2185 
2186  Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2187 
2188  TObject *pq = 0;
2189  if (!local) {
2190  GetListOfQueries(opt);
2191 
2192  if (!fQueries) return;
2193 
2194  TIter nxq(fQueries);
2195 
2196  // Queries processed by other sessions
2197  if (fOtherQueries > 0) {
2198  Printf("+++");
2199  Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2200  Int_t nq = 0;
2201  while (nq++ < fOtherQueries && (pq = nxq()))
2202  pq->Print(opt);
2203  }
2204 
2205  // Queries processed by this session
2206  Printf("+++");
2207  Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2209  while ((pq = nxq()))
2210  pq->Print(opt);
2211 
2212  } else {
2213 
2214  // Queries processed by this session
2215  Printf("+++");
2216  Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2218 
2219  // Queries available locally
2220  TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2221  if (listlocal) {
2222  Printf("+++");
2223  Printf("+++ Queries available locally: %d", listlocal->GetSize());
2224  TIter nxlq(listlocal);
2225  while ((pq = nxlq()))
2226  pq->Print(opt);
2227  }
2228  }
2229  Printf("+++");
2230 }
2231 
2232 ////////////////////////////////////////////////////////////////////////////////
2233 /// See if the data is ready to be analyzed.
2234 
2235 Bool_t TProof::IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
2236 {
2237  if (!IsValid()) return kFALSE;
2238 
2239  TList submasters;
2240  TIter nextSlave(GetListOfActiveSlaves());
2241  while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2242  if (sl->GetSlaveType() == TSlave::kMaster) {
2243  submasters.Add(sl);
2244  }
2245  }
2246 
2247  fDataReady = kTRUE; //see if any submasters set it to false
2248  fBytesReady = 0;
2249  fTotalBytes = 0;
2250  //loop over submasters and see if data is ready
2251  if (submasters.GetSize() > 0) {
2252  Broadcast(kPROOF_DATA_READY, &submasters);
2253  Collect(&submasters);
2254  }
2255 
2256  bytesready = fBytesReady;
2257  totalbytes = fTotalBytes;
2258 
2259  EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2260 
2261  PDB(kGlobal,2)
2262  Info("IsDataReady", "%lld / %lld (%s)",
2263  bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2264 
2265  return fDataReady;
2266 }
2267 
2268 ////////////////////////////////////////////////////////////////////////////////
2269 /// Send interrupt to master or slave servers.
2270 
2272 {
2273  if (!IsValid()) return;
2274 
2275  TList *slaves = 0;
2276  if (list == kAll) slaves = fSlaves;
2277  if (list == kActive) slaves = fActiveSlaves;
2278  if (list == kUnique) slaves = fUniqueSlaves;
2279  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2280 
2281  if (slaves->GetSize() == 0) return;
2282 
2283  TSlave *sl;
2284  TIter next(slaves);
2285 
2286  while ((sl = (TSlave *)next())) {
2287  if (sl->IsValid()) {
2288 
2289  // Ask slave to progate the interrupt request
2290  sl->Interrupt((Int_t)type);
2291  }
2292  }
2293 }
2294 
2295 ////////////////////////////////////////////////////////////////////////////////
2296 /// Returns number of slaves active in parallel mode. Returns 0 in case
2297 /// there are no active slaves. Returns -1 in case of error.
2298 
2300 {
2301  if (!IsValid()) return -1;
2302 
2303  // iterate over active slaves and return total number of slaves
2304  TIter nextSlave(GetListOfActiveSlaves());
2305  Int_t nparallel = 0;
2306  while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2307  if (sl->GetParallel() >= 0)
2308  nparallel += sl->GetParallel();
2309 
2310  return nparallel;
2311 }
2312 
2313 ////////////////////////////////////////////////////////////////////////////////
2314 /// Returns list of TSlaveInfo's. In case of error return 0.
2315 
2317 {
2318  if (!IsValid()) return 0;
2319 
2320  if (fSlaveInfo == 0) {
2322  fSlaveInfo->SetOwner();
2323  } else {
2324  fSlaveInfo->Delete();
2325  }
2326 
2327  TList masters;
2329  TSlave *slave;
2330 
2331  while ((slave = (TSlave *) next()) != 0) {
2332  if (slave->GetSlaveType() == TSlave::kSlave) {
2333  const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2334  TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2335  name,
2336  slave->GetPerfIdx());
2337  fSlaveInfo->Add(slaveinfo);
2338 
2339  TIter nextactive(GetListOfActiveSlaves());
2340  TSlave *activeslave;
2341  while ((activeslave = (TSlave *) nextactive())) {
2342  if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2343  slaveinfo->SetStatus(TSlaveInfo::kActive);
2344  break;
2345  }
2346  }
2347 
2348  TIter nextbad(GetListOfBadSlaves());
2349  TSlave *badslave;
2350  while ((badslave = (TSlave *) nextbad())) {
2351  if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2352  slaveinfo->SetStatus(TSlaveInfo::kBad);
2353  break;
2354  }
2355  }
2356  // Get system info if supported
2357  if (slave->IsValid()) {
2358  if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2359  MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2360  else
2361  masters.Add(slave);
2362  }
2363 
2364  } else if (slave->GetSlaveType() == TSlave::kMaster) {
2365  if (slave->IsValid()) {
2366  if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2367  MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2368  else
2369  masters.Add(slave);
2370  }
2371  } else {
2372  Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2373  R__ASSERT(0);
2374  }
2375  }
2376  if (masters.GetSize() > 0) Collect(&masters);
2377 
2378  return fSlaveInfo;
2379 }
2380 
2381 ////////////////////////////////////////////////////////////////////////////////
2382 /// Activate slave server list.
2383 
2385 {
2386  TMonitor *mon = fAllMonitor;
2387  mon->DeActivateAll();
2388 
2389  slaves = !slaves ? fActiveSlaves : slaves;
2390 
2391  TIter next(slaves);
2392  TSlave *sl;
2393  while ((sl = (TSlave*) next())) {
2394  if (sl->IsValid())
2395  mon->Activate(sl->GetSocket());
2396  }
2397 }
2398 
2399 ////////////////////////////////////////////////////////////////////////////////
2400 /// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2401 /// monitored by 'mon'.
2402 
2404 {
2405  TMonitor *m = (mon) ? mon : fCurrentMonitor;
2406  if (m) {
2407  if (on)
2408  m->ActivateAll();
2409  else
2410  m->DeActivateAll();
2411  }
2412 }
2413 
2414 ////////////////////////////////////////////////////////////////////////////////
2415 /// Broadcast the group priority to all workers in the specified list. Returns
2416 /// the number of workers the message was successfully sent to.
2417 /// Returns -1 in case of error.
2418 
2419 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2420 {
2421  if (!IsValid()) return -1;
2422 
2423  if (workers->GetSize() == 0) return 0;
2424 
2425  int nsent = 0;
2426  TIter next(workers);
2427 
2428  TSlave *wrk;
2429  while ((wrk = (TSlave *)next())) {
2430  if (wrk->IsValid()) {
2431  if (wrk->SendGroupPriority(grp, priority) == -1)
2432  MarkBad(wrk, "could not send group priority");
2433  else
2434  nsent++;
2435  }
2436  }
2437 
2438  return nsent;
2439 }
2440 
2441 ////////////////////////////////////////////////////////////////////////////////
2442 /// Broadcast the group priority to all workers in the specified list. Returns
2443 /// the number of workers the message was successfully sent to.
2444 /// Returns -1 in case of error.
2445 
2446 Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2447 {
2448  TList *workers = 0;
2449  if (list == kAll) workers = fSlaves;
2450  if (list == kActive) workers = fActiveSlaves;
2451  if (list == kUnique) workers = fUniqueSlaves;
2452  if (list == kAllUnique) workers = fAllUniqueSlaves;
2453 
2454  return BroadcastGroupPriority(grp, priority, workers);
2455 }
2456 
2457 ////////////////////////////////////////////////////////////////////////////////
2458 /// Reset the merge progress notificator
2459 
2461 {
2463 }
2464 
2465 ////////////////////////////////////////////////////////////////////////////////
2466 /// Broadcast a message to all slaves in the specified list. Returns
2467 /// the number of slaves the message was successfully sent to.
2468 /// Returns -1 in case of error.
2469 
2470 Int_t TProof::Broadcast(const TMessage &mess, TList *slaves)
2471 {
2472  if (!IsValid()) return -1;
2473 
2474  if (!slaves || slaves->GetSize() == 0) return 0;
2475 
2476  int nsent = 0;
2477  TIter next(slaves);
2478 
2479  TSlave *sl;
2480  while ((sl = (TSlave *)next())) {
2481  if (sl->IsValid()) {
2482  if (sl->GetSocket()->Send(mess) == -1)
2483  MarkBad(sl, "could not broadcast request");
2484  else
2485  nsent++;
2486  }
2487  }
2488 
2489  return nsent;
2490 }
2491 
2492 ////////////////////////////////////////////////////////////////////////////////
2493 /// Broadcast a message to all slaves in the specified list (either
2494 /// all slaves or only the active slaves). Returns the number of slaves
2495 /// the message was successfully sent to. Returns -1 in case of error.
2496 
2498 {
2499  TList *slaves = 0;
2500  if (list == kAll) slaves = fSlaves;
2501  if (list == kActive) slaves = fActiveSlaves;
2502  if (list == kUnique) slaves = fUniqueSlaves;
2503  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2504 
2505  return Broadcast(mess, slaves);
2506 }
2507 
2508 ////////////////////////////////////////////////////////////////////////////////
2509 /// Broadcast a character string buffer to all slaves in the specified
2510 /// list. Use kind to set the TMessage what field. Returns the number of
2511 /// slaves the message was sent to. Returns -1 in case of error.
2512 
2513 Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2514 {
2515  TMessage mess(kind);
2516  if (str) mess.WriteString(str);
2517  return Broadcast(mess, slaves);
2518 }
2519 
2520 ////////////////////////////////////////////////////////////////////////////////
2521 /// Broadcast a character string buffer to all slaves in the specified
2522 /// list (either all slaves or only the active slaves). Use kind to
2523 /// set the TMessage what field. Returns the number of slaves the message
2524 /// was sent to. Returns -1 in case of error.
2525 
2526 Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2527 {
2528  TMessage mess(kind);
2529  if (str) mess.WriteString(str);
2530  return Broadcast(mess, list);
2531 }
2532 
2533 ////////////////////////////////////////////////////////////////////////////////
2534 /// Broadcast an object to all slaves in the specified list. Use kind to
2535 /// set the TMEssage what field. Returns the number of slaves the message
2536 /// was sent to. Returns -1 in case of error.
2537 
2539 {
2540  TMessage mess(kind);
2541  mess.WriteObject(obj);
2542  return Broadcast(mess, slaves);
2543 }
2544 
2545 ////////////////////////////////////////////////////////////////////////////////
2546 /// Broadcast an object to all slaves in the specified list. Use kind to
2547 /// set the TMEssage what field. Returns the number of slaves the message
2548 /// was sent to. Returns -1 in case of error.
2549 
2551 {
2552  TMessage mess(kind);
2553  mess.WriteObject(obj);
2554  return Broadcast(mess, list);
2555 }
2556 
2557 ////////////////////////////////////////////////////////////////////////////////
2558 /// Broadcast a raw buffer of specified length to all slaves in the
2559 /// specified list. Returns the number of slaves the buffer was sent to.
2560 /// Returns -1 in case of error.
2561 
2562 Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2563 {
2564  if (!IsValid()) return -1;
2565 
2566  if (slaves->GetSize() == 0) return 0;
2567 
2568  int nsent = 0;
2569  TIter next(slaves);
2570 
2571  TSlave *sl;
2572  while ((sl = (TSlave *)next())) {
2573  if (sl->IsValid()) {
2574  if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2575  MarkBad(sl, "could not send broadcast-raw request");
2576  else
2577  nsent++;
2578  }
2579  }
2580 
2581  return nsent;
2582 }
2583 
2584 ////////////////////////////////////////////////////////////////////////////////
2585 /// Broadcast a raw buffer of specified length to all slaves in the
2586 /// specified list. Returns the number of slaves the buffer was sent to.
2587 /// Returns -1 in case of error.
2588 
2589 Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2590 {
2591  TList *slaves = 0;
2592  if (list == kAll) slaves = fSlaves;
2593  if (list == kActive) slaves = fActiveSlaves;
2594  if (list == kUnique) slaves = fUniqueSlaves;
2595  if (list == kAllUnique) slaves = fAllUniqueSlaves;
2596 
2597  return BroadcastRaw(buffer, length, slaves);
2598 }
2599 
2600 ////////////////////////////////////////////////////////////////////////////////
2601 /// Broadcast file to all workers in the specified list. Returns the number of workers
2602 /// the buffer was sent to.
2603 /// Returns -1 in case of error.
2604 
2605 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2606 {
2607  if (!IsValid()) return -1;
2608 
2609  if (wrks->GetSize() == 0) return 0;
2610 
2611  int nsent = 0;
2612  TIter next(wrks);
2613 
2614  TSlave *wrk;
2615  while ((wrk = (TSlave *)next())) {
2616  if (wrk->IsValid()) {
2617  if (SendFile(file, opt, rfile, wrk) < 0)
2618  Error("BroadcastFile",
2619  "problems sending file to worker %s (%s)",
2620  wrk->GetOrdinal(), wrk->GetName());
2621  else
2622  nsent++;
2623  }
2624  }
2625 
2626  return nsent;
2627 }
2628 
2629 ////////////////////////////////////////////////////////////////////////////////
2630 /// Broadcast file to all workers in the specified list. Returns the number of workers
2631 /// the buffer was sent to.
2632 /// Returns -1 in case of error.
2633 
2634 Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2635 {
2636  TList *wrks = 0;
2637  if (list == kAll) wrks = fSlaves;
2638  if (list == kActive) wrks = fActiveSlaves;
2639  if (list == kUnique) wrks = fUniqueSlaves;
2640  if (list == kAllUnique) wrks = fAllUniqueSlaves;
2641 
2642  return BroadcastFile(file, opt, rfile, wrks);
2643 }
2644 
2645 ////////////////////////////////////////////////////////////////////////////////
2646 /// Release the used monitor to be used, making sure to delete newly created
2647 /// monitors.
2648 
2650 {
2651  if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2652  && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2653  delete mon;
2654  }
2655 }
2656 
2657 ////////////////////////////////////////////////////////////////////////////////
2658 /// Collect responses from slave sl. Returns the number of slaves that
2659 /// responded (=1).
2660 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2661 /// which means wait forever).
2662 /// If defined (>= 0) endtype is the message that stops this collection.
2663 
2664 Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2665 {
2666  Int_t rc = 0;
2667 
2668  TMonitor *mon = 0;
2669  if (!sl->IsValid()) return 0;
2670 
2671  if (fCurrentMonitor == fAllMonitor) {
2672  mon = new TMonitor;
2673  } else {
2674  mon = fAllMonitor;
2675  mon->DeActivateAll();
2676  }
2677  mon->Activate(sl->GetSocket());
2678 
2679  rc = Collect(mon, timeout, endtype, deactonfail);
2680  ReleaseMonitor(mon);
2681  return rc;
2682 }
2683 
2684 ////////////////////////////////////////////////////////////////////////////////
2685 /// Collect responses from the slave servers. Returns the number of slaves
2686 /// that responded.
2687 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2688 /// which means wait forever).
2689 /// If defined (>= 0) endtype is the message that stops this collection.
2690 
2691 Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2692 {
2693  Int_t rc = 0;
2694 
2695  TMonitor *mon = 0;
2696 
2697  if (fCurrentMonitor == fAllMonitor) {
2698  mon = new TMonitor;
2699  } else {
2700  mon = fAllMonitor;
2701  mon->DeActivateAll();
2702  }
2703  TIter next(slaves);
2704  TSlave *sl;
2705  while ((sl = (TSlave*) next())) {
2706  if (sl->IsValid())
2707  mon->Activate(sl->GetSocket());
2708  }
2709 
2710  rc = Collect(mon, timeout, endtype, deactonfail);
2711  ReleaseMonitor(mon);
2712  return rc;
2713 }
2714 
2715 ////////////////////////////////////////////////////////////////////////////////
2716 /// Collect responses from the slave servers. Returns the number of slaves
2717 /// that responded.
2718 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2719 /// which means wait forever).
2720 /// If defined (>= 0) endtype is the message that stops this collection.
2721 
2722 Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2723 {
2724  Int_t rc = 0;
2725  TMonitor *mon = 0;
2726 
2727  if (list == kAll) mon = fAllMonitor;
2728  if (list == kActive) mon = fActiveMonitor;
2729  if (list == kUnique) mon = fUniqueMonitor;
2730  if (list == kAllUnique) mon = fAllUniqueMonitor;
2731  if (fCurrentMonitor == mon) {
2732  // Get a copy
2733  mon = new TMonitor(*mon);
2734  }
2735  mon->ActivateAll();
2736 
2737  rc = Collect(mon, timeout, endtype, deactonfail);
2738  ReleaseMonitor(mon);
2739  return rc;
2740 }
2741 
2742 ////////////////////////////////////////////////////////////////////////////////
2743 /// Collect responses from the slave servers. Returns the number of messages
2744 /// received. Can be 0 if there are no active slaves.
2745 /// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2746 /// which means wait forever).
2747 /// If defined (>= 0) endtype is the message that stops this collection.
2748 /// Collect also stops its execution from time to time to check for new
2749 /// workers in Dynamic Startup mode.
2750 
2751 Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2752 {
2753  Int_t collectId = gRandom->Integer(9999);
2754 
2755  PDB(kCollect, 3)
2756  Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2757 
2758  // Reset the status flag and clear the messages in the list, if any
2759  fStatus = 0;
2760  fRecvMessages->Clear();
2761 
2762  Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2763 
2764  if (!mon->GetActive(actto)) return 0;
2765 
2767 
2768  // Used by external code to know what we are monitoring
2769  TMonitor *savedMonitor = 0;
2770  if (fCurrentMonitor) {
2771  savedMonitor = fCurrentMonitor;
2772  fCurrentMonitor = mon;
2773  } else {
2774  fCurrentMonitor = mon;
2775  fBytesRead = 0;
2776  fRealTime = 0.0;
2777  fCpuTime = 0.0;
2778  }
2779 
2780  // We want messages on the main window during synchronous collection,
2781  // but we save the present status to restore it at the end
2782  Bool_t saveRedirLog = fRedirLog;
2783  if (!IsIdle() && !IsSync())
2784  fRedirLog = kFALSE;
2785 
2786  int cnt = 0, rc = 0;
2787 
2788  // Timeout counter
2789  Long_t nto = timeout;
2790  PDB(kCollect, 2)
2791  Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2792 
2793  // On clients, handle Ctrl-C during collection
2794  if (fIntHandler)
2795  fIntHandler->Add();
2796 
2797  // Sockets w/o activity during the last 'sto' millisecs are deactivated
2798  Int_t nact = 0;
2799  Long_t sto = -1;
2800  Int_t nsto = 60;
2801  Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2802  mon->ResetInterrupt();
2803  while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2804 
2805  // Dump last waiting sockets, if in debug mode
2806  PDB(kCollect, 2) {
2807  if (nact < 4) {
2808  TList *al = mon->GetListOfActives();
2809  if (al && al->GetSize() > 0) {
2810  Info("Collect"," %d node(s) still active:", al->GetSize());
2811  TIter nxs(al);
2812  TSocket *xs = 0;
2813  while ((xs = (TSocket *)nxs())) {
2814  TSlave *wrk = FindSlave(xs);
2815  if (wrk)
2816  Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2817  else
2818  Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2819  xs->GetInetAddress().GetPort());
2820  }
2821  }
2822  }
2823  }
2824 
2825  // Preemptive poll for new workers on the master only in Dynamic Mode and only
2826  // during processing (TODO: should work on Top Master only)
2828  ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2831  fLastPollWorkers_s = time(0);
2833  PDB(kCollect, 1)
2834  Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2835  }
2836 
2837  // Wait for a ready socket
2838  PDB(kCollect, 3)
2839  Info("Collect", "Will invoke Select() #%04d", collectId);
2840  TSocket *s = mon->Select(1000);
2841 
2842  if (s && s != (TSocket *)(-1)) {
2843  // Get and analyse the info it did receive
2844  rc = CollectInputFrom(s, endtype, deactonfail);
2845  if (rc == 1 || (rc == 2 && !savedMonitor)) {
2846  // Deactivate it if we are done with it
2847  mon->DeActivate(s);
2848  PDB(kCollect, 2)
2849  Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2850  s, mon->GetActive(),
2851  mon->GetListOfActives()->First());
2852  } else if (rc == 2) {
2853  // This end message was for the saved monitor
2854  // Deactivate it if we are done with it
2855  if (savedMonitor) {
2856  savedMonitor->DeActivate(s);
2857  PDB(kCollect, 2)
2858  Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2859  s, savedMonitor->GetActive(),
2860  savedMonitor->GetListOfActives()->First());
2861  }
2862  }
2863 
2864  // Update counter (if no error occured)
2865  if (rc >= 0)
2866  cnt++;
2867  } else {
2868  // If not timed-out, exit if not stopped or not aborted
2869  // (player exits status is finished in such a case); otherwise,
2870  // we still need to collect the partial output info
2871  if (!s)
2873  mon->DeActivateAll();
2874  // Decrease the timeout counter if requested
2875  if (s == (TSocket *)(-1) && nto > 0)
2876  nto--;
2877  }
2878 
2879  // Check if there are workers with ready output to be sent and ask the first to send it
2880  if (IsMaster() && fWrksOutputReady && fWrksOutputReady->GetSize() > 0) {
2881  // Maximum number of concurrent sendings
2882  Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2883  if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2884  mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2885  TIter nxwr(fWrksOutputReady);
2886  TSlave *wrk = 0;
2887  while (mxws && (wrk = (TSlave *) nxwr())) {
2888  if (!wrk->TestBit(TSlave::kOutputRequested)) {
2889  // Ask worker for output
2890  TMessage sendoutput(kPROOF_SENDOUTPUT);
2891  PDB(kCollect, 2)
2892  Info("Collect", "worker %s was asked to send its output to master",
2893  wrk->GetOrdinal());
2894  if (wrk->GetSocket()->Send(sendoutput) != 1) {
2896  mxws--;
2897  }
2898  } else {
2899  // Count
2900  mxws--;
2901  }
2902  }
2903  }
2904 
2905  // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2906  sto = -1;
2907  if (--nsto <= 0) {
2908  sto = (Long_t) actto;
2909  nsto = 60;
2910  }
2911 
2912  } // end loop over active monitors
2913 
2914  // If timed-out, deactivate the remaining sockets
2915  if (nto == 0) {
2916  TList *al = mon->GetListOfActives();
2917  if (al && al->GetSize() > 0) {
2918  // Notify the name of those which did timeout
2919  Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2920  TIter nxs(al);
2921  TSocket *xs = 0;
2922  while ((xs = (TSocket *)nxs())) {
2923  TSlave *wrk = FindSlave(xs);
2924  if (wrk)
2925  Info("Collect"," %s", wrk->GetName());
2926  else
2927  Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2928  xs->GetInetAddress().GetPort());
2929  }
2930  }
2931  mon->DeActivateAll();
2932  }
2933 
2934  // Deactivate Ctrl-C special handler
2935  if (fIntHandler)
2936  fIntHandler->Remove();
2937 
2938  // make sure group view is up to date
2939  SendGroupView();
2940 
2941  // Restore redirection setting
2942  fRedirLog = saveRedirLog;
2943 
2944  // Restore the monitor
2945  fCurrentMonitor = savedMonitor;
2946 
2948 
2949  PDB(kCollect, 3)
2950  Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2951 
2952  return cnt;
2953 }
2954 
2955 ////////////////////////////////////////////////////////////////////////////////
2956 /// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2957 /// them. Returns the number of new workers found, or <0 on errors.
2958 
2960 {
2961  // Requests for worker updates
2962  Int_t dummy = 0;
2963  TList *reqWorkers = new TList();
2964  reqWorkers->SetOwner(kFALSE);
2965 
2966  if (!TestBit(TProof::kIsMaster)) {
2967  Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2968  return -1;
2969  }
2970  if (!gProofServ) {
2971  Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2972  return -1;
2973  }
2974 
2975  gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2976 
2977  // List of new workers only (TProofNodeInfo)
2978  TList *newWorkers = new TList();
2979  newWorkers->SetOwner(kTRUE);
2980 
2981  TIter next(reqWorkers);
2982  TProofNodeInfo *ni;
2983  TString fullOrd;
2984  while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2985 
2986  // Form the full ordinal
2987  fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2988 
2989  TIter nextInner(fSlaves);
2990  TSlave *sl;
2991  Bool_t found = kFALSE;
2992  while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
2993  if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
2994  found = kTRUE;
2995  break;
2996  }
2997  }
2998 
2999  if (found) delete ni;
3000  else {
3001  newWorkers->Add(ni);
3002  PDB(kGlobal, 1)
3003  Info("PollForNewWorkers", "New worker found: %s:%s",
3004  ni->GetNodeName().Data(), fullOrd.Data());
3005  }
3006  }
3007 
3008  delete reqWorkers; // not owner
3009 
3010  Int_t nNewWorkers = newWorkers->GetEntries();
3011 
3012  // Add the new workers
3013  if (nNewWorkers > 0) {
3014  PDB(kGlobal, 1)
3015  Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
3016  Int_t rv = AddWorkers(newWorkers);
3017  if (rv < 0) {
3018  Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3019  return -1;
3020  }
3021  // Don't delete newWorkers: AddWorkers() will do that
3022  }
3023  else {
3024  PDB(kGlobal, 2)
3025  Info("PollForNewWorkers", "No new worker found");
3026  delete newWorkers;
3027  }
3028 
3029  return nNewWorkers;
3030 }
3031 
3032 ////////////////////////////////////////////////////////////////////////////////
3033 /// Remove links to objects in list 'ol' from gDirectory
3034 
3036 {
3037  if (ol) {
3038  TIter nxo(ol);
3039  TObject *o = 0;
3040  while ((o = nxo()))
3041  gDirectory->RecursiveRemove(o);
3042  }
3043 }
3044 
3045 ////////////////////////////////////////////////////////////////////////////////
3046 /// Collect and analyze available input from socket s.
3047 /// Returns 0 on success, -1 if any failure occurs.
3048 
3050 {
3051  TMessage *mess;
3052 
3053  Int_t recvrc = 0;
3054  if ((recvrc = s->Recv(mess)) < 0) {
3055  PDB(kCollect,2)
3056  Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3057  Bool_t bad = kTRUE;
3058  if (recvrc == -5) {
3059  // Broken connection: try reconnection
3061  if (s->Reconnect() == 0) {
3063  bad = kFALSE;
3064  }
3065  }
3066  if (bad)
3067  MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3068  // Ignore this wake up
3069  return -1;
3070  }
3071  if (!mess) {
3072  // we get here in case the remote server died
3073  MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3074  return -1;
3075  }
3076  Int_t rc = 0;
3077 
3078  Int_t what = mess->What();
3079  TSlave *sl = FindSlave(s);
3080  rc = HandleInputMessage(sl, mess, deactonfail);
3081  if (rc == 1 && (endtype >= 0) && (what != endtype))
3082  // This message was for the base monitor in recursive case
3083  rc = 2;
3084 
3085  // We are done successfully
3086  return rc;
3087 }
3088 
3089 ////////////////////////////////////////////////////////////////////////////////
3090 /// Analyze the received message.
3091 /// Returns 0 on success (1 if this the last message from this socket), -1 if
3092 /// any failure occurs.
3093 
3095 {
3096  char str[512];
3097  TObject *obj;
3098  Int_t rc = 0;
3099 
3100  if (!mess || !sl) {
3101  Warning("HandleInputMessage", "given an empty message or undefined worker");
3102  return -1;
3103  }
3104  Bool_t delete_mess = kTRUE;
3105  TSocket *s = sl->GetSocket();
3106  if (!s) {
3107  Warning("HandleInputMessage", "worker socket is undefined");
3108  return -1;
3109  }
3110 
3111  // The message type
3112  Int_t what = mess->What();
3113 
3114  PDB(kCollect,3)
3115  Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3116 
3117  switch (what) {
3118 
3119  case kMESS_OK:
3120  // Add the message to the list
3121  fRecvMessages->Add(mess);
3122  delete_mess = kFALSE;
3123  break;
3124 
3125  case kMESS_OBJECT:
3126  if (fPlayer) fPlayer->HandleRecvHisto(mess);
3127  break;
3128 
3129  case kPROOF_FATAL:
3130  { TString msg;
3131  if ((mess->BufferSize() > mess->Length()))
3132  (*mess) >> msg;
3133  if (msg.IsNull()) {
3134  MarkBad(s, "received kPROOF_FATAL");
3135  } else {
3136  MarkBad(s, msg);
3137  }
3138  }
3139  if (fProgressDialogStarted) {
3140  // Finalize the progress dialog
3141  Emit("StopProcess(Bool_t)", kTRUE);
3142  }
3143  break;
3144 
3145  case kPROOF_STOP:
3146  // Stop collection from this worker
3147  Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3148  sl->GetOrdinal());
3149  rc = 1;
3150  break;
3151 
3152  case kPROOF_GETTREEHEADER:
3153  // Add the message to the list
3154  fRecvMessages->Add(mess);
3155  delete_mess = kFALSE;
3156  rc = 1;
3157  break;
3158 
3159  case kPROOF_TOUCH:
3160  // send a request for touching the remote admin file
3161  {
3162  sl->Touch();
3163  }
3164  break;
3165 
3166  case kPROOF_GETOBJECT:
3167  // send slave object it asks for
3168  mess->ReadString(str, sizeof(str));
3169  obj = gDirectory->Get(str);
3170  if (obj)
3171  s->SendObject(obj);
3172  else
3173  s->Send(kMESS_NOTOK);
3174  break;
3175 
3176  case kPROOF_GETPACKET:
3177  {
3178  PDB(kGlobal,2)
3179  Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3180  TDSetElement *elem = 0;
3181  elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3182 
3183  if (elem != (TDSetElement*) -1) {
3184  TMessage answ(kPROOF_GETPACKET);
3185  answ << elem;
3186  s->Send(answ);
3187 
3188  while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3189  TPair *p = (TPair*) fWaitingSlaves->First();
3190  s = (TSocket*) p->Key();
3191  TMessage *m = (TMessage*) p->Value();
3192 
3193  elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3194  if (elem != (TDSetElement*) -1) {
3196  a << elem;
3197  s->Send(a);
3198  // remove has to happen via Links because TPair does not have
3199  // a Compare() function and therefore RemoveFirst() and
3200  // Remove(TObject*) do not work
3202  delete p;
3203  delete m;
3204  } else {
3205  break;
3206  }
3207  }
3208  } else {
3209  if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3210  fWaitingSlaves->Add(new TPair(s, mess));
3211  delete_mess = kFALSE;
3212  }
3213  }
3214  break;
3215 
3216  case kPROOF_LOGFILE:
3217  {
3218  Int_t size;
3219  (*mess) >> size;
3220  PDB(kGlobal,2)
3221  Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3222  RecvLogFile(s, size);
3223  }
3224  break;
3225 
3226  case kPROOF_LOGDONE:
3227  (*mess) >> sl->fStatus >> sl->fParallel;
3228  PDB(kCollect,2)
3229  Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3230  sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3231  if (sl->fStatus != 0) {
3232  // Return last nonzero status
3233  fStatus = sl->fStatus;
3234  // Deactivate the worker, if required
3235  if (deactonfail) DeactivateWorker(sl->fOrdinal);
3236  }
3237  // Remove from the workers-ready list
3240  fWrksOutputReady->Remove(sl);
3241  }
3242  rc = 1;
3243  break;
3244 
3245  case kPROOF_GETSTATS:
3246  {
3247  (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3248  >> sl->fWorkDir >> sl->fProofWorkDir;
3249  PDB(kCollect,2)
3250  Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3251  TString img;
3252  if ((mess->BufferSize() > mess->Length()))
3253  (*mess) >> img;
3254  // Set image
3255  if (img.IsNull()) {
3256  if (sl->fImage.IsNull())
3257  sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3258  sl->fProofWorkDir.Data());
3259  } else {
3260  sl->fImage = img;
3261  }
3262  PDB(kGlobal,2)
3263  Info("HandleInputMessage",
3264  "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3265 
3266  fBytesRead += sl->fBytesRead;
3267  fRealTime += sl->fRealTime;
3268  fCpuTime += sl->fCpuTime;
3269  rc = 1;
3270  }
3271  break;
3272 
3273  case kPROOF_GETPARALLEL:
3274  {
3275  Bool_t async = kFALSE;
3276  (*mess) >> sl->fParallel;
3277  if ((mess->BufferSize() > mess->Length()))
3278  (*mess) >> async;
3279  rc = (async) ? 0 : 1;
3280  }
3281  break;
3282 
3283  case kPROOF_CHECKFILE:
3284  { // New servers (>= 5.22) send the status
3285  if ((mess->BufferSize() > mess->Length())) {
3286  (*mess) >> fCheckFileStatus;
3287  } else {
3288  // Form old servers this meant success (failure was signaled with the
3289  // dangerous kPROOF_FATAL)
3290  fCheckFileStatus = 1;
3291  }
3292  rc = 1;
3293  }
3294  break;
3295 
3296  case kPROOF_SENDFILE:
3297  { // New server: signals ending of sendfile operation
3298  rc = 1;
3299  }
3300  break;
3301 
3302  case kPROOF_PACKAGE_LIST:
3303  {
3304  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3305  Int_t type = 0;
3306  (*mess) >> type;
3307  switch (type) {
3311  if (fEnabledPackages) {
3313  } else {
3314  Error("HandleInputMessage",
3315  "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3316  }
3317  break;
3318  case TProof::kListPackages:
3321  if (fAvailablePackages) {
3323  } else {
3324  Error("HandleInputMessage",
3325  "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3326  }
3327  break;
3328  default:
3329  Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3330  }
3331  }
3332  break;
3333 
3334  case kPROOF_SENDOUTPUT:
3335  {
3336  // We start measuring the merging time
3337  fPlayer->SetMerging();
3338 
3339  // Worker is ready to send output: make sure the relevant bit is reset
3341  PDB(kGlobal,2)
3342  Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3343  // Create the list if not yet done
3344  if (!fWrksOutputReady) {
3345  fWrksOutputReady = new TList;
3347  }
3348  fWrksOutputReady->Add(sl);
3349  }
3350  break;
3351 
3352  case kPROOF_OUTPUTOBJECT:
3353  {
3354  // We start measuring the merging time
3355  fPlayer->SetMerging();
3356 
3357  PDB(kGlobal,2)
3358  Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3359  Int_t type = 0;
3360  const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3362  Info("HandleInputMessage", "finalization on %s started ...", prefix);
3364  }
3365 
3366  while ((mess->BufferSize() > mess->Length())) {
3367  (*mess) >> type;
3368  // If a query result header, add it to the player list
3369  if (fPlayer) {
3370  if (type == 0) {
3371  // Retrieve query result instance (output list not filled)
3372  TQueryResult *pq =
3374  if (pq) {
3375  // Add query to the result list in TProofPlayer
3376  fPlayer->AddQueryResult(pq);
3377  fPlayer->SetCurrentQuery(pq);
3378  // And clear the output list, as we start merging a new set of results
3379  if (fPlayer->GetOutputList())
3380  fPlayer->GetOutputList()->Clear();
3381  // Add the unique query tag as TNamed object to the input list
3382  // so that it is available in TSelectors for monitoring
3383  TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3384  if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3385  fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3386  fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3387  } else {
3388  Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3389  }
3390  } else if (type > 0) {
3391  // Read object
3392  TObject *o = mess->ReadObject(TObject::Class());
3393  // Increment counter on the client side
3395  TString msg;
3396  Bool_t changed = kFALSE;
3397  msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3398  if (gProofServ) {
3400  } else if (IsTty() || changed) {
3401  fprintf(stderr, "%s\r", msg.Data());
3402  }
3403  // Add or merge it
3404  if ((fPlayer->AddOutputObject(o) == 1)) {
3405  // Remove the object if it has been merged
3406  SafeDelete(o);
3407  }
3408  if (type > 1) {
3409  // Update the merger progress info
3411  if (TestBit(TProof::kIsClient) && !IsLite()) {
3412  // In PROOFLite this has to be done once only in TProofLite::Process
3414  if (pq) {
3416  // Add input objects (do not override remote settings, if any)
3417  TObject *xo = 0;
3418  TIter nxin(fPlayer->GetInputList());
3419  // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3420  if (!pq->GetInputList()) pq->SetInputList(new TList());
3421  while ((xo = nxin()))
3422  if (!pq->GetInputList()->FindObject(xo->GetName()))
3423  pq->AddInput(xo->Clone());
3424  // If the last object, notify the GUI that the result arrived
3425  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3426  }
3427  // Processing is over
3428  UpdateDialog();
3429  }
3430  }
3431  }
3432  } else {
3433  Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3434  }
3435  }
3436  }
3437  break;
3438 
3439  case kPROOF_OUTPUTLIST:
3440  {
3441  // We start measuring the merging time
3442  fPlayer->SetMerging();
3443 
3444  PDB(kGlobal,2)
3445  Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3446  TList *out = 0;
3447  if (fPlayer) {
3448  if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3449  out = (TList *) mess->ReadObject(TList::Class());
3450  } else {
3451  TQueryResult *pq =
3453  if (pq) {
3454  // Add query to the result list in TProofPlayer
3455  fPlayer->AddQueryResult(pq);
3456  fPlayer->SetCurrentQuery(pq);
3457  // To avoid accidental cleanups from anywhere else
3458  // remove objects from gDirectory and clone the list
3459  out = pq->GetOutputList();
3460  CleanGDirectory(out);
3461  out = (TList *) out->Clone();
3462  // Notify the GUI that the result arrived
3463  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3464  } else {
3465  PDB(kGlobal,2)
3466  Info("HandleInputMessage",
3467  "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3468  }
3469  }
3470  if (out) {
3471  out->SetOwner();
3472  fPlayer->AddOutput(out); // Incorporate the list
3473  SafeDelete(out);
3474  } else {
3475  PDB(kGlobal,2)
3476  Info("HandleInputMessage",
3477  "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3478  }
3479  } else {
3480  Warning("HandleInputMessage",
3481  "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3482  }
3483  // On clients at this point processing is over
3484  if (TestBit(TProof::kIsClient) && !IsLite())
3485  UpdateDialog();
3486  }
3487  break;
3488 
3489  case kPROOF_QUERYLIST:
3490  {
3491  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3492  (*mess) >> fOtherQueries >> fDrawQueries;
3493  if (fQueries) {
3494  fQueries->Delete();
3495  delete fQueries;
3496  fQueries = 0;
3497  }
3498  fQueries = (TList *) mess->ReadObject(TList::Class());
3499  }
3500  break;
3501 
3502  case kPROOF_RETRIEVE:
3503  {
3504  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3505  TQueryResult *pq =
3507  if (pq && fPlayer) {
3508  fPlayer->AddQueryResult(pq);
3509  // Notify the GUI that the result arrived
3510  QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3511  } else {
3512  PDB(kGlobal,2)
3513  Info("HandleInputMessage",
3514  "kPROOF_RETRIEVE: query result missing or player undefined");
3515  }
3516  }
3517  break;
3518 
3519  case kPROOF_MAXQUERIES:
3520  {
3521  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3522  Int_t max = 0;
3523 
3524  (*mess) >> max;
3525  Printf("Number of queries fully kept remotely: %d", max);
3526  }
3527  break;
3528 
3529  case kPROOF_SERVERSTARTED:
3530  {
3531  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3532 
3533  UInt_t tot = 0, done = 0;
3534  TString action;
3535  Bool_t st = kTRUE;
3536 
3537  (*mess) >> action >> tot >> done >> st;
3538 
3539  if (TestBit(TProof::kIsClient)) {
3540  if (tot) {
3541  TString type = (action.Contains("submas")) ? "submasters"
3542  : "workers";
3543  Int_t frac = (Int_t) (done*100.)/tot;
3544  char msg[512] = {0};
3545  if (frac >= 100) {
3546  snprintf(msg, 512, "%s: OK (%d %s) \n",
3547  action.Data(),tot, type.Data());
3548  } else {
3549  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3550  action.Data(), done, tot, frac);
3551  }
3552  if (fSync)
3553  fprintf(stderr,"%s", msg);
3554  else
3555  NotifyLogMsg(msg, 0);
3556  }
3557  // Notify GUIs
3558  StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3559  } else {
3560 
3561  // Just send the message one level up
3563  m << action << tot << done << st;
3564  gProofServ->GetSocket()->Send(m);
3565  }
3566  }
3567  break;
3568 
3569  case kPROOF_DATASET_STATUS:
3570  {
3571  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3572 
3573  UInt_t tot = 0, done = 0;
3574  TString action;
3575  Bool_t st = kTRUE;
3576 
3577  (*mess) >> action >> tot >> done >> st;
3578 
3579  if (TestBit(TProof::kIsClient)) {
3580  if (tot) {
3581  TString type = "files";
3582  Int_t frac = (Int_t) (done*100.)/tot;
3583  char msg[512] = {0};
3584  if (frac >= 100) {
3585  snprintf(msg, 512, "%s: OK (%d %s) \n",
3586  action.Data(),tot, type.Data());
3587  } else {
3588  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3589  action.Data(), done, tot, frac);
3590  }
3591  if (fSync)
3592  fprintf(stderr,"%s", msg);
3593  else
3594  NotifyLogMsg(msg, 0);
3595  }
3596  // Notify GUIs
3597  DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3598  } else {
3599 
3600  // Just send the message one level up
3602  m << action << tot << done << st;
3603  gProofServ->GetSocket()->Send(m);
3604  }
3605  }
3606  break;
3607 
3608  case kPROOF_STARTPROCESS:
3609  {
3610  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3611 
3612  // For Proof-Lite this variable is the number of workers and is set
3613  // by the player
3614  if (!IsLite()) {
3615  fNotIdle = 1;
3616  fIsWaiting = kFALSE;
3617  }
3618 
3619  // Redirect the output, if needed
3620  fRedirLog = (fSync) ? fRedirLog : kTRUE;
3621 
3622  // The signal is used on masters by XrdProofdProtocol to catch
3623  // the start of processing; on clients it allows to update the
3624  // progress dialog
3625  if (!TestBit(TProof::kIsMaster)) {
3626 
3627  // This is the end of preparation
3628  fQuerySTW.Stop();
3630  PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3631 
3632  TString selec;
3633  Int_t dsz = -1;
3634  Long64_t first = -1, nent = -1;
3635  (*mess) >> selec >> dsz >> first >> nent;
3636  // Start or reset the progress dialog
3637  if (!gROOT->IsBatch()) {
3638  if (fProgressDialog &&
3640  if (!fProgressDialogStarted) {
3641  fProgressDialog->ExecPlugin(5, this,
3642  selec.Data(), dsz, first, nent);
3644  } else {
3645  ResetProgressDialog(selec, dsz, first, nent);
3646  }
3647  }
3649  }
3650  }
3651  }
3652  break;
3653 
3654  case kPROOF_ENDINIT:
3655  {
3656  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3657 
3658  if (TestBit(TProof::kIsMaster)) {
3659  if (fPlayer)
3660  fPlayer->SetInitTime();
3661  }
3662  }
3663  break;
3664 
3665  case kPROOF_SETIDLE:
3666  {
3667  PDB(kGlobal,2)
3668  Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3669 
3670  // The session is idle
3671  if (IsLite()) {
3672  if (fNotIdle > 0) {
3673  fNotIdle--;
3674  PDB(kGlobal,2)
3675  Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3676  } else {
3677  Warning("HandleInputMessage",
3678  "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3679  sl->GetOrdinal());
3680  }
3681  } else {
3682  fNotIdle = 0;
3683  // Check if the query has been enqueued
3684  if ((mess->BufferSize() > mess->Length()))
3685  (*mess) >> fIsWaiting;
3686  }
3687  }
3688  break;
3689 
3690  case kPROOF_QUERYSUBMITTED:
3691  {
3692  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3693 
3694  // We have received the sequential number
3695  (*mess) >> fSeqNum;
3696  Bool_t sync = fSync;
3697  if ((mess->BufferSize() > mess->Length()))
3698  (*mess) >> sync;
3699  if (sync != fSync && fSync) {
3700  // The server required to switch to asynchronous mode
3701  Activate();
3702  fSync = kFALSE;
3703  }
3704  DisableGoAsyn();
3705  // Check if the query has been enqueued
3706  fIsWaiting = kTRUE;
3707  // For Proof-Lite this variable is the number of workers and is set by the player
3708  if (!IsLite())
3709  fNotIdle = 1;
3710 
3711  rc = 1;
3712  }
3713  break;
3714 
3715  case kPROOF_SESSIONTAG:
3716  {
3717  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3718 
3719  // We have received the unique tag and save it as name of this object
3720  TString stag;
3721  (*mess) >> stag;
3722  SetName(stag);
3723  // In the TSlave object
3724  sl->SetSessionTag(stag);
3725  // Server may have also sent the group
3726  if ((mess->BufferSize() > mess->Length()))
3727  (*mess) >> fGroup;
3728  // Server may have also sent the user
3729  if ((mess->BufferSize() > mess->Length())) {
3730  TString usr;
3731  (*mess) >> usr;
3732  if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3733  }
3734  }
3735  break;
3736 
3737  case kPROOF_FEEDBACK:
3738  {
3739  PDB(kGlobal,2)
3740  Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3741  TList *out = (TList *) mess->ReadObject(TList::Class());
3742  out->SetOwner();
3743  if (fPlayer)
3744  fPlayer->StoreFeedback(sl, out); // Adopts the list
3745  else
3746  // Not yet ready: stop collect asap
3747  rc = 1;
3748  }
3749  break;
3750 
3751  case kPROOF_AUTOBIN:
3752  {
3753  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3754 
3755  TString name;
3756  Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3757 
3758  (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3759 
3760  if (fPlayer) fPlayer->UpdateAutoBin(name,xmin,xmax,ymin,ymax,zmin,zmax);
3761 
3762  TMessage answ(kPROOF_AUTOBIN);
3763 
3764  answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3765 
3766  s->Send(answ);
3767  }
3768  break;
3769 
3770  case kPROOF_PROGRESS:
3771  {
3772  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3773 
3774  if (GetRemoteProtocol() > 25) {
3775  // New format
3776  TProofProgressInfo *pi = 0;
3777  (*mess) >> pi;
3778  fPlayer->Progress(sl,pi);
3779  } else if (GetRemoteProtocol() > 11) {
3780  Long64_t total, processed, bytesread;
3781  Float_t initTime, procTime, evtrti, mbrti;
3782  (*mess) >> total >> processed >> bytesread
3783  >> initTime >> procTime
3784  >> evtrti >> mbrti;
3785  if (fPlayer)
3786  fPlayer->Progress(sl, total, processed, bytesread,
3787  initTime, procTime, evtrti, mbrti);
3788 
3789  } else {
3790  // Old format
3791  Long64_t total, processed;
3792  (*mess) >> total >> processed;
3793  if (fPlayer)
3794  fPlayer->Progress(sl, total, processed);
3795  }
3796  }
3797  break;
3798 
3799  case kPROOF_STOPPROCESS:
3800  {
3801  // This message is sent from a worker that finished processing.
3802  // We determine whether it was asked to finish by the
3803  // packetizer or stopped during processing a packet
3804  // (by TProof::RemoveWorkers() or by an external signal).
3805  // In the later case call packetizer->MarkBad.
3806  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3807 
3808  Long64_t events = 0;
3809  Bool_t abort = kFALSE;
3811 
3812  if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3813  (*mess) >> status >> abort;
3814  } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3815  (*mess) >> events >> abort;
3816  } else {
3817  (*mess) >> events;
3818  }
3819  if (fPlayer) {
3820  if (fProtocol > 18) {
3821  TList *listOfMissingFiles = 0;
3822  if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3823  listOfMissingFiles = new TList();
3824  listOfMissingFiles->SetName("MissingFiles");
3825  if (fPlayer)
3826  fPlayer->AddOutputObject(listOfMissingFiles);
3827  }
3828  if (fPlayer->GetPacketizer()) {
3829  Int_t ret =
3830  fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3831  if (ret > 0)
3832  fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3833  // This object is now owned by the packetizer
3834  status = 0;
3835  }
3836  if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3837  } else {
3838  fPlayer->AddEventsProcessed(events);
3839  }
3840  }
3841  SafeDelete(status);
3842  if (!TestBit(TProof::kIsMaster))
3843  Emit("StopProcess(Bool_t)", abort);
3844  break;
3845  }
3846 
3847  case kPROOF_SUBMERGER:
3848  {
3849  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3850  HandleSubmerger(mess, sl);
3851  }
3852  break;
3853 
3854  case kPROOF_GETSLAVEINFO:
3855  {
3856  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3857 
3858  Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3859  Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3860  TList* tmpinfo = 0;
3861  (*mess) >> tmpinfo;
3862  if (tmpinfo == 0) {
3863  Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3864  } else {
3865  tmpinfo->SetOwner(kFALSE);
3866  Int_t nentries = tmpinfo->GetSize();
3867  for (Int_t i=0; i<nentries; i++) {
3868  TSlaveInfo* slinfo =
3869  dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3870  if (slinfo) {
3871  // If PROOF-Lite
3872  if (IsLite()) slinfo->fHostName = gSystem->HostName();
3873  // Check if we have already a instance for this worker
3874  TIter nxw(fSlaveInfo);
3875  TSlaveInfo *ourwi = 0;
3876  while ((ourwi = (TSlaveInfo *)nxw())) {
3877  if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3878  ourwi->SetSysInfo(slinfo->GetSysInfo());
3879  ourwi->fHostName = slinfo->GetName();
3880  if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3881  ourwi->fDataDir = slinfo->GetDataDir();
3882  break;
3883  }
3884  }
3885  if (!ourwi) {
3886  fSlaveInfo->Add(slinfo);
3887  } else {
3888  slinfo = ourwi;
3889  }
3890  if (slinfo->fStatus != TSlaveInfo::kBad) {
3891  if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3892  if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3893  }
3894  if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3895  slinfo->fMsd = sl->GetMsd();
3896  }
3897  }
3898  delete tmpinfo;
3899  rc = 1;
3900  }
3901  }
3902  break;
3903 
3904  case kPROOF_VALIDATE_DSET:
3905  {
3906  PDB(kGlobal,2)
3907  Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3908  TDSet* dset = 0;
3909  (*mess) >> dset;
3910  if (!fDSet)
3911  Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3912  else
3913  fDSet->Validate(dset);
3914  delete dset;
3915  }
3916  break;
3917 
3918  case kPROOF_DATA_READY:
3919  {
3920  PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3921  Bool_t dataready = kFALSE;
3922  Long64_t totalbytes, bytesready;
3923  (*mess) >> dataready >> totalbytes >> bytesready;
3924  fTotalBytes += totalbytes;
3925  fBytesReady += bytesready;
3926  if (dataready == kFALSE) fDataReady = dataready;
3927  }
3928  break;
3929 
3930  case kPROOF_PING:
3931  // do nothing (ping is already acknowledged)
3932  break;
3933 
3934  case kPROOF_MESSAGE:
3935  {
3936  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3937 
3938  // We have received the unique tag and save it as name of this object
3939  TString msg;
3940  (*mess) >> msg;
3941  Bool_t lfeed = kTRUE;
3942  if ((mess->BufferSize() > mess->Length()))
3943  (*mess) >> lfeed;
3944 
3945  if (TestBit(TProof::kIsClient)) {
3946 
3947  if (fSync) {
3948  // Notify locally
3949  fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3950  } else {
3951  // Notify locally taking care of redirection, windows logs, ...
3952  NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3953  }
3954  } else {
3955 
3956  // The message is logged for debugging purposes.
3957  fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3958  if (gProofServ) {
3959  // We hide it during normal operations
3961 
3962  // And send the message one level up
3963  gProofServ->SendAsynMessage(msg, lfeed);
3964  }
3965  }
3966  }
3967  break;
3968 
3969  case kPROOF_VERSARCHCOMP:
3970  {
3971  TString vac;
3972  (*mess) >> vac;
3973  PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3974  Int_t from = 0;
3975  TString vers, archcomp;
3976  if (vac.Tokenize(vers, from, "|"))
3977  vac.Tokenize(archcomp, from, "|");
3978  sl->SetArchCompiler(archcomp);
3979  vers.ReplaceAll(":","|");
3980  sl->SetROOTVersion(vers);
3981  }
3982  break;
3983 
3984  default:
3985  {
3986  Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3987  sl->GetOrdinal(), what);
3988  }
3989  break;
3990  }
3991 
3992  // Cleanup
3993  if (delete_mess)
3994  delete mess;
3995 
3996  // We are done successfully
3997  return rc;
3998 }
3999 
4000 ////////////////////////////////////////////////////////////////////////////////
4001 /// Process a message of type kPROOF_SUBMERGER
4002 
4004 {
4005  // Message sub-type
4006  Int_t type = 0;
4007  (*mess) >> type;
4008  TSocket *s = sl->GetSocket();
4009 
4010  switch (type) {
4011  case kOutputSent:
4012  {
4013  if (IsEndMaster()) {
4014  Int_t merger_id = -1;
4015  (*mess) >> merger_id;
4016 
4017  PDB(kSubmerger, 2)
4018  Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4019  sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4020 
4021  if (!fMergers || fMergers->GetSize() <= merger_id) {
4022  Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4023  break;
4024  }
4025  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4026  mi->SetMergedWorker();
4027  if (mi->AreAllWorkersMerged()) {
4028  mi->Deactivate();
4029  if (GetActiveMergersCount() == 0) {
4030  fMergers->Clear();
4031  delete fMergers;
4032  fMergersSet = kFALSE;
4033  fMergersCount = -1;
4034  fLastAssignedMerger = 0;
4035  PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4036  }
4037  }
4038  } else {
4039  PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4040  }
4041  }
4042  break;
4043 
4044  case kMergerDown:
4045  {
4046  Int_t merger_id = -1;
4047  (*mess) >> merger_id;
4048 
4049  PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4050 
4051  if (!fMergers || fMergers->GetSize() <= merger_id) {
4052  Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4053  break;
4054  }
4055 
4056  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4057  if (!mi->IsActive()) {
4058  break;
4059  } else {
4060  mi->Deactivate();
4061  }
4062 
4063  // Stop the invalid merger in the case it is still listening
4064  TMessage stop(kPROOF_SUBMERGER);
4065  stop << Int_t(kStopMerging);
4066  stop << 0;
4067  s->Send(stop);
4068 
4069  // Ask for results from merger (only original results from this node as worker are returned)
4070  AskForOutput(mi->GetMerger());
4071 
4072  // Ask for results from all workers assigned to this merger
4073  TIter nxo(mi->GetWorkers());
4074  TObject * o = 0;
4075  while ((o = nxo())) {
4076  AskForOutput((TSlave *)o);
4077  }
4078  PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4079  }
4080  break;
4081 
4082  case kOutputSize:
4083  {
4084  if (IsEndMaster()) {
4085  PDB(kSubmerger, 2)
4086  Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4087 
4088  const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4089  if (!fFinalizationRunning) {
4090  Info("HandleSubmerger", "finalization on %s started ...", prefix);
4092  }
4093 
4094  Int_t output_size = 0;
4095  Int_t merging_port = 0;
4096  (*mess) >> output_size >> merging_port;
4097 
4098  PDB(kSubmerger, 2) Info("HandleSubmerger",
4099  "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4100  sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4101  TString msg;
4102  if (!fMergersSet) {
4103 
4105 
4106  // First pass - setting number of mergers according to user or dynamically
4107  fMergersCount = -1; // No mergers used if not set by user
4108  TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4109  if (mc) fMergersCount = mc->GetVal(); // Value set by user
4110  TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4111  if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4112 
4113  // Mergers count specified by user but not valid
4114  if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4115  msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4116  prefix, fMergersCount, activeWorkers);
4117  if (gProofServ)
4119  else
4120  Printf("%s",msg.Data());
4121  fMergersCount = 0;
4122  }
4123  // Mergers count will be set dynamically
4124  if ((fMergersCount == 0) && (!fMergersByHost)) {
4125  if (activeWorkers > 1) {
4126  fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4127  if (activeWorkers / fMergersCount < 2)
4128  fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4129  }
4130  if (fMergersCount > 1)
4131  msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4132  prefix, fMergersCount, activeWorkers);
4133  else {
4134  msg.Form("%s: No mergers will be used for %d workers",
4135  prefix, activeWorkers);
4136  fMergersCount = -1;
4137  }
4138  if (gProofServ)
4140  else
4141  Printf("%s",msg.Data());
4142  } else if (fMergersByHost) {
4143  // We force mergers at host level to minimize network traffic
4144  if (activeWorkers > 1) {
4145  fMergersCount = 0;
4146  THashList hosts;
4147  TIter nxwk(fSlaves);
4148  TObject *wrk = 0;
4149  while ((wrk = nxwk())) {
4150  if (!hosts.FindObject(wrk->GetName())) {
4151  hosts.Add(new TObjString(wrk->GetName()));
4152  fMergersCount++;
4153  }
4154  }
4155  }
4156  if (fMergersCount > 1)
4157  msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4158  prefix, fMergersCount, activeWorkers);
4159  else {
4160  msg.Form("%s: No mergers will be used for %d workers",
4161  prefix, activeWorkers);
4162  fMergersCount = -1;
4163  }
4164  if (gProofServ)
4166  else
4167  Printf("%s",msg.Data());
4168  } else {
4169  msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4170  prefix, fMergersCount, activeWorkers);
4171  if (gProofServ)
4173  else
4174  Printf("%s",msg.Data());
4175  }
4176 
4177  // We started merging; we call it here because fMergersCount is still the original number
4178  // and can be saved internally
4180 
4181  // Update merger counters (new workers are not yet active)
4183 
4184  if (fMergersCount > 0) {
4185 
4186  fMergers = new TList();
4187  fLastAssignedMerger = 0;
4188  // Total number of workers, which will not act as mergers ('pure workers')
4189  fWorkersToMerge = (activeWorkers - fMergersCount);
4190  // Establish the first merger
4191  if (!CreateMerger(sl, merging_port)) {
4192  // Cannot establish first merger
4193  AskForOutput(sl);
4194  fWorkersToMerge--;
4195  fMergersCount--;
4196  }
4198  } else {
4199  AskForOutput(sl);
4200  }
4201  fMergersSet = kTRUE;
4202  } else {
4203  // Multiple pass
4204  if (fMergersCount == -1) {
4205  // No mergers. Workers send their outputs directly to master
4206  AskForOutput(sl);
4207  } else {
4208  if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4209  RedirectWorker(s, sl, output_size);
4210  fRedirectNext--;
4211  } else {
4212  Bool_t newMerger = kTRUE;
4213  if (fMergersByHost) {
4214  TIter nxmg(fMergers);
4215  TMergerInfo *mgi = 0;
4216  while ((mgi = (TMergerInfo *) nxmg())) {
4217  if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4218  newMerger = kFALSE;
4219  break;
4220  }
4221  }
4222  }
4223  if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4224  // Still not enough mergers established
4225  if (!CreateMerger(sl, merging_port)) {
4226  // Cannot establish a merger
4227  AskForOutput(sl);
4228  fWorkersToMerge--;
4229  fMergersCount--;
4230  }
4231  } else
4232  RedirectWorker(s, sl, output_size);
4233  }
4234  }
4235  }
4236  } else {
4237  Error("HandleSubMerger","kOutputSize received not on endmaster!");
4238  }
4239  }
4240  break;
4241  }
4242 }
4243 
4244 ////////////////////////////////////////////////////////////////////////////////
4245 /// Redirect output of worker sl to some merger
4246 
4247 void TProof::RedirectWorker(TSocket *s, TSlave * sl, Int_t output_size)
4248 {
4249  Int_t merger_id = -1;
4250 
4251  if (fMergersByHost) {
4252  for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4253  TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4254  if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4255  merger_id = i;
4256  break;
4257  }
4258  }
4259  } else {
4260  merger_id = FindNextFreeMerger();
4261  }
4262 
4263  if (merger_id == -1) {
4264  // No free merger (probably it had crashed before)
4265  AskForOutput(sl);
4266  } else {
4267  TMessage sendoutput(kPROOF_SUBMERGER);
4268  sendoutput << Int_t(kSendOutput);
4269  PDB(kSubmerger, 2)
4270  Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4271 
4272  PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4273  if (!fMergers || fMergers->GetSize() <= merger_id) {
4274  Error("RedirectWorker", "#%d not in list ", merger_id);
4275  return;
4276  }
4277  TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4278 
4279  TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4280  sendoutput << merger_id;
4281  sendoutput << hname;
4282  sendoutput << mi->GetPort();
4283  s->Send(sendoutput);
4284  mi->AddMergedObjects(output_size);
4285  mi->AddWorker(sl);
4286  }
4287 }
4288 
4289 ////////////////////////////////////////////////////////////////////////////////
4290 /// Return a merger, which is both active and still accepts some workers to be
4291 /// assigned to it. It works on the 'round-robin' basis.
4292 
4294 {
4295  while (fLastAssignedMerger < fMergers->GetSize() &&
4296  (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4297  ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4299  }
4300 
4301  if (fLastAssignedMerger == fMergers->GetSize()) {
4302  fLastAssignedMerger = 0;
4303  } else {
4304  return fLastAssignedMerger++;
4305  }
4306 
4307  while (fLastAssignedMerger < fMergers->GetSize() &&
4308  (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4309  ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4311  }
4312 
4313  if (fLastAssignedMerger == fMergers->GetSize()) {
4314  return -1;
4315  } else {
4316  return fLastAssignedMerger++;
4317  }
4318 }
4319 
4320 ////////////////////////////////////////////////////////////////////////////////
4321 /// Master asks for output from worker sl
4322 
4324 {
4325  TMessage sendoutput(kPROOF_SUBMERGER);
4326  sendoutput << Int_t(kSendOutput);
4327 
4328  PDB(kSubmerger, 2) Info("AskForOutput",
4329  "worker %s was asked to send its output to master",
4330  sl->GetOrdinal());
4331 
4332  sendoutput << -1;
4333  sendoutput << TString("master");
4334  sendoutput << -1;
4335  sl->GetSocket()->Send(sendoutput);
4336  if (IsLite()) fMergePrg.IncreaseNWrks();
4337 }
4338 
4339 ////////////////////////////////////////////////////////////////////////////////
4340 /// Final update of the progress dialog
4341 
4343 {
4344  if (!fPlayer) return;
4345 
4346  // Handle abort ...
4348  if (fSync)
4349  Info("UpdateDialog",
4350  "processing was aborted - %lld events processed",
4352 
4353  if (GetRemoteProtocol() > 11) {
4354  // New format
4355  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4356  } else {
4358  }
4359  Emit("StopProcess(Bool_t)", kTRUE);
4360  }
4361 
4362  // Handle stop ...
4364  if (fSync)
4365  Info("UpdateDialog",
4366  "processing was stopped - %lld events processed",
4368 
4369  if (GetRemoteProtocol() > 25) {
4370  // New format
4371  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4372  } else if (GetRemoteProtocol() > 11) {
4373  Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4374  } else {
4376  }
4377  Emit("StopProcess(Bool_t)", kFALSE);
4378  }
4379 
4380  // Final update of the dialog box
4381  if (GetRemoteProtocol() > 25) {
4382  // New format
4383  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4384  10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4385  (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4386  } else if (GetRemoteProtocol() > 11) {
4387  // New format
4388  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4389  7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4390  (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4391  } else {
4392  EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4393  }
4394 }
4395 
4396 ////////////////////////////////////////////////////////////////////////////////
4397 /// Activate the a-sync input handler.
4398 
4400 {
4401  TIter next(fSlaves);
4402  TSlave *sl;
4403 
4404  while ((sl = (TSlave*) next()))
4405  if (sl->GetInputHandler())
4406  sl->GetInputHandler()->Add();
4407 }
4408 
4409 ////////////////////////////////////////////////////////////////////////////////
4410 /// De-activate a-sync input handler.
4411 
4413 {
4414  TIter next(fSlaves);
4415  TSlave *sl;
4416 
4417  while ((sl = (TSlave*) next()))
4418  if (sl->GetInputHandler())
4419  sl->GetInputHandler()->Remove();
4420 }
4421 
4422 ////////////////////////////////////////////////////////////////////////////////
4423 /// Get the active mergers count
4424 
4426 {
4427  if (!fMergers) return 0;
4428 
4429  Int_t active_mergers = 0;
4430 
4431  TIter mergers(fMergers);
4432  TMergerInfo *mi = 0;
4433  while ((mi = (TMergerInfo *)mergers())) {
4434  if (mi->IsActive()) active_mergers++;
4435  }
4436 
4437  return active_mergers;
4438 }
4439 
4440 ////////////////////////////////////////////////////////////////////////////////
4441 /// Create a new merger
4442 
4444 {
4445  PDB(kSubmerger, 2)
4446  Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4447 
4448  PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4449 
4450  if (port <= 0) {
4451  PDB(kSubmerger,2)
4452  Info("CreateMerger", "cannot create merger on port %d - exit", port);
4453  return kFALSE;
4454  }
4455 
4456  Int_t workers = -1;
4457  if (!fMergersByHost) {
4458  Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4459  // Number of pure workers, which are not simply divisible by mergers
4460  Int_t rest = fWorkersToMerge % mergersToCreate;
4461  // We add one more worker for each of the first 'rest' mergers being established
4462  if (rest > 0 && fMergers->GetSize() < rest) {
4463  rest = 1;
4464  } else {
4465  rest = 0;
4466  }
4467  workers = (fWorkersToMerge / mergersToCreate) + rest;
4468  } else {
4469  Int_t workersOnHost = 0;
4470  for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4471  if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4472  }
4473  workers = workersOnHost - 1;
4474  }
4475 
4476  TString msg;
4477  msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4478 
4479  if (gProofServ) {
4481  } else {
4482  Printf("%s",msg.Data());
4483  }
4484  TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4485 
4486  TMessage bemerger(kPROOF_SUBMERGER);
4487  bemerger << Int_t(kBeMerger);
4488  bemerger << fMergers->GetSize();
4489  bemerger << workers;
4490  sl->GetSocket()->Send(bemerger);
4491 
4492  PDB(kSubmerger,2) Info("CreateMerger",
4493  "merger #%d (port: %d) for %d workers started",
4494  fMergers->GetSize(), port, workers);
4495 
4496  fMergers->Add(merger);
4497  fWorkersToMerge = fWorkersToMerge - workers;
4498 
4499  fRedirectNext = workers / 2;
4500 
4501  PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4502  return kTRUE;
4503 }
4504 
4505 ////////////////////////////////////////////////////////////////////////////////
4506 /// Add a bad slave server to the bad slave list and remove it from
4507 /// the active list and from the two monitor objects. Assume that the work
4508 /// done by this worker was lost and ask packerizer to reassign it.
4509 
4510 void TProof::MarkBad(TSlave *wrk, const char *reason)
4511 {
4513 
4514 
4515  // We may have been invalidated in the meanwhile: nothing to do in such a case
4516  if (!IsValid()) return;
4517 
4518  if (!wrk) {
4519  Error("MarkBad", "worker instance undefined: protocol error? ");
4520  return;
4521  }
4522 
4523  // Local URL
4524  static TString thisurl;
4525  if (thisurl.IsNull()) {
4526  if (IsMaster()) {
4527  Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4528  thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4529  if (port > 0) thisurl += TString::Format(":%d", port);
4530  } else {
4531  thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4532  }
4533  }
4534 
4535  if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4536  // Message for notification
4537  const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4538  TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4539  TString msg;
4540  msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4541  src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4542  (reason && strlen(reason)) ? reason : "unknown");
4543  Info("MarkBad", "%s", msg.Data());
4544  // Notify one level up, if the case
4545  // Add some hint for diagnostics
4546  if (gProofServ) {
4547  msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4548  wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4549  } else {
4550  msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4551  }
4552  msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4553  msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4554  msg += TString::Format(" +++\n");
4555  if (gProofServ) {
4556  msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4557  "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4559  } else {
4560  msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4561  "Display(\"*\")\n\n", thisurl.Data());
4562  Printf("%s", msg.Data());
4563  }
4564  } else if (reason) {
4565  if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4566  Info("MarkBad", "worker %s at %s:%d asked to terminate",
4567  wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4568  }
4569  }
4570 
4571  if (IsMaster() && reason) {
4572  if (strcmp(reason, kPROOF_TerminateWorker)) {
4573  // if the reason was not a planned termination
4574  TList *listOfMissingFiles = 0;
4575  if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4576  listOfMissingFiles = new TList();
4577  listOfMissingFiles->SetName("MissingFiles");
4578  if (fPlayer)
4579  fPlayer->AddOutputObject(listOfMissingFiles);
4580  }
4581  // If a query is being processed, assume that the work done by
4582  // the worker was lost and needs to be reassigned.
4583  TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4584  if (packetizer) {
4585  // the worker was lost so do resubmit the packets
4586  packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4587  }
4588  } else {
4589  // Tell the coordinator that we are gone
4590  if (gProofServ) {
4591  TString ord(wrk->GetOrdinal());
4592  Int_t id = ord.Last('.');
4593  if (id != kNPOS) ord.Remove(0, id+1);
4594  gProofServ->ReleaseWorker(ord.Data());
4595  }
4596  }
4597  } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4598  // We are invalid after this
4599  fValid = kFALSE;
4600  }
4601 
4602  fActiveSlaves->Remove(wrk);
4603  FindUniqueSlaves();
4604 
4605  fAllMonitor->Remove(wrk->GetSocket());
4606  fActiveMonitor->Remove(wrk->GetSocket());
4607 
4609 
4610  if (IsMaster()) {
4611  if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4612  // if the reason was a planned termination then delete the worker and
4613  // remove it from all the lists
4614  fSlaves->Remove(wrk);
4615  fBadSlaves->Remove(wrk);
4616  fActiveSlaves->Remove(wrk);
4617  fInactiveSlaves->Remove(wrk);
4618  fUniqueSlaves->Remove(wrk);
4619  fAllUniqueSlaves->Remove(wrk);
4620  fNonUniqueMasters->Remove(wrk);
4621 
4622  // we add it to the list of terminated slave infos instead, so that it
4623  // stays available in the .workers persistent file
4624  TSlaveInfo *si = new TSlaveInfo(
4625  wrk->GetOrdinal(),
4626  Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4627  0, "", wrk->GetWorkDir());
4629  else delete si;
4630 
4631  delete wrk;
4632  } else {
4633  fBadSlaves->Add(wrk);
4634  fActiveSlaves->Remove(wrk);
4635  fUniqueSlaves->Remove(wrk);
4636  fAllUniqueSlaves->Remove(wrk);
4637  fNonUniqueMasters->Remove(wrk);
4639  wrk->Close();
4640  // Update the mergers count, if needed
4641  if (fMergersSet) {
4642  Int_t mergersCount = -1;
4643  TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4644  if (mc) mergersCount = mc->GetVal(); // Value set by user
4645  // Mergers count is set dynamically: recalculate it
4646  if (mergersCount == 0) {
4648  if (activeWorkers > 1) {
4649  fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4650  if (activeWorkers / fMergersCount < 2)
4651  fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4652  }
4653  }
4654  }
4655  }
4656 
4657  // Update session workers files
4658  SaveWorkerInfo();
4659  } else {
4660  // On clients the proof session should be removed from the lists
4661  // and deleted, since it is not valid anymore
4662  fSlaves->Remove(wrk);
4663  if (fManager)
4664  fManager->DiscardSession(this);
4665  }
4666 }
4667 
4668 ////////////////////////////////////////////////////////////////////////////////
4669 /// Add slave with socket s to the bad slave list and remove if from
4670 /// the active list and from the two monitor objects.
4671 
4672 void TProof::MarkBad(TSocket *s, const char *reason)
4673 {
4675 
4676  // We may have been invalidated in the meanwhile: nothing to do in such a case
4677  if (!IsValid()) return;
4678 
4679  TSlave *wrk = FindSlave(s);
4680  MarkBad(wrk, reason);
4681 }
4682 
4683 ////////////////////////////////////////////////////////////////////////////////
4684 /// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4685 
4687 {
4688  if (!wrk) {
4689  Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4690  return;
4691  }
4692 
4693  // Send stop message
4694  if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4695  TMessage mess(kPROOF_STOP);
4696  wrk->GetSocket()->Send(mess);
4697  } else {
4698  if (gDebug > 0)
4699  Info("TerminateWorker", "connection to worker is already down: cannot"
4700  " send termination message");
4701  }
4702 
4703  // This is a bad worker from now on
4705 }
4706 
4707 ////////////////////////////////////////////////////////////////////////////////
4708 /// Ask an active worker 'ord' to terminate, i.e. to shutdown
4709 
4710 void TProof::TerminateWorker(const char *ord)
4711 {
4712  if (ord && strlen(ord) > 0) {
4713  Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4714  if (IsMaster()) {
4715  TIter nxw(fSlaves);
4716  TSlave *wrk = 0;
4717  while ((wrk = (TSlave *)nxw())) {
4718  if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4719  TerminateWorker(wrk);
4720  if (!all) break;
4721  }
4722  }
4723  } else {
4724  TMessage mess(kPROOF_STOP);
4725  mess << TString(ord);
4726  Broadcast(mess);
4727  }
4728  }
4729 }
4730 
4731 ////////////////////////////////////////////////////////////////////////////////
4732 /// Ping PROOF. Returns 1 if master server responded.
4733 
4735 {
4736  return Ping(kActive);
4737 }
4738 
4739 ////////////////////////////////////////////////////////////////////////////////
4740 /// Ping PROOF slaves. Returns the number of slaves that responded.
4741 
4743 {
4744  TList *slaves = 0;
4745  if (list == kAll) slaves = fSlaves;
4746  if (list == kActive) slaves = fActiveSlaves;
4747  if (list == kUnique) slaves = fUniqueSlaves;
4748  if (list == kAllUnique) slaves = fAllUniqueSlaves;
4749 
4750  if (slaves->GetSize() == 0) return 0;
4751 
4752  int nsent = 0;
4753  TIter next(slaves);
4754 
4755  TSlave *sl;
4756  while ((sl = (TSlave *)next())) {
4757  if (sl->IsValid()) {
4758  if (sl->Ping() == -1) {
4759  MarkBad(sl, "ping unsuccessful");
4760  } else {
4761  nsent++;
4762  }
4763  }
4764  }
4765 
4766  return nsent;
4767 }
4768 
4769 ////////////////////////////////////////////////////////////////////////////////
4770 /// Ping PROOF slaves. Returns the number of slaves that responded.
4771 
4773 {
4774  TList *slaves = fSlaves;
4775 
4776  if (slaves->GetSize() == 0) return;
4777 
4778  TIter next(slaves);
4779 
4780  TSlave *sl;
4781  while ((sl = (TSlave *)next())) {
4782  if (sl->IsValid()) {
4783  sl->Touch();
4784  }
4785  }
4786 
4787  return;
4788 }
4789 
4790 ////////////////////////////////////////////////////////////////////////////////
4791 /// Print status of PROOF cluster.
4792 
4793 void TProof::Print(Option_t *option) const
4794 {
4795  TString secCont;
4796 
4797  if (TestBit(TProof::kIsClient)) {
4798  Printf("Connected to: %s (%s)", GetMaster(),
4799  IsValid() ? "valid" : "invalid");
4800  Printf("Port number: %d", GetPort());
4801  Printf("User: %s", GetUser());
4802  Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4803  Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4805  TSlave *sl = (TSlave *)fActiveSlaves->First();
4806  if (sl) {
4807  TString sc;
4808  if (sl->GetSocket()->GetSecContext())
4809  Printf("Security context: %s",
4810  sl->GetSocket()->GetSecContext()->AsString(sc));
4811  Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4812  } else {
4813  Printf("Security context: Error - No connection");
4814  Printf("Proofd protocol version: Error - No connection");
4815  }
4816  Printf("Client protocol version: %d", GetClientProtocol());
4817  Printf("Remote protocol version: %d", GetRemoteProtocol());
4818  Printf("Log level: %d", GetLogLevel());
4819  Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4820  Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4821  if (IsValid())
4822  const_cast<TProof*>(this)->SendPrint(option);
4823  } else {
4824  const_cast<TProof*>(this)->AskStatistics();
4825  if (IsParallel())
4826  Printf("*** Master server %s (parallel mode, %d workers):",
4828  else
4829  Printf("*** Master server %s (sequential mode):",
4830  gProofServ->GetOrdinal());
4831 
4832  Printf("Master host name: %s", gSystem->HostName());
4833  Printf("Port number: %d", GetPort());
4834  if (strlen(gProofServ->GetGroup()) > 0) {
4835  Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4836  } else {
4837  Printf("User: %s", GetUser());
4838  }
4839  TString ver;
4840  ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4841  if (gSystem->Getenv("ROOTVERSIONTAG"))
4842  ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4843  Printf("ROOT version|rev|tag: %s", ver.Data());
4844  Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4846  Printf("Protocol version: %d", GetClientProtocol());
4847  Printf("Image name: %s", GetImage());
4848  Printf("Working directory: %s", gSystem->WorkingDirectory());
4849  Printf("Config directory: %s", GetConfDir());
4850  Printf("Config file: %s", GetConfFile());
4851  Printf("Log level: %d", GetLogLevel());
4852  Printf("Number of workers: %d", GetNumberOfSlaves());
4853  Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4854  Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4855  Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4856  Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4857  Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4858  Printf("Total real time used (s): %.3f", GetRealTime());
4859  Printf("Total CPU time used (s): %.3f", GetCpuTime());
4860  if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4861  Printf("List of workers:");
4862  TList masters;
4863  TIter nextslave(fSlaves);
4864  while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4865  if (!sl->IsValid()) continue;
4866 
4867  if (sl->GetSlaveType() == TSlave::kSlave) {
4868  sl->Print(option);
4869  } else if (sl->GetSlaveType() == TSlave::kMaster) {
4870  TMessage mess(kPROOF_PRINT);
4871  mess.WriteString(option);
4872  if (sl->GetSocket()->Send(mess) == -1)
4873  const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4874  else
4875  masters.Add(sl);
4876  } else {
4877  Error("Print", "TSlave is neither Master nor Worker");
4878  R__ASSERT(0);
4879  }
4880  }
4881  const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4882  }
4883  }
4884 }
4885 
4886 ////////////////////////////////////////////////////////////////////////////////
4887 /// Extract from opt information about output handling settings.
4888 /// The understood keywords are:
4889 /// of=<file>, outfile=<file> output file location
4890 /// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4891 /// mutually exclusive,execution stops
4892 /// if both are found)
4893 /// sft[=<opt>], savetofile[=<opt>] control saving to file
4894 ///
4895 /// For 'mvf', the <opt> integer has the following meaning:
4896 /// <opt> = <how>*10 + <force>
4897 /// <force> = 0 save to file if memory threshold is reached
4898 /// (the memory threshold is set by the cluster
4899 /// admin); in case an output file is defined, the
4900 /// files are merged at the end;
4901 /// 1 save results to file.
4902 /// <how> = 0 save at the end of the query
4903 /// 1 save results after each packet (to reduce the
4904 /// loss in case of crash).
4905 ///
4906 /// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4907 /// to save results after each packet.
4908 ///
4909 /// The separator from the next option is either a ' ' or a ';'
4910 ///
4911 /// All recognized settings are removed from the input string opt.
4912 /// If action == 0, set up the output file accordingly, if action == 1 clean related
4913 /// output file settings.
4914 /// If the final target file is local then 'target' is set to the final local path
4915 /// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4916 ///
4917 /// Output file settings are in the form
4918 ///
4919 /// <previous_option>of=name <next_option>
4920 /// <previous_option>outfile=name,...;<next_option>
4921 ///
4922 /// The separator from the next option is either a ' ' or a ';'
4923 /// Called interanally by TProof::Process.
4924 ///
4925 /// Returns 0 on success, -1 on error.
4926 
4928 {
4929  TString outfile, dsname, stfopt;
4930  if (action == 0) {
4931  TString tagf, tagd, tags, oo;
4932  Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4933  while (opt.Tokenize(oo, from, "[; ]")) {
4934  if (oo.BeginsWith("of=")) {
4935  tagf = "of=";
4936  iof = opt.Index(tagf);
4937  } else if (oo.BeginsWith("outfile=")) {
4938  tagf = "outfile=";
4939  iof = opt.Index(tagf);
4940  } else if (oo.BeginsWith("ds")) {
4941  tagd = "ds";
4942  iod = opt.Index(tagd);
4943  } else if (oo.BeginsWith("dataset")) {
4944  tagd = "dataset";
4945  iod = opt.Index(tagd);
4946  } else if (oo.BeginsWith("stf")) {
4947  tags = "stf";
4948  ios = opt.Index(tags);
4949  } else if (oo.BeginsWith("savetofile")) {
4950  tags = "savetofile";
4951  ios = opt.Index(tags);
4952  }
4953  }
4954  // Check consistency
4955  if (iof != kNPOS && iod != kNPOS) {
4956  Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4957  return -1;
4958  }
4959 
4960  // Check output file first
4961  if (iof != kNPOS) {
4962  from = iof + tagf.Length();
4963  if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4964  Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4965  return -1;
4966  }
4967  // For removal from original options string
4968  tagf += outfile;
4969  }
4970  // Check dataset
4971  if (iod != kNPOS) {
4972  from = iod + tagd.Length();
4973  if (!opt.Tokenize(dsname, from, "[; ]"))
4974  if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4975  // For removal from original options string
4976  tagd += dsname;
4977  // The name may be empty or beginning with a '='
4978  if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4979  if (dsname.Contains("|V")) {
4980  target = "ds|V";
4981  dsname.ReplaceAll("|V", "");
4982  }
4983  if (dsname.IsNull()) dsname = "dataset_<qtag>";
4984  }
4985  // Check stf
4986  if (ios != kNPOS) {
4987  from = ios + tags.Length();
4988  if (!opt.Tokenize(stfopt, from, "[; ]"))
4989  if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
4990  // For removal from original options string
4991  tags += stfopt;
4992  // It must be digit
4993  if (!stfopt.IsNull()) {
4994  if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
4995  if (!stfopt.IsNull()) {
4996  if (!stfopt.IsDigit()) {
4997  Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
4998  return -1;
4999  }
5000  } else {
5001  // Default
5002  stfopt = "1";
5003  }
5004  } else {
5005  // Default
5006  stfopt = "1";
5007  }
5008  }
5009  // Remove from original options string
5010  opt.ReplaceAll(tagf, "");
5011  opt.ReplaceAll(tagd, "");
5012  opt.ReplaceAll(tags, "");
5013  }
5014 
5015  // Parse now
5016  if (action == 0) {
5017  // Output file
5018  if (!outfile.IsNull()) {
5019  if (!outfile.BeginsWith("master:")) {
5021  Warning("HandleOutputOptions",
5022  "directory '%s' for the output file does not exists or is not writable:"
5023  " saving to master", gSystem->DirName(outfile.Data()));
5024  outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5025  } else {
5026  if (!IsLite()) {
5027  // The target file is local, so we need to retrieve it
5028  target = outfile;
5029  if (!stfopt.IsNull()) {
5030  outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5031  } else {
5032  outfile = "";
5033  }
5034  }
5035  }
5036  }
5037  if (outfile.BeginsWith("master:")) {
5038  outfile.ReplaceAll("master:", "");
5039  if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5040  // Get the master data dir
5041  TString ddir, emsg;
5042  if (!IsLite()) {
5043  if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5044  TObjString *os = fMacroLog.GetLineWith("const char");
5045  if (os) {
5046  Ssiz_t fst = os->GetString().First('\"');
5047  Ssiz_t lst = os->GetString().Last('\"');
5048  ddir = os->GetString()(fst+1, lst-fst-1);
5049  } else {
5050  emsg = "could not find 'const char *' string in macro log! cannot continue";
5051  }
5052  } else {
5053  emsg = "could not retrieve master data directory info! cannot continue";
5054  }
5055  if (!emsg.IsNull()) {
5056  Error("HandleOutputOptions", "%s", emsg.Data());
5057  return -1;
5058  }
5059  }
5060  if (!ddir.IsNull()) ddir += "/";
5061  if (outfile.IsNull()) {
5062  outfile.Form("%s<file>", ddir.Data());
5063  } else {
5064  outfile.Insert(0, TString::Format("%s", ddir.Data()));
5065  }
5066  }
5067  }
5068  // Set the parameter
5069  if (!outfile.IsNull()) {
5070  if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5071  SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5072  }
5073  }
5074  // Dataset creation
5075  if (!dsname.IsNull()) {
5076  dsname.Insert(0, "ds:");
5077  // Set the parameter
5078  SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5079  // Check the Save-To-File option
5080  if (!stfopt.IsNull()) {
5081  Int_t ostf = (Int_t) stfopt.Atoi();
5082  if (ostf%10 <= 0) {
5083  Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5084  stfopt.Form("%d", ostf+1);
5085  }
5086  } else {
5087  // Minimal setting
5088  stfopt = "1";
5089  }
5090  }
5091  // Save-To-File options
5092  if (!stfopt.IsNull()) {
5093  // Set the parameter
5094  SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5095  }
5096  } else {
5097  // Retrieve the file, if required
5098  if (GetOutputList()) {
5099  if (target == "ds|V") {
5100  // Find the dataset
5101  dsname = "";
5102  TIter nxo(GetOutputList());
5103  TObject *o = 0;
5104  while ((o = nxo())) {
5106  VerifyDataSet(o->GetName());
5107  dsname = o->GetName();
5108  break;
5109  }
5110  }
5111  if (!dsname.IsNull()) {
5112  TFileCollection *fc = GetDataSet(dsname);
5113  if (fc) {
5114  fc->Print();
5115  } else {
5116  Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5117  }
5118  } else {
5119  Warning("HandleOutputOptions", "dataset not found!");
5120  }
5121  } else {
5122  Bool_t targetcopied = kFALSE;
5123  TProofOutputFile *pf = 0;
5124  if (!target.IsNull())
5126  if (pf) {
5127  // Copy the file
5128  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5129  TUrl(target, kTRUE).GetUrl())) {
5130  if (TFile::Cp(pf->GetOutputFileName(), target)) {
5131  Printf(" Output successfully copied to %s", target.Data());
5132  targetcopied = kTRUE;
5133  } else {
5134  Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5135  }
5136  }
5137  }
5138  TFile *fout = 0;
5139  TObject *o = 0;
5140  TIter nxo(GetOutputList());
5141  Bool_t swapcopied = kFALSE;
5142  while ((o = nxo())) {
5143  TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5144  if (pof) {
5145  if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5146  if (pof == pf && targetcopied) continue;
5147  // Copy the file
5148  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5149  TUrl(target, kTRUE).GetUrl())) {
5150  if (TFile::Cp(pof->GetOutputFileName(), target)) {
5151  Printf(" Output successfully copied to %s", target.Data());
5152  swapcopied = kTRUE;
5153  } else {
5154  Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5155  }
5156  }
5157  } else if (pof->IsRetrieve()) {
5158  // Retrieve this file to the local path indicated in the title
5159  if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5160  TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5161  if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5162  Printf(" Output successfully copied to %s", pof->GetTitle());
5163  } else {
5164  Warning("HandleOutputOptions",
5165  "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5166  }
5167  }
5168  }
5169  }
5170  }
5171  if (!target.IsNull() && !swapcopied) {
5172  if (!fout && !pf) {
5173  fout = TFile::Open(target, "RECREATE");
5174  if (!fout || (fout && fout->IsZombie())) {
5175  SafeDelete(fout);
5176  Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5177  }
5178  }
5179  if (fout) {
5180  nxo.Reset();
5181  while ((o = nxo())) {
5182  TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5183  if (!pof) {
5184  // Write the object to the open output file
5185  o->Write();
5186  }
5187  }
5188  }
5189  }
5190  // Clean-up
5191  if (fout) {
5192  fout->Close();
5193  SafeDelete(fout);
5194  Printf(" Output saved to %s", target.Data());
5195  }
5196  }
5197  }
5198  // Remove the parameter
5199  DeleteParameters("PROOF_DefaultOutputOption");
5200  // Remove the parameter
5201  DeleteParameters("PROOF_SavePartialResults");
5202  }
5203  // Done
5204  return 0;
5205 }
5206 
5207 ////////////////////////////////////////////////////////////////////////////////
5208 /// Extract from opt in optfb information about wanted feedback settings.
5209 /// Feedback are removed from the input string opt.
5210 /// If action == 0, set up feedback accordingly, if action == 1 clean related
5211 /// feedback settings (using info in optfb, if available, or reparsing opt).
5212 ///
5213 /// Feedback requirements are in the form
5214 ///
5215 /// <previous_option>fb=name1,name2,name3,... <next_option>
5216 /// <previous_option>feedback=name1,name2,name3,...;<next_option>
5217 ///
5218 /// The special name 'stats' triggers feedback about events and packets.
5219 /// The separator from the next option is either a ' ' or a ';'.
5220 /// Called interanally by TProof::Process.
5221 
5222 void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5223 {
5224  Ssiz_t from = 0;
5225  if (action == 0 || (action == 1 && optfb.IsNull())) {
5226  TString tag("fb=");
5227  Ssiz_t ifb = opt.Index(tag);
5228  if (ifb == kNPOS) {
5229  tag = "feedback=";
5230  ifb = opt.Index(tag);
5231  }
5232  if (ifb == kNPOS) return;
5233  from = ifb + tag.Length();
5234 
5235  if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5236  Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5237  return;
5238  }
5239  // Remove from original options string
5240  tag += optfb;
5241  opt.ReplaceAll(tag, "");
5242  }
5243 
5244  // Parse now
5245  TString nm, startdraw, stopdraw;
5246  from = 0;
5247  while (optfb.Tokenize(nm, from, ",")) {
5248  // Special name first
5249  if (nm == "stats") {
5250  if (action == 0) {
5251  startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5252  gROOT->ProcessLine(startdraw.Data());
5253  SetParameter("PROOF_StatsHist", "");
5254  AddFeedback("PROOF_EventsHist");
5255  AddFeedback("PROOF_PacketsHist");
5256  AddFeedback("PROOF_ProcPcktHist");
5257  } else {
5258  stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5259  " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5260  " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5261  gROOT->ProcessLine(stopdraw.Data());
5262  DeleteParameters("PROOF_StatsHist");
5263  RemoveFeedback("PROOF_EventsHist");
5264  RemoveFeedback("PROOF_PacketsHist");
5265  RemoveFeedback("PROOF_ProcPcktHist");
5266  }
5267  } else {
5268  if (action == 0) {
5269  // Enable or
5270  AddFeedback(nm);
5271  startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5272  gROOT->ProcessLine(startdraw.Data());
5273  } else {
5274  // ... or disable
5275  RemoveFeedback(nm);
5276  stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5277  " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5278  " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5279  gROOT->ProcessLine(stopdraw.Data());
5280  }
5281  }
5282  }
5283 }
5284 
5285 ////////////////////////////////////////////////////////////////////////////////
5286 /// Process a data set (TDSet) using the specified selector (.C) file or
5287 /// Tselector object
5288 /// Entry- or event-lists should be set in the data set object using
5289 /// TDSet::SetEntryList.
5290 /// The return value is -1 in case of error and TSelector::GetStatus() in
5291 /// in case of success.
5292 
5293 Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5294  Long64_t nentries, Long64_t first)
5295 {
5296  if (!IsValid() || !fPlayer) return -1;
5297 
5298  // Set PROOF to running state
5300 
5301  TString opt(option), optfb, outfile;
5302  // Enable feedback, if required
5303  if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5304  // Define output file, either from 'opt' or the default one
5305  if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5306 
5307  // Resolve query mode
5308  fSync = (GetQueryMode(opt) == kSync);
5309 
5310  if (fSync && (!IsIdle() || IsWaiting())) {
5311  // Already queued or processing queries: switch to asynchronous mode
5312  Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5313  fSync = kFALSE;
5314  opt.ReplaceAll("SYNC","");
5315  opt += "ASYN";
5316  }
5317 
5318  // Cleanup old temporary datasets
5319  if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5321  fRunningDSets->Delete();
5322  }
5323 
5324  // deactivate the default application interrupt handler
5325  // ctrl-c's will be forwarded to PROOF to stop the processing
5326  TSignalHandler *sh = 0;
5327  if (fSync) {
5328  if (gApplication)
5330  }
5331 
5332  // Make sure we get a fresh result
5333  fOutputList.Clear();
5334 
5335  // Make sure that the workers ready list is empty
5336  if (fWrksOutputReady) {
5339  }
5340 
5341  // Reset time measurements
5342  fQuerySTW.Reset();
5343 
5344  Long64_t rv = -1;
5345  if (selector && strlen(selector)) {
5346  rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5347  } else if (fSelector) {
5348  rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5349  } else {
5350  Error("Process", "neither a selecrot file nor a selector object have"
5351  " been specified: cannot process!");
5352  }
5353 
5354  // This is the end of merging
5355  fQuerySTW.Stop();
5356  Float_t rt = fQuerySTW.RealTime();
5357  // Update the query content
5358  TQueryResult *qr = GetQueryResult();
5359  if (qr) {
5360  qr->SetTermTime(rt);
5361  qr->SetPrepTime(fPrepTime);
5362  }
5363 
5364  // Disable feedback, if required
5365  if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5366  // Finalise output file settings (opt is ignored in here)
5367  if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5368 
5369  // Retrieve status from the output list
5370  if (rv >= 0) {
5371  TParameter<Long64_t> *sst =
5372  (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5373  if (sst) rv = sst->GetVal();
5374  }
5375 
5376  if (fSync) {
5377  // reactivate the default application interrupt handler
5378  if (sh)
5380  // Save the performance info, if required
5381  if (!fPerfTree.IsNull()) {
5382  if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5383  // Must be re-enabled each time
5384  SetPerfTree(0);
5385  }
5386  }
5387 
5388  return rv;
5389 }
5390 
5391 ////////////////////////////////////////////////////////////////////////////////
5392 /// Process a data set (TFileCollection) using the specified selector (.C) file
5393 /// or TSelector object.
5394 /// The default tree is analyzed (i.e. the first one found). To specify another
5395 /// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5396 /// The return value is -1 in case of error and TSelector::GetStatus() in
5397 /// in case of success.
5398 
5400  Option_t *option, Long64_t nentries, Long64_t first)
5401 {
5402  if (!IsValid() || !fPlayer) return -1;
5403 
5404  if (fProtocol < 17) {
5405  Info("Process", "server version < 5.18/00:"
5406  " processing of TFileCollection not supported");
5407  return -1;
5408  }
5409 
5410  // We include the TFileCollection to the input list and we create a
5411  // fake TDSet with infor about it
5412  TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5413  fPlayer->AddInput(fc);
5414 
5415 
5416  Long64_t retval = -1;
5417  if (selector && strlen(selector)) {
5418  retval = Process(dset, selector, option, nentries, first);
5419  } else if (fSelector) {
5420  retval = Process(dset, fSelector, option, nentries, first);
5421  } else {
5422  Error("Process", "neither a selecrot file nor a selector object have"
5423  " been specified: cannot process!");
5424  }
5425  fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5426 
5427  // Cleanup
5428  if (IsLite() && !fSync) {
5429  if (!fRunningDSets) fRunningDSets = new TList;
5430  fRunningDSets->Add(dset);
5431  } else {
5432  delete dset;
5433  }
5434 
5435  return retval;
5436 }
5437 
5438 ////////////////////////////////////////////////////////////////////////////////
5439 /// Process a dataset which is stored on the master with name 'dsetname'.
5440 /// The syntax for dsetname is name[#[dir/]objname], e.g.
5441 /// "mydset" analysis of the first tree in the top dir of the dataset
5442 /// named "mydset"
5443 /// "mydset#T" analysis tree "T" in the top dir of the dataset
5444 /// named "mydset"
5445 /// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5446 /// named "mydset"
5447 /// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5448 /// dataset named "mydset"
5449 /// The component 'name' in its more general form contains also the group and
5450 /// user name following "/<group>/<user>/<dsname>". Each of these components
5451 /// can contain one or more wildcards '*', in which case all the datasets matching
5452 /// the expression are added together as a global dataset (wildcard support has
5453 /// been added in version 5.27/02).
5454 /// The last argument 'elist' specifies an entry- or event-list to be used as
5455 /// event selection.
5456 /// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5457 /// at once in a more flexible way that the one provided by wildcarding. There
5458 /// are three possibilities:
5459 /// 1) specifying the dataset names separated by the OR operator '|', e.g.
5460 /// dsetname = "<dset1>|<dset2>|<dset3>|..."
5461 /// in this case the datasets are a seen as a global unique dataset
5462 /// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5463 /// dsetname = "<dset1>,<dset2> <dset3>,..."
5464 /// in this case the datasets are processed one after the other and the
5465 /// selector is notified when switching dataset via a bit in the current
5466 /// processed element.
5467 /// 3) giving the path of a textfile where the dataset names are specified
5468 /// on one or multiple lines; the lines found are joined as in 1), unless
5469 /// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5470 /// with the dataset names listed in 'datasets.txt') in which case they are
5471 /// treated as in 2); the file is open in raw mode with TFile::Open and
5472 /// therefore it cane be remote, e.g. on a Web server.
5473 /// Each <dsetj> has the format specified above for the single dataset processing,
5474 /// included wildcarding (the name of the tree and subdirectory must be same for
5475 /// all the datasets).
5476 /// In the case of multiple datasets, 'elist' is treated a global entry list.
5477 /// It is possible to specify per-dataset entry lists using the syntax
5478 /// "mydset[#adir/[T]]?enl=entrylist"
5479 /// or
5480 /// "mydset[#adir/[T]]<<entrylist"
5481 /// Here 'entrylist' is a tag identifying, in the order :
5482 /// i. a named entry-list in the input list or in the input data list
5483 /// ii. a named entry-list in memory (in gDirectory)
5484 /// iii. the path of a file containing the entry-list to be used
5485 /// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5486 /// data list.
5487 /// The return value is -1 in case of error and TSelector::GetStatus() in
5488 /// in case of success.
5489 
5490 Long64_t TProof::Process(const char *dsetname, const char *selector,
5491  Option_t *option, Long64_t nentries,
5492  Long64_t first, TObject *elist)
5493 {
5494  if (fProtocol < 13) {
5495  Info("Process", "processing 'by name' not supported by the server");
5496  return -1;
5497  }
5498 
5499  TString dsname, fname(dsetname);
5500  // If the 'dsetname' corresponds to an existing and readable file we will try to
5501  // interpretate its content as names of datasets to be processed. One line can contain
5502  // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5503  // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5504  // joined with ','.
5505  const char *separator = (fname.EndsWith(",")) ? "," : "|";
5506  if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5507  if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5508  TUrl uf(fname, kTRUE);
5509  uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5510  TFile *f = TFile::Open(uf.GetUrl());
5511  if (f && !(f->IsZombie())) {
5512  const Int_t blen = 8192;
5513  char buf[blen];
5514  Long64_t rest = f->GetSize();
5515  while (rest > 0) {
5516  Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5517  if (f->ReadBuffer(buf, len)) {
5518  Error("Process", "problems reading from file '%s'", fname.Data());
5519  dsname = "";
5520  break;
5521  }
5522  buf[len] = '\0';
5523  dsname += buf;
5524  rest -= len;
5525  }
5526  f->Close();
5527  SafeDelete(f);
5528  // We fail if a failure occured
5529  if (rest > 0) return -1;
5530  } else {
5531  Error("Process", "could not open file '%s'", fname.Data());
5532  return -1;
5533  }
5534  }
5535  if (dsname.IsNull()) {
5536  dsname = dsetname;
5537  } else {
5538  // Remove trailing '\n'
5539  if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5540  // Replace all '\n' with the proper separator
5541  dsname.ReplaceAll("\n", separator);
5542  if (gDebug > 0) {
5543  Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5544  Info("Process", " '%s'", dsname.Data());
5545  }
5546  }
5547 
5548  TString names(dsname), name, enl, newname;
5549  // If multi-dataset check if server supports it
5550  if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5551  Info("Process", "multi-dataset processing not supported by the server");
5552  return -1;
5553  }
5554 
5555  TEntryList *el = 0;
5556  TString dsobj, dsdir;
5557  Int_t from = 0;
5558  while (names.Tokenize(name, from, "[, |]")) {
5559 
5560  newname = name;
5561  // Extract the specific entry-list, if any
5562  enl = "";
5563  Int_t ienl = name.Index("?enl=");
5564  if (ienl == kNPOS) {
5565  ienl = name.Index("<<");
5566  if (ienl != kNPOS) {
5567  newname.Remove(ienl);
5568  ienl += strlen("<<");
5569  }
5570  } else {
5571  newname.Remove(ienl);
5572  ienl += strlen("?enl=");
5573  }
5574 
5575  // Check the name syntax first
5576  TString obj, dir("/");
5577  Int_t idxc = newname.Index("#");
5578  if (idxc != kNPOS) {
5579  Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5580  if (idxs != kNPOS) {
5581  obj = newname(idxs+1, newname.Length());
5582  dir = newname(idxc+1, newname.Length());
5583  dir.Remove(dir.Index("/") + 1);
5584  newname.Remove(idxc);
5585  } else {
5586  obj = newname(idxc+1, newname.Length());
5587  newname.Remove(idxc);
5588  }
5589  } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5590  // protection against using ':' instead of '#'
5591  Error("Process", "bad name syntax (%s): please use"
5592  " a '#' after the dataset name", name.Data());
5593  dsname.ReplaceAll(name, "");
5594  continue;
5595  }
5596  if (dsobj.IsNull() && dsdir.IsNull()) {
5597  // The first one specifies obj and dir
5598  dsobj = obj;
5599  dsdir = dir;
5600  } else if (obj != dsobj || dir != dsdir) {
5601  // Inconsistent specification: not supported
5602  Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5603  }
5604  // Process the entry-list name, if any
5605  if (ienl != kNPOS) {
5606  // Get entrylist name or path
5607  enl = name(ienl, name.Length());
5608  el = 0;
5609  TObject *oel = 0;
5610  // If not in the input list ...
5611  TList *inpl = GetInputList();
5612  if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5613  // ... check the heap
5614  if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5615  if ((el = dynamic_cast<TEntryList *>(oel))) {
5616  // Add to the input list (input data not available on master where
5617  // this info will be processed)
5618  if (fProtocol >= 28)
5619  if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5620  }
5621  }
5622  // If not in the heap, check a file, if any
5623  if (!el) {
5624  if (!gSystem->AccessPathName(enl)) {
5625  TFile *f = TFile::Open(enl);
5626  if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5627  TIter nxk(f->GetListOfKeys());
5628  TKey *k = 0;
5629  while ((k = (TKey *) nxk())) {
5630  if (!strcmp(k->GetClassName(), "TEntryList")) {
5631  if (!el) {
5632  if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5633  // Add to the input list (input data not available on master where
5634  // this info will be processed)
5635  if (fProtocol >= 28) {
5636  if (!(inpl->FindObject(el->GetName()))) {
5637  el = (TEntryList *) el->Clone();
5638  AddInput(el);
5639  }
5640  } else {
5641  el = (TEntryList *) el->Clone();
5642  }
5643  }
5644  } else if (strcmp(el->GetName(), k->GetName())) {
5645  Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5646  "if this is not what you want, load first the content in memory"
5647  "and select it by name ", enl.Data());
5648  }
5649  }
5650  }
5651  } else {
5652  Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5653  }
5654  }
5655  }
5656  // Transmit the information
5657  if (fProtocol >= 28) {
5658  newname += "?enl=";
5659  if (el) {
5660  // An entry list object is avalaible in the input list: add its name
5661  newname += el->GetName();
5662  } else {
5663  // The entry list object was not found: send the name, the future entry list manager will
5664  // find it on the server side
5665  newname += enl;
5666  }
5667  }
5668  }
5669  // Adjust the name for this dataset
5670  dsname.ReplaceAll(name, newname);
5671  }
5672 
5673  // Create the dataset object
5674  TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5675  // Set entry list
5676  if (el && fProtocol < 28) {
5677  dset->SetEntryList(el);
5678  } else {
5679  dset->SetEntryList(elist);
5680  }
5681  // Run
5682  Long64_t retval = -1;
5683  if (selector && strlen(selector)) {
5684  retval = Process(dset, selector, option, nentries, first);
5685  } else if (fSelector) {
5686  retval = Process(dset, fSelector, option, nentries, first);
5687  } else {
5688  Error("Process", "neither a selector file nor a selector object have"
5689  " been specified: cannot process!");
5690  }
5691  // Cleanup
5692  if (IsLite() && !fSync) {
5693  if (!fRunningDSets) fRunningDSets = new TList;
5694  fRunningDSets->Add(dset);
5695  } else {
5696  delete dset;
5697  }
5698 
5699  return retval;
5700 }
5701 
5702 ////////////////////////////////////////////////////////////////////////////////
5703 /// Generic (non-data based) selector processing: the Process() method of the
5704 /// specified selector (.C) or TSelector object is called 'n' times.
5705 /// The return value is -1 in case of error and TSelector::GetStatus() in
5706 /// in case of success.
5707 
5708 Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5709 {
5710  if (!IsValid()) return -1;
5711 
5712  if (fProtocol < 16) {
5713  Info("Process", "server version < 5.17/04: generic processing not supported");
5714  return -1;
5715  }
5716 
5717  // Fake data set
5718  TDSet *dset = new TDSet;
5719  dset->SetBit(TDSet::kEmpty);
5720 
5721  Long64_t retval = -1;
5722  if (selector && strlen(selector)) {
5723  retval = Process(dset, selector, option, n);
5724  } else if (fSelector) {
5725  retval = Process(dset, fSelector, option, n);
5726  } else {
5727  Error("Process", "neither a selector file nor a selector object have"
5728  " been specified: cannot process!");
5729  }
5730 
5731  // Cleanup
5732  if (IsLite() && !fSync) {
5733  if (!fRunningDSets) fRunningDSets = new TList;
5734  fRunningDSets->Add(dset);
5735  } else {
5736  delete dset;
5737  }
5738  return retval;
5739 }
5740 
5741 ////////////////////////////////////////////////////////////////////////////////
5742 /// Process a data set (TDSet) using the specified selector object.
5743 /// Entry- or event-lists should be set in the data set object using
5744 /// TDSet::SetEntryList.
5745 /// The return value is -1 in case of error and TSelector::GetStatus() in
5746 /// in case of success.
5747 
5749  Long64_t nentries, Long64_t first)
5750 {
5751  if (fProtocol < 34) {
5752  Error("Process", "server version < 5.33/02:"
5753  "processing by object not supported");
5754  return -1;
5755  }
5756  if (!selector) {
5757  Error("Process", "selector object undefined!");
5758  return -1;
5759  }
5760  fSelector = selector;
5761  Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5762  fSelector = 0;
5763  // Done
5764  return rc;
5765 }
5766 
5767 ////////////////////////////////////////////////////////////////////////////////
5768 /// Process a data set (TFileCollection) using the specified selector object
5769 /// The default tree is analyzed (i.e. the first one found). To specify another
5770 /// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5771 /// The return value is -1 in case of error and TSelector::GetStatus() in
5772 /// in case of success.
5773 
5775  Option_t *option, Long64_t nentries, Long64_t first)
5776 {
5777  if (fProtocol < 34) {
5778  Error("Process", "server version < 5.33/02:"
5779  "processing by object not supported");
5780  return -1;
5781  }
5782  if (!selector) {
5783  Error("Process", "selector object undefined!");
5784  return -1;
5785  }
5786  fSelector = selector;
5787  Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5788  fSelector = 0;
5789  // Done
5790  return rc;
5791 }
5792 
5793 ////////////////////////////////////////////////////////////////////////////////
5794 /// Process with name of dataset and TSelector object
5795 
5796 Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5797  Option_t *option, Long64_t nentries,
5798  Long64_t first, TObject *elist)
5799 {
5800  if (fProtocol < 34) {
5801  Error("Process", "server version < 5.33/02:"
5802  "processing by object not supported");
5803  return -1;
5804  }
5805  if (!selector) {
5806  Error("Process", "selector object undefined!");
5807  return -1;
5808  }
5809  fSelector = selector;
5810  Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5811  fSelector = 0;
5812  // Done
5813  return rc;
5814 }
5815 
5816 ////////////////////////////////////////////////////////////////////////////////
5817 /// Generic (non-data based) selector processing: the Process() method of the
5818 /// specified selector is called 'n' times.
5819 /// The return value is -1 in case of error and TSelector::GetStatus() in
5820 /// in case of success.
5821 
5823 {
5824  if (fProtocol < 34) {
5825  Error("Process", "server version < 5.33/02:"
5826  "processing by object not supported");
5827  return -1;
5828  }
5829  if (!selector) {
5830  Error("Process", "selector object undefined!");
5831  return -1;
5832  }
5833  fSelector = selector;
5834  Long64_t rc = Process((const char*)0, n, option);
5835  fSelector = 0;
5836  // Done
5837  return rc;
5838 }
5839 
5840 ////////////////////////////////////////////////////////////////////////////////
5841 /// Get reference for the qry-th query in fQueries (as
5842 /// displayed by ShowQueries).
5843 
5845 {
5846  ref = "";
5847  if (qry > 0) {
5848  if (!fQueries)
5849  GetListOfQueries();
5850  if (fQueries) {
5851  TIter nxq(fQueries);
5852  TQueryResult *qr = 0;
5853  while ((qr = (TQueryResult *) nxq()))
5854  if (qr->GetSeqNum() == qry) {
5855  ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5856  return 0;
5857  }
5858  }
5859  }
5860  return -1;
5861 }
5862 
5863 ////////////////////////////////////////////////////////////////////////////////
5864 /// Finalize the qry-th query in fQueries.
5865 /// If force, force retrieval if the query is found in the local list
5866 /// but has already been finalized (default kFALSE).
5867 /// If query < 0, finalize current query.
5868 /// Return 0 on success, -1 on error
5869 
5871 {
5872  if (fPlayer) {
5873  if (qry > 0) {
5874  TString ref;
5875  if (GetQueryReference(qry, ref) == 0) {
5876  return Finalize(ref, force);
5877  } else {
5878  Info("Finalize", "query #%d not found", qry);
5879  }
5880  } else {
5881  // The last query
5882  return Finalize("", force);
5883  }
5884  }
5885  return -1;
5886 }
5887 
5888 ////////////////////////////////////////////////////////////////////////////////
5889 /// Finalize query with reference ref.
5890 /// If force, force retrieval if the query is found in the local list
5891 /// but has already been finalized (default kFALSE).
5892 /// If ref = 0, finalize current query.
5893 /// Return 0 on success, -1 on error
5894 
5895 Long64_t TProof::Finalize(const char *ref, Bool_t force)
5896 {
5897  if (fPlayer) {
5898  // Get the pointer to the query
5899  TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5900  : GetQueryResult();
5902  TString xref(ref);
5903  if (!qr) {
5904  if (!xref.IsNull()) {
5905  retrieve = kTRUE;
5906  }
5907  } else {
5908  if (qr->IsFinalized()) {
5909  if (force) {
5910  retrieve = kTRUE;
5911  } else {
5912  Info("Finalize","query already finalized:"
5913  " use Finalize(<qry>,kTRUE) to force new retrieval");
5914  qr = 0;
5915  }
5916  } else {
5917  retrieve = kTRUE;
5918  xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5919  }
5920  }
5921  if (retrieve) {
5922  Retrieve(xref.Data());
5923  qr = fPlayer->GetQueryResult(xref.Data());
5924  }
5925  if (qr)
5926  return fPlayer->Finalize(qr);
5927  }
5928  return -1;
5929 }
5930 
5931 ////////////////////////////////////////////////////////////////////////////////
5932 /// Send retrieve request for the qry-th query in fQueries.
5933 /// If path is defined save it to path.
5934 
5935 Int_t TProof::Retrieve(Int_t qry, const char *path)
5936 {
5937  if (qry > 0) {
5938  TString ref;
5939  if (GetQueryReference(qry, ref) == 0)
5940  return Retrieve(ref, path);
5941  else
5942  Info("Retrieve", "query #%d not found", qry);
5943  } else {
5944  Info("Retrieve","positive argument required - do nothing");
5945  }
5946  return -1;
5947 }
5948 
5949 ////////////////////////////////////////////////////////////////////////////////
5950 /// Send retrieve request for the query specified by ref.
5951 /// If path is defined save it to path.
5952 /// Generic method working for all queries known by the server.
5953 
5954 Int_t TProof::Retrieve(const char *ref, const char *path)
5955 {
5956  if (ref) {
5958  m << TString(ref);
5959  Broadcast(m, kActive);
5961 
5962  // Archive it locally, if required
5963  if (path) {
5964 
5965  // Get pointer to query
5966  TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5967 
5968  if (qr) {
5969 
5970  TFile *farc = TFile::Open(path,"UPDATE");
5971  if (!farc || (farc && !(farc->IsOpen()))) {
5972  Info("Retrieve", "archive file cannot be open (%s)", path);
5973  return 0;
5974  }
5975  farc->cd();
5976 
5977  // Update query status
5978  qr->SetArchived(path);
5979 
5980  // Write to file
5981  qr->Write();
5982 
5983  farc->Close();
5984  SafeDelete(farc);
5985 
5986  } else {
5987  Info("Retrieve", "query not found after retrieve");
5988  return -1;
5989  }
5990  }
5991 
5992  return 0;
5993  }
5994  return -1;
5995 }
5996 
5997 ////////////////////////////////////////////////////////////////////////////////
5998 /// Send remove request for the qry-th query in fQueries.
5999 
6001 {
6002  if (qry > 0) {
6003  TString ref;
6004  if (GetQueryReference(qry, ref) == 0)
6005  return Remove(ref, all);
6006  else
6007  Info("Remove", "query #%d not found", qry);
6008  } else {
6009  Info("Remove","positive argument required - do nothing");
6010  }
6011  return -1;
6012 }
6013 
6014 ////////////////////////////////////////////////////////////////////////////////
6015 /// Send remove request for the query specified by ref.
6016 /// If all = TRUE remove also local copies of the query, if any.
6017 /// Generic method working for all queries known by the server.
6018 /// This method can be also used to reset the list of queries
6019 /// waiting to be processed: for that purpose use ref == "cleanupqueue".
6020 
6021 Int_t TProof::Remove(const char *ref, Bool_t all)
6022 {
6023  if (all) {
6024  // Remove also local copies, if any
6025  if (fPlayer)
6026  fPlayer->RemoveQueryResult(ref);
6027  }
6028 
6029  if (IsLite()) return 0;
6030 
6031  if (ref) {
6033  m << TString(ref);
6034  Broadcast(m, kActive);
6036  return 0;
6037  }
6038  return -1;
6039 }
6040 
6041 ////////////////////////////////////////////////////////////////////////////////
6042 /// Send archive request for the qry-th query in fQueries.
6043 
6044 Int_t TProof::Archive(Int_t qry, const char *path)
6045 {
6046  if (qry > 0) {
6047  TString ref;
6048  if (GetQueryReference(qry, ref) == 0)
6049  return Archive(ref, path);
6050  else
6051  Info("Archive", "query #%d not found", qry);
6052  } else {
6053  Info("Archive","positive argument required - do nothing");
6054  }
6055  return -1;
6056 }
6057 
6058 ////////////////////////////////////////////////////////////////////////////////
6059 /// Send archive request for the query specified by ref.
6060 /// Generic method working for all queries known by the server.
6061 /// If ref == "Default", path is understood as a default path for
6062 /// archiving.
6063 
6064 Int_t TProof::Archive(const char *ref, const char *path)
6065 {
6066  if (ref) {
6068  m << TString(ref) << TString(path);
6069  Broadcast(m, kActive);
6071  return 0;
6072  }
6073  return -1;
6074 }
6075 
6076 ////////////////////////////////////////////////////////////////////////////////
6077 /// Send cleanup request for the session specified by tag.
6078 
6079 Int_t TProof::CleanupSession(const char *sessiontag)
6080 {
6081  if (sessiontag) {
6083  m << TString(sessiontag);
6084  Broadcast(m, kActive);
6086  return 0;
6087  }
6088  return -1;
6089 }
6090 
6091 ////////////////////////////////////////////////////////////////////////////////
6092 /// Change query running mode to the one specified by 'mode'.
6093 
6095 {
6096  fQueryMode = mode;
6097 
6098  if (gDebug > 0)
6099  Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6100  "Sync" : "Async");
6101 }
6102 
6103 ////////////////////////////////////////////////////////////////////////////////
6104 /// Find out the query mode based on the current setting and 'mode'.
6105 
6107 {
6108  EQueryMode qmode = fQueryMode;
6109 
6110  if (mode && (strlen(mode) > 0)) {
6111  TString m(mode);
6112  m.ToUpper();
6113  if (m.Contains("ASYN")) {
6114  qmode = kAsync;
6115  } else if (m.Contains("SYNC")) {
6116  qmode = kSync;
6117  }
6118  }
6119 
6120  if (gDebug > 0)
6121  Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6122  "Sync" : "Async");
6123 
6124  return qmode;
6125 }
6126 
6127 ////////////////////////////////////////////////////////////////////////////////
6128 /// Execute the specified drawing action on a data set (TDSet).
6129 /// Event- or Entry-lists should be set in the data set object using
6130 /// TDSet::SetEntryList.
6131 /// Returns -1 in case of error or number of selected events otherwise.
6132 
6133 Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6134  const char *selection, Option_t *option,
6135  Long64_t nentries, Long64_t first)
6136 {
6137  if (!IsValid() || !fPlayer) return -1;
6138 
6139  // Make sure that asynchronous processing is not active
6140  if (!IsIdle()) {
6141  Info("DrawSelect","not idle, asynchronous Draw not supported");
6142  return -1;
6143  }
6144  TString opt(option);
6145  Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6146  if (idx != kNPOS)
6147  opt.Replace(idx,4,"");
6148 
6149  return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6150 }
6151 
6152 ////////////////////////////////////////////////////////////////////////////////
6153 /// Execute the specified drawing action on a data set which is stored on the
6154 /// master with name 'dsetname'.
6155 /// The syntax for dsetname is name[#[dir/]objname], e.g.
6156 /// "mydset" analysis of the first tree in the top dir of the dataset
6157 /// named "mydset"
6158 /// "mydset#T" analysis tree "T" in the top dir of the dataset
6159 /// named "mydset"
6160 /// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6161 /// named "mydset"
6162 /// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6163 /// dataset named "mydset"
6164 /// The last argument 'enl' specifies an entry- or event-list to be used as
6165 /// event selection.
6166 /// The return value is -1 in case of error and TSelector::GetStatus() in
6167 /// in case of success.
6168 
6169 Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6170  const char *selection, Option_t *option,
6171  Long64_t nentries, Long64_t first, TObject *enl)
6172 {
6173  if (fProtocol < 13) {
6174  Info("Process", "processing 'by name' not supported by the server");
6175  return -1;
6176  }
6177 
6178  TString name(dsetname);
6179  TString obj;
6180  TString dir = "/";
6181  Int_t idxc = name.Index("#");
6182  if (idxc != kNPOS) {
6183  Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6184  if (idxs != kNPOS) {
6185  obj = name(idxs+1, name.Length());
6186  dir = name(idxc+1, name.Length());
6187  dir.Remove(dir.Index("/") + 1);
6188  name.Remove(idxc);
6189  } else {
6190  obj = name(idxc+1, name.Length());
6191  name.Remove(idxc);
6192  }
6193  } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6194  // protection against using ':' instead of '#'
6195  Error("DrawSelect", "bad name syntax (%s): please use"
6196  " a '#' after the dataset name", dsetname);
6197  return -1;
6198  }
6199 
6200  TDSet *dset = new TDSet(name, obj, dir);
6201  // Set entry-list, if required
6202  dset->SetEntryList(enl);
6203  Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6204  delete dset;
6205  return retval;
6206 }
6207 
6208 ////////////////////////////////////////////////////////////////////////////////
6209 /// Send STOPPROCESS message to master and workers.
6210 
6211 void TProof::StopProcess(Bool_t abort, Int_t timeout)
6212 {
6213  PDB(kGlobal,2)
6214  Info("StopProcess","enter %d", abort);
6215 
6216  if (!IsValid())
6217  return;
6218 
6219  // Flag that we have been stopped
6221  SetRunStatus(rst);
6222 
6223  if (fPlayer)
6224  fPlayer->StopProcess(abort, timeout);
6225 
6226  // Stop any blocking 'Collect' request; on masters we do this only if
6227  // aborting; when stopping, we still need to receive the results
6228  if (TestBit(TProof::kIsClient) || abort)
6230 
6231  if (fSlaves->GetSize() == 0)
6232  return;
6233 
6234  // Notify the remote counterpart
6235  TSlave *sl;
6236  TIter next(fSlaves);
6237  while ((sl = (TSlave *)next()))
6238  if (sl->IsValid())
6239  // Ask slave to progate the stop/abort request
6240  sl->StopProcess(abort, timeout);
6241 }
6242 
6243 ////////////////////////////////////////////////////////////////////////////////
6244 /// Signal to disable related switches
6245 
6247 {
6248  Emit("DisableGoAsyn()");
6249 }
6250 
6251 ////////////////////////////////////////////////////////////////////////////////
6252 /// Send GOASYNC message to the master.
6253 
6255 {
6256  if (!IsValid()) return;
6257 
6258  if (GetRemoteProtocol() < 22) {
6259  Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6260  return;
6261  }
6262 
6263  if (fSync && !IsIdle()) {
6265  Broadcast(m);
6266  } else {
6267  Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6268  }
6269 }
6270 
6271 ////////////////////////////////////////////////////////////////////////////////
6272 /// Receive the log file of the slave with socket s.
6273 
6275 {
6276  const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6277  char buf[kMAXBUF];
6278 
6279  // If macro saving is enabled prepare macro
6283  }
6284 
6285  // Append messages to active logging unit
6286  Int_t fdout = -1;
6287  if (!fLogToWindowOnly) {
6288  fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6289  if (fdout < 0) {
6290  Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6291  " will not log msgs", fdout);
6292  return;
6293  }
6294  lseek(fdout, (off_t) 0, SEEK_END);
6295  }
6296 
6297  Int_t left, rec, r;
6298  Long_t filesize = 0;
6299 
6300  while (filesize < size) {
6301  left = Int_t(size - filesize);
6302  if (left >= kMAXBUF)
6303  left = kMAXBUF-1;
6304  rec = s->RecvRaw(&buf, left);
6305  filesize = (rec > 0) ? (filesize + rec) : filesize;
6306  if (!fLogToWindowOnly && !fSaveLogToMacro) {
6307  if (rec > 0) {
6308 
6309  char *p = buf;
6310  r = rec;
6311  while (r) {
6312  Int_t w;
6313 
6314  w = write(fdout, p, r);
6315 
6316  if (w < 0) {
6317  SysError("RecvLogFile", "error writing to unit: %d", fdout);
6318  break;
6319  }
6320  r -= w;
6321  p += w;
6322  }
6323  } else if (rec < 0) {
6324  Error("RecvLogFile", "error during receiving log file");
6325  break;
6326  }
6327  }
6328  if (rec > 0) {
6329  buf[rec] = 0;
6330  EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6331  // If macro saving is enabled add to TMacro
6332  if (fSaveLogToMacro) fMacroLog.AddLine(buf);
6333  }
6334  }
6335 
6336  // If idle restore logs to main session window
6337  if (fRedirLog && IsIdle() && !TestBit(TProof::kIsMaster))
6338  fRedirLog = kFALSE;
6339 }
6340 
6341 ////////////////////////////////////////////////////////////////////////////////
6342 /// Notify locally 'msg' to the appropriate units (file, stdout, window)
6343 /// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6344 
6345 void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6346 {
6347  // Must have somenthing to notify
6348  Int_t len = 0;
6349  if (!msg || (len = strlen(msg)) <= 0)
6350  return;
6351 
6352  // Get suffix length if any
6353  Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6354 
6355  // Append messages to active logging unit
6356  Int_t fdout = -1;
6357  if (!fLogToWindowOnly) {
6358  fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6359  if (fdout < 0) {
6360  Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6361  " will not notify msgs", fdout);
6362  return;
6363  }
6364  lseek(fdout, (off_t) 0, SEEK_END);
6365  }
6366 
6367  if (!fLogToWindowOnly) {
6368  // Write to output unit (stdout or a log file)
6369  if (len > 0) {
6370  char *p = (char *)msg;
6371  Int_t r = len;
6372  while (r) {
6373  Int_t w = write(fdout, p, r);
6374  if (w < 0) {
6375  SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6376  break;
6377  }
6378  r -= w;
6379  p += w;
6380  }
6381  // Add a suffix, if requested
6382  if (lsfx > 0)
6383  if (write(fdout, sfx, lsfx) != lsfx)
6384  SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6385  }
6386  }
6387  if (len > 0) {
6388  // Publish the message to the separate window (if the latter is missing
6389  // the message will just get lost)
6390  EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6391  }
6392 
6393  // If idle restore logs to main session window
6394  if (fRedirLog && IsIdle())
6395  fRedirLog = kFALSE;
6396 }
6397 
6398 ////////////////////////////////////////////////////////////////////////////////
6399 /// Log a message into the appropriate window by emitting a signal.
6400 
6401 void TProof::LogMessage(const char *msg, Bool_t all)
6402 {
6403  PDB(kGlobal,1)
6404  Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6405  all ? "true" : "false");
6406 
6407  if (gROOT->IsBatch()) {
6408  PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6409  return;
6410  }
6411 
6412  if (msg)
6413  EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6414 
6415  // Re-position at the beginning of the file, if requested.
6416  // This is used by the dialog when it re-opens the log window to
6417  // provide all the session messages
6418  if (all)
6419  lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6420 
6421  const Int_t kMAXBUF = 32768;
6422  char buf[kMAXBUF];
6423  Int_t len;
6424  do {
6425  while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6426  TSystem::GetErrno() == EINTR)
6428 
6429  if (len < 0) {
6430  Error("LogMessage", "error reading log file");
6431  break;
6432  }
6433 
6434  if (len > 0) {
6435  buf[len] = 0;
6436  EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6437  }
6438 
6439  } while (len > 0);
6440 }
6441 
6442 ////////////////////////////////////////////////////////////////////////////////
6443 /// Send to all active slaves servers the current slave group size
6444 /// and their unique id. Returns number of active slaves.
6445 /// Returns -1 in case of error.
6446 
6448 {
6449  if (!IsValid()) return -1;
6450  if (TestBit(TProof::kIsClient)) return 0;
6451  if (!fSendGroupView) return 0;
6453 
6455  TSlave *sl;
6456 
6457  int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6458  char str[32];
6459 
6460  while ((sl = (TSlave *)next())) {
6461  snprintf(str, 32, "%d %d", cnt, size);
6462  if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6463  MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6464  bad++;
6465  } else
6466  cnt++;
6467  }
6468 
6469  // Send the group view again in case there was a change in the
6470  // group size due to a bad slave
6471 
6472  if (bad) SendGroupView();
6473 
6474  return GetNumberOfActiveSlaves();
6475 }
6476 
6477 ////////////////////////////////////////////////////////////////////////////////
6478 /// Static method to extract the filename (if any) form a CINT command.
6479 /// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6480 /// appliable.
6481 
6482 Bool_t TProof::GetFileInCmd(const char *cmd, TString &fn)
6483 {
6484  TString s = cmd;
6485  s = s.Strip(TString::kBoth);
6486 
6487  if (s.Length() > 0 &&
6488  (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6489  TString file = s(2, s.Length());
6490  TString acm, arg, io;
6491  fn = gSystem->SplitAclicMode(file, acm, arg, io);
6492  if (!fn.IsNull())
6493  return kTRUE;
6494  }
6495 
6496  // Not found
6497  return kFALSE;
6498 }
6499 
6500 ////////////////////////////////////////////////////////////////////////////////
6501 /// Send command to be executed on the PROOF master and/or slaves.
6502 /// If plusMaster is kTRUE then exeucte on slaves and master too.
6503 /// Command can be any legal command line command. Commands like
6504 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6505 /// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6506 /// succes.
6507 
6508 Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6509 {
6510  return Exec(cmd, kActive, plusMaster);
6511 }
6512 
6513 ////////////////////////////////////////////////////////////////////////////////
6514 /// Send command to be executed on the PROOF master and/or slaves.
6515 /// Command can be any legal command line command. Commands like
6516 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6517 /// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6518 /// succes.
6519 
6520 Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6521 {
6522  if (!IsValid()) return -1;
6523 
6524  TString s = cmd;
6525  s = s.Strip(TString::kBoth);
6526 
6527  if (!s.Length()) return 0;
6528 
6529  // check for macro file and make sure the file is available on all slaves
6530  TString filename;
6531  if (TProof::GetFileInCmd(s.Data(), filename)) {
6532  char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6533  if (fn) {
6534  if (GetNumberOfUniqueSlaves() > 0) {
6535  if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6536  Error("Exec", "file %s could not be transfered", fn);
6537  delete [] fn;
6538  return -1;
6539  }
6540  } else {
6541  TString scmd = s(0,3) + fn;
6542  Int_t n = SendCommand(scmd, list);
6543  delete [] fn;
6544  return n;
6545  }
6546  } else {
6547  Error("Exec", "macro %s not found", filename.Data());
6548  return -1;
6549  }
6550  delete [] fn;
6551  }
6552 
6553  if (plusMaster) {
6554  if (IsLite()) {
6555  gROOT->ProcessLine(cmd);
6556  } else {
6557  DeactivateWorker("*");
6558  Int_t res = SendCommand(cmd, list);
6559  ActivateWorker("restore");
6560  if (res < 0)
6561  return res;
6562  }
6563  }
6564  return SendCommand(cmd, list);
6565 }
6566 
6567 ////////////////////////////////////////////////////////////////////////////////
6568 /// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6569 /// Command can be any legal command line command. Commands like
6570 /// ".x file.C" or ".L file.C" will cause the file file.C to be send
6571 /// to the PROOF cluster.
6572 /// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6573 /// TMacro, accessible via TMacro::GetMacroLog();
6574 /// Returns -1 in case of error, >=0 in case of succes.
6575 
6576 Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6577 {
6578  if (!IsValid()) return -1;
6579 
6580  TString s = cmd;
6581  s = s.Strip(TString::kBoth);
6582 
6583  if (!s.Length()) return 0;
6584 
6585  Int_t res = 0;
6586  if (IsLite()) {
6587  gROOT->ProcessLine(cmd);
6588  } else {
6589  Bool_t oldRedirLog = fRedirLog;
6590  fRedirLog = kTRUE;
6591  // Deactivate all workers
6592  DeactivateWorker("*");
6593  fRedirLog = kFALSE;
6594  // Reactivate the target ones, if needed
6595  if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6596  // Honour log-to-macro-saving settings
6597  Bool_t oldSaveLog = fSaveLogToMacro;
6598  fSaveLogToMacro = logtomacro;
6599  res = SendCommand(cmd, kActive);
6600  fSaveLogToMacro = oldSaveLog;
6601  fRedirLog = kTRUE;
6602  ActivateWorker("restore");
6603  fRedirLog = oldRedirLog;
6604  }
6605  // Done
6606  return res;
6607 }
6608 
6609 ////////////////////////////////////////////////////////////////////////////////
6610 /// Send command to be executed on the PROOF master and/or slaves.
6611 /// Command can be any legal command line command, however commands
6612 /// like ".x file.C" or ".L file.C" will not cause the file.C to be
6613 /// transfered to the PROOF cluster. In that case use TProof::Exec().
6614 /// Returns the status send by the remote server as part of the
6615 /// kPROOF_LOGDONE message. Typically this is the return code of the
6616 /// command on the remote side. Returns -1 in case of error.
6617 
6618 Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6619 {
6620  if (!IsValid()) return -1;
6621 
6622  Broadcast(cmd, kMESS_CINT, list);
6623  Collect(list);
6624 
6625  return fStatus;
6626 }
6627 
6628 ////////////////////////////////////////////////////////////////////////////////
6629 /// Get value of environment variable 'env' on node 'ord'
6630 
6631 TString TProof::Getenv(const char *env, const char *ord)
6632 {
6633  // The command to be executed
6634  TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6635  if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6636  // Get the line
6637  TObjString *os = fMacroLog.GetLineWith("const char");
6638  if (os) {
6639  TString info;
6640  Ssiz_t from = 0;
6641  os->GetString().Tokenize(info, from, "\"");
6642  os->GetString().Tokenize(info, from, "\"");
6643  if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6644  return info;
6645  }
6646  return TString("");
6647 }
6648 
6649 ////////////////////////////////////////////////////////////////////////////////
6650 /// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6651 
6652 Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6653 {
6654  // The command to be executed
6655  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6656  // Exectute the command saving the logs to macro
6657  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6658  // Get the line
6659  TObjString *os = fMacroLog.GetLineWith("const char");
6660  Int_t rc = -1;
6661  if (os) {
6662  Ssiz_t fst = os->GetString().First('\"');
6663  Ssiz_t lst = os->GetString().Last('\"');
6664  TString info = os->GetString()(fst+1, lst-fst-1);
6665  if (info.IsDigit()) {
6666  env = info.Atoi();
6667  rc = 0;
6668  if (gDebug > 0)
6669  Printf("%s: %d", rcenv, env);
6670  }
6671  }
6672  return rc;
6673 }
6674 
6675 ////////////////////////////////////////////////////////////////////////////////
6676 /// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6677 
6678 Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6679 {
6680  // The command to be executed
6681  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6682  // Exectute the command saving the logs to macro
6683  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6684  // Get the line
6685  TObjString *os = fMacroLog.GetLineWith("const char");
6686  Int_t rc = -1;
6687  if (os) {
6688  Ssiz_t fst = os->GetString().First('\"');
6689  Ssiz_t lst = os->GetString().Last('\"');
6690  TString info = os->GetString()(fst+1, lst-fst-1);
6691  if (info.IsFloat()) {
6692  env = info.Atof();
6693  rc = 0;
6694  if (gDebug > 0)
6695  Printf("%s: %f", rcenv, env);
6696  }
6697  }
6698  return rc;
6699 }
6700 
6701 ////////////////////////////////////////////////////////////////////////////////
6702 /// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6703 
6704 Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6705 {
6706  // The command to be executed
6707  TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6708  // Exectute the command saving the logs to macro
6709  if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6710  // Get the line
6711  TObjString *os = fMacroLog.GetLineWith("const char");
6712  Int_t rc = -1;
6713  if (os) {
6714  Ssiz_t fst = os->GetString().First('\"');
6715  Ssiz_t lst = os->GetString().Last('\"');
6716  env = os->GetString()(fst+1, lst-fst-1);
6717  rc = 0;
6718  if (gDebug > 0)
6719  Printf("%s: %s", rcenv, env.Data());
6720  }
6721  return rc;
6722 }
6723 
6724 ////////////////////////////////////////////////////////////////////////////////
6725 /// Transfer the current state of the master to the active slave servers.
6726 /// The current state includes: the current working directory, etc.
6727 /// Returns the number of active slaves. Returns -1 in case of error.
6728 
6730 {
6731  if (!IsValid()) return -1;
6732 
6733  // Go to the new directory, reset the interpreter environment and
6734  // tell slave to delete all objects from its new current directory.
6735  Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6736 
6737  return GetParallel();
6738 }
6739 
6740 ////////////////////////////////////////////////////////////////////////////////
6741 /// Transfer the current state of the master to the active slave servers.
6742 /// The current state includes: the current working directory, etc.
6743 /// Returns the number of active slaves. Returns -1 in case of error.
6744 
6746 {
6747  if (!IsValid()) return -1;
6748 
6749  // Go to the new directory, reset the interpreter environment and
6750  // tell slave to delete all objects from its new current directory.
6751  Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6752 
6753  return GetParallel();
6754 }
6755 
6756 ////////////////////////////////////////////////////////////////////////////////
6757 /// Transfer the initial (i.e. current) state of the master to all
6758 /// slave servers. Currently the initial state includes: log level.
6759 /// Returns the number of active slaves. Returns -1 in case of error.
6760 
6762 {
6763  if (!IsValid()) return -1;
6764 
6766 
6767  return GetNumberOfActiveSlaves();
6768 }
6769 
6770 ////////////////////////////////////////////////////////////////////////////////
6771 /// Check if a file needs to be send to the slave. Use the following
6772 /// algorithm:
6773 /// - check if file appears in file map
6774 /// - if yes, get file's modtime and check against time in map,
6775 /// if modtime not same get md5 and compare against md5 in map,
6776 /// if not same return kTRUE.
6777 /// - if no, get file's md5 and modtime and store in file map, ask
6778 /// slave if file exists with specific md5, if yes return kFALSE,
6779 /// if no return kTRUE.
6780 /// The options 'cpopt' define if to copy things from cache to sandbox and what.
6781 /// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6782 /// must be set in cpopt; the default is copy everything.
6783 /// Returns kTRUE in case file needs to be send, returns kFALSE in case
6784 /// file is already on remote node.
6785 
6786 Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6787 {
6788  Bool_t sendto = kFALSE;
6789 
6790  // create worker based filename
6791  TString sn = slave->GetName();
6792  sn += ":";
6793  sn += slave->GetOrdinal();
6794  sn += ":";
6795  sn += gSystem->BaseName(file);
6796 
6797  // check if file is in map
6798  FileMap_t::const_iterator it;
6799  if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6800  // file in map
6801  MD5Mod_t md = (*it).second;
6802  if (md.fModtime != modtime) {
6803  TMD5 *md5 = TMD5::FileChecksum(file);
6804  if (md5) {
6805  if ((*md5) != md.fMD5) {
6806  sendto = kTRUE;
6807  md.fMD5 = *md5;
6808  md.fModtime = modtime;
6809  fFileMap[sn] = md;
6810  // When on the master, the master and/or slaves may share
6811  // their file systems and cache. Therefore always make a
6812  // check for the file. If the file already exists with the
6813  // expected md5 the kPROOF_CHECKFILE command will cause the
6814  // file to be copied from cache to slave sandbox.
6815  if (TestBit(TProof::kIsMaster)) {
6816  sendto = kFALSE;
6817  TMessage mess(kPROOF_CHECKFILE);
6818  mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6819  slave->GetSocket()->Send(mess);
6820 
6821  fCheckFileStatus = 0;
6823  sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6824  }
6825  }
6826  delete md5;
6827  } else {
6828  Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6829  return kFALSE;
6830  }
6831  }
6832  } else {
6833  // file not in map
6834  TMD5 *md5 = TMD5::FileChecksum(file);
6835  MD5Mod_t md;
6836  if (md5) {
6837  md.fMD5 = *md5;
6838  md.fModtime = modtime;
6839  fFileMap[sn] = md;
6840  delete md5;
6841  } else {
6842  Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6843  return kFALSE;
6844  }
6845  TMessage mess(kPROOF_CHECKFILE);
6846  mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6847  slave->GetSocket()->Send(mess);
6848 
6849  fCheckFileStatus = 0;
6851  sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6852  }
6853 
6854  return sendto;
6855 }
6856 
6857 ////////////////////////////////////////////////////////////////////////////////
6858 /// Send a file to master or slave servers. Returns number of slaves
6859 /// the file was sent to, maybe 0 in case master and slaves have the same
6860 /// file system image, -1 in case of error.
6861 /// If defined, send to worker 'wrk' only.
6862 /// If defined, the full path of the remote path will be rfile.
6863 /// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6864 /// (to copy to the cache on a different name use rfile = "cache:newname").
6865 /// The mask 'opt' is an or of ESendFileOpt:
6866 ///
6867 /// kAscii (0x0) if set true ascii file transfer is used
6868 /// kBinary (0x1) if set true binary file transfer is used
6869 /// kForce (0x2) if not set an attempt is done to find out
6870 /// whether the file really needs to be downloaded
6871 /// (a valid copy may already exist in the cache
6872 /// from a previous run); the bit is set by
6873 /// UploadPackage, since the check is done elsewhere.
6874 /// kForward (0x4) if set, ask server to forward the file to slave
6875 /// or submaster (meaningless for slave servers).
6876 /// kCpBin (0x8) Retrieve from the cache the binaries associated
6877 /// with the file
6878 /// kCp (0x10) Retrieve the files from the cache
6879 ///
6880 
6881 Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6882 {
6883  if (!IsValid()) return -1;
6884 
6885  // Use the active slaves list ...
6886  TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6887  // ... or the specified slave, if any
6888  if (wrk) {
6889  slaves = new TList();
6890  slaves->Add(wrk);
6891  }
6892 
6893  if (slaves->GetSize() == 0) return 0;
6894 
6895 #ifndef R__WIN32
6896  Int_t fd = open(file, O_RDONLY);
6897 #else
6898  Int_t fd = open(file, O_RDONLY | O_BINARY);
6899 #endif
6900  if (fd < 0) {
6901  SysError("SendFile", "cannot open file %s", file);
6902  return -1;
6903  }
6904 
6905  // Get info about the file
6906  Long64_t size = -1;
6907  Long_t id, flags, modtime = 0;
6908  if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6909  Error("SendFile", "cannot stat file %s", file);
6910  close(fd);
6911  return -1;
6912  }
6913  if (size == 0) {
6914  Error("SendFile", "empty file %s", file);
6915  close(fd);
6916  return -1;
6917  }
6918 
6919  // Decode options
6920  Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6921  Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6922  Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6923 
6924  // Copy options
6925  Int_t cpopt = 0;
6926  if ((opt & kCp)) cpopt |= kCp;
6927  if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6928 
6929  const Int_t kMAXBUF = 32768; //16384 //65536;
6930  char buf[kMAXBUF];
6931  Int_t nsl = 0;
6932 
6933  TIter next(slaves);
6934  TSlave *sl;
6935  TString fnam(rfile);
6936  if (fnam == "cache") {
6937  fnam += TString::Format(":%s", gSystem->BaseName(file));
6938  } else if (fnam.IsNull()) {
6939  fnam = gSystem->BaseName(file);
6940  }
6941  // List on which we will collect the results
6942  fStatus = 0;
6943  while ((sl = (TSlave *)next())) {
6944  if (!sl->IsValid())
6945  continue;
6946 
6947  Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6948  // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6949  // is false. Masters might still need to send the file to newly added
6950  // slaves.
6951  PDB(kPackage,2) {
6952  const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6953  Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6954  file, sl->GetName(), sl->GetOrdinal(), sendto);
6955  }
6956  if (sl->fSlaveType == TSlave::kSlave && !sendto)
6957  continue;
6958  // The value of 'size' is used as flag remotely, so we need to
6959  // reset it to 0 if we are not going to send the file
6960  Long64_t siz = sendto ? size : 0;
6961  snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6962  if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6963  MarkBad(sl, "could not send kPROOF_SENDFILE request");
6964  continue;
6965  }
6966 
6967  if (sendto) {
6968 
6969  lseek(fd, 0, SEEK_SET);
6970 
6971  Int_t len;
6972  do {
6973  while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6975 
6976  if (len < 0) {
6977  SysError("SendFile", "error reading from file %s", file);
6979  close(fd);
6980  return -1;
6981  }
6982 
6983  if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6984  SysError("SendFile", "error writing to slave %s:%s (now offline)",
6985  sl->GetName(), sl->GetOrdinal());
6986  MarkBad(sl, "sendraw failure");
6987  sl = 0;
6988  break;
6989  }
6990 
6991  } while (len > 0);
6992 
6993  nsl++;
6994  }
6995  // Wait for the operation to be done
6996  if (sl)
6998  }
6999 
7000  close(fd);
7001 
7002  // Cleanup temporary list, if any
7003  if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
7004  SafeDelete(slaves);
7005 
7006  // We return failure is at least one unique worker failed
7007  return (fStatus != 0) ? -1 : nsl;
7008 }
7009 
7010 ////////////////////////////////////////////////////////////////////////////////
7011 /// Sends an object to master and workers and expect them to send back a
7012 /// message with the output of its TObject::Print(). Returns -1 on error, the
7013 /// number of workers that received the objects on success.
7014 
7016 {
7017  if (!IsValid() || !obj) return -1;
7018  TMessage mess(kPROOF_ECHO);
7019  mess.WriteObject(obj);
7020  return Broadcast(mess);
7021 }
7022 
7023 ////////////////////////////////////////////////////////////////////////////////
7024 /// Sends a string to master and workers and expect them to echo it back to
7025 /// the client via a message. It is a special case of the generic Echo()
7026 /// that works with TObjects. Returns -1 on error, the number of workers that
7027 /// received the message on success.
7028 
7029 Int_t TProof::Echo(const char *str)
7030 {
7031  TObjString *os = new TObjString(str);
7032  Int_t rv = Echo(os);
7033  delete os;
7034  return rv;
7035 }
7036 
7037 ////////////////////////////////////////////////////////////////////////////////
7038 /// Send object to master or slave servers. Returns number of slaves object
7039 /// was sent to, -1 in case of error.
7040 
7042 {
7043  if (!IsValid() || !obj) return -1;
7044 
7045  TMessage mess(kMESS_OBJECT);
7046 
7047  mess.WriteObject(obj);
7048  return Broadcast(mess, list);
7049 }
7050 
7051 ////////////////////////////////////////////////////////////////////////////////
7052 /// Send print command to master server. Returns number of slaves message
7053 /// was sent to. Returns -1 in case of error.
7054 
7056 {
7057  if (!IsValid()) return -1;
7058 
7059  Broadcast(option, kPROOF_PRINT, kActive);
7060  return Collect(kActive, fCollectTimeout);
7061 }
7062 
7063 ////////////////////////////////////////////////////////////////////////////////
7064 /// Set server logging level.
7065 
7067 {
7068  char str[32];
7069  fLogLevel = level;
7070  gProofDebugLevel = level;
7072  snprintf(str, 32, "%d %u", level, mask);
7074 }
7075 
7076 ////////////////////////////////////////////////////////////////////////////////
7077 /// Switch ON/OFF the real-time logging facility. When this option is
7078 /// ON, log messages from processing are sent back as they come, instead of
7079 /// being sent back at the end in one go. This may help debugging or monitoring
7080 /// in some cases, but, depending on the amount of log, it may have significant
7081 /// consequencies on the load over the network, so it must be used with care.
7082 
7084 {
7085  if (IsValid()) {
7087  mess << on;
7088  Broadcast(mess);
7089  } else {
7090  Warning("SetRealTimeLog","session is invalid - do nothing");
7091  }
7092 }
7093 
7094 ////////////////////////////////////////////////////////////////////////////////
7095 /// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7096 /// selection is done (if nodes is less than the available nodes).
7097 /// Returns the number of parallel slaves. Returns -1 in case of error.
7098 
7100 {
7101  if (!IsValid()) return -1;
7102 
7103  if (TestBit(TProof::kIsMaster)) {
7104  if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7105  return SendCurrentState();
7106  } else {
7107  if (nodes < 0) {
7108  PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7109  } else {
7110  PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7111  nodes == 1 ? "" : "s");
7112  }
7113  TMessage mess(kPROOF_PARALLEL);
7114  mess << nodes << random;
7115  Broadcast(mess);
7117  Int_t n = GetParallel();
7118  PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7119  return n;
7120  }
7121 }
7122 
7123 ////////////////////////////////////////////////////////////////////////////////
7124 /// Tell PROOF how many slaves to use in parallel. Returns the number of
7125 /// parallel slaves. Returns -1 in case of error.
7126 
7128 {
7129  // If delayed startup reset settings, if required
7130  if (fDynamicStartup && nodes < 0) {
7131  if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7132  }
7133 
7134  Int_t n = SetParallelSilent(nodes, random);
7135  if (TestBit(TProof::kIsClient)) {
7136  if (n < 1) {
7137  Printf("PROOF set to sequential mode");
7138  } else {
7139  TString subfix = (n == 1) ? "" : "s";
7140  if (random)
7141  subfix += ", randomly selected";
7142  Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7143  }
7144  } else if (fDynamicStartup && nodes >= 0) {
7145  if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7146  gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7147  }
7148  return n;
7149 }
7150 
7151 ////////////////////////////////////////////////////////////////////////////////
7152 /// Add nWorkersToAdd workers to current list of workers. This function is
7153 /// works on the master only, and only when an analysis is ongoing. A message
7154 /// is sent back to the client when we go "more" parallel.
7155 /// Returns -1 on error, number of total (not added!) workers on success.
7156 
7158 {
7159  if (!IsValid() || !IsMaster() || IsIdle()) {
7160  Error("GoMoreParallel", "can't invoke here -- should not happen!");
7161  return -1;
7162  }
7163  if (!gProofServ && !IsLite()) {
7164  Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7165  return -1;
7166  }
7167 
7168  TSlave *sl = 0x0;
7169  TIter next( fSlaves );
7170  Int_t nAddedWorkers = 0;
7171 
7172  while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7173  (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7174 
7175  // If worker is of an invalid type, break everything: it should not happen!
7176  if ((sl->GetSlaveType() != TSlave::kSlave) &&
7177  (sl->GetSlaveType() != TSlave::kMaster)) {
7178  Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7179  sl->GetName(), sl->GetOrdinal());
7180  R__ASSERT(0);
7181  }
7182 
7183  // Skip current worker if it is not a good candidate
7184  if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7185  (strcmp("IGNORE", sl->GetImage()) == 0)) {
7186  PDB(kGlobal, 2)
7187  Info("GoMoreParallel", "Worker %s:%s won't be considered",
7188  sl->GetName(), sl->GetOrdinal());
7189  continue;
7190  }
7191 
7192  // Worker is good but it is already active: skip it
7193  if (fActiveSlaves->FindObject(sl)) {
7194  Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7195  sl->GetName(), sl->GetOrdinal());
7196  continue;
7197  }
7198 
7199  //
7200  // From here on: worker is a good candidate
7201  //
7202 
7203  if (sl->GetSlaveType() == TSlave::kSlave) {
7205  fActiveSlaves->Add(sl);
7206  fInactiveSlaves->Remove(sl);
7207  fActiveMonitor->Add(sl->GetSocket());
7208  nAddedWorkers++;
7209  PDB(kGlobal, 2)
7210  Info("GoMoreParallel", "Worker %s:%s marked as active!",
7211  sl->GetName(), sl->GetOrdinal());
7212  }
7213  else {
7214  // Can't add masters dynamically: this should not happen!
7215  Error("GoMoreParallel", "Dynamic addition of master is not supported");
7216  R__ASSERT(0);
7217  }
7218 
7219  } // end loop over all slaves
7220 
7221  // Get slave status (will set the slaves fWorkDir correctly)
7222  PDB(kGlobal, 3)
7223  Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7224  AskStatistics();
7225 
7226  // Find active slaves with unique image
7227  PDB(kGlobal, 3)
7228  Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7229  FindUniqueSlaves();
7230 
7231  // Send new group-view to slaves
7232  PDB(kGlobal, 3)
7233  Info("GoMoreParallel", "Will invoke SendGroupView()");
7234  SendGroupView();
7235 
7236  PDB(kGlobal, 3)
7237  Info("GoMoreParallel", "Will invoke GetParallel()");
7238  Int_t nTotalWorkers = GetParallel();
7239 
7240  // Notify the client that we've got more workers, and print info on
7241  // Master's log as well
7242  TString s;
7243  s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7244  nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7245  nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7247  Info("GoMoreParallel", "%s", s.Data());
7248 
7249  return nTotalWorkers;
7250 }
7251 
7252 ////////////////////////////////////////////////////////////////////////////////
7253 /// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7254 /// list is sorted by slave performace the active list will contain first
7255 /// the most performant nodes. Returns the number of active slaves.
7256 /// If random is TRUE, and nodes is less than the number of available workers,
7257 /// a random selection is done.
7258 /// Returns -1 in case of error.
7259 
7261 {
7262  if (!IsValid()) return -1;
7263 
7264  fActiveSlaves->Clear();
7266 
7267  // Prepare the list of candidates first.
7268  // Algorithm depends on random option.
7269  TSlave *sl = 0;
7270  TList *wlst = new TList;
7271  TIter nxt(fSlaves);
7273  while ((sl = (TSlave *)nxt())) {
7274  if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7275  if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7276  if ((sl->GetSlaveType() != TSlave::kSlave) &&
7277  (sl->GetSlaveType() != TSlave::kMaster)) {
7278  Error("GoParallel", "TSlave is neither Master nor Slave");
7279  R__ASSERT(0);
7280  }
7281  // Good candidate
7282  wlst->Add(sl);
7283  // Set it inactive
7284  fInactiveSlaves->Add(sl);
7286  }
7287  }
7288  Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7289  int cnt = 0;
7291  while (cnt < nwrks) {
7292  // Random choice, if requested
7293  if (random) {
7294  Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7295  sl = (TSlave *) wlst->At(iwrk);
7296  } else {
7297  // The first available
7298  sl = (TSlave *) wlst->First();
7299  }
7300  if (!sl) {
7301  Error("GoParallel", "attaching to candidate!");
7302  break;
7303  }
7304  // Remove from the list
7305  wlst->Remove(sl);
7306 
7307  Int_t slavenodes = 0;
7308  if (sl->GetSlaveType() == TSlave::kSlave) {
7310  fActiveSlaves->Add(sl);
7311  fInactiveSlaves->Remove(sl);
7312  fActiveMonitor->Add(sl->GetSocket());
7313  slavenodes = 1;
7314  } else if (sl->GetSlaveType() == TSlave::kMaster) {
7315  fEndMaster = kFALSE;
7316  TMessage mess(kPROOF_PARALLEL);
7317  if (!attach) {
7318  Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7319  mess << nn;
7320  } else {
7321  // To get the number of slaves
7322  mess.SetWhat(kPROOF_LOGFILE);
7323  mess << -1 << -1;
7324  }
7325  if (sl->GetSocket()->Send(mess) == -1) {
7326  MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7327  slavenodes = 0;
7328  } else {
7329  Collect(sl, fCollectTimeout);
7330  if (sl->IsValid()) {
7332  fActiveSlaves->Add(sl);
7333  fInactiveSlaves->Remove(sl);
7334  fActiveMonitor->Add(sl->GetSocket());
7335  if (sl->GetParallel() > 0) {
7336  slavenodes = sl->GetParallel();
7337  } else {
7338  // Sequential mode: the master acts as a worker
7339  slavenodes = 1;
7340  }
7341  } else {
7342  MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7343  slavenodes = 0;
7344  }
7345  }
7346  }
7347  // 'slavenodes' may be different than 1 in multimaster setups
7348  cnt += slavenodes;
7349  }
7350 
7351  // Cleanup list
7352  wlst->SetOwner(0);
7353  SafeDelete(wlst);
7354 
7355  // Get slave status (will set the slaves fWorkDir correctly)
7356  AskStatistics();
7357 
7358  // Find active slaves with unique image
7359  FindUniqueSlaves();
7360 
7361  // Send new group-view to slaves
7362  if (!attach)
7363  SendGroupView();
7364 
7365  Int_t n = GetParallel();
7366 
7367  if (TestBit(TProof::kIsClient)) {
7368  if (n < 1)
7369  printf("PROOF set to sequential mode\n");
7370  else
7371  printf("PROOF set to parallel mode (%d worker%s)\n",
7372  n, n == 1 ? "" : "s");
7373  }
7374 
7375  PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7376  return n;
7377 }
7378 
7379 ////////////////////////////////////////////////////////////////////////////////
7380 /// List contents of the data directory in the sandbox.
7381 /// This is the place where files produced by the client queries are kept
7382 
7384 {
7385  if (!IsValid() || !fManager) return;
7386 
7387  // This is run via the manager
7388  fManager->Find("~/data", "-type f", "all");
7389 }
7390 
7391 ////////////////////////////////////////////////////////////////////////////////
7392 /// Remove files for the data directory.
7393 /// The option 'what' can take the values:
7394 /// kPurge remove all files and directories under '~/data'
7395 /// kUnregistered remove only files not in registered datasets (default)
7396 /// kDataset remove files belonging to dataset 'dsname'
7397 /// User is prompt for confirmation, unless kForceClear is ORed with the option
7398 
7399 void TProof::ClearData(UInt_t what, const char *dsname)
7400 {
7401  if (!IsValid() || !fManager) return;
7402 
7403  // Check whether we need to prompt
7404  TString prompt, a("Y");
7405  Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7406  Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7407 
7408  // If all just send the request
7409  if ((what & TProof::kPurge)) {
7410  // Prompt, if requested
7411  if (doask && !Prompt("Do you really want to remove all data files")) return;
7412  if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7413  Warning("ClearData", "problems purging data directory");
7414  return;
7415  } else if ((what & TProof::kDataset)) {
7416  // We must have got a name
7417  if (!dsname || strlen(dsname) <= 0) {
7418  Error("ClearData", "dataset name mandatory when removing a full dataset");
7419  return;
7420  }
7421  // Check if the dataset is registered
7422  if (!ExistsDataSet(dsname)) {
7423  Error("ClearData", "dataset '%s' does not exists", dsname);
7424  return;
7425  }
7426  // Get the file content
7427  TFileCollection *fc = GetDataSet(dsname);
7428  if (!fc) {
7429  Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7430  return;
7431  }
7432  // Prompt, if requested
7433  TString pmpt = TString::Format("Do you really want to remove all data files"
7434  " of dataset '%s'", dsname);
7435  if (doask && !Prompt(pmpt.Data())) return;
7436 
7437  // Loop through the files
7438  Bool_t rmds = kTRUE;
7439  TIter nxf(fc->GetList());
7440  TFileInfo *fi = 0;
7441  Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7442  while ((fi = (TFileInfo *) nxf())) {
7443  // Fill the host info
7444  TString host, file;
7445  // Take info from the current url
7446  if (!(fi->GetFirstUrl())) {
7447  Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7448  fi->GetName());
7449  continue;
7450  }
7451  TUrl uf(*(fi->GetFirstUrl()));
7452  file = uf.GetFile();
7453  host = uf.GetHost();
7454  // Now search for any "file:" url
7455  Int_t nurl = fi->GetNUrls();
7456  fi->ResetUrl();
7457  TUrl *up = 0;
7458  while (nurl-- && fi->NextUrl()) {
7459  up = fi->GetCurrentUrl();
7460  if (!strcmp(up->GetProtocol(), "file")) {
7461  TString opt(up->GetOptions());
7462  if (opt.BeginsWith("node=")) {
7463  host=opt;
7464  host.ReplaceAll("node=","");
7465  file = up->GetFile();
7466  break;
7467  }
7468  }
7469  }
7470  // Issue a remove request now
7471  if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7472  Error("ClearData", "problems removing '%s'", file.Data());
7473  // Some files not removed: keep the meta info about this dataset
7474  rmds = kFALSE;
7475  }
7476  rfiles++;
7477  ClearDataProgress(rfiles, nfiles);
7478  }
7479  fprintf(stderr, "\n");
7480  if (rmds) {
7481  // All files were removed successfully: remove also the dataset meta info
7482  RemoveDataSet(dsname);
7483  }
7484  } else if (what & TProof::kUnregistered) {
7485 
7486  // Get the existing files
7487  TString outtmp("ProofClearData_");
7488  FILE *ftmp = gSystem->TempFileName(outtmp);
7489  if (!ftmp) {
7490  Error("ClearData", "cannot create temp file for logs");
7491  return;
7492  }
7493  fclose(ftmp);
7495  gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7496  ShowData();
7497  gSystem->RedirectOutput(0, 0, &h);
7498  // Parse the output file now
7499  std::ifstream in;
7500  in.open(outtmp.Data());
7501  if (!in.is_open()) {
7502  Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7503  gSystem->Unlink(outtmp);
7504  return;
7505  }
7506  // Go through
7507  Int_t nfiles = 0;
7508  TMap *afmap = new TMap;
7509  TString line, host, file;
7510  Int_t from = 0;
7511  while (in.good()) {
7512  line.ReadLine(in);
7513  if (line.IsNull()) continue;
7514  while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7515  from = 0;
7516  host = "";
7517  if (!line.Tokenize(host, from, "| ")) continue;
7518  file = "";
7519  if (!line.Tokenize(file, from, "| ")) continue;
7520  if (!host.IsNull() && !file.IsNull()) {
7521  TList *fl = (TList *) afmap->GetValue(host.Data());
7522  if (!fl) {
7523  fl = new TList();
7524  fl->SetName(host);
7525  afmap->Add(new TObjString(host), fl);
7526  }
7527  fl->Add(new TObjString(file));
7528  nfiles++;
7529  PDB(kDataset,2)
7530  Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7531  } else {
7532  Warning("ClearData", "found incomplete line: '%s'", line.Data());
7533  }
7534  }
7535  // Close and remove the file
7536  in.close();
7537  gSystem->Unlink(outtmp);
7538 
7539  // Get registered data files
7540  TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7541  TMap *fcmap = GetDataSets(sel);
7542  if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7543  PDB(kDataset,1)
7544  Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7545  SafeDelete(fcmap);
7546  }
7547 
7548  // Go thorugh and prepare the lists per node
7549  TString opt;
7550  TObjString *os = 0;
7551  if (fcmap) {
7552  TIter nxfc(fcmap);
7553  while ((os = (TObjString *) nxfc())) {
7554  TFileCollection *fc = 0;
7555  if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7556  TFileInfo *fi = 0;
7557  TIter nxfi(fc->GetList());
7558  while ((fi = (TFileInfo *) nxfi())) {
7559  // Get special "file:" url
7560  fi->ResetUrl();
7561  Int_t nurl = fi->GetNUrls();
7562  TUrl *up = 0;
7563  while (nurl-- && fi->NextUrl()) {
7564  up = fi->GetCurrentUrl();
7565  if (!strcmp(up->GetProtocol(), "file")) {
7566  opt = up->GetOptions();
7567  if (opt.BeginsWith("node=")) {
7568  host=opt;
7569  host.ReplaceAll("node=","");
7570  file = up->GetFile();
7571  PDB(kDataset,2)
7572  Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7573  // Remove this from the full list, if there
7574  TList *fl = (TList *) afmap->GetValue(host.Data());
7575  if (fl) {
7576  TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7577  if (fn) {
7578  fl->Remove(fn);
7579  SafeDelete(fn);
7580  nfiles--;
7581  } else {
7582  Warning("ClearData",
7583  "registered file '%s' not found in the full list!",
7584  file.Data());
7585  }
7586  }
7587  break;
7588  }
7589  }
7590  }
7591  }
7592  }
7593  }
7594  // Clean up the the received map
7595  if (fcmap) fcmap->SetOwner(kTRUE);
7596  SafeDelete(fcmap);
7597  }
7598  // List of the files to be removed
7599  Info("ClearData", "%d unregistered files to be removed:", nfiles);
7600  afmap->Print();
7601  // Prompt, if requested
7602  TString pmpt = TString::Format("Do you really want to remove all %d"
7603  " unregistered data files", nfiles);
7604  if (doask && !Prompt(pmpt.Data())) return;
7605 
7606  // Remove one by one; we may implement a bloc remove in the future
7607  Int_t rfiles = 0;
7608  TIter nxls(afmap);
7609  while ((os = (TObjString *) nxls())) {
7610  TList *fl = 0;
7611  if ((fl = (TList *) afmap->GetValue(os))) {
7612  TIter nxf(fl);
7613  TObjString *fn = 0;
7614  while ((fn = (TObjString *) nxf())) {
7615  // Issue a remove request now
7616  if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7617  Error("ClearData", "problems removing '%s' on host '%s'",
7618  fn->GetName(), os->GetName());
7619  }
7620  rfiles++;
7621  ClearDataProgress(rfiles, nfiles);
7622  }
7623  }
7624  }
7625  fprintf(stderr, "\n");
7626  // Final cleanup
7627  afmap->SetOwner(kTRUE);
7628  SafeDelete(afmap);
7629  }
7630 }
7631 
7632 ////////////////////////////////////////////////////////////////////////////////
7633 /// Prompt the question 'p' requiring an answer y,Y,n,N
7634 /// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7635 
7636 Bool_t TProof::Prompt(const char *p)
7637 {
7638  TString pp(p);
7639  if (!pp.Contains("?")) pp += "?";
7640  if (!pp.Contains("[y/N]")) pp += " [y/N]";
7641  TString a = Getline(pp.Data());
7642  if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7643  Printf("Please answer y, Y, n or N");
7644  // Unclear answer: assume negative
7645  return kFALSE;
7646  } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7647  // Explicitly Negative answer
7648  return kFALSE;
7649  }
7650  // Explicitly Positive answer
7651  return kTRUE;
7652 }
7653 
7654 ////////////////////////////////////////////////////////////////////////////////
7655 /// Progress bar for clear data
7656 
7658 {
7659  fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7660  for (Int_t l = 0; l < 20; l++) {
7661  if (r > 0 && t > 0) {
7662  if (l < 20*r/t)
7663  fprintf(stderr, "=");
7664  else if (l == 20*r/t)
7665  fprintf(stderr, ">");
7666  else if (l > 20*r/t)
7667  fprintf(stderr, ".");
7668  } else
7669  fprintf(stderr, "=");
7670  }
7671  fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7672 }
7673 
7674 ////////////////////////////////////////////////////////////////////////////////
7675 /// List contents of file cache. If all is true show all caches also on
7676 /// slaves. If everything is ok all caches are to be the same.
7677 
7679 {
7680  if (!IsValid()) return;
7681 
7682  TMessage mess(kPROOF_CACHE);
7683  mess << Int_t(kShowCache) << all;
7684  Broadcast(mess, kUnique);
7685 
7686  if (all) {
7687  TMessage mess2(kPROOF_CACHE);
7688  mess2 << Int_t(kShowSubCache) << all;
7689  Broadcast(mess2, fNonUniqueMasters);
7690 
7692  } else {
7694  }
7695 }
7696 
7697 ////////////////////////////////////////////////////////////////////////////////
7698 /// Remove file from all file caches. If file is 0 or "" or "*", remove all
7699 /// the files
7700 
7701 void TProof::ClearCache(const char *file)
7702 {
7703  if (!IsValid()) return;
7704 
7705  TMessage mess(kPROOF_CACHE);
7706  mess << Int_t(kClearCache) << TString(file);
7707  Broadcast(mess, kUnique);
7708 
7709  TMessage mess2(kPROOF_CACHE);
7710  mess2 << Int_t(kClearSubCache) << TString(file);
7711  Broadcast(mess2, fNonUniqueMasters);
7712 
7714 
7715  // clear file map so files get send again to remote nodes
7716  fFileMap.clear();
7717 }
7718 
7719 ////////////////////////////////////////////////////////////////////////////////
7720 /// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7721 
7722 void TProof::SystemCmd(const char *cmd, Int_t fdout)
7723 {
7724  if (fdout < 0) {
7725  // Exec directly the command
7726  gSystem->Exec(cmd);
7727  } else {
7728  // Exec via a pipe
7729  FILE *fin = gSystem->OpenPipe(cmd, "r");
7730  if (fin) {
7731  // Now we go
7732  char line[2048];
7733  while (fgets(line, 2048, fin)) {
7734  Int_t r = strlen(line);
7735  if (r > 0) {
7736  if (write(fdout, line, r) < 0) {
7737  ::Warning("TProof::SystemCmd",
7738  "errno %d writing to file descriptor %d",
7739  TSystem::GetErrno(), fdout);
7740  }
7741  } else {
7742  // Done
7743  break;
7744  }
7745  }
7746  gSystem->ClosePipe(fin);
7747  }
7748  }
7749 }
7750 
7751 ////////////////////////////////////////////////////////////////////////////////
7752 /// List contents of package directory. If all is true show all package
7753 /// directories also on slaves. If everything is ok all package directories
7754 /// should be the same. If redir is kTRUE the result is redirected to the log
7755 /// file (option available for internal actions).
7756 
7758 {
7759  if (!IsValid()) return;
7760 
7761  Bool_t oldredir = fRedirLog;
7762  if (redirlog) fRedirLog = kTRUE;
7763 
7764  // Active logging unit
7765  FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7766  if (!fout) {
7767  Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7768  " will not log msgs", fout);
7769  return;
7770  }
7771  lseek(fileno(fout), (off_t) 0, SEEK_END);
7772 
7773  if (TestBit(TProof::kIsClient)) {
7775  // Scan the list of global packages dirs
7777  TNamed *nm = 0;
7778  while ((nm = (TNamed *)nxd())) {
7779  fprintf(fout, "*** Global Package cache %s client:%s ***\n",
7780  nm->GetName(), nm->GetTitle());
7781  fflush(fout);
7782  SystemCmd(TString::Format("%s %s", kLS, nm->GetTitle()), fileno(fout));
7783  fprintf(fout, "\n");
7784  fflush(fout);
7785  }
7786  }
7787  fprintf(fout, "*** Package cache client:%s ***\n", fPackageDir.Data());
7788  fflush(fout);
7789  SystemCmd(TString::Format("%s %s", kLS, fPackageDir.Data()), fileno(fout));
7790  fprintf(fout, "\n");
7791  }
7792 
7793  // Nothing more to do if we are a Lite-session
7794  if (IsLite()) {
7795  fRedirLog = oldredir;
7796  return;
7797  }
7798 
7799  TMessage mess(kPROOF_CACHE);
7800  mess << Int_t(kShowPackages) << all;
7801  Broadcast(mess, kUnique);
7802 
7803  if (all) {
7804  TMessage mess2(kPROOF_CACHE);
7805  mess2 << Int_t(kShowSubPackages) << all;
7806  Broadcast(mess2, fNonUniqueMasters);
7807 
7809  } else {
7811  }
7812  // Restore logging option
7813  fRedirLog = oldredir;
7814 }
7815 
7816 ////////////////////////////////////////////////////////////////////////////////
7817 /// List which packages are enabled. If all is true show enabled packages
7818 /// for all active slaves. If everything is ok all active slaves should
7819 /// have the same packages enabled.
7820 
7822 {
7823  if (!IsValid()) return;
7824 
7825  if (TestBit(TProof::kIsClient)) {
7826  printf("*** Enabled packages on client on %s\n", gSystem->HostName());
7828  while (TObjString *str = (TObjString*) next())
7829  printf("%s\n", str->GetName());
7830  }
7831 
7832  // Nothing more to do if we are a Lite-session
7833  if (IsLite()) return;
7834 
7835  TMessage mess(kPROOF_CACHE);
7836  mess << Int_t(kShowEnabledPackages) << all;
7837  Broadcast(mess);
7839 }
7840 
7841 ////////////////////////////////////////////////////////////////////////////////
7842 /// Remove all packages.
7843 /// Returns 0 in case of success and -1 in case of error.
7844 
7846 {
7847  if (!IsValid()) return -1;
7848 
7849  if (UnloadPackages() == -1)
7850  return -1;
7851 
7852  if (DisablePackages() == -1)
7853  return -1;
7854 
7855  return fStatus;
7856 }
7857 
7858 ////////////////////////////////////////////////////////////////////////////////
7859 /// Remove a specific package.
7860 /// Returns 0 in case of success and -1 in case of error.
7861 
7862 Int_t TProof::ClearPackage(const char *package)
7863 {
7864  if (!IsValid()) return -1;
7865 
7866  if (!package || !package[0]) {
7867  Error("ClearPackage", "need to specify a package name");
7868  return -1;
7869  }
7870 
7871  // if name, erroneously, is a par pathname strip off .par and path
7872  TString pac = package;
7873  if (pac.EndsWith(".par"))
7874  pac.Remove(pac.Length()-4);
7875  pac = gSystem->BaseName(pac);
7876 
7877  if (UnloadPackage(pac) == -1)
7878  return -1;
7879 
7880  if (DisablePackage(pac) == -1)
7881  return -1;
7882 
7883  return fStatus;
7884 }
7885 
7886 ////////////////////////////////////////////////////////////////////////////////
7887 /// Remove a specific package.
7888 /// Returns 0 in case of success and -1 in case of error.
7889 
7890 Int_t TProof::DisablePackage(const char *package)
7891 {
7892  if (!IsValid()) return -1;
7893 
7894  if (!package || !package[0]) {
7895  Error("DisablePackage", "need to specify a package name");
7896  return -1;
7897  }
7898 
7899  // if name, erroneously, is a par pathname strip off .par and path
7900  TString pac = package;
7901  if (pac.EndsWith(".par"))
7902  pac.Remove(pac.Length()-4);
7903  pac = gSystem->BaseName(pac);
7904 
7905  if (DisablePackageOnClient(pac) == -1)
7906  return -1;
7907 
7908  // Nothing more to do if we are a Lite-session
7909  if (IsLite()) return 0;
7910 
7911  Int_t st = -1;
7912  Bool_t done = kFALSE;
7913  if (fManager) {
7914  // Try to do it via XROOTD (new way)
7915  TString path;
7916  path.Form("~/packages/%s", package);
7917  if (fManager->Rm(path, "-rf", "all") != -1) {
7918  path.Append(".par");
7919  if (fManager->Rm(path, "-f", "all") != -1) {
7920  done = kTRUE;
7921  st = 0;
7922  }
7923  }
7924  }
7925  if (!done) {
7926  // Try via TProofServ (old way)
7927  TMessage mess(kPROOF_CACHE);
7928  mess << Int_t(kDisablePackage) << pac;
7929  Broadcast(mess, kUnique);
7930 
7931  TMessage mess2(kPROOF_CACHE);
7932  mess2 << Int_t(kDisableSubPackage) << pac;
7933  Broadcast(mess2, fNonUniqueMasters);
7934 
7936  st = fStatus;
7937  }
7938 
7939  // Done
7940  return st;
7941 }
7942 
7943 ////////////////////////////////////////////////////////////////////////////////
7944 /// Remove a specific package 'pack' from the client.
7945 /// Returns 0 in case of success and -1 in case of error.
7946 
7948 {
7949  TString s;
7950  if (TestBit(TProof::kIsClient)) {
7951  // Remove the package directory and the par file locally
7952  fPackageLock->Lock();
7953  s.Form("%s %s/%s", kRM, fPackageDir.Data(), pack);
7954  gSystem->Exec(s.Data());
7955  s.Form("%s %s/%s.par", kRM, fPackageDir.Data(), pack);
7956  gSystem->Exec(s.Data());
7957  s.Form("%s %s/%s/%s.par", kRM, fPackageDir.Data(), kPROOF_PackDownloadDir, pack);
7958  gSystem->Exec(s.Data());
7959  fPackageLock->Unlock();
7960  // Check the result
7961  s.Form("%s/%s/%s.par", fPackageDir.Data(), kPROOF_PackDownloadDir, pack);
7962  if (!gSystem->AccessPathName(s.Data()))
7963  Warning("DisablePackageOnClient",
7964  "unable to remove cached package PAR file for %s (%s)", pack, s.Data());
7965  s.Form("%s/%s.par", fPackageDir.Data(), pack);
7966  if (!gSystem->AccessPathName(s.Data()))
7967  Warning("DisablePackageOnClient",
7968  "unable to remove package PAR file for %s (%s)", pack, s.Data());
7969  s.Form("%s/%s", fPackageDir.Data(), pack);
7970  if (!gSystem->AccessPathName(s.Data()))
7971  Warning("DisablePackageOnClient",
7972  "unable to remove package directory for %s (%s)", pack, s.Data());
7973  }
7974 
7975  return 0;
7976 }
7977 
7978 ////////////////////////////////////////////////////////////////////////////////
7979 /// Remove all packages.
7980 /// Returns 0 in case of success and -1 in case of error.
7981 
7983 {
7984  if (!IsValid()) return -1;
7985 
7986  // remove all packages on client
7987  if (TestBit(TProof::kIsClient)) {
7988  fPackageLock->Lock();
7989  gSystem->Exec(TString::Format("%s %s/*", kRM, fPackageDir.Data()));
7990  fPackageLock->Unlock();
7991  }
7992 
7993  // Nothing more to do if we are a Lite-session
7994  if (IsLite()) return 0;
7995 
7996  Int_t st = -1;
7997  Bool_t done = kFALSE;
7998  if (fManager) {
7999  // Try to do it via XROOTD (new way)
8000  if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
8001  done = kTRUE;
8002  st = 0;
8003  }
8004  }
8005  if (!done) {
8006 
8007  TMessage mess(kPROOF_CACHE);
8008  mess << Int_t(kDisablePackages);
8009  Broadcast(mess, kUnique);
8010 
8011  TMessage mess2(kPROOF_CACHE);
8012  mess2 << Int_t(kDisableSubPackages);
8013  Broadcast(mess2, fNonUniqueMasters);
8014 
8016  st = fStatus;
8017  }
8018 
8019  // Done
8020  return st;
8021 }
8022 
8023 ////////////////////////////////////////////////////////////////////////////////
8024 /// Build specified package. Executes the PROOF-INF/BUILD.sh
8025 /// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
8026 /// then submit build command to slaves, but don't wait
8027 /// for results. If opt is kCollectBuildResults then collect result
8028 /// from slaves. To be used on the master.
8029 /// If opt = kBuildAll (default) then submit and wait for results
8030 /// (to be used on the client).
8031 /// Returns 0 in case of success and -1 in case of error.
8032 
8033 Int_t TProof::BuildPackage(const char *package,
8034  EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
8035 {
8036  if (!IsValid()) return -1;
8037 
8038  if (!package || !package[0]) {
8039  Error("BuildPackage", "need to specify a package name");
8040  return -1;
8041  }
8042 
8043  // if name, erroneously, is a par pathname strip off .par and path
8044  TString pac = package;
8045  if (pac.EndsWith(".par"))
8046  pac.Remove(pac.Length()-4);
8047  pac = gSystem->BaseName(pac);
8048 
8049  Bool_t buildOnClient = kTRUE;
8050  if (opt == kDontBuildOnClient) {
8051  buildOnClient = kFALSE;
8052  opt = kBuildAll;
8053  }
8054  // Prepare the local package
8055  TString pdir;
8056  Int_t st = 0;
8057  if (buildOnClient) {
8059  if ((st = BuildPackageOnClient(pac, 1, &pdir, chkveropt) != 0)) {
8061  return -1;
8062  }
8063  }
8064 
8065  if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
8066  if (workers) {
8067  TMessage mess(kPROOF_CACHE);
8068  mess << Int_t(kBuildPackage) << pac << chkveropt;
8069  Broadcast(mess, workers);
8070 
8071  } else {
8072  TMessage mess(kPROOF_CACHE);
8073  mess << Int_t(kBuildPackage) << pac << chkveropt;
8074  Broadcast(mess, kUnique);
8075 
8076  TMessage mess2(kPROOF_CACHE);
8077  mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8078  Broadcast(mess2, fNonUniqueMasters);
8079  }
8080  }
8081 
8082  if (opt >= kBuildAll) {
8083  // by first forwarding the build commands to the master and slaves
8084  // and only then building locally we build in parallel
8085  if (buildOnClient) {
8086  st = BuildPackageOnClient(pac, 2, &pdir, chkveropt);
8088  }
8089 
8090 
8091  fStatus = 0;
8092  if (!IsLite() || !buildOnClient) {
8093 
8094  // On the master, workers that fail are deactivated
8095  // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8096  if (workers) {
8097 // Collect(workers, -1, -1, deactivateOnFailure);
8098  Collect(workers);
8099  } else {
8101  }
8102  }
8103 
8104  if (fStatus < 0 || st < 0)
8105  return -1;
8106  }
8107 
8108  return 0;
8109 }
8110 
8111 ////////////////////////////////////////////////////////////////////////////////
8112 /// Build specified package on the client. Executes the PROOF-INF/BUILD.sh
8113 /// script if it exists on the client.
8114 /// If opt == 0, both the preparation and building phases are run.
8115 /// If opt == 1, only the preparation phase (asserting and, eventually, downloading
8116 /// of the package) is done; '*path' contains the full path to the
8117 /// package to be passed in the next call
8118 /// If opt == 2, only the building phase is run using *path .
8119 /// Returns 0 in case of success and -1 in case of error.
8120 /// The code is equivalent to the one in TProofServ.cxx (TProof::kBuildPackage
8121 /// case). Keep in sync in case of changes.
8122 
8123 Int_t TProof::BuildPackageOnClient(const char *pack, Int_t opt, TString *path, Int_t chkveropt)
8124 {
8125  TString downloaddir;
8126  downloaddir.Form("%s/%s", fPackageDir.Data(), kPROOF_PackDownloadDir);
8127 
8128  if (opt != 0 && !path) {
8129  Error("BuildPackageOnClient", "for opt=%d != 0 'patyh' must be defined", opt);
8130  return -1;
8131  }
8132 
8133  if (TestBit(TProof::kIsClient)) {
8134  Int_t status = 0;
8135  TString pdir, ocwd;
8136 
8137  if (opt == 0 || opt == 1) {
8138  // Package path
8139  pdir.Form("%s/%s", fPackageDir.Data(), pack);
8140  if (gSystem->AccessPathName(pdir, kReadPermission) ||
8141  gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
8142  pdir = "";
8143  // Is there a global package with this name?
8145  // Scan the list of global packages dirs
8147  TNamed *nm = 0;
8148  while ((nm = (TNamed *)nxd())) {
8149  pdir = Form("%s/%s", nm->GetTitle(), pack);
8150  if (!gSystem->AccessPathName(pdir, kReadPermission) &&
8151  !gSystem->AccessPathName(pdir + "/PROOF-INF", kReadPermission)) {
8152  // Package found, stop searching
8153  break;
8154  }
8155  pdir = "";
8156  }
8157  }
8158  } else {
8159  // Check if the related PAR file still exists (private versions could have gone:
8160  // in such a case we should take the reference from the repository, by first cleaning
8161  // the existing directory)
8162  TString tpar(pdir);
8163  if (!tpar.EndsWith(".par")) tpar += ".par";
8164  Bool_t badPAR = kTRUE;
8165  FileStat_t stpar;
8166  if (gSystem->GetPathInfo(tpar, stpar) == 0) {
8167 #ifndef WIN32
8168  char ctmp[1024];
8169  if (!R_ISLNK(stpar.fMode) || readlink(tpar.Data(), ctmp, 1024) > 0) {
8170  // The file exists
8171  badPAR = kFALSE;
8172  }
8173 #else
8174  // The file exists
8175  badPAR = kFALSE;
8176 #endif
8177  }
8178  // Cleanup, if bad
8179  if (badPAR) {
8180  // Remove package directory
8181  gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
8182  // Remove link or bad file
8183  gSystem->Exec(TString::Format("%s %s", kRM, tpar.Data()));
8184  // Reset variable
8185  pdir = "";
8186  }
8187  }
8188  // Check if the package was downloaded from the master
8189  Bool_t wasDownloaded = kFALSE;
8190  TString dlpar;
8191  dlpar.Form("%s/%s", downloaddir.Data(), gSystem->BaseName(pack));
8192  if (!dlpar.EndsWith(".par")) dlpar += ".par";
8193  if (!pdir.IsNull()) {
8194  if (!gSystem->AccessPathName(dlpar, kFileExists))
8195  wasDownloaded = kTRUE;
8196  }
8197  if (pdir.IsNull() || wasDownloaded) {
8198  // Try to download it
8199  if (DownloadPackage(pack, downloaddir) != 0) {
8200  Error("BuildPackageOnClient",
8201  "PAR file '%s.par' not found and could not be downloaded", pack);
8202  return -1;
8203  } else {
8204  TMD5 *md5 = TMD5::FileChecksum(dlpar);
8205  if (UploadPackageOnClient(dlpar, kUntar, md5) == -1) {
8206  Error("BuildPackageOnClient",
8207  "PAR file '%s.par' not found and could not be unpacked locally", pack);
8208  delete md5;
8209  return -1;
8210  }
8211  delete md5;
8212  // The package is now linked from the default package dir
8213  pdir.Form("%s/%s", fPackageDir.Data(), pack);
8214  }
8215  } else if (pdir.IsNull()) {
8216  Error("BuildPackageOnClient", "PAR file '%s.par' not found", pack);
8217  return -1;
8218  }
8219  PDB(kPackage, 1)
8220  Info("BuildPackageOnClient", "package %s exists and has PROOF-INF directory", pack);
8221  // We are done if only prepare was requested
8222  if (opt == 1) {
8223  *path = pdir;
8224  return 0;
8225  }
8226  }
8227 
8228  if (opt == 0 || opt == 2) {
8229  if (opt == 2) pdir = path->Data();
8230 
8231  ocwd = gSystem->WorkingDirectory();
8232  gSystem->ChangeDirectory(pdir);
8233 
8234  // check for BUILD.sh and execute
8235  if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
8236 
8237  // read version from file proofvers.txt, and if current version is
8238  // not the same do a "BUILD.sh clean"
8239  Bool_t goodver = kTRUE;
8240  Bool_t savever = kFALSE;
8241  TString v, r;
8242  FILE *f = fopen("PROOF-INF/proofvers.txt", "r");
8243  if (f) {
8244  v.Gets(f);
8245  r.Gets(f);
8246  fclose(f);
8247  if (chkveropt == kCheckROOT || chkveropt == kCheckSVN) {
8248  if (v != gROOT->GetVersion()) goodver = kFALSE;
8249  if (goodver && chkveropt == kCheckSVN)
8250  if (r != gROOT->GetGitCommit()) goodver = kFALSE;
8251  }
8252  }
8253  if (!f || !goodver) {
8254  savever = kTRUE;
8255  Info("BuildPackageOnClient",
8256  "%s: version change (current: %s:%s, build: %s:%s): cleaning ... ",
8257  pack, gROOT->GetVersion(), gROOT->GetGitCommit(), v.Data(), r.Data());
8258  // Hard cleanup: go up the dir tree
8260  // remove package directory
8261  gSystem->Exec(TString::Format("%s %s", kRM, pdir.Data()));
8262  // find gunzip...
8263  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP, kExecutePermission);
8264  if (gunzip) {
8265  TString par = TString::Format("%s.par", pdir.Data());
8266  // untar package
8267  TString cmd(TString::Format(kUNTAR3, gunzip, par.Data()));
8268  status = gSystem->Exec(cmd);
8269  if ((status = gSystem->Exec(cmd))) {
8270  Error("BuildPackageOnClient", "failure executing: %s", cmd.Data());
8271  } else {
8272  // Go down to the package directory
8273  gSystem->ChangeDirectory(pdir);
8274  }
8275  delete [] gunzip;
8276  } else {
8277  Error("BuildPackageOnClient", "%s not found", kGUNZIP);
8278  status = -1;
8279  }
8280  }
8281 
8282  if (gSystem->Exec("export ROOTPROOFCLIENT=\"1\" ; PROOF-INF/BUILD.sh")) {
8283  Error("BuildPackageOnClient", "building package %s on the client failed", pack);
8284  status = -1;
8285  }
8286 
8287  if (savever && !status) {
8288  f = fopen("PROOF-INF/proofvers.txt", "w");
8289  if (f) {
8290  fputs(gROOT->GetVersion(), f);
8291  fputs(TString::Format("\n%s", gROOT->GetGitCommit()), f);
8292  fclose(f);
8293  }
8294  }
8295  } else {
8296  PDB(kPackage, 1)
8297  Info("BuildPackageOnClient",
8298  "package %s exists but has no PROOF-INF/BUILD.sh script", pack);
8299  }
8300 
8301  gSystem->ChangeDirectory(ocwd);
8302 
8303  return status;
8304  }
8305  }
8306  return 0;
8307 }
8308 
8309 ////////////////////////////////////////////////////////////////////////////////
8310 /// Load specified package. Executes the PROOF-INF/SETUP.C script
8311 /// on all active nodes. If notOnClient = true, don't load package
8312 /// on the client. The default is to load the package also on the client.
8313 /// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8314 /// The objects in the list must be streamable; the SETUP macro will be executed
8315 /// like this: SETUP.C(loadopts).
8316 /// Returns 0 in case of success and -1 in case of error.
8317 
8318 Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8319  TList *loadopts, TList *workers)
8320 {
8321  if (!IsValid()) return -1;
8322 
8323  if (!package || !package[0]) {
8324  Error("LoadPackage", "need to specify a package name");
8325  return -1;
8326  }
8327 
8328  // if name, erroneously, is a par pathname strip off .par and path
8329  TString pac = package;
8330  if (pac.EndsWith(".par"))
8331  pac.Remove(pac.Length()-4);
8332  pac = gSystem->BaseName(pac);
8333 
8334  if (!notOnClient)
8335  if (LoadPackageOnClient(pac, loadopts) == -1)
8336  return -1;
8337 
8338  TMessage mess(kPROOF_CACHE);
8339  mess << Int_t(kLoadPackage) << pac;
8340  if (loadopts) mess << loadopts;
8341 
8342  // On the master, workers that fail are deactivated
8343  Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8344 
8345  Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8346 
8347  if (workers) {
8348  PDB(kPackage, 3)
8349  Info("LoadPackage", "Sending load message to selected workers only");
8350  Broadcast(mess, workers);
8351  if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8352  } else {
8353  Broadcast(mess);
8354  Collect(kActive, -1, -1, deactivateOnFailure);
8355  }
8356 
8357  return fStatus;
8358 }
8359 
8360 ////////////////////////////////////////////////////////////////////////////////
8361 /// Load specified package in the client. Executes the PROOF-INF/SETUP.C
8362 /// script on the client. Returns 0 in case of success and -1 in case of error.
8363 /// The code is equivalent to the one in TProofServ.cxx (TProof::kLoadPackage
8364 /// case). Keep in sync in case of changes.
8365 /// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8366 /// The objects in the list must be streamable; the SETUP macro will be executed
8367 /// like this: SETUP.C(loadopts).
8368 /// Returns 0 in case of success and -1 in case of error.
8369 
8370 Int_t TProof::LoadPackageOnClient(const char *pack, TList *loadopts)
8371 {
8372  if (TestBit(TProof::kIsClient)) {
8373  Int_t status = 0;
8374  TString pdir, ocwd;
8375  // If already loaded don't do it again
8376  if (fEnabledPackagesOnClient->FindObject(pack)) {
8377  Info("LoadPackageOnClient", "package %s already loaded", pack);
8378  return 0;
8379  }
8380 
8381  // always follows BuildPackage so no need to check for PROOF-INF
8382  pdir.Form("%s/%s", fPackageDir.Data(), pack);
8383 
8384  if (gSystem->AccessPathName(pdir, kReadPermission)) {
8385  // Is there a global package with this name?
8387  // Scan the list of global packages dirs
8389  TNamed *nm = 0;
8390  while ((nm = (TNamed *)nxd())) {
8391  pdir.Form("%s/%s", nm->GetTitle(), pack);
8392  if (!gSystem->AccessPathName(pdir, kReadPermission)) {
8393  // Package found, stop searching
8394  break;
8395  }
8396  pdir = "";
8397  }
8398  if (pdir.Length() <= 0) {
8399  // Package not found
8400  Error("LoadPackageOnClient", "failure locating %s ...", pack);
8401  return -1;
8402  }
8403  }
8404  }
8405 
8406  ocwd = gSystem->WorkingDirectory();
8407  gSystem->ChangeDirectory(pdir);
8408 
8409  // check for SETUP.C and execute
8410  if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
8411 
8412  // We need to change the name of the function to avoid problems when we load more packages
8413  TString setup;
8414  setup.Form("SETUP_%d_%x", gSystem->GetPid(), TString(pack).Hash());
8415  // setupfn.Form("%s/%s.C", gSystem->TempDirectory(), setup.Data());
8416  TMacro setupmc("PROOF-INF/SETUP.C");
8417  TObjString *setupline = setupmc.GetLineWith("SETUP(");
8418  if (setupline) {
8419  TString setupstring(setupline->GetString());
8420  setupstring.ReplaceAll("SETUP(", TString::Format("%s(", setup.Data()));
8421  setupline->SetString(setupstring);
8422  } else {
8423  // Macro does not contain SETUP()
8424  Warning("LoadPackageOnClient", "macro '%s/PROOF-INF/SETUP.C' does not contain a SETUP()"
8425  " function", pack);
8426  }
8427 
8428  if (!setupmc.Load()) {
8429  // Macro could not be loaded
8430  Error("LoadPackageOnClient", "macro '%s/PROOF-INF/SETUP.C' could not be loaded:"
8431  " cannot continue", pack);
8432  status = -1;
8433  } else {
8434  // Check the signature
8435  TFunction *fun = (TFunction *) gROOT->GetListOfGlobalFunctions()->FindObject(setup);
8436  if (!fun) {
8437  // Notify the upper level
8438  Error("LoadPackageOnClient", "function SETUP() not found in macro '%s/PROOF-INF/SETUP.C':"
8439  " cannot continue", pack);
8440  status = -1;
8441  } else {
8442  TMethodCall callEnv;
8443  // Check the number of arguments
8444  if (fun->GetNargs() == 0) {
8445  // No arguments (basic signature)
8446  callEnv.Init(fun);
8447  // Warn that the argument (if any) if ignored
8448  if (loadopts)
8449  Warning("LoadPackageOnClient", "loaded SETUP() does not take any argument:"
8450  " the specified TList object will be ignored");
8451  } else if (fun->GetNargs() == 1) {
8452  TMethodArg *arg = (TMethodArg *) fun->GetListOfMethodArgs()->First();
8453  if (arg) {
8454  callEnv.Init(fun);
8455  // Check argument type
8456  TString argsig(arg->GetTitle());
8457  if (argsig.BeginsWith("TList")) {
8458  callEnv.ResetParam();
8459  callEnv.SetParam((Long_t) loadopts);
8460  } else if (argsig.BeginsWith("const char")) {
8461  callEnv.ResetParam();
8462  TObjString *os = loadopts ? dynamic_cast<TObjString *>(loadopts->First()) : 0;
8463  if (os) {
8464  callEnv.SetParam((Long_t) os->GetName());
8465  } else {
8466  if (loadopts && loadopts->First()) {
8467  Warning("LoadPackageOnClient", "found object argument of type %s:"
8468  " SETUP expects 'const char *': ignoring",
8469  loadopts->First()->ClassName());
8470  }
8471  callEnv.SetParam((Long_t) 0);
8472  }
8473  } else {
8474  // Notify the upper level
8475  Error("LoadPackageOnClient", "unsupported SETUP signature: SETUP(%s)"
8476  " cannot continue", arg->GetTitle());
8477  status = -1;
8478  }
8479  } else {
8480  // Notify the upper level
8481  Error("LoadPackageOnClient", "cannot get information about the SETUP() argument:"
8482  " cannot continue");
8483  status = -1;
8484  }
8485  } else if (fun->GetNargs() > 1) {
8486  // Notify the upper level
8487  Error("LoadPackageOnClient", "function SETUP() can have at most a 'TList *' argument:"
8488  " cannot continue");
8489  status = -1;
8490  }
8491  // Execute
8492  Long_t setuprc = (status == 0) ? 0 : -1;
8493  if (status == 0) {
8494  callEnv.Execute(setuprc);
8495  if (setuprc < 0) status = -1;
8496  }
8497  }
8498  }
8499  } else {
8500  PDB(kPackage, 1)
8501  Info("LoadPackageOnClient",
8502  "package %s exists but has no PROOF-INF/SETUP.C script", pack);
8503  }
8504 
8505  gSystem->ChangeDirectory(ocwd);
8506 
8507  if (status == 0) {
8508 
8509  // Add package directory to list of include directories to be searched by ACliC
8510  gSystem->AddIncludePath(TString("-I") + pdir);
8511 
8512  // add package directory to list of include directories to be searched by CINT
8513  gROOT->ProcessLine(TString(".I ") + pdir);
8514 
8516  PDB(kPackage, 1)
8517  Info("LoadPackageOnClient", "package %s successfully loaded", pack);
8518  } else
8519  Error("LoadPackageOnClient", "loading package %s on client failed", pack);
8520 
8521  return status;
8522  }
8523  return 0;
8524 }
8525 
8526 ////////////////////////////////////////////////////////////////////////////////
8527 /// Unload specified package.
8528 /// Returns 0 in case of success and -1 in case of error.
8529 
8530 Int_t TProof::UnloadPackage(const char *package)
8531 {
8532  if (!IsValid()) return -1;
8533 
8534  if (!package || !package[0]) {
8535  Error("UnloadPackage", "need to specify a package name");
8536  return -1;
8537  }
8538 
8539  // if name, erroneously, is a par pathname strip off .par and path
8540  TString pac = package;
8541  if (pac.EndsWith(".par"))
8542  pac.Remove(pac.Length()-4);
8543  pac = gSystem->BaseName(pac);
8544 
8545  if (UnloadPackageOnClient(pac) == -1)
8546  return -1;
8547 
8548  // Nothing more to do if we are a Lite-session
8549  if (IsLite()) return 0;
8550 
8551  TMessage mess(kPROOF_CACHE);
8552  mess << Int_t(kUnloadPackage) << pac;
8553  Broadcast(mess);
8554  Collect();
8555 
8556  return fStatus;
8557 }
8558 
8559 ////////////////////////////////////////////////////////////////////////////////
8560 /// Unload a specific package on the client.
8561 /// Returns 0 in case of success and -1 in case of error.
8562 /// The code is equivalent to the one in TProofServ.cxx (TProof::UnloadPackage
8563 /// case). Keep in sync in case of changes.
8564 
8566 {
8567  if (TestBit(TProof::kIsClient)) {
8569  if (pack) {
8570  // Remove entry from include path
8571  TString aclicincpath = gSystem->GetIncludePath();
8572  TString cintincpath = gInterpreter->GetIncludePath();
8573  // remove interpreter part of gSystem->GetIncludePath()
8574  aclicincpath.Remove(aclicincpath.Length() - cintincpath.Length() - 1);
8575  // remove package's include path
8576  aclicincpath.ReplaceAll(TString(" -I") + package, "");
8577  gSystem->SetIncludePath(aclicincpath);
8578 
8579  //TODO reset interpreter include path
8580 
8581  // remove entry from enabled packages list
8583  }
8584 
8585  // cleanup the link
8586  if (!gSystem->AccessPathName(package))
8587  if (gSystem->Unlink(package) != 0)
8588  Warning("UnloadPackageOnClient", "unable to remove symlink to %s", package);
8589 
8590  // delete entry
8591  delete pack;
8592  }
8593  return 0;
8594 }
8595 
8596 ////////////////////////////////////////////////////////////////////////////////
8597 /// Unload all packages.
8598 /// Returns 0 in case of success and -1 in case of error.
8599 
8601 {
8602  if (!IsValid()) return -1;
8603 
8604  if (TestBit(TProof::kIsClient)) {
8605  // Iterate over packages on the client and remove each package
8606  TIter nextpackage(fEnabledPackagesOnClient);
8607  while (TObjString *objstr = dynamic_cast<TObjString*>(nextpackage()))
8608  if (UnloadPackageOnClient(objstr->String()) == -1 )
8609  return -1;
8610  }
8611 
8612  // Nothing more to do if we are a Lite-session
8613  if (IsLite()) return 0;
8614 
8615  TMessage mess(kPROOF_CACHE);
8616  mess << Int_t(kUnloadPackages);
8617  Broadcast(mess);
8618  Collect();
8619 
8620  return fStatus;
8621 }
8622 
8623 ////////////////////////////////////////////////////////////////////////////////
8624 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8625 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8626 /// In case notOnClient = true, don't enable the package on the client.
8627 /// The default is to enable packages also on the client.
8628 /// If specified, enables packages only on the specified workers.
8629 /// Returns 0 in case of success and -1 in case of error.
8630 /// Provided for backward compatibility.
8631 
8632 Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8633  TList *workers)
8634 {
8635  return EnablePackage(package, (TList *)0, notOnClient, workers);
8636 }
8637 
8638 ////////////////////////////////////////////////////////////////////////////////
8639 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8640 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8641 /// In case notOnClient = true, don't enable the package on the client.
8642 /// The default is to enable packages also on the client.
8643 /// It is is possible to specify options for the loading step via 'loadopts';
8644 /// the string will be passed passed as argument to SETUP.
8645 /// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8646 /// plugin version checking during building: possible choices are:
8647 /// off no check; failure may occur at loading
8648 /// on check ROOT version [default]
8649 /// svn check ROOT version and Git commit SHA1.
8650 /// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8651 /// If specified, enables packages only on the specified workers.
8652 /// Returns 0 in case of success and -1 in case of error.
8653 
8654 Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8655  Bool_t notOnClient, TList *workers)
8656 {
8657  TList *optls = 0;
8658  if (loadopts && strlen(loadopts)) {
8659  if (fProtocol > 28) {
8660  TObjString *os = new TObjString(loadopts);
8661  // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8662  os->String().ReplaceAll("checkversion=", "chkv=");
8663  Ssiz_t fcv = kNPOS, lcv = kNPOS;
8664  if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8665  TRegexp re("[; |]");
8666  if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8667  lcv = os->String().Length();
8668  }
8669  TString ocv = os->String()(fcv, lcv - fcv);
8670  Int_t cvopt = -1;
8671  if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8672  cvopt = (Int_t) kDontCheck;
8673  else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8674  cvopt = (Int_t) kCheckROOT;
8675  else if (ocv.EndsWith("=svn") || ocv.EndsWith("=2"))
8676  cvopt = (Int_t) kCheckSVN;
8677  else
8678  Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8679  if (cvopt > -1) {
8680  if (gDebug > 0)
8681  Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8682  optls = new TList;
8683  optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8684  // Remove the special option from; we leave a separator if there were two (one before and one after)
8685  if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8686  if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8687  os->String().ReplaceAll(ocv.Data(), "");
8688  }
8689  }
8690  if (!os->String().IsNull()) {
8691  if (!optls) optls = new TList;
8692  optls->Add(new TObjString(os->String().Data()));
8693  }
8694  if (optls) optls->SetOwner(kTRUE);
8695  } else {
8696  // Notify
8697  Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8698  }
8699  }
8700  // Run
8701  Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8702  // Clean up
8703  SafeDelete(optls);
8704  // Done
8705  return rc;
8706 }
8707 
8708 ////////////////////////////////////////////////////////////////////////////////
8709 /// Enable specified package. Executes the PROOF-INF/BUILD.sh
8710 /// script if it exists followed by the PROOF-INF/SETUP.C script.
8711 /// In case notOnClient = true, don't enable the package on the client.
8712 /// The default is to enable packages also on the client.
8713 /// It is is possible to specify a list of objects to be passed to the SETUP
8714 /// functions via 'loadopts'; the objects must be streamable.
8715 /// Returns 0 in case of success and -1 in case of error.
8716 
8717 Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8718  Bool_t notOnClient, TList *workers)
8719 {
8720  if (!IsValid()) return -1;
8721 
8722  if (!package || !package[0]) {
8723  Error("EnablePackage", "need to specify a package name");
8724  return -1;
8725  }
8726 
8727  // if name, erroneously, is a par pathname strip off .par and path
8728  TString pac = package;
8729  if (pac.EndsWith(".par"))
8730  pac.Remove(pac.Length()-4);
8731  pac = gSystem->BaseName(pac);
8732 
8734  if (notOnClient)
8735  opt = kDontBuildOnClient;
8736 
8737  // Get check version option; user settings have priority
8738  Int_t chkveropt = kCheckROOT;
8739  TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8740  if (!ocv.IsNull()) {
8741  if (ocv == "off" || ocv == "0")
8742  chkveropt = (Int_t) kDontCheck;
8743  else if (ocv == "on" || ocv == "1")
8744  chkveropt = (Int_t) kCheckROOT;
8745  else if (ocv == "svn" || ocv == "2")
8746  chkveropt = (Int_t) kCheckSVN;
8747  else
8748  Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8749  }
8750  if (loadopts) {
8751  TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8752  if (pcv) {
8753  chkveropt = pcv->GetVal();
8754  loadopts->Remove(pcv);
8755  delete pcv;
8756  }
8757  }
8758  if (gDebug > 0)
8759  Info("EnablePackage", "using check version option: %d", chkveropt);
8760 
8761  if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8762  return -1;
8763 
8764  TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8765  if (optls && fProtocol <= 28) {
8766  Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8767  optls = 0;
8768  }
8769 
8770  if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8771  return -1;
8772 
8773  // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8775  TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8776  : new TPair(new TObjString(pac), 0);
8778  }
8779 
8780  return 0;
8781 }
8782 
8783 ////////////////////////////////////////////////////////////////////////////////
8784 /// Download a PROOF archive (PAR file) from the master package repository.
8785 /// The PAR file is downloaded in the current directory or in the directory
8786 /// specified by 'dstdir'. If a package with the same name already exists
8787 /// at destination, a check on the MD5 sum is done and the user warned or
8788 /// prompted for action, depending is the file is equal or different.
8789 /// Returns 0 in case of success and -1 in case of error.
8790 
8791 Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8792 {
8793  if (!fManager || !(fManager->IsValid())) {
8794  Error("DownloadPackage", "the manager is undefined!");
8795  return -1;
8796  }
8797 
8798  // Create the default source and destination paths
8799  TString parname(gSystem->BaseName(pack)), src, dst;
8800  if (!parname.EndsWith(".par")) parname += ".par";
8801  src.Form("packages/%s", parname.Data());
8802  if (!dstdir || strlen(dstdir) <= 0) {
8803  dst.Form("./%s", parname.Data());
8804  } else {
8805  // Check the destination directory
8806  FileStat_t st;
8807  if (gSystem->GetPathInfo(dstdir, st) != 0) {
8808  // Directory does not exit: create it
8809  if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8810  Error("DownloadPackage",
8811  "could not create the destination directory '%s' (errno: %d)",
8812  dstdir, TSystem::GetErrno());
8813  return -1;
8814  }
8815  } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8816  Error("DownloadPackage",
8817  "destination path '%s' exist but is not a directory!", dstdir);
8818  return -1;
8819  }
8820  dst.Form("%s/%s", dstdir, parname.Data());
8821  }
8822 
8823  // Make sure the source file exists
8824  FileStat_t stsrc;
8825  RedirectHandle_t rh;
8826  if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8827  Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8828  Int_t rc = fManager->Stat(src, stsrc);
8829  if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8830  Warning("DownloadPackage", "problems restoring output");
8831  if (rc != 0) {
8832  // Check if there is another possible source
8834  TMacro *mp = GetLastLog();
8835  if (mp) {
8836  // Look for global directories
8837  Bool_t isGlobal = kFALSE;
8838  TIter nxl(mp->GetListOfLines());
8839  TObjString *os = 0;
8840  TString globaldir;
8841  while ((os = (TObjString *) nxl())) {
8842  TString s(os->GetName());
8843  if (s.Contains("*** Global Package cache")) {
8844  // Get the directory
8845  s.Remove(0, s.Last(':') + 1);
8846  s.Remove(s.Last(' '));
8847  globaldir = s;
8848  isGlobal = kTRUE;
8849  } else if (s.Contains("*** Package cache")) {
8850  isGlobal = kFALSE;
8851  globaldir = "";
8852  }
8853  // Check for the package
8854  if (isGlobal && s.Contains(parname)) {
8855  src.Form("%s/%s", globaldir.Data(), parname.Data());
8856  break;
8857  }
8858  }
8859  // Cleanup
8860  delete mp;
8861  }
8862  }
8863 
8864  // Do it via the manager
8865  if (fManager->GetFile(src, dst, "silent") != 0) {
8866  Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8867  pack, src.Data(), dst.Data());
8868  return -1;
8869  } else {
8870  Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8871  pack, dst.Data());
8872  }
8873  // Done
8874  return 0;
8875 }
8876 
8877 ////////////////////////////////////////////////////////////////////////////////
8878 /// Upload a PROOF archive (PAR file). A PAR file is a compressed
8879 /// tar file with one special additional directory, PROOF-INF
8880 /// (blatantly copied from Java's jar format). It must have the extension
8881 /// .par. A PAR file can be directly a binary or a source with a build
8882 /// procedure. In the PROOF-INF directory there can be a build script:
8883 /// BUILD.sh to be called to build the package, in case of a binary PAR
8884 /// file don't specify a build script or make it a no-op. Then there is
8885 /// SETUP.C which sets the right environment variables to use the package,
8886 /// like LD_LIBRARY_PATH, etc.
8887 /// The 'opt' allows to specify whether the .PAR should be just unpacked
8888 /// in the existing dir (opt = kUntar, default) or a remove of the existing
8889 /// directory should be executed (opt = kRemoveOld), so triggering a full
8890 /// re-build. The option if effective only for PROOF protocol > 8 .
8891 /// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8892 /// an alternative global directory for global usage. This may require special
8893 /// privileges.
8894 /// If download is kTRUE and the package is not found locally, then it is downloaded
8895 /// from the master repository.
8896 /// Returns 0 in case of success and -1 in case of error.
8897 
8899  TList *workers)
8900 {
8901  if (!IsValid()) return -1;
8902 
8903  TString par(pack), base, name;
8904  if (par.EndsWith(".par")) {
8905  base = gSystem->BaseName(par);
8906  name = base(0, base.Length() - strlen(".par"));
8907  } else {
8908  name = gSystem->BaseName(par);
8909  base.Form("%s.par", name.Data());
8910  par += ".par";
8911  }
8912 
8913  // Default location is the local working dir; then the package dir
8916  TString tried = par;
8917  // Try the package dir
8918  par.Form("%s/%s", fPackageDir.Data(), base.Data());
8920  // Is the package a global one
8922  // Scan the list of global packages dirs
8924  TNamed *nm = 0;
8925  TString pdir;
8926  while ((nm = (TNamed *)nxd())) {
8927  pdir.Form("%s/%s", nm->GetTitle(), name.Data());
8928  if (!gSystem->AccessPathName(pdir, kReadPermission)) {
8929  // Package found, stop searching
8930  break;
8931  }
8932  pdir = "";
8933  }
8934  if (pdir.Length() > 0) {
8935  // Package is in the global dirs
8936  if (gDebug > 0)
8937  Info("UploadPackage", "global package found (%s): no upload needed",
8938  pdir.Data());
8939  return 0;
8940  }
8941  }
8942  Error("UploadPackage", "PAR file '%s' not found; paths tried: %s, %s",
8943  gSystem->BaseName(par), tried.Data(), par.Data());
8944  return -1;
8945  }
8946  }
8947 
8948  // Strategy:
8949  // On the client:
8950  // get md5 of package and check if it is different
8951  // from the one stored in the local package directory. If it is lock
8952  // the package directory and copy the package, unlock the directory.
8953  // On the masters:
8954  // get md5 of package and check if it is different from the
8955  // one stored on the remote node. If it is different lock the remote
8956  // package directory and use TFTP or SendFile to ftp the package to the
8957  // remote node, unlock the directory.
8958 
8959  TMD5 *md5 = TMD5::FileChecksum(par);
8960 
8961  if (TestBit(TProof::kIsClient)) {
8962  if (!md5 || (md5 && UploadPackageOnClient(par, opt, md5) == -1)) {
8963  if (md5) delete md5;
8964  return -1;
8965  }
8966  }
8967 
8968  // Nothing more to do if we are a Lite-session
8969  if (IsLite()) {
8970  delete md5;
8971  return 0;
8972  }
8973 
8974  TString smsg;
8975  smsg.Form("+%s", base.Data());
8976 
8977  TMessage mess(kPROOF_CHECKFILE);
8978  mess << smsg << (*md5);
8979  TMessage mess2(kPROOF_CHECKFILE);
8980  smsg.Replace(0, 1, "-");
8981  mess2 << smsg << (*md5);
8982  TMessage mess3(kPROOF_CHECKFILE);
8983  smsg.Replace(0, 1, "=");
8984  mess3 << smsg << (*md5);
8985 
8986  delete md5;
8987 
8988  if (fProtocol > 8) {
8989  // Send also the option
8990  mess << (UInt_t) opt;
8991  mess2 << (UInt_t) opt;
8992  mess3 << (UInt_t) opt;
8993  }
8994 
8995  // Loop over all slaves with unique fs image, or to a selected
8996  // list of workers, if specified
8997  if (!workers)
8998  workers = fUniqueSlaves;
8999  TIter next(workers);
9000  TSlave *sl = 0;
9001  while ((sl = (TSlave *) next())) {
9002  if (!sl->IsValid())
9003  continue;
9004 
9005  sl->GetSocket()->Send(mess);
9006 
9007  fCheckFileStatus = 0;
9009  if (fCheckFileStatus == 0) {
9010 
9011  if (fProtocol > 5) {
9012  // remote directory is locked, upload file over the open channel
9013  smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
9014  if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
9015  Error("UploadPackage", "%s: problems uploading file %s",
9016  sl->GetOrdinal(), par.Data());
9017  return -1;
9018  }
9019  } else {
9020  // old servers receive it via TFTP
9021  TFTP ftp(TString("root://")+sl->GetName(), 1);
9022  if (!ftp.IsZombie()) {
9023  smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
9024  ftp.cd(smsg.Data());
9025  ftp.put(par, base.Data());
9026  }
9027  }
9028 
9029  // install package and unlock dir
9030  sl->GetSocket()->Send(mess2);
9031  fCheckFileStatus = 0;
9033  if (fCheckFileStatus == 0) {
9034  Error("UploadPackage", "%s: unpacking of package %s failed",
9035  sl->GetOrdinal(), base.Data());
9036  return -1;
9037  }
9038  }
9039  }
9040 
9041  // loop over all other master nodes
9042  TIter nextmaster(fNonUniqueMasters);
9043  TSlave *ma;
9044  while ((ma = (TSlave *) nextmaster())) {
9045  if (!ma->IsValid())
9046  continue;
9047 
9048  ma->GetSocket()->Send(mess3);
9049 
9050  fCheckFileStatus = 0;
9052  if (fCheckFileStatus == 0) {
9053  // error -> package should have been found
9054  Error("UploadPackage", "package %s did not exist on submaster %s",
9055  base.Data(), ma->GetOrdinal());
9056  return -1;
9057  }
9058  }
9059 
9060  return 0;
9061 }
9062 
9063 ////////////////////////////////////////////////////////////////////////////////
9064 /// Upload a package on the client in ~/.proof/packages.
9065 /// The 'opt' allows to specify whether the .PAR should be just unpacked
9066 /// in the existing dir (opt = kUntar, default) or a remove of the existing
9067 /// directory should be executed (opt = kRemoveOld), thereby triggering a full
9068 /// re-build. This option if effective only for PROOF protocol > 8.
9069 /// Returns 0 in case of success and -1 in case of error.
9070 
9072 {
9073  // Strategy:
9074  // get md5 of package and check if it is different
9075  // from the one stored in the local package directory. If it is lock
9076  // the package directory and copy the package, unlock the directory.
9077 
9078  Int_t status = 0;
9079 
9080  if (TestBit(TProof::kIsClient)) {
9081  // Make sure that 'par' is the real path and not a symlink
9082  TString par(parpack);
9083 #ifndef WIN32
9084  char ctmp[4096];
9085  ssize_t sz = readlink(par.Data(), ctmp, 4096);
9086  if (sz >= 4096) sz = 4095;
9087  if (sz > 0) {
9088  ctmp[sz] = '\0';
9089  par = ctmp;
9090  } else if (TSystem::GetErrno() != EINVAL) {
9091  Warning("UploadPackageOnClient",
9092  "could not resolve the symbolik link '%s'", par.Data());
9093  }
9094 #endif
9095  // The fPackageDir directory exists (has been created in Init());
9096  // create symlink to the par file in the fPackageDir (needed by
9097  // master in case we run on the localhost)
9098  fPackageLock->Lock();
9099 
9100  // Check if the requested PAR has been downloaded: if not, clean any
9101  // existing downloaded file with the same name: this is because now
9102  // the client has its own version of the package and should not check
9103  // the master repository anymore for updates
9104  TString downloadpath;
9105  downloadpath.Form("%s/%s/%s", fPackageDir.Data(),
9107  if (!gSystem->AccessPathName(downloadpath, kFileExists) && downloadpath != par) {
9108  if (gSystem->Unlink(downloadpath) != 0) {
9109  Warning("UploadPackageOnClient",
9110  "problems removing downloaded version of '%s' (%s):\n"
9111  "may imply inconsistencies in subsequent updates",
9112  gSystem->BaseName(par), downloadpath.Data());
9113  }
9114  }
9115  TString lpar;
9116  lpar.Form("%s/%s", fPackageDir.Data(), gSystem->BaseName(par));
9117  FileStat_t stat;
9118  Int_t st = gSystem->GetPathInfo(lpar, stat);
9119  // check if symlink, if so unlink, if not give error
9120  // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
9121  // existing file, but if fIsLink is true the symlink exists
9122  if (stat.fIsLink)
9123  gSystem->Unlink(lpar);
9124  else if (st == 0) {
9125  Error("UploadPackageOnClient", "cannot create symlink %s on client, "
9126  "another item with same name already exists",
9127  lpar.Data());
9128  fPackageLock->Unlock();
9129  return -1;
9130  }
9131  if (!gSystem->IsAbsoluteFileName(par)) {
9132  TString fpar = par;
9134  } else
9135  gSystem->Symlink(par, lpar);
9136  // TODO: On Windows need to copy instead of symlink
9137 
9138  TString cmd;
9139  // Compare md5
9140  TString packnam = par(0, par.Length() - 4); // strip off ".par"
9141  packnam = gSystem->BaseName(packnam); // strip off path
9142  TString md5f = fPackageDir + "/" + packnam + "/PROOF-INF/md5.txt";
9143  TMD5 *md5local = TMD5::ReadChecksum(md5f);
9144  if (!md5local || (*md5) != (*md5local)) {
9145  // if not, unzip and untar package in package directory
9146  if ((opt & TProof::kRemoveOld)) {
9147  // remove any previous package directory with same name
9148  cmd.Form("%s %s/%s", kRM, fPackageDir.Data(), packnam.Data());
9149  if (gSystem->Exec(cmd.Data()))
9150  Error("UploadPackageOnClient", "failure executing: %s", cmd.Data());
9151  }
9152  // find gunzip
9153  char *gunzip = gSystem->Which(gSystem->Getenv("PATH"), kGUNZIP,
9155  if (gunzip) {
9156  // untar package
9157  cmd.Form(kUNTAR2, gunzip, par.Data(), fPackageDir.Data());
9158  if (gSystem->Exec(cmd.Data()))
9159  Error("Uploadpackage", "failure executing: %s", cmd.Data());
9160  delete [] gunzip;
9161  } else
9162  Error("UploadPackageOnClient", "%s not found", kGUNZIP);
9163 
9164  // check that fPackageDir/packnam now exists
9165  if (gSystem->AccessPathName(fPackageDir + "/" + packnam, kWritePermission)) {
9166  // par file did not unpack itself in the expected directory, failure
9167  Error("UploadPackageOnClient",
9168  "package %s did not unpack into %s/%s", par.Data(), fPackageDir.Data(),
9169  packnam.Data());
9170  status = -1;
9171  } else {
9172  // store md5 in package/PROOF-INF/md5.txt
9173  TMD5::WriteChecksum(md5f, md5);
9174  }
9175  }
9176  fPackageLock->Unlock();
9177  delete md5local;
9178  }
9179  return status;
9180 }
9181 
9182 ////////////////////////////////////////////////////////////////////////////////
9183 /// Load the specified macro on master, workers and, if notOnClient is
9184 /// kFALSE, on the client. The macro file is uploaded if new or updated.
9185 /// Additional files to be uploaded (or updated, if needed) can be specified
9186 /// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
9187 /// If existing in the same directory, a header basename(macro).h or .hh, is also
9188 /// uploaded.
9189 /// The default is to load the macro also on the client; notOnClient can be used
9190 /// to avoid loading on the client.
9191 /// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
9192 /// only, and collection is not done; if uniqueWorkers is kFALSE, collection
9193 /// from the previous request is done, and broadcasting + collection from the
9194 /// other workers is done.
9195 /// The wrks arg can be used on the master to limit the set of workers.
9196 /// Returns 0 in case of success and -1 in case of error.
9197 
9198 Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
9199  TList *wrks)
9200 {
9201  if (!IsValid()) return -1;
9202 
9203  if (!macro || !macro[0]) {
9204  Error("Load", "need to specify a macro name");
9205  return -1;
9206  }
9207 
9208  if (TestBit(TProof::kIsClient) && !wrks) {
9209 
9210  // Extract the file implementation name first
9211  TString addsname, implname = macro;
9212  Ssiz_t icom = implname.Index(",");
9213  if (icom != kNPOS) {
9214  addsname = implname(icom + 1, implname.Length());
9215  implname.Remove(icom);
9216  }
9217  TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
9218  TString bmsg(basemacro), acmode, args, io;
9219  implname = gSystem->SplitAclicMode(implname, acmode, args, io);
9220 
9221  // Macro names must have a standard format
9222  Int_t dot = implname.Last('.');
9223  if (dot == kNPOS) {
9224  Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
9225  return -1;
9226  }
9227 
9228  // Is there any associated header file
9229  Bool_t hasHeader = kTRUE;
9230  TString headname = implname;
9231  headname.Remove(dot);
9232  headname += ".h";
9233  if (gSystem->AccessPathName(headname, kReadPermission)) {
9234  TString h = headname;
9235  headname.Remove(dot);
9236  headname += ".hh";
9237  if (gSystem->AccessPathName(headname, kReadPermission)) {
9238  hasHeader = kFALSE;
9239  if (gDebug > 0)
9240  Info("Load", "no associated header file found: tried: %s %s",
9241  h.Data(), headname.Data());
9242  }
9243  }
9244 
9245  // Is there any additional file ?
9246  TString addincs;
9247  TList addfiles;
9248  if (!addsname.IsNull()) {
9249  TString fn;
9250  Int_t from = 0;
9251  while (addsname.Tokenize(fn, from, ",")) {
9253  Error("Load", "additional file '%s' not found", fn.Data());
9254  return -1;
9255  }
9256  // Create the additional include statement
9257  if (!notOnClient) {
9258  TString dirn(gSystem->DirName(fn));
9259  if (addincs.IsNull()) {
9260  addincs.Form("-I%s", dirn.Data());
9261  } else if (!addincs.Contains(dirn)) {
9262  addincs += TString::Format(" -I%s", dirn.Data());
9263  }
9264  }
9265  // Remember these files ...
9266  addfiles.Add(new TObjString(fn));
9267  }
9268  }
9269 
9270  // Send files now; the md5 check is run here; see SendFile for more
9271  // details.
9272  if (SendFile(implname, kAscii | kForward , "cache") == -1) {
9273  Error("Load", "problems sending implementation file %s", implname.Data());
9274  return -1;
9275  }
9276  if (hasHeader)
9277  if (SendFile(headname, kAscii | kForward , "cache") == -1) {
9278  Error("Load", "problems sending header file %s", headname.Data());
9279  return -1;
9280  }
9281  // Additional files
9282  if (addfiles.GetSize() > 0) {
9283  TIter nxfn(&addfiles);
9284  TObjString *os = 0;
9285  while ((os = (TObjString *) nxfn())) {
9286  // These files need to be available everywhere, cache and sandbox
9287  if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
9288  Error("Load", "problems sending additional file %s", os->GetName());
9289  return -1;
9290  }
9291  // Add the base names to the message broadcasted
9292  bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
9293  }
9294  addfiles.SetOwner(kTRUE);
9295  }
9296 
9297  // The files are now on the workers: now we send the loading request
9298  TMessage mess(kPROOF_CACHE);
9299  if (GetRemoteProtocol() < 34) {
9300  mess << Int_t(kLoadMacro) << basemacro;
9301  // This may be needed
9302  AddIncludePath("../../cache");
9303  } else {
9304  mess << Int_t(kLoadMacro) << bmsg;
9305  }
9306  Broadcast(mess, kActive);
9307 
9308  // Load locally, if required
9309  if (!notOnClient) {
9310  // Mofify the include path
9311  TString oldincs = gSystem->GetIncludePath();
9312  if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
9313 
9314  // By first forwarding the load command to the master and workers
9315  // and only then loading locally we load/build in parallel
9316  gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
9317 
9318  // Restore include path
9319  if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
9320 
9321  // Update the macro path
9323  TString np(gSystem->DirName(macro));
9324  if (!np.IsNull()) {
9325  np += ":";
9326  if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
9327  Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
9328  mp.Insert(ip, np);
9329  TROOT::SetMacroPath(mp);
9330  if (gDebug > 0)
9331  Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
9332  }
9333  }
9334  }
9335 
9336  // Wait for master and workers to be done
9337  Collect(kActive);
9338 
9339  if (IsLite()) {
9340  PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
9341  if (!fLoadedMacros) {
9342  fLoadedMacros = new TList();
9344  }
9345  // if wrks is specified the macro should already be loaded on the master.
9346  fLoadedMacros->Add(new TObjString(macro));
9347  }
9348 
9349  } else {
9350  // On master
9351 
9352  // The files are now on the workers: now we send the loading request first
9353  // to the unique workers, so that the eventual compilation occurs only once.
9354  TString basemacro = gSystem->BaseName(macro);
9355  TMessage mess(kPROOF_CACHE);
9356 
9357  if (uniqueWorkers) {
9358  mess << Int_t(kLoadMacro) << basemacro;
9359  if (wrks) {
9360  Broadcast(mess, wrks);
9361  Collect(wrks);
9362  } else {
9363  Broadcast(mess, kUnique);
9364  }
9365  } else {
9366  // Wait for the result of the previous sending
9367  Collect(kUnique);
9368 
9369  // We then send a tuned loading request to the other workers
9370  TList others;
9371  TSlave *wrk = 0;
9372  TIter nxw(fActiveSlaves);
9373  while ((wrk = (TSlave *)nxw())) {
9374  if (!fUniqueSlaves->FindObject(wrk)) {
9375  others.Add(wrk);
9376  }
9377  }
9378 
9379  // Do not force compilation, if it was requested
9380  Int_t ld = basemacro.Last('.');
9381  if (ld != kNPOS) {
9382  Int_t lpp = basemacro.Index("++", ld);
9383  if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
9384  }
9385  mess << Int_t(kLoadMacro) << basemacro;
9386  Broadcast(mess, &others);
9387  Collect(&others);
9388  }
9389 
9390  PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
9391  if (!fLoadedMacros) {
9392  fLoadedMacros = new TList();
9394  }
9395  // if wrks is specified the macro should already be loaded on the master.
9396  if (!wrks)
9397  fLoadedMacros->Add(new TObjString(macro));
9398  }
9399 
9400  // Done
9401  return 0;
9402 }
9403 
9404 ////////////////////////////////////////////////////////////////////////////////
9405 /// Add 'libpath' to the lib path search.
9406 /// Multiple paths can be specified at once separating them with a comma or
9407 /// a blank.
9408 /// Return 0 on success, -1 otherwise
9409 
9410 Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
9411  Bool_t doCollect)
9412 {
9413  if ((!libpath || !libpath[0])) {
9414  if (gDebug > 0)
9415  Info("AddDynamicPath", "list is empty - nothing to do");
9416  return 0;
9417  }
9418 
9419  // Do it also on clients, if required
9420  if (onClient)
9421  HandleLibIncPath("lib", kTRUE, libpath);
9422 
9424  m << TString("lib") << (Bool_t)kTRUE;
9425 
9426  // Add paths
9427  if (libpath && strlen(libpath)) {
9428  m << TString(libpath);
9429  } else {
9430  m << TString("-");
9431  }
9432 
9433  // Tell the server to send back or not
9434  m << (Int_t)doCollect;
9435 
9436  // Forward the request
9437  if (wrks) {
9438  Broadcast(m, wrks);
9439  if (doCollect)
9440  Collect(wrks, fCollectTimeout);
9441  } else {
9442  Broadcast(m);
9444  }
9445 
9446  return 0;
9447 }
9448 
9449 ////////////////////////////////////////////////////////////////////////////////
9450 /// Add 'incpath' to the inc path search.
9451 /// Multiple paths can be specified at once separating them with a comma or
9452 /// a blank.
9453 /// Return 0 on success, -1 otherwise
9454 
9455 Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
9456  Bool_t doCollect)
9457 {
9458  if ((!incpath || !incpath[0])) {
9459  if (gDebug > 0)
9460  Info("AddIncludePath", "list is empty - nothing to do");
9461  return 0;
9462  }
9463 
9464  // Do it also on clients, if required
9465  if (onClient)
9466  HandleLibIncPath("inc", kTRUE, incpath);
9467 
9469  m << TString("inc") << (Bool_t)kTRUE;
9470 
9471  // Add paths
9472  if (incpath && strlen(incpath)) {
9473  m << TString(incpath);
9474  } else {
9475  m << TString("-");
9476  }
9477 
9478  // Tell the server to send back or not
9479  m << (Int_t)doCollect;
9480 
9481  // Forward the request
9482  if (wrks) {
9483  Broadcast(m, wrks);
9484  if (doCollect)
9485  Collect(wrks, fCollectTimeout);
9486  } else {
9487  Broadcast(m);
9489  }
9490 
9491  return 0;
9492 }
9493 
9494 ////////////////////////////////////////////////////////////////////////////////
9495 /// Remove 'libpath' from the lib path search.
9496 /// Multiple paths can be specified at once separating them with a comma or
9497 /// a blank.
9498 /// Return 0 on success, -1 otherwise
9499 
9500 Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
9501 {
9502  if ((!libpath || !libpath[0])) {
9503  if (gDebug > 0)
9504  Info("RemoveDynamicPath", "list is empty - nothing to do");
9505  return 0;
9506  }
9507 
9508  // Do it also on clients, if required
9509  if (onClient)
9510  HandleLibIncPath("lib", kFALSE, libpath);
9511 
9513  m << TString("lib") <<(Bool_t)kFALSE;
9514 
9515  // Add paths
9516  if (libpath && strlen(libpath))
9517  m << TString(libpath);
9518  else
9519  m << TString("-");
9520 
9521  // Forward the request
9522  Broadcast(m);
9524 
9525  return 0;
9526 }
9527 
9528 ////////////////////////////////////////////////////////////////////////////////
9529 /// Remove 'incpath' from the inc path search.
9530 /// Multiple paths can be specified at once separating them with a comma or
9531 /// a blank.
9532 /// Return 0 on success, -1 otherwise
9533 
9534 Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
9535 {
9536  if ((!incpath || !incpath[0])) {
9537  if (gDebug > 0)
9538  Info("RemoveIncludePath", "list is empty - nothing to do");
9539  return 0;
9540  }
9541 
9542  // Do it also on clients, if required
9543  if (onClient)
9544  HandleLibIncPath("in", kFALSE, incpath);
9545 
9547  m << TString("inc") << (Bool_t)kFALSE;
9548 
9549  // Add paths
9550  if (incpath && strlen(incpath))
9551  m << TString(incpath);
9552  else
9553  m << TString("-");
9554 
9555  // Forward the request
9556  Broadcast(m);
9558 
9559  return 0;
9560 }
9561 
9562 ////////////////////////////////////////////////////////////////////////////////
9563 /// Handle lib, inc search paths modification request
9564 
9565 void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
9566 {
9567  TString type(what);
9568  TString path(dirs);
9569 
9570  // Check type of action
9571  if ((type != "lib") && (type != "inc")) {
9572  Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
9573  return;
9574  }
9575 
9576  // Separators can be either commas or blanks
9577  path.ReplaceAll(","," ");
9578 
9579  // Decompose lists
9580  TObjArray *op = 0;
9581  if (path.Length() > 0 && path != "-") {
9582  if (!(op = path.Tokenize(" "))) {
9583  Warning("HandleLibIncPath","decomposing path %s", path.Data());
9584  return;
9585  }
9586  }
9587 
9588  if (add) {
9589 
9590  if (type == "lib") {
9591 
9592  // Add libs
9593  TIter nxl(op, kIterBackward);
9594  TObjString *lib = 0;
9595  while ((lib = (TObjString *) nxl())) {
9596  // Expand path
9597  TString xlib = lib->GetName();
9598  gSystem->ExpandPathName(xlib);
9599  // Add to the dynamic lib search path if it exists and can be read
9600  if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9601  TString newlibpath = gSystem->GetDynamicPath();
9602  // In the first position after the working dir
9603  Int_t pos = 0;
9604  if (newlibpath.BeginsWith(".:"))
9605  pos = 2;
9606  if (newlibpath.Index(xlib) == kNPOS) {
9607  newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9608  gSystem->SetDynamicPath(newlibpath);
9609  }
9610  } else {
9611  if (gDebug > 0)
9612  Info("HandleLibIncPath",
9613  "libpath %s does not exist or cannot be read - not added", xlib.Data());
9614  }
9615  }
9616 
9617  } else {
9618 
9619  // Add incs
9620  TIter nxi(op);
9621  TObjString *inc = 0;
9622  while ((inc = (TObjString *) nxi())) {
9623  // Expand path
9624  TString xinc = inc->GetName();
9625  gSystem->ExpandPathName(xinc);
9626  // Add to the dynamic lib search path if it exists and can be read
9627  if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9628  TString curincpath = gSystem->GetIncludePath();
9629  if (curincpath.Index(xinc) == kNPOS)
9630  gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9631  } else
9632  if (gDebug > 0)
9633  Info("HandleLibIncPath",
9634  "incpath %s does not exist or cannot be read - not added", xinc.Data());
9635  }
9636  }
9637 
9638 
9639  } else {
9640 
9641  if (type == "lib") {
9642 
9643  // Remove libs
9644  TIter nxl(op);
9645  TObjString *lib = 0;
9646  while ((lib = (TObjString *) nxl())) {
9647  // Expand path
9648  TString xlib = lib->GetName();
9649  gSystem->ExpandPathName(xlib);
9650  // Remove from the dynamic lib search path
9651  TString newlibpath = gSystem->GetDynamicPath();
9652  newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9653  gSystem->SetDynamicPath(newlibpath);
9654  }
9655 
9656  } else {
9657 
9658  // Remove incs
9659  TIter nxi(op);
9660  TObjString *inc = 0;
9661  while ((inc = (TObjString *) nxi())) {
9662  TString newincpath = gSystem->GetIncludePath();
9663  newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9664  // Remove the interpreter path (added anyhow internally)
9665  newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9666  gSystem->SetIncludePath(newincpath);
9667  }
9668  }
9669  }
9670 }
9671 
9672 ////////////////////////////////////////////////////////////////////////////////
9673 /// Get from the master the list of names of the packages available.
9674 
9676 {
9677  if (!IsValid())
9678  return (TList *)0;
9679 
9680  TMessage mess(kPROOF_CACHE);
9681  mess << Int_t(kListPackages);
9682  Broadcast(mess);
9684 
9685  return fAvailablePackages;
9686 }
9687 
9688 ////////////////////////////////////////////////////////////////////////////////
9689 /// Get from the master the list of names of the packages enabled.
9690 
9692 {
9693  if (!IsValid())
9694  return (TList *)0;
9695 
9696  TMessage mess(kPROOF_CACHE);
9697  mess << Int_t(kListEnabledPackages);
9698  Broadcast(mess);
9700 
9701  return fEnabledPackages;
9702 }
9703 
9704 ////////////////////////////////////////////////////////////////////////////////
9705 /// Print a progress bar on stderr. Used in batch mode.
9706 
9708  Float_t procTime, Long64_t bytesread)
9709 {
9710  if (fPrintProgress) {
9711  Bool_t redirlog = fRedirLog;
9712  fRedirLog = kFALSE;
9713  // Call the external function
9714  (*fPrintProgress)(total, processed, procTime, bytesread);
9715  fRedirLog = redirlog;
9716  return;
9717  }
9718 
9719  fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9720 
9721  for (int l = 0; l < 20; l++) {
9722  if (total > 0) {
9723  if (l < 20*processed/total)
9724  fprintf(stderr, "=");
9725  else if (l == 20*processed/total)
9726  fprintf(stderr, ">");
9727  else if (l > 20*processed/total)
9728  fprintf(stderr, ".");
9729  } else
9730  fprintf(stderr, "=");
9731  }
9732  Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9733  Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9734  TString sunit("B/s");
9735  if (evtrti > 0.) {
9736  Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9737  if (mbsrti > 0.) {
9738  const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9739  if (mbsrti >= toG) {
9740  mbsrti /= toG;
9741  sunit = "GB/s";
9742  } else if (mbsrti >= toM) {
9743  mbsrti /= toM;
9744  sunit = "MB/s";
9745  } else if (mbsrti >= toK) {
9746  mbsrti /= toK;
9747  sunit = "kB/s";
9748  }
9749  fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9750  (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9751  } else {
9752  fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9753  (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9754  }
9755  } else {
9756  fprintf(stderr, "| %.02f %%\r",
9757  (total ? ((100.0*processed)/total) : 100.0));
9758  }
9759  if (processed >= total) {
9760  fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9761  }
9762 }
9763 
9764 ////////////////////////////////////////////////////////////////////////////////
9765 /// Get query progress information. Connect a slot to this signal
9766 /// to track progress.
9767 
9769 {
9770  if (fPrintProgress) {
9771  // Call the external function
9772  return (*fPrintProgress)(total, processed, -1., -1);
9773  }
9774 
9775  PDB(kGlobal,1)
9776  Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9777 
9778  if (gROOT->IsBatch()) {
9779  // Simple progress bar
9780  if (total > 0)
9781  PrintProgress(total, processed);
9782  } else {
9783  EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9784  }
9785 }
9786 
9787 ////////////////////////////////////////////////////////////////////////////////
9788 /// Get query progress information. Connect a slot to this signal
9789 /// to track progress.
9790 
9791 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
9792  Float_t initTime, Float_t procTime,
9793  Float_t evtrti, Float_t mbrti)
9794 {
9795  PDB(kGlobal,1)
9796  Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9797  initTime, procTime, evtrti, mbrti);
9798 
9799  if (gROOT->IsBatch()) {
9800  // Simple progress bar
9801  if (total > 0)
9802  PrintProgress(total, processed, procTime, bytesread);
9803  } else {
9804  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9805  7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9806  }
9807 }
9808 
9809 ////////////////////////////////////////////////////////////////////////////////
9810 /// Get query progress information. Connect a slot to this signal
9811 /// to track progress.
9812 
9813 void TProof::Progress(Long64_t total, Long64_t processed, Long64_t bytesread,
9814  Float_t initTime, Float_t procTime,
9815  Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9816 {
9817  PDB(kGlobal,1)
9818  Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9819  initTime, procTime, evtrti, mbrti, actw, eses);
9820 
9821  if (gROOT->IsBatch()) {
9822  // Simple progress bar
9823  if (total > 0)
9824  PrintProgress(total, processed, procTime, bytesread);
9825  } else {
9826  EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9827  10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9828  }
9829 }
9830 
9831 ////////////////////////////////////////////////////////////////////////////////
9832 /// Get list of feedback objects. Connect a slot to this signal
9833 /// to monitor the feedback object.
9834 
9836 {
9837  PDB(kGlobal,1)
9838  Info("Feedback","%d objects", objs->GetSize());
9839  PDB(kFeedback,1) {
9840  Info("Feedback","%d objects", objs->GetSize());
9841  objs->ls();
9842  }
9843 
9844  Emit("Feedback(TList *objs)", (Long_t) objs);
9845 }
9846 
9847 ////////////////////////////////////////////////////////////////////////////////
9848 /// Close progress dialog.
9849 
9851 {
9852  PDB(kGlobal,1)
9853  Info("CloseProgressDialog",
9854  "called: have progress dialog: %d", fProgressDialogStarted);
9855 
9856  // Nothing to do if not there
9858  return;
9859 
9860  Emit("CloseProgressDialog()");
9861 }
9862 
9863 ////////////////////////////////////////////////////////////////////////////////
9864 /// Reset progress dialog.
9865 
9866 void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9867  Long64_t ent)
9868 {
9869  PDB(kGlobal,1)
9870  Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9871 
9872  EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9873  4, sel, sz, fst, ent);
9874 }
9875 
9876 ////////////////////////////////////////////////////////////////////////////////
9877 /// Send startup message.
9878 
9879 void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9880 {
9881  PDB(kGlobal,1)
9882  Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9883 
9884  EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9885  4, msg, st, done, total);
9886 }
9887 
9888 ////////////////////////////////////////////////////////////////////////////////
9889 /// Send dataset preparation status.
9890 
9891 void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9892 {
9893  PDB(kGlobal,1)
9894  Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9895 
9896  EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9897  4, msg, st, done, total);
9898 }
9899 
9900 ////////////////////////////////////////////////////////////////////////////////
9901 /// Send or notify data set status
9902 
9903 void TProof::SendDataSetStatus(const char *action, UInt_t done,
9904  UInt_t tot, Bool_t st)
9905 {
9906  if (IsLite()) {
9907  if (tot) {
9908  TString type = "files";
9909  Int_t frac = (Int_t) (done*100.)/tot;
9910  char msg[512] = {0};
9911  if (frac >= 100) {
9912  snprintf(msg, 512, "%s: OK (%d %s) \n",
9913  action,tot, type.Data());
9914  } else {
9915  snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9916  action, done, tot, frac);
9917  }
9918  if (fSync)
9919  fprintf(stderr,"%s", msg);
9920  else
9921  NotifyLogMsg(msg, 0);
9922  }
9923  return;
9924  }
9925 
9926  if (TestBit(TProof::kIsMaster)) {
9928  mess << TString(action) << tot << done << st;
9929  gProofServ->GetSocket()->Send(mess);
9930  }
9931 }
9932 
9933 ////////////////////////////////////////////////////////////////////////////////
9934 /// Notify availability of a query result.
9935 
9936 void TProof::QueryResultReady(const char *ref)
9937 {
9938  PDB(kGlobal,1)
9939  Info("QueryResultReady","ref: %s", ref);
9940 
9941  Emit("QueryResultReady(const char*)",ref);
9942 }
9943 
9944 ////////////////////////////////////////////////////////////////////////////////
9945 /// Validate a TDSet.
9946 
9948 {
9949  if (dset->ElementsValid()) return;
9950 
9951  TList nodes;
9952  nodes.SetOwner();
9953 
9954  TList slholder;
9955  slholder.SetOwner();
9956  TList elemholder;
9957  elemholder.SetOwner();
9958 
9959  // build nodelist with slaves and elements
9960  TIter nextSlave(GetListOfActiveSlaves());
9961  while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9962  TList *sllist = 0;
9963  TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9964  if (!p) {
9965  sllist = new TList;
9966  sllist->SetName(sl->GetName());
9967  slholder.Add(sllist);
9968  TList *elemlist = new TList;
9969  elemlist->SetName(TString(sl->GetName())+"_elem");
9970  elemholder.Add(elemlist);
9971  nodes.Add(new TPair(sllist, elemlist));
9972  } else {
9973  sllist = dynamic_cast<TList*>(p->Key());
9974  }
9975  if (sllist) sllist->Add(sl);
9976  }
9977 
9978  // add local elements to nodes
9979  TList nonLocal; // list of nonlocal elements
9980  // make two iterations - first add local elements - then distribute nonlocals
9981  for (Int_t i = 0; i < 2; i++) {
9982  Bool_t local = i>0?kFALSE:kTRUE;
9983  TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9984  while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9985  if (elem->GetValid()) continue;
9986  TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9987  if (p) {
9988  TList *eli = dynamic_cast<TList*>(p->Value());
9989  TList *sli = dynamic_cast<TList*>(p->Key());
9990  if (eli && sli) {
9991  eli->Add(elem);
9992 
9993  // order list by elements/slave
9994  TPair *p2 = p;
9995  Bool_t stop = kFALSE;
9996  while (!stop) {
9997  TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9998  if (p3) {
9999  TList *p3v = dynamic_cast<TList*>(p3->Value());
10000  TList *p3k = dynamic_cast<TList*>(p3->Key());
10001  if (p3v && p3k) {
10002  Int_t nelem = p3v->GetSize();
10003  Int_t nsl = p3k->GetSize();
10004  if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
10005  else stop = kTRUE;
10006  }
10007  } else {
10008  stop = kTRUE;
10009  }
10010  }
10011 
10012  if (p2!=p) {
10013  nodes.Remove(p->Key());
10014  nodes.AddAfter(p2->Key(), p);
10015  }
10016  } else {
10017  Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
10018  continue;
10019  }
10020 
10021  } else {
10022  if (local) {
10023  nonLocal.Add(elem);
10024  } else {
10025  Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
10026  }
10027  }
10028  }
10029  }
10030 
10031  // send to slaves
10032  TList usedslaves;
10033  TIter nextNode(&nodes);
10034  SetDSet(dset); // set dset to be validated in Collect()
10035  while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
10036  TList *slaves = dynamic_cast<TList*>(node->Key());
10037  TList *setelements = dynamic_cast<TList*>(node->Value());
10038  if (!slaves || !setelements) continue;
10039  // distribute elements over the slaves
10040  Int_t nslaves = slaves->GetSize();
10041  Int_t nelements = setelements->GetSize();
10042  for (Int_t i=0; i<nslaves; i++) {
10043 
10044  TDSet copyset(dset->GetType(), dset->GetObjName(),
10045  dset->GetDirectory());
10046  for (Int_t j = (i*nelements)/nslaves;
10047  j < ((i+1)*nelements)/nslaves;
10048  j++) {
10049  TDSetElement *elem =
10050  dynamic_cast<TDSetElement*>(setelements->At(j));
10051  if (elem) {
10052  copyset.Add(elem->GetFileName(), elem->GetObjName(),
10053  elem->GetDirectory(), elem->GetFirst(),
10054  elem->GetNum(), elem->GetMsd());
10055  }
10056  }
10057 
10058  if (copyset.GetListOfElements()->GetSize()>0) {
10060  mesg << &copyset;
10061 
10062  TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
10063  if (sl) {
10064  PDB(kGlobal,1) Info("ValidateDSet",
10065  "Sending TDSet with %d elements to slave %s"
10066  " to be validated",
10067  copyset.GetListOfElements()->GetSize(),
10068  sl->GetOrdinal());
10069  sl->GetSocket()->Send(mesg);
10070  usedslaves.Add(sl);
10071  }
10072  }
10073  }
10074  }
10075 
10076  PDB(kGlobal,1)
10077  Info("ValidateDSet","Calling Collect");
10078  Collect(&usedslaves);
10079  SetDSet(0);
10080 }
10081 
10082 ////////////////////////////////////////////////////////////////////////////////
10083 /// Add data objects that might be needed during the processing of
10084 /// the selector (see Process()). This object can be very large, so they
10085 /// are distributed in an optimized way using a dedicated file.
10086 /// If push is TRUE the input data are sent over even if no apparent change
10087 /// occured to the list.
10088 
10090 {
10091  if (obj) {
10092  if (!fInputData) fInputData = new TList;
10093  if (!fInputData->FindObject(obj)) {
10094  fInputData->Add(obj);
10096  }
10097  }
10098  if (push) SetBit(TProof::kNewInputData);
10099 }
10100 
10101 ////////////////////////////////////////////////////////////////////////////////
10102 /// Remove obj form the input data list; if obj is null (default), clear the
10103 /// input data info.
10104 
10106 {
10107  if (!obj) {
10108  if (fInputData) {
10111  }
10113 
10114  // Also remove any info about input data in the input list
10115  TObject *o = 0;
10116  TList *in = GetInputList();
10117  while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
10118  in->Remove(o);
10119  while ((o = GetInputList()->FindObject("PROOF_InputData")))
10120  in->Remove(o);
10121 
10122  // ... and reset the file
10123  fInputDataFile = "";
10125 
10126  } else if (fInputData) {
10127  Int_t sz = fInputData->GetSize();
10128  while (fInputData->FindObject(obj))
10129  fInputData->Remove(obj);
10130  // Flag for update, if anything changed
10131  if (sz != fInputData->GetSize())
10133  }
10134 }
10135 
10136 ////////////////////////////////////////////////////////////////////////////////
10137 /// Remove obj 'name' form the input data list;
10138 
10139 void TProof::ClearInputData(const char *name)
10140 {
10141  TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
10142  if (obj) ClearInputData(obj);
10143 }
10144 
10145 ////////////////////////////////////////////////////////////////////////////////
10146 /// Set the file to be used to optimally distribute the input data objects.
10147 /// If the file exists the object in the file are added to those in the
10148 /// fInputData list. If the file path is null, a default file will be created
10149 /// at the moment of sending the processing request with the content of
10150 /// the fInputData list. See also SendInputDataFile.
10151 
10152 void TProof::SetInputDataFile(const char *datafile)
10153 {
10154  if (datafile && strlen(datafile) > 0) {
10155  if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
10157  fInputDataFile = datafile;
10158  } else {
10159  if (!fInputDataFile.IsNull())
10161  fInputDataFile = "";
10162  }
10163  // Make sure that the chosen file is readable
10166  fInputDataFile = "";
10167  }
10168 }
10169 
10170 ////////////////////////////////////////////////////////////////////////////////
10171 /// Send the input data objects to the master; the objects are taken from the
10172 /// dedicated list and / or the specified file.
10173 /// If the fInputData is empty the specified file is sent over.
10174 /// If there is no specified file, a file named "inputdata.root" is created locally
10175 /// with the content of fInputData and sent over to the master.
10176 /// If both fInputData and the specified file are not empty, a copy of the file
10177 /// is made locally and augmented with the content of fInputData.
10178 
10180 {
10181  // Prepare the file
10182  TString dataFile;
10183  PrepareInputDataFile(dataFile);
10184 
10185  // Send it, if not empty
10186  if (dataFile.Length() > 0) {
10187 
10188  Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
10189  BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
10190 
10191  // Set the name in the input list
10192  TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
10193  AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
10194  }
10195 }
10196 
10197 ////////////////////////////////////////////////////////////////////////////////
10198 /// Prepare the file with the input data objects to be sent the master; the
10199 /// objects are taken from the dedicated list and / or the specified file.
10200 /// If the fInputData is empty the specified file is sent over.
10201 /// If there is no specified file, a file named "inputdata.root" is created locally
10202 /// with the content of fInputData and sent over to the master.
10203 /// If both fInputData and the specified file are not empty, a copy of the file
10204 /// is made locally and augmented with the content of fInputData.
10205 
10207 {
10208  // Save info about new data for usage in this call;
10210  // Next time we need some change
10212 
10213  // Check the list
10214  Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
10215  // Check the file
10216  Bool_t file_ok = kFALSE;
10219  // It must contain something
10221  if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
10222  file_ok = kTRUE;
10223  }
10224 
10225  // Remove any info about input data in the input list
10226  TObject *o = 0;
10227  TList *in = GetInputList();
10228  while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
10229  in->Remove(o);
10230  while ((o = GetInputList()->FindObject("PROOF_InputData")))
10231  in->Remove(o);
10232 
10233  // We must have something to send
10234  dataFile = "";
10235  if (!list_ok && !file_ok) return;
10236 
10237  // Three cases:
10238  if (file_ok && !list_ok) {
10239  // Just send the file
10240  dataFile = fInputDataFile;
10241  } else if (!file_ok && list_ok) {
10243  // Nothing to do, if no new data
10244  if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
10245  // Create the file first
10246  TFile *f = TFile::Open(fInputDataFile, "RECREATE");
10247  if (f) {
10248  f->cd();
10250  TObject *obj;
10251  while ((obj = next())) {
10252  obj->Write(0, TObject::kSingleKey, 0);
10253  }
10254  f->Close();
10255  SafeDelete(f);
10256  } else {
10257  Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
10258  return;
10259  }
10260  dataFile = fInputDataFile;
10261  } else if (file_ok && list_ok) {
10262  dataFile = kPROOF_InputDataFile;
10263  // Create the file if not existing or there are new data
10264  if (newdata || gSystem->AccessPathName(dataFile)) {
10265  // Cleanup previous file if obsolete
10266  if (!gSystem->AccessPathName(dataFile))
10267  gSystem->Unlink(dataFile);
10268  if (dataFile != fInputDataFile) {
10269  // Make a local copy first
10270  if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
10271  Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
10272  return;
10273  }
10274  }
10275  // Add the input data list
10276  TFile *f = TFile::Open(dataFile, "UPDATE");
10277  if (f) {
10278  f->cd();
10280  TObject *obj = 0;
10281  while ((obj = next())) {
10282  obj->Write(0, TObject::kSingleKey, 0);
10283  }
10284  f->Close();
10285  SafeDelete(f);
10286  } else {
10287  Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
10288  return;
10289  }
10290  }
10291  }
10292 
10293  // Done
10294  return;
10295 }
10296 
10297 ////////////////////////////////////////////////////////////////////////////////
10298 /// Add objects that might be needed during the processing of
10299 /// the selector (see Process()).
10300 
10302 {
10303  if (fPlayer) fPlayer->AddInput(obj);
10304 }
10305 
10306 ////////////////////////////////////////////////////////////////////////////////
10307 /// Clear input object list.
10308 
10310 {
10311  if (fPlayer) fPlayer->ClearInput();
10312 
10313  // the system feedback list is always in the input list
10315 }
10316 
10317 ////////////////////////////////////////////////////////////////////////////////
10318 /// Get input list.
10319 
10321 {
10322  return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
10323 }
10324 
10325 ////////////////////////////////////////////////////////////////////////////////
10326 /// Get specified object that has been produced during the processing
10327 /// (see Process()).
10328 
10330 {
10331 
10333  // Can be called by MarkBad on the master before the player is initialized
10334  return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
10335 
10336  // This checks also associated output files
10337  return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
10338 }
10339 
10340 ////////////////////////////////////////////////////////////////////////////////
10341 /// Find object 'name' in list 'out' or in the files specified in there
10342 
10344 {
10345  TObject *o = 0;
10346  if (!name || (name && strlen(name) <= 0) ||
10347  !out || (out && out->GetSize() <= 0)) return o;
10348  if ((o = out->FindObject(name))) return o;
10349 
10350  // For the time being we always check for all the files; this may require
10351  // some caching
10352  TProofOutputFile *pf = 0;
10353  TIter nxo(out);
10354  while ((o = nxo())) {
10355  if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
10356  TFile *f = 0;
10357  if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
10358  TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
10359  f = TFile::Open(fn.Data());
10360  if (!f || (f && f->IsZombie())) {
10361  ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
10362  }
10363  }
10364  if (f && (o = f->Get(name))) return o;
10365  }
10366  }
10367 
10368  // Done, unsuccessfully
10369  return o;
10370 }
10371 
10372 ////////////////////////////////////////////////////////////////////////////////
10373 /// Get list with all object created during processing (see Process()).
10374 
10376 {
10377  if (fOutputList.GetSize() > 0) return &fOutputList;
10378  if (fPlayer) {
10380  return &fOutputList;
10381  }
10382  return (TList *)0;
10383 }
10384 
10385 ////////////////////////////////////////////////////////////////////////////////
10386 /// Set input list parameter. If the parameter is already
10387 /// set it will be set to the new value.
10388 
10389 void TProof::SetParameter(const char *par, const char *value)
10390 {
10391  if (!fPlayer) {
10392  Warning("SetParameter", "player undefined! Ignoring");
10393  return;
10394  }
10395 
10396  TList *il = fPlayer->GetInputList();
10397  TObject *item = il->FindObject(par);
10398  if (item) {
10399  il->Remove(item);
10400  delete item;
10401  }
10402  il->Add(new TNamed(par, value));
10403 }
10404 
10405 ////////////////////////////////////////////////////////////////////////////////
10406 /// Set an input list parameter.
10407 
10409 {
10410  if (!fPlayer) {
10411  Warning("SetParameter", "player undefined! Ignoring");
10412  return;
10413  }
10414 
10415  TList *il = fPlayer->GetInputList();
10416  TObject *item = il->FindObject(par);
10417  if (item) {
10418  il->Remove(item);
10419  delete item;
10420  }
10421  il->Add(new TParameter<Int_t>(par, value));
10422 }
10423 
10424 ////////////////////////////////////////////////////////////////////////////////
10425 /// Set an input list parameter.
10426 
10428 {
10429  if (!fPlayer) {
10430  Warning("SetParameter", "player undefined! Ignoring");
10431  return;
10432  }
10433 
10434  TList *il = fPlayer->GetInputList();
10435  TObject *item = il->FindObject(par);
10436  if (item) {
10437  il->Remove(item);
10438  delete item;
10439  }
10440  il->Add(new TParameter<Long_t>(par, value));
10441 }
10442 
10443 ////////////////////////////////////////////////////////////////////////////////
10444 /// Set an input list parameter.
10445 
10447 {
10448  if (!fPlayer) {
10449  Warning("SetParameter", "player undefined! Ignoring");
10450  return;
10451  }
10452 
10453  TList *il = fPlayer->GetInputList();
10454  TObject *item = il->FindObject(par);
10455  if (item) {
10456  il->Remove(item);
10457  delete item;
10458  }
10459  il->Add(new TParameter<Long64_t>(par, value));
10460 }
10461 
10462 ////////////////////////////////////////////////////////////////////////////////
10463 /// Set an input list parameter.
10464 
10466 {
10467  if (!fPlayer) {
10468  Warning("SetParameter", "player undefined! Ignoring");
10469  return;
10470  }
10471 
10472  TList *il = fPlayer->GetInputList();
10473  TObject *item = il->FindObject(par);
10474  if (item) {
10475  il->Remove(item);
10476  delete item;
10477  }
10478  il->Add(new TParameter<Double_t>(par, value));
10479 }
10480 
10481 ////////////////////////////////////////////////////////////////////////////////
10482 /// Get specified parameter. A parameter set via SetParameter() is either
10483 /// a TParameter or a TNamed or 0 in case par is not defined.
10484 
10485 TObject *TProof::GetParameter(const char *par) const
10486 {
10487  if (!fPlayer) {
10488  Warning("GetParameter", "player undefined! Ignoring");
10489  return (TObject *)0;
10490  }
10491 
10492  TList *il = fPlayer->GetInputList();
10493  return il->FindObject(par);
10494 }
10495 
10496 ////////////////////////////////////////////////////////////////////////////////
10497 /// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
10498 /// or exact name (e.g. PROOF_MaxSlavesPerNode).
10499 
10500 void TProof::DeleteParameters(const char *wildcard)
10501 {
10502  if (!fPlayer) return;
10503 
10504  if (!wildcard) wildcard = "";
10505  TRegexp re(wildcard, kTRUE);
10506  Int_t nch = strlen(wildcard);
10507 
10508  TList *il = fPlayer->GetInputList();
10509  if (il) {
10510  TObject *p = 0;
10511  TIter next(il);
10512  while ((p = next())) {
10513  TString s = p->GetName();
10514  if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
10515  il->Remove(p);
10516  delete p;
10517  }
10518  }
10519 }
10520 
10521 ////////////////////////////////////////////////////////////////////////////////
10522 /// Show the input list parameters specified by the wildcard.
10523 /// Default is the special PROOF control parameters (PROOF_*).
10524 
10525 void TProof::ShowParameters(const char *wildcard) const
10526 {
10527  if (!fPlayer) return;
10528 
10529  if (!wildcard) wildcard = "";
10530  TRegexp re(wildcard, kTRUE);
10531  Int_t nch = strlen(wildcard);
10532 
10533  TList *il = fPlayer->GetInputList();
10534  TObject *p;
10535  TIter next(il);
10536  while ((p = next())) {
10537  TString s = p->GetName();
10538  if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
10539  if (p->IsA() == TNamed::Class()) {
10540  Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
10541  } else if (p->IsA() == TParameter<Long_t>::Class()) {
10542  Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
10543  } else if (p->IsA() == TParameter<Long64_t>::Class()) {
10544  Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
10545  } else if (p->IsA() == TParameter<Double_t>::Class()) {
10546  Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
10547  } else {
10548  Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
10549  }
10550  }
10551 }
10552 
10553 ////////////////////////////////////////////////////////////////////////////////
10554 /// Add object to feedback list.
10555 
10556 void TProof::AddFeedback(const char *name)
10557 {
10558  PDB(kFeedback, 3)
10559  Info("AddFeedback", "Adding object \"%s\" to feedback", name);
10560  if (fFeedback->FindObject(name) == 0)
10561  fFeedback->Add(new TObjString(name));
10562 }
10563 
10564 ////////////////////////////////////////////////////////////////////////////////
10565 /// Remove object from feedback list.
10566 
10567 void TProof::RemoveFeedback(const char *name)
10568 {
10569  TObject *obj = fFeedback->FindObject(name);
10570  if (obj != 0) {
10571  fFeedback->Remove(obj);
10572  delete obj;
10573  }
10574 }
10575 
10576 ////////////////////////////////////////////////////////////////////////////////
10577 /// Clear feedback list.
10578 
10580 {
10581  fFeedback->Delete();
10582 }
10583 
10584 ////////////////////////////////////////////////////////////////////////////////
10585 /// Show items in feedback list.
10586 
10588 {
10589  if (fFeedback->GetSize() == 0) {
10590  Info("","no feedback requested");
10591  return;
10592  }
10593 
10594  fFeedback->Print();
10595 }
10596 
10597 ////////////////////////////////////////////////////////////////////////////////
10598 /// Return feedback list.
10599 
10601 {
10602  return fFeedback;
10603 }
10604 
10605 ////////////////////////////////////////////////////////////////////////////////
10606 /// Creates a tree header (a tree with nonexisting files) object for
10607 /// the DataSet.
10608 
10610 {
10612  TSlave *sl = (TSlave*) l->First();
10613  if (sl == 0) {
10614  Error("GetTreeHeader", "No connection");
10615  return 0;
10616  }
10617 
10618  TSocket *soc = sl->GetSocket();
10620 
10621  msg << dset;
10622 
10623  soc->Send(msg);
10624 
10625  TMessage *reply;
10626  Int_t d = -1;
10627  if (fProtocol >= 20) {
10629  reply = (TMessage *) fRecvMessages->First();
10630  } else {
10631  d = soc->Recv(reply);
10632  }
10633  if (!reply) {
10634  Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10635  return 0;
10636  }
10637 
10638  TString s1;
10639  TTree *t = 0;
10640  (*reply) >> s1;
10641  if (s1 == "Success")
10642  (*reply) >> t;
10643 
10644  PDB(kGlobal, 1) {
10645  if (t) {
10646  Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10647  s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10648  } else {
10649  Info("GetTreeHeader", "tree header retrieval failed");
10650  }
10651  }
10652  delete reply;
10653 
10654  return t;
10655 }
10656 
10657 ////////////////////////////////////////////////////////////////////////////////
10658 /// Draw feedback creation proxy. When accessed via TProof avoids
10659 /// link dependency on libProofPlayer.
10660 
10662 {
10663  return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10664 }
10665 
10666 ////////////////////////////////////////////////////////////////////////////////
10667 /// Set draw feedback option.
10668 
10670 {
10671  if (fPlayer) fPlayer->SetDrawFeedbackOption(f, opt);
10672 }
10673 
10674 ////////////////////////////////////////////////////////////////////////////////
10675 /// Delete draw feedback object.
10676 
10678 {
10680 }
10681 
10682 ////////////////////////////////////////////////////////////////////////////////
10683 /// FIXME: to be written
10684 
10686 {
10687  return 0;
10688 /*
10689  TMessage msg(kPROOF_GETOUTPUTLIST);
10690  TList* slaves = fActiveSlaves;
10691  Broadcast(msg, slaves);
10692  TMonitor mon;
10693  TList* outputList = new TList();
10694 
10695  TIter si(slaves);
10696  TSlave *slave;
10697  while ((slave = (TSlave*)si.Next()) != 0) {
10698  PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10699  slave->GetSocket(), slave->GetName());
10700  mon.Add(slave->GetSocket());
10701  }
10702  mon.ActivateAll();
10703  ((TProof*)gProof)->DeActivateAsyncInput();
10704  ((TProof*)gProof)->fCurrentMonitor = &mon;
10705 
10706  while (mon.GetActive() != 0) {
10707  TSocket *sock = mon.Select();
10708  if (!sock) {
10709  Error("GetOutputList","TMonitor::.Select failed!");
10710  break;
10711  }
10712  mon.DeActivate(sock);
10713  TMessage *reply;
10714  if (sock->Recv(reply) <= 0) {
10715  MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10716 // Error("GetOutputList","Recv failed! for slave-%d (%s)",
10717 // slave->GetOrdinal(), slave->GetName());
10718  continue;
10719  }
10720  if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10721 // Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10722 // slave->GetOrdinal(), slave->GetName());
10723  MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10724  continue;
10725  }
10726  TList* l;
10727 
10728  (*reply) >> l;
10729  TIter next(l);
10730  TNamed *n;
10731  while ( (n = dynamic_cast<TNamed*> (next())) ) {
10732  if (!outputList->FindObject(n->GetName()))
10733  outputList->Add(n);
10734  }
10735  delete reply;
10736  }
10737  ((TProof*)gProof)->fCurrentMonitor = 0;
10738 
10739  return outputList;
10740 */
10741 }
10742 
10743 ////////////////////////////////////////////////////////////////////////////////
10744 /// Build the PROOF's structure in the browser.
10745 
10747 {
10748  b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10749  b->Add(&fMaster, fMaster.Class(), "fMaster");
10750  b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10751  b->Add(fChains, fChains->Class(), "fChains");
10752 
10753  if (fPlayer) {
10754  b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10755  if (fPlayer->GetOutputList())
10756  b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10757  if (fPlayer->GetListOfResults())
10759  fPlayer->GetListOfResults()->Class(), "ListOfResults");
10760  }
10761 }
10762 
10763 ////////////////////////////////////////////////////////////////////////////////
10764 /// Set a new PROOF player.
10765 
10767 {
10768  if (fPlayer)
10769  delete fPlayer;
10770  fPlayer = player;
10771 };
10772 
10773 ////////////////////////////////////////////////////////////////////////////////
10774 /// Construct a TProofPlayer object. The player string specifies which
10775 /// player should be created: remote, slave, sm (supermaster) or base.
10776 /// Default is remote. Socket is needed in case a slave player is created.
10777 
10779 {
10780  if (!player)
10781  player = "remote";
10782 
10783  SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10784  return GetPlayer();
10785 }
10786 
10787 ////////////////////////////////////////////////////////////////////////////////
10788 /// Add chain to data set
10789 
10791 {
10792  fChains->Add(chain);
10793 }
10794 
10795 ////////////////////////////////////////////////////////////////////////////////
10796 /// Remove chain from data set
10797 
10799 {
10800  fChains->Remove(chain);
10801 }
10802 
10803 ////////////////////////////////////////////////////////////////////////////////
10804 /// Ask for remote logs in the range [start, end]. If start == -1 all the
10805 /// messages not yet received are sent back.
10806 
10807 void TProof::GetLog(Int_t start, Int_t end)
10808 {
10809  if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10810 
10811  TMessage msg(kPROOF_LOGFILE);
10812 
10813  msg << start << end;
10814 
10815  Broadcast(msg, kActive);
10817 }
10818 
10819 ////////////////////////////////////////////////////////////////////////////////
10820 /// Fill a TMacro with the log lines since the last reading (fLogFileR)
10821 /// Return (TMacro *)0 if no line was logged.
10822 /// The returned TMacro must be deleted by the caller.
10823 
10825 {
10826  TMacro *maclog = 0;
10827 
10828  // Save present offset
10829  off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10830  if (nowlog < 0) {
10831  SysError("GetLastLog",
10832  "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10833  return maclog;
10834  }
10835 
10836  // Get extremes
10837  off_t startlog = nowlog;
10838  off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10839  if (endlog < 0) {
10840  SysError("GetLastLog",
10841  "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10842  return maclog;
10843  }
10844 
10845  // Perhaps nothing to log
10846  UInt_t tolog = (UInt_t)(endlog - startlog);
10847  if (tolog <= 0) return maclog;
10848 
10849  // Set starting point
10850  if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10851  SysError("GetLastLog",
10852  "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10853  return maclog;
10854  }
10855 
10856  // Create the output object
10857  maclog = new TMacro;
10858 
10859  // Now we go
10860  char line[2048];
10861  Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10862  while (fgets(line, wanted, fLogFileR)) {
10863  Int_t r = strlen(line);
10864  if (r > 0) {
10865  if (line[r-1] == '\n') line[r-1] = '\0';
10866  maclog->AddLine(line);
10867  } else {
10868  // Done
10869  break;
10870  }
10871  tolog -= r;
10872  wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10873  }
10874 
10875  // Restore original pointer
10876  if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10877  Warning("GetLastLog",
10878  "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10879  }
10880 
10881  // Done
10882  return maclog;
10883 }
10884 
10885 ////////////////////////////////////////////////////////////////////////////////
10886 /// Display log of query pq into the log window frame
10887 
10889 {
10890  if (!pq) return;
10891 
10892  TList *lines = pq->GetLogFile()->GetListOfLines();
10893  if (lines) {
10894  TIter nxl(lines);
10895  TObjString *l = 0;
10896  while ((l = (TObjString *)nxl()))
10897  EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10898  }
10899 }
10900 
10901 ////////////////////////////////////////////////////////////////////////////////
10902 /// Display on screen the content of the temporary log file for query
10903 /// in reference
10904 
10905 void TProof::ShowLog(const char *queryref)
10906 {
10907  // Make sure we have all info (GetListOfQueries retrieves the
10908  // head info only)
10909  Retrieve(queryref);
10910 
10911  if (fPlayer) {
10912  if (queryref) {
10913  if (fPlayer->GetListOfResults()) {
10914  TIter nxq(fPlayer->GetListOfResults());
10915  TQueryResult *qr = 0;
10916  while ((qr = (TQueryResult *) nxq()))
10917  if (strstr(queryref, qr->GetTitle()) &&
10918  strstr(queryref, qr->GetName()))
10919  break;
10920  if (qr) {
10921  PutLog(qr);
10922  return;
10923  }
10924 
10925  }
10926  }
10927  }
10928 }
10929 
10930 ////////////////////////////////////////////////////////////////////////////////
10931 /// Display on screen the content of the temporary log file.
10932 /// If qry == -2 show messages from the last (current) query.
10933 /// If qry == -1 all the messages not yet displayed are shown (default).
10934 /// If qry == 0, all the messages in the file are shown.
10935 /// If qry > 0, only the messages related to query 'qry' are shown.
10936 /// For qry != -1 the original file offset is restored at the end
10937 
10939 {
10940  // Save present offset
10941  off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10942  if (nowlog < 0) {
10943  SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10944  return;
10945  }
10946 
10947  // Get extremes
10948  off_t startlog = nowlog;
10949  off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10950  if (endlog < 0) {
10951  SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10952  return;
10953  }
10954 
10955  lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10956  if (qry == 0) {
10957  startlog = 0;
10958  lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10959  } else if (qry != -1) {
10960 
10961  TQueryResult *pq = 0;
10962  if (qry == -2) {
10963  // Pickup the last one
10964  pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10965  if (!pq) {
10966  GetListOfQueries();
10967  if (fQueries)
10968  pq = (TQueryResult *)(fQueries->Last());
10969  }
10970  } else if (qry > 0) {
10971  TList *queries = GetQueryResults();
10972  if (queries) {
10973  TIter nxq(queries);
10974  while ((pq = (TQueryResult *)nxq()))
10975  if (qry == pq->GetSeqNum())
10976  break;
10977  }
10978  if (!pq) {
10979  queries = GetListOfQueries();
10980  TIter nxq(queries);
10981  while ((pq = (TQueryResult *)nxq()))
10982  if (qry == pq->GetSeqNum())
10983  break;
10984  }
10985  }
10986  if (pq) {
10987  PutLog(pq);
10988  return;
10989  } else {
10990  if (gDebug > 0)
10991  Info("ShowLog","query %d not found in list", qry);
10992  qry = -1;
10993  }
10994  }
10995 
10996  // Number of bytes to log
10997  UInt_t tolog = (UInt_t)(endlog - startlog);
10998 
10999  // Perhaps nothing
11000  if (tolog <= 0)
11001 
11002  // Set starting point
11003  lseek(fileno(fLogFileR), startlog, SEEK_SET);
11004 
11005  // Now we go
11006  Int_t np = 0;
11007  char line[2048];
11008  Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
11009  while (fgets(line, wanted, fLogFileR)) {
11010 
11011  Int_t r = strlen(line);
11012  if (!SendingLogToWindow()) {
11013  if (line[r-1] != '\n') line[r-1] = '\n';
11014  if (r > 0) {
11015  char *p = line;
11016  while (r) {
11017  Int_t w = write(fileno(stdout), p, r);
11018  if (w < 0) {
11019  SysError("ShowLog", "error writing to stdout");
11020  break;
11021  }
11022  r -= w;
11023  p += w;
11024  }
11025  }
11026  tolog -= strlen(line);
11027  np++;
11028 
11029  // Ask if more is wanted
11030  if (!(np%10)) {
11031  const char *opt = Getline("More (y/n)? [y]");
11032  if (opt[0] == 'n')
11033  break;
11034  }
11035 
11036  // We may be over
11037  if (tolog <= 0)
11038  break;
11039 
11040  // Update wanted bytes
11041  wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
11042  } else {
11043  // Log to window
11044  if (line[r-1] == '\n') line[r-1] = 0;
11045  LogMessage(line, kFALSE);
11046  }
11047  }
11048  if (!SendingLogToWindow()) {
11049  // Avoid screwing up the prompt
11050  if (write(fileno(stdout), "\n", 1) != 1)
11051  SysError("ShowLog", "error writing to stdout");
11052  }
11053 
11054  // Restore original pointer
11055  if (qry > -1)
11056  lseek(fileno(fLogFileR), nowlog, SEEK_SET);
11057 }
11058 
11059 ////////////////////////////////////////////////////////////////////////////////
11060 /// Set session with 'id' the default one. If 'id' is not found in the list,
11061 /// the current session is set as default
11062 
11064 {
11065  if (GetManager()) {
11066  TProofDesc *d = GetManager()->GetProofDesc(id);
11067  if (d) {
11068  if (d->GetProof()) {
11069  gProof = d->GetProof();
11070  return;
11071  }
11072  }
11073 
11074  // Id not found or undefined: set as default this session
11075  gProof = this;
11076  }
11077 
11078  return;
11079 }
11080 
11081 ////////////////////////////////////////////////////////////////////////////////
11082 /// Detach this instance to its proofserv.
11083 /// If opt is 'S' or 's' the remote server is shutdown
11084 
11086 {
11087  // Nothing to do if not in contact with proofserv
11088  if (!IsValid()) return;
11089 
11090  // Get worker and socket instances
11091  TSlave *sl = (TSlave *) fActiveSlaves->First();
11092  TSocket *s = 0;
11093  if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
11094  Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
11095  return;
11096  }
11097 
11098  Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
11099 
11100  // If processing, try to stop processing first
11101  if (shutdown && !IsIdle()) {
11102  // Remove pending requests
11103  Remove("cleanupqueue");
11104  // Do not wait for ever, but al least 20 seconds
11105  Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
11106  timeout = (timeout > 20) ? timeout : 20;
11107  // Send stop signal
11108  StopProcess(kFALSE, (Long_t) (timeout / 2));
11109  // Receive results
11110  Collect(kActive, timeout);
11111  }
11112 
11113  // Avoid spurious messages: deactivate new inputs ...
11115 
11116  // ... and discard existing ones
11117  sl->FlushSocket();
11118 
11119  // Close session (we always close the connection)
11120  Close(opt);
11121 
11122  // Close the progress dialog, if any
11125 
11126  // Update info in the table of our manager, if any
11127  if (GetManager() && GetManager()->QuerySessions("L")) {
11128  TIter nxd(GetManager()->QuerySessions("L"));
11129  TProofDesc *d = 0;
11130  while ((d = (TProofDesc *)nxd())) {
11131  if (d->GetProof() == this) {
11132  d->SetProof(0);
11133  GetManager()->QuerySessions("L")->Remove(d);
11134  break;
11135  }
11136  }
11137  }
11138 
11139  // Invalidate this instance
11140  fValid = kFALSE;
11141 
11142  return;
11143 }
11144 
11145 ////////////////////////////////////////////////////////////////////////////////
11146 /// Set an alias for this session. If reconnection is supported, the alias
11147 /// will be communicated to the remote coordinator so that it can be recovered
11148 /// when reconnecting
11149 
11150 void TProof::SetAlias(const char *alias)
11151 {
11152  // Set it locally
11153  TNamed::SetTitle(alias);
11155  // Set the name at the same value
11156  TNamed::SetName(alias);
11157 
11158  // Nothing to do if not in contact with coordinator
11159  if (!IsValid()) return;
11160 
11161  if (!IsProofd() && TestBit(TProof::kIsClient)) {
11162  TSlave *sl = (TSlave *) fActiveSlaves->First();
11163  if (sl)
11164  sl->SetAlias(alias);
11165  }
11166 
11167  return;
11168 }
11169 
11170 ////////////////////////////////////////////////////////////////////////////////
11171 /// *** This function is deprecated and will disappear in future versions ***
11172 /// *** It is just a wrapper around TFile::Cp.
11173 /// *** Please use TProofMgr::UploadFiles.
11174 ///
11175 /// Upload a set of files and save the list of files by name dataSetName.
11176 /// The 'files' argument is a list of TFileInfo objects describing the files
11177 /// as first url.
11178 /// The mask 'opt' is a combination of EUploadOpt:
11179 /// kAppend (0x1) if set true files will be appended to
11180 /// the dataset existing by given name
11181 /// kOverwriteDataSet (0x2) if dataset with given name exited it
11182 /// would be overwritten
11183 /// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
11184 /// kOverwriteAllFiles (0x8) overwrite all files that may exist
11185 /// kOverwriteNoFiles (0x10) overwrite none
11186 /// kAskUser (0x0) ask user before overwriteng dataset/files
11187 /// The default value is kAskUser.
11188 /// The user will be asked to confirm overwriting dataset or files unless
11189 /// specified opt provides the answer!
11190 /// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
11191 /// skippedFiles argument. The function will add to this list TFileInfo
11192 /// objects describing all files that existed on the cluster and were
11193 /// not uploaded.
11194 ///
11195 /// Communication Summary
11196 /// Client Master
11197 /// |------------>DataSetName----------->|
11198 /// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
11199 /// (*)|-------> call RegisterDataSet ------->|
11200 /// (*) - optional
11201 
11202 Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
11203 {
11204  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
11205 
11206  return -1;
11207 }
11208 
11209 ////////////////////////////////////////////////////////////////////////////////
11210 /// *** This function is deprecated and will disappear in future versions ***
11211 /// *** It is just a wrapper around TFile::Cp.
11212 /// *** Please use TProofMgr::UploadFiles.
11213 ///
11214 /// Upload a set of files and save the list of files by name dataSetName.
11215 /// The mask 'opt' is a combination of EUploadOpt:
11216 /// kAppend (0x1) if set true files will be appended to
11217 /// the dataset existing by given name
11218 /// kOverwriteDataSet (0x2) if dataset with given name exited it
11219 /// would be overwritten
11220 /// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
11221 /// kOverwriteAllFiles (0x8) overwrite all files that may exist
11222 /// kOverwriteNoFiles (0x10) overwrite none
11223 /// kAskUser (0x0) ask user before overwriteng dataset/files
11224 /// The default value is kAskUser.
11225 /// The user will be asked to confirm overwriting dataset or files unless
11226 /// specified opt provides the answer!
11227 /// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
11228 /// skippedFiles argument. The function will add to this list TFileInfo
11229 /// objects describing all files that existed on the cluster and were
11230 /// not uploaded.
11231 ///
11232 
11233 Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
11234 {
11235  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
11236 
11237  return -1;
11238 }
11239 
11240 ////////////////////////////////////////////////////////////////////////////////
11241 /// *** This function is deprecated and will disappear in future versions ***
11242 /// *** It is just a wrapper around TFile::Cp.
11243 /// *** Please use TProofMgr::UploadFiles.
11244 ///
11245 /// Upload files listed in "file" to PROOF cluster.
11246 /// Where file = name of file containing list of files and
11247 /// dataset = dataset name and opt is a combination of EUploadOpt bits.
11248 /// Each file description (line) can include wildcards.
11249 /// Check TFileInfo compatibility
11250 
11251 Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
11252 {
11253  Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
11254 
11255  // Done
11256  return -1;
11257 }
11258 
11259 ////////////////////////////////////////////////////////////////////////////////
11260 /// Register the 'dataSet' on the cluster under the current
11261 /// user, group and the given 'dataSetName'.
11262 /// If a dataset with the same name already exists the action fails unless 'opts'
11263 /// contains 'O', in which case the old dataset is overwritten, or contains 'U',
11264 /// in which case 'newDataSet' is added to the existing dataset (duplications are
11265 /// ignored, if any).
11266 /// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
11267 /// is configured to allow so). By default the dataset is not verified.
11268 /// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
11269 /// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
11270 /// If 'opts' contains 'S' validation would be run serially (meaningful only if
11271 /// validation is required).
11272 /// Returns kTRUE on success.
11273 
11274 Bool_t TProof::RegisterDataSet(const char *dataSetName,
11275  TFileCollection *dataSet, const char *optStr)
11276 {
11277  // Check TFileInfo compatibility
11278  if (fProtocol < 17) {
11279  Info("RegisterDataSet",
11280  "functionality not available: the server does not have dataset support");
11281  return kFALSE;
11282  }
11283 
11284  if (!dataSetName || strlen(dataSetName) <= 0) {
11285  Info("RegisterDataSet", "specifying a dataset name is mandatory");
11286  return kFALSE;
11287  }
11288 
11289  Bool_t parallelverify = kFALSE;
11290  TString sopt(optStr);
11291  if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
11292  // We do verification in parallel later on; just register for now
11293  parallelverify = kTRUE;
11294  sopt.ReplaceAll("V", "");
11295  }
11296  // This would screw up things remotely, make sure is not there
11297  sopt.ReplaceAll("S", "");
11298 
11299  TMessage mess(kPROOF_DATASETS);
11300  mess << Int_t(kRegisterDataSet);
11301  mess << TString(dataSetName);
11302  mess << sopt;
11303  mess.WriteObject(dataSet);
11304  Broadcast(mess);
11305 
11306  Bool_t result = kTRUE;
11307  Collect();
11308  if (fStatus != 0) {
11309  Error("RegisterDataSet", "dataset was not saved");
11310  result = kFALSE;
11311  return result;
11312  }
11313 
11314  // If old server or not verifying in parallel we are done
11315  if (!parallelverify) return result;
11316 
11317  // If we are here it means that we will verify in parallel
11318  sopt += "V";
11319  if (VerifyDataSet(dataSetName, sopt) < 0){
11320  Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
11321  return kFALSE;
11322  }
11323 
11324  // We are done
11325  return kTRUE;
11326 }
11327 
11328 ////////////////////////////////////////////////////////////////////////////////
11329 /// Set/Change the name of the default tree. The tree name may contain
11330 /// subdir specification in the form "subdir/name".
11331 /// Returns 0 on success, -1 otherwise.
11332 
11333 Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
11334 {
11335  // Check TFileInfo compatibility
11336  if (fProtocol < 23) {
11337  Info("SetDataSetTreeName", "functionality not supported by the server");
11338  return -1;
11339  }
11340 
11341  if (!dataset || strlen(dataset) <= 0) {
11342  Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
11343  return -1;
11344  }
11345 
11346  if (!treename || strlen(treename) <= 0) {
11347  Info("SetDataSetTreeName", "specifying a tree name is mandatory");
11348  return -1;
11349  }
11350 
11351  TUri uri(dataset);
11352  TString fragment(treename);
11353  if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
11354  uri.SetFragment(fragment);
11355 
11356  TMessage mess(kPROOF_DATASETS);
11357  mess << Int_t(kSetDefaultTreeName);
11358  mess << uri.GetUri();
11359  Broadcast(mess);
11360 
11361  Collect();
11362  if (fStatus != 0) {
11363  Error("SetDataSetTreeName", "some error occured: default tree name not changed");
11364  return -1;
11365  }
11366  return 0;
11367 }
11368 
11369 ////////////////////////////////////////////////////////////////////////////////
11370 /// Lists all datasets that match given uri.
11371 /// The 'optStr' can contain a comma-separated list of servers for which the
11372 /// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
11373 /// only the global information in the TFileCollection is retrieved; useful to only
11374 /// get the list of available datasets.
11375 
11376 TMap *TProof::GetDataSets(const char *uri, const char *optStr)
11377 {
11378  if (fProtocol < 15) {
11379  Info("GetDataSets",
11380  "functionality not available: the server does not have dataset support");
11381  return 0;
11382  }
11383  if (fProtocol < 31 && strstr(optStr, ":lite:"))
11384  Warning("GetDataSets", "'lite' option not supported by the server");
11385 
11386  TMessage mess(kPROOF_DATASETS);
11387  mess << Int_t(kGetDataSets);
11388  mess << TString(uri ? uri : "");
11389  mess << TString(optStr ? optStr : "");
11390  Broadcast(mess);
11392 
11393  TMap *dataSetMap = 0;
11394  if (fStatus != 0) {
11395  Error("GetDataSets", "error receiving datasets information");
11396  } else {
11397  // Look in the list
11398  TMessage *retMess = (TMessage *) fRecvMessages->First();
11399  if (retMess && retMess->What() == kMESS_OK) {
11400  if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
11401  Error("GetDataSets", "error receiving datasets");
11402  } else
11403  Error("GetDataSets", "message not found or wrong type (%p)", retMess);
11404  }
11405 
11406  return dataSetMap;
11407 }
11408 
11409 ////////////////////////////////////////////////////////////////////////////////
11410 /// Shows datasets in locations that match the uri.
11411 /// By default shows the user's datasets and global ones
11412 
11413 void TProof::ShowDataSets(const char *uri, const char* optStr)
11414 {
11415  if (fProtocol < 15) {
11416  Info("ShowDataSets",
11417  "functionality not available: the server does not have dataset support");
11418  return;
11419  }
11420 
11421  TMessage mess(kPROOF_DATASETS);
11422  mess << Int_t(kShowDataSets);
11423  mess << TString(uri ? uri : "");
11424  mess << TString(optStr ? optStr : "");
11425  Broadcast(mess);
11426 
11428  if (fStatus != 0)
11429  Error("ShowDataSets", "error receiving datasets information");
11430 }
11431 
11432 ////////////////////////////////////////////////////////////////////////////////
11433 /// Returns kTRUE if 'dataset' exists, kFALSE otherwise
11434 
11435 Bool_t TProof::ExistsDataSet(const char *dataset)
11436 {
11437  if (fProtocol < 15) {
11438  Info("ExistsDataSet", "functionality not available: the server has an"
11439  " incompatible version of TFileInfo");
11440  return kFALSE;
11441  }
11442 
11443  if (!dataset || strlen(dataset) <= 0) {
11444  Error("ExistsDataSet", "dataset name missing");
11445  return kFALSE;
11446  }
11447 
11449  msg << Int_t(kCheckDataSetName) << TString(dataset);
11450  Broadcast(msg);
11452  if (fStatus == -1) {
11453  // The dataset exists
11454  return kTRUE;
11455  }
11456  // The dataset does not exists
11457  return kFALSE;
11458 }
11459 
11460 ////////////////////////////////////////////////////////////////////////////////
11461 /// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
11462 
11463 void TProof::ClearDataSetCache(const char *dataset)
11464 {
11465  if (fProtocol < 28) {
11466  Info("ClearDataSetCache", "functionality not available on server");
11467  return;
11468  }
11469 
11471  msg << Int_t(kCache) << TString(dataset) << TString("clear");
11472  Broadcast(msg);
11474  // Done
11475  return;
11476 }
11477 
11478 ////////////////////////////////////////////////////////////////////////////////
11479 /// Display the content of the dataset cache, if any (matching 'dataset', if defined).
11480 
11481 void TProof::ShowDataSetCache(const char *dataset)
11482 {
11483  if (fProtocol < 28) {
11484  Info("ShowDataSetCache", "functionality not available on server");
11485  return;
11486  }
11487 
11489  msg << Int_t(kCache) << TString(dataset) << TString("show");
11490  Broadcast(msg);
11492  // Done
11493  return;
11494 }
11495 
11496 ////////////////////////////////////////////////////////////////////////////////
11497 /// Get a list of TFileInfo objects describing the files of the specified
11498 /// dataset.
11499 /// To get the short version (containing only the global meta information)
11500 /// specify optStr = "S:" or optStr = "short:".
11501 /// To get the sub-dataset of files located on a given server(s) specify
11502 /// the list of servers (comma-separated) in the 'optStr' field.
11503 
11504 TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
11505 {
11506  if (fProtocol < 15) {
11507  Info("GetDataSet", "functionality not available: the server has an"
11508  " incompatible version of TFileInfo");
11509  return 0;
11510  }
11511 
11512  if (!uri || strlen(uri) <= 0) {
11513  Info("GetDataSet", "specifying a dataset name is mandatory");
11514  return 0;
11515  }
11516 
11517  TMessage nameMess(kPROOF_DATASETS);
11518  nameMess << Int_t(kGetDataSet);
11519  nameMess << TString(uri);
11520  nameMess << TString(optStr ? optStr: "");
11521  if (Broadcast(nameMess) < 0)
11522  Error("GetDataSet", "sending request failed");
11523 
11525  TFileCollection *fileList = 0;
11526  if (fStatus != 0) {
11527  Error("GetDataSet", "error receiving datasets information");
11528  } else {
11529  // Look in the list
11530  TMessage *retMess = (TMessage *) fRecvMessages->First();
11531  if (retMess && retMess->What() == kMESS_OK) {
11532  if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
11533  Error("GetDataSet", "error reading list of files");
11534  } else
11535  Error("GetDataSet", "message not found or wrong type (%p)", retMess);
11536  }
11537 
11538  return fileList;
11539 }
11540 
11541 ////////////////////////////////////////////////////////////////////////////////
11542 /// display meta-info for given dataset usi
11543 
11544 void TProof::ShowDataSet(const char *uri, const char* opt)
11545 {
11546  TFileCollection *fileList = 0;
11547  if ((fileList = GetDataSet(uri))) {
11548  fileList->Print(opt);
11549  delete fileList;
11550  } else
11551  Warning("ShowDataSet","no such dataset: %s", uri);
11552 }
11553 
11554 ////////////////////////////////////////////////////////////////////////////////
11555 /// Remove the specified dataset from the PROOF cluster.
11556 /// Files are not deleted.
11557 
11558 Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
11559 {
11560  TMessage nameMess(kPROOF_DATASETS);
11561  nameMess << Int_t(kRemoveDataSet);
11562  nameMess << TString(uri?uri:"");
11563  nameMess << TString(optStr?optStr:"");
11564  if (Broadcast(nameMess) < 0)
11565  Error("RemoveDataSet", "sending request failed");
11567 
11568  if (fStatus != 0)
11569  return -1;
11570  else
11571  return 0;
11572 }
11573 
11574 ////////////////////////////////////////////////////////////////////////////////
11575 /// Find datasets, returns in a TList all found datasets.
11576 
11577 TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
11578 {
11579  Error ("FindDataSets", "not yet implemented");
11580  return (TList *) 0;
11581 }
11582 
11583 ////////////////////////////////////////////////////////////////////////////////
11584 /// Allows users to request staging of a particular dataset. Requests are
11585 /// saved in a special dataset repository and must be honored by the endpoint.
11586 
11588 {
11589  if (fProtocol < 35) {
11590  Error("RequestStagingDataSet",
11591  "functionality not supported by the server");
11592  return kFALSE;
11593  }
11594 
11595  TMessage mess(kPROOF_DATASETS);
11596  mess << Int_t(kRequestStaging);
11597  mess << TString(dataset);
11598  Broadcast(mess);
11599 
11600  Collect();
11601  if (fStatus != 0) {
11602  Error("RequestStagingDataSet", "staging request was unsuccessful");
11603  return kFALSE;
11604  }
11605 
11606  return kTRUE;
11607 }
11608 
11609 ////////////////////////////////////////////////////////////////////////////////
11610 /// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11611 /// failure. Dataset not found equals to a failure.
11612 
11614 {
11615  if (fProtocol < 36) {
11616  Error("CancelStagingDataSet",
11617  "functionality not supported by the server");
11618  return kFALSE;
11619  }
11620 
11621  TMessage mess(kPROOF_DATASETS);
11622  mess << Int_t(kCancelStaging);
11623  mess << TString(dataset);
11624  Broadcast(mess);
11625 
11626  Collect();
11627  if (fStatus != 0) {
11628  Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11629  return kFALSE;
11630  }
11631 
11632  return kTRUE;
11633 }
11634 
11635 ////////////////////////////////////////////////////////////////////////////////
11636 /// Obtains a TFileCollection showing the staging status of the specified
11637 /// dataset. A valid dataset manager and dataset staging requests repository
11638 /// must be present on the endpoint.
11639 
11641 {
11642  if (fProtocol < 35) {
11643  Error("GetStagingStatusDataSet",
11644  "functionality not supported by the server");
11645  return NULL;
11646  }
11647 
11648  TMessage nameMess(kPROOF_DATASETS);
11649  nameMess << Int_t(kStagingStatus);
11650  nameMess << TString(dataset);
11651  if (Broadcast(nameMess) < 0) {
11652  Error("GetStagingStatusDataSet", "sending request failed");
11653  return NULL;
11654  }
11655 
11657  TFileCollection *fc = NULL;
11658 
11659  if (fStatus < 0) {
11660  Error("GetStagingStatusDataSet", "problem processing the request");
11661  }
11662  else if (fStatus == 0) {
11663  TMessage *retMess = (TMessage *)fRecvMessages->First();
11664  if (retMess && (retMess->What() == kMESS_OK)) {
11665  fc = (TFileCollection *)(
11666  retMess->ReadObject(TFileCollection::Class()) );
11667  if (!fc)
11668  Error("GetStagingStatusDataSet", "error reading list of files");
11669  }
11670  else {
11671  Error("GetStagingStatusDataSet",
11672  "response message not found or wrong type (%p)", retMess);
11673  }
11674  }
11675  //else {}
11676 
11677  return fc;
11678 }
11679 
11680 ////////////////////////////////////////////////////////////////////////////////
11681 /// Like GetStagingStatusDataSet, but displays results immediately.
11682 
11683 void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11684 {
11686  if (fc) {
11687  fc->Print(opt);
11688  delete fc;
11689  }
11690 }
11691 
11692 ////////////////////////////////////////////////////////////////////////////////
11693 /// Verify if all files in the specified dataset are available.
11694 /// Print a list and return the number of missing files.
11695 /// Returns -1 in case of error.
11696 
11697 Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11698 {
11699  if (fProtocol < 15) {
11700  Info("VerifyDataSet", "functionality not available: the server has an"
11701  " incompatible version of TFileInfo");
11702  return -1;
11703  }
11704 
11705  // Sanity check
11706  if (!uri || (uri && strlen(uri) <= 0)) {
11707  Error("VerifyDataSet", "dataset name is is mandatory");
11708  return -1;
11709  }
11710 
11711  Int_t nmissingfiles = 0;
11712 
11713  TString sopt(optStr);
11714  if (fProtocol < 34 || sopt.Contains("S")) {
11715  sopt.ReplaceAll("S", "");
11716  Info("VerifyDataSet", "Master-only verification");
11717  TMessage nameMess(kPROOF_DATASETS);
11718  nameMess << Int_t(kVerifyDataSet);
11719  nameMess << TString(uri ? uri : "");
11720  nameMess << sopt;
11721  Broadcast(nameMess);
11722 
11724 
11725  if (fStatus < 0) {
11726  Info("VerifyDataSet", "no such dataset %s", uri);
11727  return -1;
11728  } else
11729  nmissingfiles = fStatus;
11730  return nmissingfiles;
11731  }
11732 
11733  // Request for parallel verification: can only be done if we have workers
11734  if (!IsParallel() && !fDynamicStartup) {
11735  Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11736  Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11737  return -1;
11738  }
11739 
11740  // Do parallel verification
11741  return VerifyDataSetParallel(uri, optStr);
11742 }
11743 
11744 ////////////////////////////////////////////////////////////////////////////////
11745 /// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11746 /// TProofLite::VerifyDataSet
11747 
11748 Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11749 {
11750  Int_t nmissingfiles = 0;
11751 
11752  // Let PROOF master prepare node-files map
11753  SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11754 
11755  // Use TPacketizerFile
11756  TString oldpack;
11757  if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11758  SetParameter("PROOF_Packetizer", "TPacketizerFile");
11759 
11760  // Add dataset name
11761  SetParameter("PROOF_VerifyDataSet", uri);
11762  // Add options
11763  SetParameter("PROOF_VerifyDataSetOption", optStr);
11764  SetParameter("PROOF_SavePartialResults", (Int_t)0);
11765  Int_t oldifiip = -1;
11766  if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11767  SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11768 
11769  // TO DO : figure out mss and stageoption
11770  const char* mss="";
11771  SetParameter("PROOF_MSS", mss);
11772  const char* stageoption="";
11773  SetParameter("PROOF_StageOption", stageoption);
11774 
11775  // Process verification in parallel
11776  Process("TSelVerifyDataSet", (Long64_t) 1);
11777 
11778  // Restore packetizer
11779  if (!oldpack.IsNull())
11780  SetParameter("PROOF_Packetizer", oldpack);
11781  else
11782  DeleteParameters("PROOF_Packetizer");
11783 
11784  // Delete or restore parameters
11785  DeleteParameters("PROOF_FilesToProcess");
11786  DeleteParameters("PROOF_VerifyDataSet");
11787  DeleteParameters("PROOF_VerifyDataSetOption");
11788  DeleteParameters("PROOF_MSS");
11789  DeleteParameters("PROOF_StageOption");
11790  if (oldifiip > -1) {
11791  SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11792  } else {
11793  DeleteParameters("PROOF_IncludeFileInfoInPacket");
11794  }
11795  DeleteParameters("PROOF_SavePartialResults");
11796 
11797  // Merge outputs
11798  Int_t nopened = 0;
11799  Int_t ntouched = 0;
11800  Bool_t changed_ds = kFALSE;
11801 
11802  TIter nxtout(GetOutputList());
11803  TObject* obj;
11804  TList *lfiindout = new TList;
11805  while ((obj = nxtout())) {
11806  TList *l = dynamic_cast<TList *>(obj);
11807  if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11808  TIter nxt(l);
11809  TFileInfo *fiindout = 0;
11810  while ((fiindout = (TFileInfo*) nxt())) {
11811  lfiindout->Add(fiindout);
11812  }
11813  }
11814  // Add up number of disppeared files
11815  TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11816  if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11817  nmissingfiles += pdisappeared->GetVal();
11818  }
11819  TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11820  if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11821  nopened += pnopened->GetVal();
11822  }
11823  TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11824  if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11825  ntouched += pntouched->GetVal();
11826  }
11827  TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11828  if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11829  if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11830  }
11831  }
11832 
11833  Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11834  " # missing files = %d)",
11835  uri, changed_ds, nopened, ntouched, nmissingfiles);
11836  // Done
11837  return nmissingfiles;
11838 }
11839 
11840 ////////////////////////////////////////////////////////////////////////////////
11841 /// returns a map of the quotas of all groups
11842 
11843 TMap *TProof::GetDataSetQuota(const char* optStr)
11844 {
11845  if (IsLite()) {
11846  Info("UploadDataSet", "Lite-session: functionality not implemented");
11847  return (TMap *)0;
11848  }
11849 
11850  TMessage mess(kPROOF_DATASETS);
11851  mess << Int_t(kGetQuota);
11852  mess << TString(optStr?optStr:"");
11853  Broadcast(mess);
11854 
11856  TMap *groupQuotaMap = 0;
11857  if (fStatus < 0) {
11858  Info("GetDataSetQuota", "could not receive quota");
11859  } else {
11860  // Look in the list
11861  TMessage *retMess = (TMessage *) fRecvMessages->First();
11862  if (retMess && retMess->What() == kMESS_OK) {
11863  if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11864  Error("GetDataSetQuota", "error getting quotas");
11865  } else
11866  Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11867  }
11868 
11869  return groupQuotaMap;
11870 }
11871 
11872 ////////////////////////////////////////////////////////////////////////////////
11873 /// shows the quota and usage of all groups
11874 /// if opt contains "U" shows also distribution of usage on user-level
11875 
11877 {
11878  if (fProtocol < 15) {
11879  Info("ShowDataSetQuota",
11880  "functionality not available: the server does not have dataset support");
11881  return;
11882  }
11883 
11884  if (IsLite()) {
11885  Info("UploadDataSet", "Lite-session: functionality not implemented");
11886  return;
11887  }
11888 
11889  TMessage mess(kPROOF_DATASETS);
11890  mess << Int_t(kShowQuota);
11891  mess << TString(opt?opt:"");
11892  Broadcast(mess);
11893 
11894  Collect();
11895  if (fStatus != 0)
11896  Error("ShowDataSetQuota", "error receiving quota information");
11897 }
11898 
11899 ////////////////////////////////////////////////////////////////////////////////
11900 /// If in active in a monitor set ready state
11901 
11903 {
11904  if (fCurrentMonitor)
11906 }
11907 
11908 ////////////////////////////////////////////////////////////////////////////////
11909 /// Make sure that the worker identified by the ordinal number 'ord' is
11910 /// in the active list. The request will be forwarded to the master
11911 /// in direct contact with the worker. If needed, this master will move
11912 /// the worker from the inactive to the active list and rebuild the list
11913 /// of unique workers.
11914 /// Use ord = "*" to activate all inactive workers.
11915 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11916 /// status of which will be modified at once.
11917 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11918 /// or the number of workers with status change (on master; 0 on client).
11919 
11921 {
11922  return ModifyWorkerLists(ord, kTRUE, save);
11923 }
11924 
11925 ////////////////////////////////////////////////////////////////////////////////
11926 /// Remove the worker identified by the ordinal number 'ord' from the
11927 /// the active list. The request will be forwarded to the master
11928 /// in direct contact with the worker. If needed, this master will move
11929 /// the worker from the active to the inactive list and rebuild the list
11930 /// of unique workers.
11931 /// Use ord = "*" to deactivate all active workers.
11932 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11933 /// status of which will be modified at once.
11934 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11935 /// or the number of workers with status change (on master; 0 on client).
11936 
11938 {
11939  return ModifyWorkerLists(ord, kFALSE, save);
11940 }
11941 
11942 ////////////////////////////////////////////////////////////////////////////////
11943 /// Modify the worker active/inactive list by making the worker identified by
11944 /// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11945 /// The string 'ord' can also be a comma-separated list of ordinal numbers the
11946 /// status of which will be modified at once.
11947 /// If needed, the request will be forwarded to the master in direct contact
11948 /// with the worker. The end-master will move the worker from one list to the
11949 /// other active and rebuild the list of unique active workers.
11950 /// Use ord = "*" to deactivate all active workers.
11951 /// If save is TRUE the current active list is saved before any modification is
11952 /// done; re-running with ord = "restore" restores the saved list
11953 /// Return <0 if something went wrong (-2 if at least one worker was not found)
11954 /// or the number of workers with status change (on master; 0 on client).
11955 
11957 {
11958  // Make sure the input make sense
11959  if (!ord || strlen(ord) <= 0) {
11960  Info("ModifyWorkerLists",
11961  "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11962  return -1;
11963  }
11964  if (gDebug > 0)
11965  Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11966 
11967  Int_t nwc = 0;
11968  Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11969  if (IsEndMaster()) {
11970  if (restoring) {
11971  // We are asked to restore the previous settings
11972  nwc = RestoreActiveList();
11973  } else {
11974  if (save) SaveActiveList();
11975  }
11976  }
11977 
11978  Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11979 
11980  // Check if this is for us
11982  if (!allord &&
11983  strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11984  return 0;
11985  }
11986 
11987  Bool_t fw = kTRUE; // Whether to forward one step down
11988  Bool_t rs = kFALSE; // Whether to rescan for unique workers
11989 
11990  // Appropriate list pointing
11991  TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11992  TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11993 
11994  if (IsEndMaster() && !restoring) {
11995  // Create the hash list of ordinal numbers
11996  THashList *ords = 0;
11997  if (!allord) {
11998  ords = new THashList();
11999  const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
12000  TString oo(ord), o;
12001  Int_t from = 0;
12002  while(oo.Tokenize(o, from, ","))
12003  if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
12004  }
12005  // We do not need to send forward
12006  fw = kFALSE;
12007  // Look for the worker in the initial list
12008  TObject *os = 0;
12009  TSlave *wrk = 0;
12010  if (in->GetSize() > 0) {
12011  TIter nxw(in);
12012  while ((wrk = (TSlave *) nxw())) {
12013  os = 0;
12014  if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
12015  // Add it to the final list
12016  if (!out->FindObject(wrk)) {
12017  out->Add(wrk);
12018  if (add)
12019  fActiveMonitor->Add(wrk->GetSocket());
12020  }
12021  // Remove it from the initial list
12022  in->Remove(wrk);
12023  if (!add) {
12024  fActiveMonitor->Remove(wrk->GetSocket());
12026  } else
12027  wrk->SetStatus(TSlave::kActive);
12028  // Count
12029  nwc++;
12030  // Nothing to forward (ord is unique)
12031  fw = kFALSE;
12032  // Rescan for unique workers (active list modified)
12033  rs = kTRUE;
12034  // We may be done, if not option 'all'
12035  if (!allord && ords) {
12036  if (os) ords->Remove(os);
12037  if (ords->GetSize() == 0) break;
12038  SafeDelete(os);
12039  }
12040  }
12041  }
12042  }
12043  // If some worker not found, notify it if at the end
12044  if (!fw && ords && ords->GetSize() > 0) {
12045  TString oo;
12046  TIter nxo(ords);
12047  while ((os = nxo())) {
12048  TIter nxw(out);
12049  while ((wrk = (TSlave *) nxw()))
12050  if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
12051  if (!wrk) {
12052  if (!oo.IsNull()) oo += ",";
12053  oo += os->GetName();
12054  }
12055  }
12056  if (!oo.IsNull()) {
12057  Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
12058  nwc = -2;
12059  }
12060  }
12061  // Cleanup hash list
12062  if (ords) {
12063  ords->Delete();
12064  SafeDelete(ords);
12065  }
12066  }
12067 
12068  // Rescan for unique workers
12069  if (rs)
12070  FindUniqueSlaves();
12071 
12072  // Forward the request one step down, if needed
12073  Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
12074  if (fw) {
12075  if (fProtocol > 32) {
12077  mess << action << TString(ord);
12078  Broadcast(mess);
12080  if (fStatus != 0) {
12081  nwc = (fStatus < nwc) ? fStatus : nwc;
12082  if (fStatus == -2) {
12083  if (gDebug > 0)
12084  Warning("ModifyWorkerLists", "request not completely full filled");
12085  } else {
12086  Error("ModifyWorkerLists", "request failed");
12087  }
12088  }
12089  } else {
12090  TString oo(ord), o;
12091  if (oo.Contains(","))
12092  Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
12093  Int_t from = 0;
12094  while(oo.Tokenize(o, from, ",")) {
12096  mess << action << o;
12097  Broadcast(mess);
12099  }
12100  }
12101  }
12102  // Done
12103  return nwc;
12104 }
12105 
12106 ////////////////////////////////////////////////////////////////////////////////
12107 /// Save current list of active workers
12108 
12110 {
12112  if (fInactiveSlaves->GetSize() == 0) {
12113  fActiveSlavesSaved = "*";
12114  } else {
12115  TIter nxw(fActiveSlaves);
12116  TSlave *wk = 0;
12117  while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
12118  }
12119 }
12120 
12121 ////////////////////////////////////////////////////////////////////////////////
12122 /// Restore saved list of active workers
12123 
12125 {
12126  // Clear the current active list
12127  DeactivateWorker("*", kFALSE);
12128  // Restore the previous active list
12129  if (!fActiveSlavesSaved.IsNull())
12131 
12132  return 0;
12133 }
12134 
12135 ////////////////////////////////////////////////////////////////////////////////
12136 /// Start a PROOF session on a specific cluster. If cluster is 0 (the
12137 /// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
12138 /// If cluster is "lite://" we start a PROOF-lite session.
12139 /// If cluster is "" (empty string) then we connect to the cluster specified
12140 /// by 'Proof.LocalDefault', defaulting to "lite://".
12141 /// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
12142 /// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
12143 /// Via conffile a specific PROOF config file in the confir directory can be specified.
12144 /// Use loglevel to set the default loging level for debugging.
12145 /// The appropriate instance of TProofMgr is created, if not
12146 /// yet existing. The instantiated TProof object is returned.
12147 /// Use TProof::cd() to switch between PROOF sessions.
12148 /// For more info on PROOF see the TProof ctor.
12149 
12150 TProof *TProof::Open(const char *cluster, const char *conffile,
12151  const char *confdir, Int_t loglevel)
12152 {
12153  const char *pn = "TProof::Open";
12154 
12155  // Make sure libProof and dependents are loaded and TProof can be created,
12156  // dependents are loaded via the information in the [system].rootmap file
12157  if (!cluster) {
12158 
12159  TPluginManager *pm = gROOT->GetPluginManager();
12160  if (!pm) {
12161  ::Error(pn, "plugin manager not found");
12162  return 0;
12163  }
12164 
12165  if (gROOT->IsBatch()) {
12166  ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
12167  return 0;
12168  }
12169  // start PROOF Session Viewer
12170  TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
12171  if (!sv) {
12172  ::Error(pn, "no plugin found for TSessionViewer");
12173  return 0;
12174  }
12175  if (sv->LoadPlugin() == -1) {
12176  ::Error(pn, "plugin for TSessionViewer could not be loaded");
12177  return 0;
12178  }
12179  sv->ExecPlugin(0);
12180  return 0;
12181 
12182  } else {
12183 
12184  TString clst(cluster);
12185 
12186  // Check for PoD cluster
12187  if (PoDCheckUrl( &clst ) < 0) return 0;
12188 
12189  if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
12190  if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
12191 
12192  // Parse input URL
12193  TUrl u(clst);
12194 
12195  // *** GG, 060711: this does not seem to work any more (at XrdClient level)
12196  // *** to be investigated (it is not really needed; static tunnels work).
12197  // Dynamic tunnel:
12198  // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
12199  TString opts(u.GetOptions());
12200  if (!opts.IsNull()) {
12201  Int_t it = opts.Index("tunnel=");
12202  if (it != kNPOS) {
12203  TString sport = opts(it + strlen("tunnel="), opts.Length());
12204  TString host("127.0.0.1");
12205  Int_t port = -1;
12206  Int_t ic = sport.Index(":");
12207  if (ic != kNPOS) {
12208  // Isolate the host
12209  host = sport(0, ic);
12210  sport.Remove(0, ic + 1);
12211  }
12212  if (!sport.IsDigit()) {
12213  // Remove the non digit part
12214  TRegexp re("[^0-9]");
12215  Int_t ind = sport.Index(re);
12216  if (ind != kNPOS)
12217  sport.Remove(ind);
12218  }
12219  // Set the port
12220  if (sport.IsDigit())
12221  port = sport.Atoi();
12222  if (port > 0) {
12223  // Set the relevant variables
12224  ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
12225  gEnv->SetValue("XNet.SOCKS4Host", host);
12226  gEnv->SetValue("XNet.SOCKS4Port", port);
12227  } else {
12228  // Warn parsing problems
12229  ::Warning("TProof::Open",
12230  "problems parsing tunnelling info from options: %s", opts.Data());
12231  }
12232  }
12233  }
12234 
12235  // Find out if we are required to attach to a specific session
12236  Int_t locid = -1;
12237  Bool_t create = kFALSE;
12238  if (opts.Length() > 0) {
12239  if (opts.BeginsWith("N",TString::kIgnoreCase)) {
12240  create = kTRUE;
12241  opts.Remove(0,1);
12242  u.SetOptions(opts);
12243  } else if (opts.IsDigit()) {
12244  locid = opts.Atoi();
12245  }
12246  }
12247 
12248  // Attach-to or create the appropriate manager
12249  TProofMgr *mgr = TProofMgr::Create(u.GetUrl());
12250 
12251  TProof *proof = 0;
12252  if (mgr && mgr->IsValid()) {
12253 
12254  // If XProofd we always attempt an attach first (unless
12255  // explicitly not requested).
12256  Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
12257  if (attach) {
12258  TProofDesc *d = 0;
12259  if (locid < 0)
12260  // Get the list of sessions
12261  d = (TProofDesc *) mgr->QuerySessions("")->First();
12262  else
12263  d = (TProofDesc *) mgr->GetProofDesc(locid);
12264  if (d) {
12265  proof = (TProof*) mgr->AttachSession(d);
12266  if (!proof || !proof->IsValid()) {
12267  if (locid)
12268  ::Error(pn, "new session could not be attached");
12269  SafeDelete(proof);
12270  }
12271  }
12272  }
12273 
12274  // start the PROOF session
12275  if (!proof) {
12276  proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
12277  if (!proof || !proof->IsValid()) {
12278  ::Error(pn, "new session could not be created");
12279  SafeDelete(proof);
12280  }
12281  }
12282  }
12283  return proof;
12284  }
12285 }
12286 
12287 ////////////////////////////////////////////////////////////////////////////////
12288 /// Get instance of the effective manager for 'url'
12289 /// Return 0 on failure.
12290 
12291 TProofMgr *TProof::Mgr(const char *url)
12292 {
12293  if (!url)
12294  return (TProofMgr *)0;
12295 
12296  // Attach or create the relevant instance
12297  return TProofMgr::Create(url);
12298 }
12299 
12300 ////////////////////////////////////////////////////////////////////////////////
12301 /// Wrapper around TProofMgr::Reset(...).
12302 
12303 void TProof::Reset(const char *url, Bool_t hard)
12304 {
12305  if (url) {
12306  TProofMgr *mgr = TProof::Mgr(url);
12307  if (mgr && mgr->IsValid())
12308  mgr->Reset(hard);
12309  else
12310  ::Error("TProof::Reset",
12311  "unable to initialize a valid manager instance");
12312  }
12313 }
12314 
12315 ////////////////////////////////////////////////////////////////////////////////
12316 /// Get environemnt variables.
12317 
12319 {
12320  return fgProofEnvList;
12321 }
12322 
12323 ////////////////////////////////////////////////////////////////////////////////
12324 /// Add an variable to the list of environment variables passed to proofserv
12325 /// on the master and slaves
12326 
12327 void TProof::AddEnvVar(const char *name, const char *value)
12328 {
12329  if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
12330 
12331  if (fgProofEnvList == 0) {
12332  // initialize the list if needed
12333  fgProofEnvList = new TList;
12335  } else {
12336  // replace old entries with the same name
12337  TObject *o = fgProofEnvList->FindObject(name);
12338  if (o != 0) {
12339  fgProofEnvList->Remove(o);
12340  }
12341  }
12342  fgProofEnvList->Add(new TNamed(name, value));
12343 }
12344 
12345 ////////////////////////////////////////////////////////////////////////////////
12346 /// Remove an variable from the list of environment variables passed to proofserv
12347 /// on the master and slaves
12348 
12349 void TProof::DelEnvVar(const char *name)
12350 {
12351  if (fgProofEnvList == 0) return;
12352 
12353  TObject *o = fgProofEnvList->FindObject(name);
12354  if (o != 0) {
12355  fgProofEnvList->Remove(o);
12356  }
12357 }
12358 
12359 ////////////////////////////////////////////////////////////////////////////////
12360 /// Clear the list of environment variables passed to proofserv
12361 /// on the master and slaves
12362 
12364 {
12365  if (fgProofEnvList == 0) return;
12366 
12368 }
12369 
12370 ////////////////////////////////////////////////////////////////////////////////
12371 /// Save information about the worker set in the file .workers in the working
12372 /// dir. Called each time there is a change in the worker setup, e.g. by
12373 /// TProof::MarkBad().
12374 
12376 {
12377  // We must be masters
12379  return;
12380 
12381  // We must have a server defined
12382  if (!gProofServ) {
12383  Error("SaveWorkerInfo","gProofServ undefined");
12384  return;
12385  }
12386 
12387  // The relevant lists must be defined
12388  if (!fSlaves && !fBadSlaves) {
12389  Warning("SaveWorkerInfo","all relevant worker lists is undefined");
12390  return;
12391  }
12392 
12393  // Create or truncate the file first
12394  TString fnwrk = TString::Format("%s/.workers",
12396  FILE *fwrk = fopen(fnwrk.Data(),"w");
12397  if (!fwrk) {
12398  Error("SaveWorkerInfo",
12399  "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
12400  return;
12401  }
12402 
12403  // Do we need to register an additional line for another log?
12404  TString addlogext;
12405  TString addLogTag;
12406  if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
12407  addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
12408  TPMERegexp reLogTag("^__(.*)__\\.log"); // $
12409  if (reLogTag.Match(addlogext) == 2) {
12410  addLogTag = reLogTag[1];
12411  }
12412  else {
12413  addLogTag = "+++";
12414  }
12415  if (gDebug > 0)
12416  Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
12417  }
12418 
12419  // Used to eliminate datetime and PID from workdir to obtain log file name
12420  TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
12421 
12422  // Loop over the list of workers (active is any worker not flagged as bad)
12423  TIter nxa(fSlaves);
12424  TSlave *wrk = 0;
12425  TString logfile;
12426  while ((wrk = (TSlave *) nxa())) {
12427  Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
12428  logfile = wrk->GetWorkDir();
12429  if (re.Match(logfile) == 2) logfile = re[1];
12430  else continue; // invalid (should not happen)
12431  // Write out record for this worker
12432  fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
12433  wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
12434  wrk->GetOrdinal(), logfile.Data());
12435  // Additional line, if required
12436  if (addlogext.Length() > 0) {
12437  fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
12438  wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
12439  wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
12440  }
12441 
12442  }
12443 
12444  // Loop also over the list of bad workers (if they failed to startup they are not in
12445  // the overall list
12446  TIter nxb(fBadSlaves);
12447  while ((wrk = (TSlave *) nxb())) {
12448  logfile = wrk->GetWorkDir();
12449  if (re.Match(logfile) == 2) logfile = re[1];
12450  else continue; // invalid (should not happen)
12451  if (!fSlaves->FindObject(wrk)) {
12452  // Write out record for this worker
12453  fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
12454  wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
12455  wrk->GetOrdinal(), logfile.Data());
12456  }
12457  }
12458 
12459  // Eventually loop over the list of gracefully terminated workers: we'll get
12460  // logfiles from those workers as well. They'll be shown with a special
12461  // status of "2"
12463  TSlaveInfo *sli;
12464  while (( sli = (TSlaveInfo *)nxt() )) {
12465  logfile = sli->GetDataDir();
12466  if (re.Match(logfile) == 2) logfile = re[1];
12467  else continue; // invalid (should not happen)
12468  fprintf(fwrk, "%s 2 %s %s.log\n",
12469  sli->GetName(), sli->GetOrdinal(), logfile.Data());
12470  // Additional line, if required
12471  if (addlogext.Length() > 0) {
12472  fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
12473  sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
12474  logfile.Data(), addlogext.Data());
12475  }
12476  }
12477 
12478  // Close file
12479  fclose(fwrk);
12480 
12481  // We are done
12482  return;
12483 }
12484 
12485 ////////////////////////////////////////////////////////////////////////////////
12486 /// Get the value from the specified parameter from the specified collection.
12487 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12488 /// or value type does not match), 0 otherwise.
12489 
12491 {
12492  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12493  if (obj) {
12494  TNamed *p = dynamic_cast<TNamed*>(obj);
12495  if (p) {
12496  value = p->GetTitle();
12497  return 0;
12498  }
12499  }
12500  return -1;
12501 
12502 }
12503 
12504 ////////////////////////////////////////////////////////////////////////////////
12505 /// Get the value from the specified parameter from the specified collection.
12506 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12507 /// or value type does not match), 0 otherwise.
12508 
12510 {
12511  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12512  if (obj) {
12513  TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
12514  if (p) {
12515  value = p->GetVal();
12516  return 0;
12517  }
12518  }
12519  return -1;
12520 }
12521 
12522 ////////////////////////////////////////////////////////////////////////////////
12523 /// Get the value from the specified parameter from the specified collection.
12524 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12525 /// or value type does not match), 0 otherwise.
12526 
12528 {
12529  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12530  if (obj) {
12531  TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
12532  if (p) {
12533  value = p->GetVal();
12534  return 0;
12535  }
12536  }
12537  return -1;
12538 }
12539 
12540 ////////////////////////////////////////////////////////////////////////////////
12541 /// Get the value from the specified parameter from the specified collection.
12542 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12543 /// or value type does not match), 0 otherwise.
12544 
12546 {
12547  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12548  if (obj) {
12549  TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
12550  if (p) {
12551  value = p->GetVal();
12552  return 0;
12553  }
12554  }
12555  return -1;
12556 }
12557 
12558 ////////////////////////////////////////////////////////////////////////////////
12559 /// Get the value from the specified parameter from the specified collection.
12560 /// Returns -1 in case of error (i.e. list is 0, parameter does not exist
12561 /// or value type does not match), 0 otherwise.
12562 
12564 {
12565  TObject *obj = c ? c->FindObject(par) : (TObject *)0;
12566  if (obj) {
12567  TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
12568  if (p) {
12569  value = p->GetVal();
12570  return 0;
12571  }
12572  }
12573  return -1;
12574 }
12575 
12576 ////////////////////////////////////////////////////////////////////////////////
12577 /// Make sure that dataset is in the form to be processed. This may mean
12578 /// retrieving the relevant info from the dataset manager or from the
12579 /// attached input list.
12580 /// Returns 0 on success, -1 on error
12581 
12583  TDataSetManager *mgr, TString &emsg)
12584 {
12585  emsg = "";
12586 
12587  // We must have something to process
12588  if (!dset || !input || !mgr) {
12589  emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
12590  return -1;
12591  }
12592 
12593  TList *datasets = new TList;
12594  TFileCollection *dataset = 0;
12595  TString lookupopt;
12596  TString dsname(dset->GetName());
12597  // The dataset maybe in the form of a TFileCollection in the input list
12598  if (dsname.BeginsWith("TFileCollection:")) {
12599  // Isolate the real name
12600  dsname.ReplaceAll("TFileCollection:", "");
12601  // Get the object
12602  dataset = (TFileCollection *) input->FindObject(dsname);
12603  if (!dataset) {
12604  emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12605  return -1;
12606  }
12607  // Remove from everywhere
12608  input->RecursiveRemove(dataset);
12609  // Add it to the local list
12610  datasets->Add(new TPair(dataset, new TObjString("")));
12611  // Make sure we lookup everything (unless the client or the administrator
12612  // required something else)
12613  if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12614  lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12615  input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12616  }
12617  }
12618 
12619  // This is the name we parse for additional specifications, such directory
12620  // and object name; for multiple datasets we assume that the directory and
12621  // and object name are the same for all datasets
12622  TString dsnparse;
12623  // The received message included an empty dataset, with only the name
12624  // defined: assume that a dataset, stored on the PROOF master by that
12625  // name, should be processed.
12626  if (!dataset) {
12627 
12628  // First of all check if the full string (except the "entry list" part)
12629  // is the name of a single existing dataset: if it is, don't break it
12630  // into parts
12631  TString dsns( dsname.Data() ), enl;
12632  Ssiz_t eli = dsns.Index("?enl=");
12633  TFileCollection *fc = nullptr;
12634  if (eli != kNPOS) {
12635  enl = dsns(eli+5, dsns.Length());
12636  dsns.Remove(eli, dsns.Length()-eli);
12637  }
12638 
12639  // Check if the entry list is valid. If it has spaces, commas, or pipes,
12640  // it is not considered as valid and we revert to the "multiple datasets"
12641  // case
12642  Bool_t validEnl = ((enl.Index("|") == kNPOS) &&
12643  (enl.Index(",") == kNPOS) && (enl.Index(" ") == kNPOS));
12644 
12645  if (validEnl && (( fc = mgr->GetDataSet(dsns) ))) {
12646 
12647  //
12648  // String corresponds to ONE dataset only
12649  //
12650 
12651  TIter nxfi(fc->GetList());
12652  TFileInfo *fi;
12653  while (( fi = (TFileInfo *)nxfi() ))
12654  fi->SetTitle(dsns.Data());
12655  dataset = fc;
12656  dsnparse = dsns; // without entry list
12657 
12658  // Adds the entry list (or empty string if not specified)
12659  datasets->Add( new TPair(dataset, new TObjString( enl.Data() )) );
12660 
12661  }
12662  else {
12663 
12664  //
12665  // String does NOT correspond to one dataset: check if many datasets
12666  // were specified instead
12667  //
12668 
12669  dsns = dsname.Data();
12670  TString dsn1;
12671  Int_t from1 = 0;
12672  while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12673  TString dsn2;
12674  Int_t from2 = 0;
12675  while (dsn1.Tokenize(dsn2, from2, "|")) {
12676  enl = "";
12677  Int_t ienl = dsn2.Index("?enl=");
12678  if (ienl != kNPOS) {
12679  enl = dsn2(ienl + 5, dsn2.Length());
12680  dsn2.Remove(ienl);
12681  }
12682  if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12683  // Save dataset name in TFileInfo's title to use it in TDset
12684  TIter nxfi(fc->GetList());
12685  TFileInfo *fi;
12686  while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12687  dsnparse = dsn2;
12688  if (!dataset) {
12689  // This is our dataset
12690  dataset = fc;
12691  } else {
12692  // Add it to the dataset
12693  dataset->Add(fc);
12694  SafeDelete(fc);
12695  }
12696  }
12697  }
12698  // The dataset name(s) in the first element
12699  if (dataset) {
12700  if (dataset->GetList()->First())
12701  ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12702  // Add it to the local list
12703  datasets->Add(new TPair(dataset, new TObjString(enl.Data())));
12704  }
12705  // Reset the pointer
12706  dataset = 0;
12707  }
12708 
12709  }
12710 
12711  //
12712  // At this point the dataset(s) to be processed, if any, are found in the
12713  // "datasets" variable
12714  //
12715 
12716  if (!datasets || datasets->GetSize() <= 0) {
12717  emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12718  return -1;
12719  } else {
12720  // Make 'dataset' to point to the first one in the list
12721  if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12722  emsg.Form("dataset pointer is null: corruption? - aborting");
12723  return -1;
12724  }
12725  }
12726  // Apply the lookup option requested by the client or the administartor
12727  // (by default we trust the information in the dataset)
12728  if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12729  lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12730  input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12731  }
12732  } else {
12733  // We were given a named, single, TFileCollection
12734  dsnparse = dsname;
12735  }
12736 
12737  // Logic for the subdir/obj names: try first to see if the dataset name contains
12738  // some info; if not check the settings in the TDSet object itself; if still empty
12739  // check the default tree name / path in the TFileCollection object; if still empty
12740  // use the default as the flow will determine
12741  TString dsTree;
12742  // Get the [subdir/]tree, if any
12743  mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12744  if (dsTree.IsNull()) {
12745  // Use what we have in the original dataset; we need this to locate the
12746  // meta data information
12747  dsTree += dset->GetDirectory();
12748  dsTree += dset->GetObjName();
12749  }
12750  if (!dsTree.IsNull() && dsTree != "/") {
12751  TString tree(dsTree);
12752  Int_t idx = tree.Index("/");
12753  if (idx != kNPOS) {
12754  TString dir = tree(0, idx+1);
12755  tree.Remove(0, idx);
12756  dset->SetDirectory(dir);
12757  }
12758  dset->SetObjName(tree);
12759  } else {
12760  // Use the default obj name from the TFileCollection
12761  dsTree = dataset->GetDefaultTreeName();
12762  }
12763 
12764  // Pass dataset server mapping instructions, if any
12765  TList *srvmapsref = TDataSetManager::GetDataSetSrvMaps();
12766  TList *srvmapslist = srvmapsref;
12767  TString srvmaps;
12768  if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12769  srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12770  if (gProofServ) {
12771  TString msg;
12772  if (srvmapsref && !srvmapslist) {
12773  msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12774  } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12775  msg.Form("+++ Info: dataset server mapping(s) modified by user");
12776  } else if (!srvmapsref && srvmapslist) {
12777  msg.Form("+++ Info: dataset server mapping(s) added by user");
12778  }
12780  }
12781  }
12782 
12783  // Flag multi-datasets
12784  if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12785  // Loop over the list of datasets
12786  TList *listOfMissingFiles = new TList;
12787  TEntryList *entrylist = 0;
12788  TPair *pair = 0;
12789  TIter nxds(datasets);
12790  while ((pair = (TPair *) nxds())) {
12791  // File Collection
12792  dataset = (TFileCollection *) pair->Key();
12793  // Entry list, if any
12794  TEntryList *enl = 0;
12795  TObjString *os = (TObjString *) pair->Value();
12796  if (strlen(os->GetName())) {
12797  if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12798  if (gProofServ)
12800  " entry list %s not found", os->GetName()));
12801  }
12802  if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12803  if (gProofServ)
12805  " no sub-lists in entry-list!"));
12806  }
12807  }
12808  TList *missingFiles = new TList;
12809  TSeqCollection* files = dataset->GetList();
12810  if (gDebug > 0) files->Print();
12811  Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12812  if (dset->TestBit(TDSet::kMultiDSet)) {
12813  TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12814  ds->SetSrvMaps(srvmapslist);
12815  if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12816  emsg.Form("error integrating dataset %s", dataset->GetName());
12817  continue;
12818  }
12819  // Add the TDSet object to the multi-dataset
12820  dset->Add(ds);
12821  // Add entry list if any
12822  if (enl) ds->SetEntryList(enl);
12823  } else {
12824  dset->SetSrvMaps(srvmapslist);
12825  if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12826  emsg.Form("error integrating dataset %s", dataset->GetName());
12827  continue;
12828  }
12829  if (enl) entrylist = enl;
12830  }
12831  if (missingFiles) {
12832  // The missing files objects have to be removed from the dataset
12833  // before delete.
12834  TIter next(missingFiles);
12835  TObject *file;
12836  while ((file = next())) {
12837  dataset->GetList()->Remove(file);
12838  listOfMissingFiles->Add(file);
12839  }
12840  missingFiles->SetOwner(kFALSE);
12841  missingFiles->Clear();
12842  }
12843  SafeDelete(missingFiles);
12844  }
12845  // Cleanup; we need to do this because pairs do no delete their content
12846  nxds.Reset();
12847  while ((pair = (TPair *) nxds())) {
12848  if (pair->Key()) delete pair->Key();
12849  if (pair->Value()) delete pair->Value();
12850  }
12851  datasets->SetOwner(kTRUE);
12852  SafeDelete(datasets);
12853 
12854  // Cleanup the server mapping list, if created by the user
12855  if (srvmapslist && srvmapslist != srvmapsref) {
12856  srvmapslist->SetOwner(kTRUE);
12857  SafeDelete(srvmapslist);
12858  }
12859 
12860  // Set the global entrylist, if required
12861  if (entrylist) dset->SetEntryList(entrylist);
12862 
12863  // Make sure it will be sent back merged with other similar lists created
12864  // during processing; this list will be transferred by the player to the
12865  // output list, once the latter has been created (see TProofPlayerRemote::Process)
12866  if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12867  listOfMissingFiles->SetName("MissingFiles");
12868  input->Add(listOfMissingFiles);
12869  }
12870 
12871  // Done
12872  return 0;
12873 }
12874 
12875 ////////////////////////////////////////////////////////////////////////////////
12876 /// Save input data file from 'cachedir' into the sandbox or create a the file
12877 /// with input data objects
12878 
12879 Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12880 {
12881  TList *input = 0;
12882 
12883  // We must have got something to process
12884  if (!qr || !(input = qr->GetInputList()) ||
12885  !cachedir || strlen(cachedir) <= 0) return 0;
12886 
12887  // There must be some input data or input data file
12888  TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12889  TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12890  if (!data && !inputdata) return 0;
12891  // Default dstination filename
12892  if (!data)
12893  input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12894 
12895  TString dstname(data->GetTitle()), srcname;
12896  Bool_t fromcache = kFALSE;
12897  if (dstname.BeginsWith("cache:")) {
12898  fromcache = kTRUE;
12899  dstname.ReplaceAll("cache:", "");
12900  srcname.Form("%s/%s", cachedir, dstname.Data());
12901  if (gSystem->AccessPathName(srcname)) {
12902  emsg.Form("input data file not found in cache (%s)", srcname.Data());
12903  return -1;
12904  }
12905  }
12906 
12907  // If from cache, just move the cache file
12908  if (fromcache) {
12909  if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12910  emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12911  return -1;
12912  }
12913  } else {
12914  // Create the file
12915  if (inputdata && inputdata->GetSize() > 0) {
12916  TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12917  if (f) {
12918  f->cd();
12919  inputdata->Write();
12920  f->Close();
12921  delete f;
12922  } else {
12923  emsg.Form("could not create %s", dstname.Data());
12924  return -1;
12925  }
12926  } else {
12927  emsg.Form("no input data!");
12928  return -1;
12929  }
12930  }
12931  ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12932 
12933  // Save the file name and clean up the data list
12934  data->SetTitle(dstname);
12935  if (inputdata) {
12936  input->Remove(inputdata);
12937  inputdata->SetOwner();
12938  delete inputdata;
12939  }
12940 
12941  // Done
12942  return 0;
12943 }
12944 
12945 ////////////////////////////////////////////////////////////////////////////////
12946 /// Send the input data file to the workers
12947 
12949 {
12950  TList *input = 0;
12951 
12952  // We must have got something to process
12953  if (!qr || !(input = qr->GetInputList())) return 0;
12954 
12955  // There must be some input data or input data file
12956  TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12957  if (!inputdata) return 0;
12958 
12959  TString fname(inputdata->GetTitle());
12960  if (gSystem->AccessPathName(fname)) {
12961  emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12962  return -1;
12963  }
12964 
12965  // PROOF session must available
12966  if (!p || !p->IsValid()) {
12967  emsg.Form("TProof object undefined or invalid: protocol error!");
12968  return -1;
12969  }
12970 
12971  // Send to unique workers and submasters
12972  p->BroadcastFile(fname, TProof::kBinary, "cache");
12973 
12974  // Done
12975  return 0;
12976 }
12977 
12978 ////////////////////////////////////////////////////////////////////////////////
12979 /// Get the input data from the file defined in the input list
12980 
12981 Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12982 {
12983  // We must have got something to process
12984  if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12985 
12986  // There must be some input data or input data file
12987  TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12988  if (!inputdata) return 0;
12989 
12990  TString fname;
12991  fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12992  if (gSystem->AccessPathName(fname)) {
12993  emsg.Form("input data file not found in cache (%s)", fname.Data());
12994  return -1;
12995  }
12996 
12997  // List of added objects (for proper cleaning ...)
12998  TList *added = new TList;
12999  added->SetName("PROOF_InputObjsFromFile");
13000  // Read the input data into the input list
13001  TFile *f = TFile::Open(fname.Data());
13002  if (f) {
13003  TList *keys = (TList *) f->GetListOfKeys();
13004  if (!keys) {
13005  emsg.Form("could not get list of object keys from file");
13006  return -1;
13007  }
13008  TIter nxk(keys);
13009  TKey *k = 0;
13010  while ((k = (TKey *)nxk())) {
13011  TObject *o = f->Get(k->GetName());
13012  if (o) {
13013  input->Add(o);
13014  added->Add(o);
13015  }
13016  }
13017  // Add the file as last one
13018  if (added->GetSize() > 0) {
13019  added->Add(f);
13020  input->Add(added);
13021  } else {
13022  // Cleanup the file now
13023  f->Close();
13024  delete f;
13025  }
13026  } else {
13027  emsg.Form("could not open %s", fname.Data());
13028  return -1;
13029  }
13030 
13031  // Done
13032  return 0;
13033 }
13034 
13035 ////////////////////////////////////////////////////////////////////////////////
13036 /// Start the log viewer window usign the plugin manager
13037 
13038 void TProof::LogViewer(const char *url, Int_t idx)
13039 {
13040  if (!gROOT->IsBatch()) {
13041  // Get the handler, if not yet done
13042  if (!fgLogViewer) {
13043  if ((fgLogViewer =
13044  gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
13045  if (fgLogViewer->LoadPlugin() == -1) {
13046  fgLogViewer = 0;
13047  ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
13048  return;
13049  }
13050  }
13051  }
13052  if (fgLogViewer) {
13053  // Execute the plug-in
13054  TString u = (url && strlen(url) <= 0) ? "lite" : url;
13055  fgLogViewer->ExecPlugin(2, u.Data(), idx);
13056  }
13057  } else {
13058  if (url && strlen(url) > 0) {
13059  ::Info("TProof::LogViewer",
13060  "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
13061  } else if (url && strlen(url) <= 0) {
13062  ::Info("TProof::LogViewer",
13063  "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
13064  } else {
13065  ::Info("TProof::LogViewer",
13066  "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
13067  }
13068  }
13069  // Done
13070  return;
13071 }
13072 
13073 ////////////////////////////////////////////////////////////////////////////////
13074 /// Enable/Disable the graphic progress dialog.
13075 /// By default the dialog is enabled
13076 
13078 {
13079  if (on)
13081  else
13083 }
13084 
13085 ////////////////////////////////////////////////////////////////////////////////
13086 /// Show information about missing files during query described by 'qr' or the
13087 /// last query if qr is null (default).
13088 /// A short summary is printed in the end.
13089 
13091 {
13092  TQueryResult *xqr = (qr) ? qr : GetQueryResult();
13093  if (!xqr) {
13094  Warning("ShowMissingFiles", "no (last) query found: do nothing");
13095  return;
13096  }
13097 
13098  // Get the list, if any
13099  TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
13100  if (!missing) {
13101  Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
13102  return;
13103  }
13104 
13105  Int_t nmf = 0, ncf = 0;
13106  Long64_t msz = 0, mszzip = 0, mev = 0;
13107  // Scan the list
13108  TFileInfo *fi = 0;
13109  TIter nxf(missing);
13110  while ((fi = (TFileInfo *) nxf())) {
13111  char status = 'M';
13112  if (fi->TestBit(TFileInfo::kCorrupted)) {
13113  ncf++;
13114  status = 'C';
13115  } else {
13116  nmf++;
13117  }
13118  TFileInfoMeta *im = fi->GetMetaData();
13119  if (im) {
13120  if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
13121  if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
13122  mev += im->GetEntries();
13123  Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
13124  } else {
13125  Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
13126  }
13127  }
13128 
13129  // Final notification
13130  if (msz <= 0) msz = -1;
13131  if (mszzip <= 0) mszzip = -1;
13132  Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
13133  if (msz > 0. || mszzip > 0.) {
13134  Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
13135  " about %.2f%% of the total (%lld bytes, %lld zipped)",
13136  nmf, ncf, mev, xf * 100., msz, mszzip);
13137  } else {
13138  Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
13139  " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
13140  }
13141 }
13142 
13143 ////////////////////////////////////////////////////////////////////////////////
13144 /// Get a TFileCollection with the files missing in the query described by 'qr'
13145 /// or the last query if qr is null (default).
13146 /// Return a null pointer if none were found, for whatever reason.
13147 /// The caller is responsible for the returned object.
13148 
13150 {
13151  TFileCollection *fc = 0;
13152 
13153  TQueryResult *xqr = (qr) ? qr : GetQueryResult();
13154  if (!xqr) {
13155  Warning("GetMissingFiles", "no (last) query found: do nothing");
13156  return fc;
13157  }
13158 
13159  // Get the list, if any
13160  TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
13161  if (!missing) {
13162  if (gDebug > 0)
13163  Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
13164  return fc;
13165  }
13166 
13167  // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
13168  TString fcname("unknown");
13169  TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
13170  if (ds) {
13171  fcname.Form("%s.m0", ds->GetName());
13172  Int_t j = 1;
13173  while (gDirectory->FindObject(fcname) && j < 1000)
13174  fcname.Form("%s.m%d", ds->GetName(), j++);
13175  }
13176  fc = new TFileCollection(fcname, "Missing Files");
13177  if (ds) fc->SetDefaultTreeName(ds->GetObjName());
13178  // Scan the list
13179  TFileInfo *fi = 0;
13180  TIter nxf(missing);
13181  while ((fi = (TFileInfo *) nxf())) {
13182  fc->Add((TFileInfo *) fi->Clone());
13183  }
13184  fc->Update();
13185  // Done
13186  return fc;
13187 }
13188 
13189 ////////////////////////////////////////////////////////////////////////////////
13190 /// Enable/Disable saving of the performance tree
13191 
13192 void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
13193 {
13194  if (pf && strlen(pf) > 0) {
13195  fPerfTree = pf;
13196  SetParameter("PROOF_StatsHist", "");
13197  SetParameter("PROOF_StatsTrace", "");
13198  if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
13199  Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
13200  } else {
13201  fPerfTree = "";
13202  DeleteParameters("PROOF_StatsHist");
13203  DeleteParameters("PROOF_StatsTrace");
13204  DeleteParameters("PROOF_SlaveStatsTrace");
13205  Info("SetPerfTree", "saving of the performance tree disabled");
13206  }
13207 }
13208 
13209 ////////////////////////////////////////////////////////////////////////////////
13210 /// Save performance information from TPerfStats to file 'pf'.
13211 /// If 'ref' is defined, do it for query 'ref'.
13212 /// Return 0 on sucecss, -1 in case of any error
13213 
13214 Int_t TProof::SavePerfTree(const char *pf, const char *ref)
13215 {
13216  if (!IsValid()) {
13217  Error("SafePerfTree", "this TProof instance is invalid!");
13218  return -1;
13219  }
13220 
13221  TList *outls = GetOutputList();
13222  TString sref;
13223  if (ref && strlen(ref) > 0) {
13224  if (!fPlayer) {
13225  Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
13226  return -1;
13227  }
13228  TQueryResult *qr = fPlayer->GetQueryResult(ref);
13229  if (!qr) {
13230  Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
13231  return -1;
13232  }
13233  outls = qr->GetOutputList();
13234  sref.Form(" for requested query '%s'", ref);
13235  }
13236  if (!outls || (outls && outls->GetSize() <= 0)) {
13237  Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
13238  return -1;
13239  }
13240 
13241  TString fn = fPerfTree;
13242  if (pf && strlen(pf)) fn = pf;
13243  if (fn.IsNull()) fn = "perftree.root";
13244 
13245  TFile f(fn, "RECREATE");
13246  if (f.IsZombie()) {
13247  Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
13248  } else {
13249  f.cd();
13250  TIter nxo(outls);
13251  TObject* obj = 0;
13252  while ((obj = nxo())) {
13253  TString objname(obj->GetName());
13254  if (objname.BeginsWith("PROOF_")) {
13255  // Must list the objects since other PROOF_ objects exist
13256  // besides timing objects
13257  if (objname == "PROOF_PerfStats" ||
13258  objname == "PROOF_PacketsHist" ||
13259  objname == "PROOF_EventsHist" ||
13260  objname == "PROOF_NodeHist" ||
13261  objname == "PROOF_LatencyHist" ||
13262  objname == "PROOF_ProcTimeHist" ||
13263  objname == "PROOF_CpuTimeHist")
13264  obj->Write();
13265  }
13266  }
13267  f.Close();
13268  }
13269  Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
13270 
13271  // Done
13272  return 0;
13273 }
const char * GetHost() const
Definition: TUrl.h:76
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
TList * GetListOfBadSlaves() const
Definition: TProof.h:692
virtual TQueryResult * GetQueryResult(const char *ref)=0
const char * GetSessionDir() const
Definition: TProofServ.h:259
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:259
void AddInputData(TObject *obj, Bool_t push=kFALSE)
Add data objects that might be needed during the processing of the selector (see Process()).
Definition: TProof.cxx:10089
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition: TProof.cxx:2000
virtual void DeleteDrawFeedback(TDrawFeedback *f)=0
Bool_t IsRetrieve() const
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
const char * GetDefaultTreeName() const
Returns the tree set with SetDefaultTreeName if set Returns the name of the first tree in the meta da...
TList * GetOutputList()
Definition: TQueryResult.h:139
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition: TProof.cxx:3094
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
virtual Int_t GetEntries() const
Definition: TCollection.h:92
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition: TProof.cxx:7383
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:823
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Int_t AddProcessed(TSlave *, TProofProgressStatus *, Double_t, TList **)
void AddFeedback(const char *name)
Add object to feedback list.
Definition: TProof.cxx:10556
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition: TProof.cxx:7722
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:1265
double par[1]
Definition: unuranDistr.cxx:38
void RecvLogFile(TSocket *s, Int_t size)
Receive the log file of the slave with socket s.
Definition: TProof.cxx:6274
void Interrupt(EUrgent type, ESlaves list=kActive)
Send interrupt to master or slave servers.
Definition: TProof.cxx:2271
void SetSessionTag(const char *st)
Definition: TSlave.h:165
double read(const std::string &file_name)
reading
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
virtual Int_t SendGroupPriority(const char *, Int_t)
Definition: TSlave.h:114
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition: TProof.cxx:9768
const Long64_t kPROOF_DynWrkPollInt_s
Definition: TProof.h:161
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:945
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition: TProof.cxx:11150
const char * GetOutputFileName() const
virtual TList * GetInputList() const =0
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form: ~~~ {.cpp} [path/]macro.C[+|++[k|f|g|O|c|s|d|v|-]][(args)]...
Definition: TSystem.cxx:4071
virtual void AddOutput(TList *out)=0
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:711
An array of TObjects.
Definition: TObjArray.h:39
virtual Long64_t GetSize() const
Returns the current file size.
Definition: TFile.cxx:1279
TString fPerfTree
Definition: TProof.h:588
const char * GetOrdinal() const
Definition: TSlave.h:135
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8600
float xmin
Definition: THbookFile.cxx:93
TString fPackageDir
Definition: TProof.h:560
const char *const kGUNZIP
Definition: TProof.h:170
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:404
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition: TProof.cxx:4399
Bool_t IsWaiting() const
Definition: TProof.h:974
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2072
const char * GetHostName() const
Definition: TInetAddress.h:75
void SetPort(Int_t port)
Definition: TUrl.h:97
virtual TFileCollection * GetStagingStatusDataSet(const char *dataset)
Obtains a TFileCollection showing the staging status of the specified dataset.
Definition: TProof.cxx:11640
static Bool_t GetFileInCmd(const char *cmd, TString &fn)
Static method to extract the filename (if any) form a CINT command.
Definition: TProof.cxx:6482
Int_t GetSeqNum() const
Definition: TQueryResult.h:123
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:108
Bool_t fIsWaiting
Definition: TProof.h:536
Bool_t R_ISLNK(Int_t mode)
Definition: TSystem.h:130
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7845
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
TMonitor * fAllUniqueMonitor
Definition: TProof.h:514
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:4510
virtual void AddInput(TObject *inp)=0
long long Long64_t
Definition: RtypesCore.h:69
Int_t fBusSpeed
Definition: TSystem.h:167
void Activate(TList *slaves=0)
Activate slave server list.
Definition: TProof.cxx:2384
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition: TProof.cxx:10798
const char * GetDataDir() const
Definition: TProof.h:252
TSocket * GetSocket() const
Definition: TSlave.h:138
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition: TProof.cxx:11435
Int_t fPhysRam
Definition: TSystem.h:169
Bool_t IsWorker() const
static double p3(double t, double a, double b, double c, double d)
virtual ~TProof()
Clean up PROOF environment.
Definition: TProof.cxx:636
Bool_t IsValid() const
Definition: TProof.h:970
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:10206
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:55
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition: TProof.cxx:8632
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:7399
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition: TProof.cxx:13192
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:865
virtual const char * GetName() const
Return name of this collection.
virtual Bool_t RegisterDataSet(const char *name, TFileCollection *dataset, const char *optStr="")
Register the 'dataSet' on the cluster under the current user, group and the given 'dataSetName'...
Definition: TProof.cxx:11274
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:6133
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:472
Bool_t IsFinalized() const
Definition: TQueryResult.h:153
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition: TUrl.cxx:518
void SetRealTimeLog(Bool_t on=kTRUE)
Switch ON/OFF the real-time logging facility.
Definition: TProof.cxx:7083
TString fConfDir
Definition: TProof.h:600
EUrgent
Definition: TProof.h:416
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:393
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
double write(int n, const std::string &file_name, const std::string &vector_type, int compress=0)
writing
Long64_t GetTotBytes() const
Definition: TFileInfo.h:155
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
const char *const kLS
Definition: TProof.h:166
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
Int_t fOtherQueries
Definition: TProof.h:551
virtual void FlushSocket()
Definition: TSlave.h:109
const double pi
const char Int_t const char TProof Int_t const char const char * msd
Definition: TXSlave.cxx:46
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual Double_t Rndm(Int_t i=0)
Machine independent random number generator.
Definition: TRandom.cxx:512
Int_t fWorkersToMerge
Definition: TProof.h:582
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10778
Int_t GetRemoteProtocol() const
Definition: TProof.h:946
Float_t fCpuTime
Definition: TProof.h:518
const char Option_t
Definition: RtypesCore.h:62
Bool_t fSync
Definition: TProof.h:534
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4793
void SetPrepTime(Float_t preptime)
Definition: TQueryResult.h:105
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3715
const char * GetUser() const
Definition: TSlave.h:132
virtual Bool_t IsValid() const
Definition: TSocket.h:162
float ymin
Definition: THbookFile.cxx:93
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'. ...
Definition: TProof.cxx:2403
const char * GetObjName() const
Definition: TDSet.h:229
virtual Int_t Reconnect()
Definition: TSocket.h:168
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition: TProof.cxx:11902
void SetPasswd(const char *pw)
Definition: TUrl.h:92
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:212
TList * fWrksOutputReady
Definition: TProof.h:590
virtual void SetMaxDrawQueries(Int_t max)=0
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition: TProof.cxx:1654
void EmitVA(const char *signal_name, Int_t, const T &...params)
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:520
TString fOS
Definition: TSystem.h:162
virtual void ShowDataSetCache(const char *dataset=0)
Display the content of the dataset cache, if any (matching 'dataset', if defined).
Definition: TProof.cxx:11481
void ShowParameters(const char *wildcard="PROOF_*") const
Show the input list parameters specified by the wildcard.
Definition: TProof.cxx:10525
This class represents a WWW compatible URL.
Definition: TUrl.h:41
Long64_t fBytesRead
Definition: TSlave.h:96
Bool_t fMergersSet
Definition: TProof.h:579
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
Int_t fMergedWorkers
Definition: TProof.h:279
#define assert(cond)
Definition: unittest.h:542
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition: TProof.cxx:1528
TList * GetWorkers()
Definition: TProof.h:295
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:1363
const char Int_t perf
Definition: TXSlave.cxx:46
virtual Long64_t DrawSelect(TDSet *set, const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10766
#define gDirectory
Definition: TDirectory.h:218
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
Definition: TDSet.h:153
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
TList * GetOutputNames()
FIXME: to be written.
Definition: TProof.cxx:10685
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:1070
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual TList * GetListOfKeys() const
void TerminateWorker(TSlave *wrk)
Ask an active worker 'wrk' to terminate, i.e. to shutdown.
Definition: TProof.cxx:4686
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TSlave * GetMerger()
Definition: TProof.h:297
Int_t GetPort() const
Definition: TInetAddress.h:77
const char * GetProtocol() const
Definition: TUrl.h:73
TH1 * h
Definition: legend2.C:5
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:684
virtual void FindUniqueSlaves()
Add to the fUniqueSlave list the active slaves that have a unique (user) file system image...
Definition: TProof.cxx:1907
void Interrupt()
Definition: TMonitor.h:75
Int_t FindNextFreeMerger()
Return a merger, which is both active and still accepts some workers to be assigned to it...
Definition: TProof.cxx:4293
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:10389
virtual void StoreFeedback(TObject *slave, TList *out)=0
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
Definition: TFileInfo.cxx:258
void SetROOTVersion(const char *rv)
Definition: TSlave.h:163
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:2030
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
const char *const kPROOF_WorkDir
Definition: TProof.h:147
static const TList * GetEnvVars()
Get environemnt variables.
Definition: TProof.cxx:12318
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
virtual EExitStatus GetExitStatus() const =0
virtual void Add()
Add signal handler to system signal handler list.
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition: TFile.cxx:1596
virtual TFileCollection * GetDataSet(const char *dataset, const char *optStr="")
Get a list of TFileInfo objects describing the files of the specified dataset.
Definition: TProof.cxx:11504
TList * fAllUniqueSlaves
Definition: TProof.h:510
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:10375
void SetArchCompiler(const char *ac)
Definition: TSlave.h:162
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:536
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7890
TString fImage
Definition: TProof.h:601
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1101
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
Regular expression class.
Definition: TRegexp.h:35
TFileCollection * GetMissingFiles(TQueryResult *qr=0)
Get a TFileCollection with the files missing in the query described by 'qr' or the last query if qr i...
Definition: TProof.cxx:13149
Int_t BuildPackage(const char *package, EBuildPackageOpt opt=kBuildAll, Int_t chkveropt=kCheckROOT, TList *workers=0)
Build specified package.
Definition: TProof.cxx:8033
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:856
Bool_t Notify()
Definition: TTimer.cxx:65
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
static const char * filename()
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:52
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition: TProof.cxx:1886
#define R__ASSERT(e)
Definition: TError.h:98
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:183
virtual Bool_t IsProofd() const
Definition: TProofMgr.h:86
TMacro * GetLogFile() const
Definition: TQueryResult.h:134
#define gROOT
Definition: TROOT.h:340
TString fLogFileName
Definition: TProof.h:539
Int_t GetNWrks() const
const char * GetConfFile() const
Definition: TProof.h:938
Int_t fPerfIndex
Definition: TProof.h:243
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition: TMonitor.cxx:168
virtual void StopProcess(Bool_t abort, Int_t timeout)
Sent stop/abort request to PROOF server.
Definition: TSlave.cxx:637
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:33
const char * GetFileName() const
Int_t LoadPlugin()
Load the plugin library for this handler.
#define O_BINARY
Definition: civetweb.c:273
virtual void SetCurrentQuery(TQueryResult *q)=0
const char * GetOrdinal() const
Definition: TProof.h:255
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1447
Bool_t IsZombie() const
Definition: TObject.h:141
TList * fQueries
Definition: TProof.h:550
Basic string class.
Definition: TString.h:137
const char * GetSessionTag() const
Definition: TProof.h:942
virtual void Touch()
Definition: TSlave.h:169
virtual void Add()
Add file event handler to system file handler list.
virtual void Progress(Long64_t total, Long64_t processed)=0
void SetDSet(TDSet *dset)
Definition: TProof.h:772
virtual void SetInterruptHandler(Bool_t)
Definition: TSlave.h:160
TString fGroup
Definition: TProof.h:496
TString fDataDir
Definition: TProof.h:242
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition: TMonitor.cxx:498
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition: TProof.cxx:12375
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:996
bool Bool_t
Definition: RtypesCore.h:59
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition: TProof.cxx:10567
TArc * a
Definition: textangle.C:12
TList * fUniqueSlaves
Definition: TProof.h:509
virtual Bool_t JoinProcess(TList *workers)=0
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition: TProof.cxx:13077
TVirtualMutex * fCloseMutex
Definition: TProof.h:573
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition: TProof.cxx:6401
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:600
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition: TProof.cxx:6094
Bool_t IsProofd() const
Definition: TProof.h:967
Long64_t GetZipBytes() const
Definition: TFileInfo.h:156
void SetUser(const char *user)
Definition: TUrl.h:91
TList * fWaitingSlaves
Definition: TProof.h:549
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:496
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition: TProof.cxx:2470
const char *const kRM
Definition: TProof.h:165
#define gInterpreter
Definition: TInterpreter.h:502
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition: TProof.cxx:2009
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1511
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:10938
const char *const kPROOF_PackageLockFile
Definition: TProof.h:155
This class represents a RFC 3986 compatible URI.
Definition: TUri.h:39
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:33
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition: TProof.cxx:2110
Definition: TFTP.h:42
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:666
static TPluginHandler * fgLogViewer
Definition: TProof.h:592
TString & Prepend(const char *cs)
Definition: TString.h:604
R__EXTERN TApplication * gApplication
Definition: TApplication.h:171
Float_t fRealTime
Definition: TProof.h:517
TString fHostName
Definition: TProof.h:240
Bool_t Notify()
Handle input.
Definition: TProof.cxx:149
Int_t ModifyWorkerLists(const char *ord, Bool_t add, Bool_t save)
Modify the worker active/inactive list by making the worker identified by the ordinal number 'ord' ac...
Definition: TProof.cxx:11956
Bool_t IsEqual(const TObject *obj) const
Used to compare slaveinfos by ordinal.
Definition: TProof.cxx:191
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
const char * GetGroup() const
Definition: TProofServ.h:254
const char * GetOptions() const
Definition: TUrl.h:80
TString fModel
Definition: TSystem.h:163
Long_t ExecPlugin(int nargs, const T &...params)
Int_t fWorkersToMerge
Definition: TProof.h:277
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition: TProof.cxx:10888
void CloseProgressDialog()
Close progress dialog.
Definition: TProof.cxx:9850
Bool_t IsSync() const
Definition: TProof.h:704
Int_t GetNumberOfQueries()
Number of queries processed by this session.
Definition: TProof.cxx:2100
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
Int_t AddIncludePath(const char *incpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add 'incpath' to the inc path search.
Definition: TProof.cxx:9455
static void ResolveKeywords(TString &fname, const char *path=0)
Replace , , , , , , , and placeholders in fname...
static void retrieve(const gsl_integration_workspace *workspace, double *a, double *b, double *r, double *e)
Long64_t GetBytesRead() const
Definition: TProof.h:962
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:592
TDSet * fDSet
Definition: TProof.h:531
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7701
void DisableGoAsyn()
Signal to disable related switches.
Definition: TProof.cxx:6246
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:310
TList * fInputData
Definition: TProof.h:566
Int_t SendObject(const TObject *obj, ESlaves list=kActive)
Send object to master or slave servers.
Definition: TProof.cxx:7041
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6745
TSignalHandler * GetSignalHandler() const
Definition: TApplication.h:112
Int_t BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
Broadcast a raw buffer of specified length to all slaves in the specified list.
Definition: TProof.cxx:2562
const char *const kPROOF_PackDownloadDir
Definition: TProof.h:150
void Reset(Int_t n=-1)
Definition: TProof.h:335
TVirtualProofPlayer * fPlayer
Definition: TProof.h:522
void SetProof(TProof *p)
Definition: TProofMgr.h:189
void Reset()
Definition: TCollection.h:161
Iterator of linked list.
Definition: TList.h:187
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:900
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
TList * fWorkers
Definition: TProof.h:282
virtual Bool_t IsValid() const
Definition: TProofMgr.h:87
const char * GetGroup() const
Definition: TProof.h:940
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
EQueryMode
Definition: TProof.h:372
virtual void DiscardSession(TProof *p)
Discard TProofDesc of session 'p' from the internal list.
Definition: TProofMgr.cxx:367
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:625
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2406
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:264
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition: TProof.cxx:12291
EUploadPackageOpt
Definition: TProof.h:389
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3851
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:749
Int_t fMode
Definition: TSystem.h:138
const char * GetObjName() const
Definition: TDSet.h:122
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition: TFile.cxx:4749
Bool_t fMasterServ
Definition: TProof.h:597
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:9534
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition: TProof.cxx:13214
Bool_t fFinalizationRunning
Definition: TProof.h:585
void NotifyLogMsg(const char *msg, const char *sfx="\n")
Notify locally 'msg' to the appropriate units (file, stdout, window) If defined, 'sfx' is added after...
Definition: TProof.cxx:6345
TFileHandler * GetInputHandler() const
Definition: TSlave.h:148
Long64_t GetNum() const
Definition: TDSet.h:116
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
const char * Data() const
Definition: TString.h:349
TSignalHandler * fIntHandler
Definition: TProof.h:519
Int_t GetPort() const
Definition: TProof.h:945
Int_t fDrawQueries
Definition: TProof.h:552
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
const TString & GetMsd() const
TString fDataPoolUrl
Definition: TProof.h:616
void AddMergedObjects(Int_t objects)
Definition: TProof.h:305
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
const char * GetDirectory() const
Definition: TDSet.h:230
TList * fChains
Definition: TProof.h:524
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
Int_t Update(Long64_t avgsize=-1)
Update accumulated information about the elements of the collection (e.g.
#define SafeDelete(p)
Definition: RConfig.h:436
TPluginHandler * fProgressDialog
Definition: TProof.h:520
TList * fBadSlaves
Definition: TProof.h:605
virtual TList * GetOutputList() const =0
Int_t fLastAssignedMerger
Definition: TProof.h:583
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1346
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:203
Sequenceable collection abstract base class.
Double_t dot(const TVector2 &v1, const TVector2 &v2)
Definition: CsgOps.cxx:333
Bool_t fSendGroupView
list returned by kPROOF_GETSLAVEINFO
Definition: TProof.h:502
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:75
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1373
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition: TProof.cxx:11613
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:288
const char * Export(Bool_t &changed)
Definition: TProof.h:327
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition: TProof.cxx:6211
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:2334
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:1462
void UpdateDialog()
Final update of the progress dialog.
Definition: TProof.cxx:4342
#define PDB(mask, level)
Definition: TProofDebug.h:58
Int_t GetNUrls() const
Definition: TFileInfo.h:86
TList * fEnabledPackagesOnClient
Definition: TProof.h:563
THashList * fGlobalPackageDirList
Definition: TProof.h:561
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:36
const char * ord
Definition: TXSlave.cxx:46
TSlave * CreateSlave(const char *url, const char *ord, Int_t perf, const char *image, const char *workdir)
Create a new TSlave of type TSlave::kSlave.
Definition: TProof.cxx:1848
static const std::string separator("@@@")
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:46
const char * GetMsd() const
Definition: TDSet.h:119
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition: TMonitor.cxx:284
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7066
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:8791
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition: TProof.cxx:6106
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition: TProof.cxx:4412
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
TString fOrdinal
Definition: TProof.h:239
virtual void ReleaseWorker(const char *)
Definition: TProofServ.h:317
virtual void ShowCache(Bool_t all=kFALSE)
List contents of file cache.
Definition: TProof.cxx:7678
Int_t fRedirectNext
Definition: TProof.h:586
virtual Int_t Rm(const char *, const char *=0, const char *=0)
Run 'rm' on 'what'. Locally it is just a call to TSystem::Unlink .
Definition: TProofMgr.cxx:1066
ClassImp(TProof) Bool_t TProofInterruptHandler
TProof interrupt handler.
Definition: TProof.cxx:96
void Init(const TFunction *func)
Initialize the method invocation environment based on the TFunction object.
const char *const kPROOF_WorkerIdleTO
Definition: TProof.h:158
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1757
Int_t BuildPackageOnClient(const char *package, Int_t opt=0, TString *path=0, Int_t chkveropt=kCheckROOT)
Build specified package on the client.
Definition: TProof.cxx:8123
Int_t fParallel
Definition: TSlave.h:101
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriory.
Definition: TMessage.cxx:207
void SetInputDataFile(const char *datafile)
Set the file to be used to optimally distribute the input data objects.
Definition: TProof.cxx:10152
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition: TProof.cxx:11544
static double p2(double t, double a, double b, double c)
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:751
const char * GetMaster() const
Definition: TProof.h:936
Int_t LoadPackageOnClient(const char *package, TList *loadopts=0)
Load specified package in the client.
Definition: TProof.cxx:8370
static TList * GetDataSetSrvMaps()
Static getter for server mapping list.
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1627
bool BeginsWith(const std::string &theString, const std::string &theSubstring)
virtual UInt_t Integer(UInt_t imax)
Returns a random integer on [ 0, imax-1 ].
Definition: TRandom.cxx:320
TProofLockPath * fPackageLock
Definition: TProof.h:562
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:2664
static void LogViewer(const char *url=0, Int_t sessionidx=0)
Start the log viewer window usign the plugin manager.
Definition: TProof.cxx:13038
TList * GetListOfElements() const
Definition: TDSet.h:231
void Deactivate()
Definition: TProof.h:310
void ResetMergePrg()
Reset the merge progress notificator.
Definition: TProof.cxx:2460
A sorted doubly linked list.
Definition: TSortedList.h:30
void Info(const char *location, const char *msgfmt,...)
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition: TProof.cxx:11376
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition: TProof.cxx:7157
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:734
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition: TProof.cxx:11413
TString fConfFile
Definition: TProof.h:599
virtual void AddEventsProcessed(Long64_t ev)=0
TString & Append(const char *cs)
Definition: TString.h:492
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1054
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition: TProof.cxx:2959
ESlaveStatus fStatus
Definition: TProof.h:245
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:234
void ShowFeedback() const
Show items in feedback list.
Definition: TProof.cxx:10587
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1563
TString fOrdinal
Definition: TSlave.h:90
TSlave * CreateSubmaster(const char *url, const char *ord, const char *image, const char *msd, Int_t nwk=1)
Create a new TSlave of type TSlave::kMaster.
Definition: TProof.cxx:1870
void Validate()
Validate the TDSet by opening files.
Definition: TDSet.cxx:1561
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition: TProof.cxx:7657
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to 'id'.
Definition: TProofMgr.cxx:325
const char * GetUser() const
Definition: TProof.h:939
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1964
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'...
Definition: TProof.cxx:2143
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:12150
Bool_t IsParallel() const
Definition: TProof.h:972
TList * fSlaves
Definition: TProof.h:603
Int_t fNotIdle
Definition: TProof.h:533
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
Int_t UploadDataSet(const char *, TList *, const char *=0, Int_t=0, TList *=0)
*** This function is deprecated and will disappear in future versions *** *** It is just a wrapper ar...
Definition: TProof.cxx:11202
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:30
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition: TSlave.cxx:518
XFontStruct * id
Definition: TGX11.cxx:108
Method or function calling interface.
Definition: TMethodCall.h:41
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
const char * GetWorkDir() const
Definition: TSlave.h:131
void SetDirectory(const char *dir)
Set/change directory.
Definition: TDSet.cxx:1012
const Bool_t kSortDescending
Definition: TList.h:41
friend class TProofInputHandler
Definition: TProof.h:347
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2245
TList * fInactiveSlaves
Definition: TProof.h:508
void SetSrvMaps(TList *srvmaps=0)
Set (or unset) the list for mapping servers coordinate for files.
Definition: TDSet.cxx:1143
A container class for query results.
Definition: TQueryResult.h:44
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition: TProof.cxx:2134
Int_t ActivateWorker(const char *ord, Bool_t save=kTRUE)
Make sure that the worker identified by the ordinal number 'ord' is in the active list...
Definition: TProof.cxx:11920
PrintProgress_t fPrintProgress
Definition: TProof.h:571
Int_t fCollectTimeout
Definition: TProof.h:614
Long64_t GetEntries() const
Definition: TQueryResult.h:130
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2316
Long_t fModtime
Definition: TProof.h:527
virtual void Close(Option_t *opt="")
Close slave socket.
Definition: TSlave.cxx:279
const char * GetWorkDir() const
Definition: TProofServ.h:255
void Error(const char *location, const char *msgfmt,...)
TProofMergePrg fMergePrg
Definition: TProof.h:547
static TList * fgProofEnvList
Definition: TProof.h:576
void HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
Handle lib, inc search paths modification request.
Definition: TProof.cxx:9565
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2083
char * out
Definition: TBase64.cxx:29
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
virtual Int_t SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
void SetManager(TProofMgr *mgr)
Set manager and schedule its destruction after this for clean operations.
Definition: TProof.cxx:1301
Bool_t IsLite() const
Definition: TProof.h:966
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:10485
static Int_t PoDCheckUrl(TString *_cluster)
This a private API function.
Definition: TProof.cxx:327
void Emit(const char *signal)
Acitvate signal without args.
Definition: TQObject.cxx:559
virtual Int_t GetFile(const char *, const char *, const char *=0)
Definition: TProofMgr.h:132
Long64_t GetFirst() const
Definition: TDSet.h:114
void SetTermTime(Float_t termtime)
Definition: TQueryResult.h:108
virtual TProof * AttachSession(Int_t, Bool_t=kFALSE)
Dummy version provided for completeness.
Definition: TProofMgr.cxx:124
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
virtual void SetStatus(Int_t st)
Definition: TSlave.h:117
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning...
Definition: TProof.cxx:1047
Bool_t fIsPollingWorkers
Definition: TProof.h:503
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition: TProof.cxx:493
virtual void ClearInput()=0
void AddInput(TObject *obj)
Add obj to the input list.
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:594
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
Int_t UploadPackageOnClient(const char *package, EUploadPackageOpt opt, TMD5 *md5)
Upload a package on the client in ~/.proof/packages.
Definition: TProof.cxx:9071
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition: TProof.cxx:6079
const char * GetProofWorkDir() const
Definition: TSlave.h:130
Int_t GetSlaveType() const
Definition: TSlave.h:143
Bool_t fRedirLog
Definition: TProof.h:538
const char * pwd()
Definition: TSystem.h:415
void AddChain(TChain *chain)
Add chain to data set.
Definition: TProof.cxx:10790
TMonitor * fUniqueMonitor
Definition: TProof.h:513
void SetMergedWorker()
Increase number of already merged workers by 1.
Definition: TProof.cxx:278
const char *const kPROOF_ConfFile
Definition: TProof.h:145
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition: TProof.cxx:12124
Int_t fL2Cache
Definition: TSystem.h:168
const TString & GetOrdinal() const
FileMap_t fFileMap
Definition: TProof.h:530
Int_t UnloadPackageOnClient(const char *package)
Unload a specific package on the client.
Definition: TProof.cxx:8565
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition: TProof.cxx:11063
Bool_t ElementsValid()
Check if all elements are valid.
Definition: TDSet.cxx:1527
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition: TProof.cxx:6000
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8898
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition: TProof.cxx:1982
TMonitor * fAllMonitor
Definition: TProof.h:606
Int_t GetPort() const
Definition: TUrl.h:87
const char Int_t const char TProof Int_t const char * workdir
Definition: TXSlave.cxx:46
virtual void AddQueryResult(TQueryResult *q)=0
const char * GetName() const
Returns name of object.
Definition: TSlave.h:128
Int_t Archive(Int_t query, const char *url)
Send archive request for the qry-th query in fQueries.
Definition: TProof.cxx:6044
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
void InitMembers()
Default initializations.
Definition: TProof.cxx:507
Named parameter, streamable and storable.
Definition: TParameter.h:49
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition: TMacro.cxx:245
friend class TProofInterruptHandler
Definition: TProof.h:348
TSocket * GetSocket() const
Definition: TProofServ.h:269
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition: TProof.cxx:12303
const TString & GetWorkDir() const
TString fUser
Definition: TSystem.h:152
float ymax
Definition: THbookFile.cxx:93
Int_t fLogLevel
Definition: TProof.h:497
TProofMgr * fManager
Definition: TProof.h:618
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition: TProof.cxx:10677
const char * GetName() const
Returns name of object.
virtual void Find(const char *="~/", const char *=0, const char *=0)
Definition: TProofMgr.h:123
const char *const kPROOF_TerminateWorker
Definition: TProof.h:157
TList * fActiveSlaves
Definition: TProof.h:505
void QueryResultReady(const char *ref)
Notify availability of a query result.
Definition: TProof.cxx:9936
Bool_t fSaveLogToMacro
Definition: TProof.h:544
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:9903
Bool_t fValid
Definition: TProof.h:492
Bool_t fDataReady
Definition: TProof.h:607
const char * GetFileName() const
Definition: TDSet.h:113
void DecreaseNWrks()
Definition: TProof.h:332
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1611
virtual Long64_t Finalize(Bool_t force=kFALSE, Bool_t sync=kFALSE)=0
virtual TObject * GetOutput(const char *name) const =0
Int_t fCpus
Definition: TSystem.h:165
TString GetString() const
Definition: TObjString.h:50
const char * GetPrefix() const
Definition: TProofServ.h:288
ROOT::R::TRInterface & r
Definition: Object.C:4
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4772
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
Definition: TFileInfo.cxx:422
Int_t DisablePackages()
Remove all packages.
Definition: TProof.cxx:7982
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
SysInfo_t fSysInfo
Definition: TProof.h:244
Double_t length(const TVector2 &v)
Definition: CsgOps.cxx:347
Bool_t fIsLink
Definition: TSystem.h:143
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition: TProof.cxx:11587
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
TString fWorkDir
Definition: TProof.h:495
const TString GetUri() const
Returns the whole URI - an implementation of chapter 5.3 component recomposition. ...
Definition: TUri.cxx:139
static Int_t WriteChecksum(const char *file, const TMD5 *md5)
Writes checksum in ASCII format to specified file.
Definition: TMD5.cxx:450
SVector< double, 2 > v
Definition: Dict.h:5
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition: TSlave.cxx:501
ERunStatus fRunStatus
Definition: TProof.h:535
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition: TProof.cxx:5844
TString fWorkDir
Definition: TSlave.h:86
const char * GetName() const
Returns name of object.
Definition: TParameter.h:76
virtual TProof * CreateSession(const char *=0, const char *=0, Int_t=-1)
Create a new remote session (master and associated workers).
Definition: TProofMgr.cxx:387
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:11876
TList * GetListOfSlaves() const
Definition: TProof.h:689
TMonitor * fCurrentMonitor
Definition: TProof.h:515
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:2538
Int_t Add(TFileInfo *info)
Add TFileInfo to the collection.
const char * GetDataPoolUrl() const
Definition: TProof.h:1076
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
Int_t GetLogLevel() const
Definition: TProof.h:949
TList * GetListOfLines() const
Definition: TMacro.h:53
virtual void SetInitTime()=0
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:674
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7757
const char *const kPROOF_ConfDir
Definition: TProof.h:146
Bool_t Gets(FILE *fp, Bool_t chop=kTRUE)
Read one line from the stream, including the , or until EOF.
Definition: Stringio.cxx:198
void SaveActiveList()
Save current list of active workers.
Definition: TProof.cxx:12109
Bool_t ParseUri(const char *uri, TString *dsGroup=0, TString *dsUser=0, TString *dsName=0, TString *dsTree=0, Bool_t onlyCurrent=kFALSE, Bool_t wildcards=kFALSE)
Parses a (relative) URI that describes a DataSet on the cluster.
Int_t fSeqNum
Definition: TProof.h:554
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1768
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:284
Collection abstract base class.
Definition: TCollection.h:48
void SetActive(Bool_t=kTRUE)
Definition: TProof.h:1021
SysInfo_t GetSysInfo() const
Definition: TProof.h:256
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
TObject * Value() const
Definition: TMap.h:125
virtual void ClearDataSetCache(const char *dataset=0)
Clear the content of the dataset cache, if any (matching 'dataset', if defined).
Definition: TProof.cxx:11463
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition: TProof.cxx:2123
virtual Int_t VerifyDataSet(const char *dataset, const char *optStr="")
Verify if all files in the specified dataset are available.
Definition: TProof.cxx:11697
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
TList * fSlaveInfo
Definition: TProof.h:501
unsigned int UInt_t
Definition: RtypesCore.h:42
TList * GetInputList()
Definition: TQueryResult.h:128
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TMarker * m
Definition: textangle.C:8
TMacro fMacroLog
Definition: TProof.h:545
bool verbose
Int_t GetPort()
Definition: TProof.h:298
char * Form(const char *fmt,...)
Long64_t GetEntries() const
Definition: TFileInfo.h:151
TObject * GetOutput(const char *name)
Get specified object that has been produced during the processing (see Process()).
Definition: TProof.cxx:10329
Bool_t IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
See if the data is ready to be analyzed.
Definition: TProof.cxx:2235
void IncreaseIdx()
Definition: TProof.h:334
This class implements a plugin library manager.
virtual void SetMerging(Bool_t on=kTRUE)=0
virtual Int_t Echo(const TObject *obj)
Sends an object to master and workers and expect them to send back a message with the output of its T...
Definition: TProof.cxx:7015
virtual Int_t Stat(const char *, FileStat_t &, const char *=0)
Definition: TProofMgr.h:130
const char *const kUNTAR2
Definition: TProof.h:168
TLine * l
Definition: textangle.C:4
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
static void AddEnvVar(const char *name, const char *value)
Add an variable to the list of environment variables passed to proofserv on the master and slaves...
Definition: TProof.cxx:12327
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1069
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:12363
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:6786
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:307
Bool_t SetFragment(const TString &fragment)
Set fragment component of URI: fragment = *( pchar / "/" / "?" ).
Definition: TUri.cxx:497
virtual Long64_t Process(TDSet *dset, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)
Process a data set (TDSet) using the specified selector (.C) file or Tselector object Entry- or event...
Definition: TProof.cxx:5293
Bool_t fProgressDialogStarted
Definition: TProof.h:521
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:657
const Int_t kPROOF_Protocol
Definition: TProof.h:143
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition: TProof.cxx:6447
float xmax
Definition: THbookFile.cxx:93
TStopwatch fQuerySTW
Definition: TProof.h:624
Bool_t fMergersByHost
Definition: TProof.h:580
TString fInputDataFile
Definition: TProof.h:567
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:6520
void SetStatus(ESlaveStatus stat)
Definition: TProof.h:257
Bool_t IsNull() const
Definition: TString.h:387
virtual TObjLink * FirstLink() const
Definition: TList.h:101
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1591
FILE * fLogFileR
Definition: TProof.h:541
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3731
void SetName(const char *name)
Definition: TCollection.h:116
Int_t fProtocol
Definition: TProof.h:602
const char * GetUrl()
Definition: TProof.h:944
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:6881
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
Long64_t GetEntries() const
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition: TProof.cxx:4247
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:9707
Bool_t fLogToWindowOnly
Definition: TProof.h:542
TString & String()
Definition: TObjString.h:52
void ReleaseMonitor(TMonitor *mon)
Release the used monitor to be used, making sure to delete newly created monitors.
Definition: TProof.cxx:2649
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1619
TList * fFeedback
Definition: TProof.h:523
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition: TProof.cxx:9891
const char * GetUser() const
Definition: TProofServ.h:253
Int_t DisablePackageOnClient(const char *package)
Remove a specific package 'pack' from the client.
Definition: TProof.cxx:7947
const char * GetImage() const
Definition: TProofServ.h:256
void AddInput(TObject *obj)
Add objects that might be needed during the processing of the selector (see Process()).
Definition: TProof.cxx:10301
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:675
TString fMsd
Definition: TProof.h:241
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9947
Float_t fPrepTime
Definition: TProof.h:625
#define Printf
Definition: TGeoToOCC.h:18
TList * fRunningDSets
Definition: TProof.h:612
TList * GetFeedbackList() const
Return feedback list.
Definition: TProof.cxx:10600
const char * GetImage() const
Definition: TSlave.h:129
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition: TProof.cxx:10824
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition: TProof.cxx:11748
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:9500
Bool_t fDynamicStartup
Definition: TProof.h:620
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:449
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void GoAsynchronous()
Send GOASYNC message to the master.
Definition: TProof.cxx:6254
virtual void RemoveQueryResult(const char *ref)=0
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition: TSlave.cxx:663
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:10105
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6618
static unsigned int total
Int_t AssertPath(const char *path, Bool_t writable)
Make sure that 'path' exists; if 'writable' is kTRUE, make also sure that the path is writable...
Definition: TProof.cxx:1269
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:580
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:1677
void Print(Option_t *option="") const
Print slave info.
Definition: TProof.cxx:205
Int_t LoadPackage(const char *package, Bool_t notOnClient=kFALSE, TList *loadopts=0, TList *workers=0)
Load specified package.
Definition: TProof.cxx:8318
void SetHost(const char *host)
Definition: TUrl.h:93
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
Float_t GetRealTime() const
Definition: TProof.h:963
int Ssiz_t
Definition: RtypesCore.h:63
Int_t GetPerfIdx() const
Definition: TSlave.h:136
TList * GetInputList()
Get input list.
Definition: TProof.cxx:10320
TString fName
Definition: TSlave.h:83
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition: TSystem.cxx:1471
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition: TProof.cxx:4927
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition: TProof.cxx:311
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:932
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:106
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:546
Bool_t fEndMaster
Definition: TProof.h:558
void Close(Option_t *option="")
Close all open slave servers.
Definition: TProof.cxx:1792
TList * GetListOfActiveSlaves() const
Definition: TProof.h:758
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3805
virtual Int_t GetSize() const
Definition: TCollection.h:95
void SetFeedback(TString &opt, TString &optfb, Int_t action)
Extract from opt in optfb information about wanted feedback settings.
Definition: TProof.cxx:5222
virtual Bool_t IsLite() const
Definition: TProofMgr.h:85
void SetDefaultTreeName(const char *treeName)
Int_t GetStatus() const
Definition: TSlave.h:144
double f(double x)
const char *const kPROOF_InputDataFile
Definition: TProof.h:159
TDrawFeedback * CreateDrawFeedback()
Draw feedback creation proxy.
Definition: TProof.cxx:10661
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
virtual Long64_t GetEventsProcessed() const =0
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:248
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:10500
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:126
Int_t SetParallelSilent(Int_t nodes, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7099
Long64_t fBytesRead
Definition: TProof.h:516
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
Int_t GoParallel(Int_t nodes, Bool_t accept=kFALSE, Bool_t random=kFALSE)
Go in parallel mode with at most "nodes" slaves.
Definition: TProof.cxx:7260
Int_t fMergersCount
Definition: TProof.h:581
void SetObjName(const char *objname)
Set/change object name.
Definition: TDSet.cxx:997
double Double_t
Definition: RtypesCore.h:55
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:307
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition: TSystem.cxx:1337
ESlaves
Definition: TProof.h:595
Int_t Lock()
Locks the directory.
Int_t GetParallel() const
Definition: TSlave.h:145
virtual void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)=0
TObject * Key() const
Definition: TMap.h:124
static Int_t GetInputData(TList *input, const char *cachedir, TString &emsg)
Get the input data from the file defined in the input list.
Definition: TProof.cxx:12981
void ClearInput()
Clear input object list.
Definition: TProof.cxx:10309
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition: TDSet.cxx:1865
TList * fEnabledPackages
Definition: TProof.h:611
virtual void Remove()
Remove signal handler from system signal handler list.
void Feedback(TList *objs)
Get list of feedback objects.
Definition: TProof.cxx:9835
TList * fNonUniqueMasters
Definition: TProof.h:511
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:44
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
TList * fRecvMessages
Definition: TProof.h:500
const char * GetOrdinal() const
Definition: TProofServ.h:265
TString fCpuType
Definition: TSystem.h:164
TNamed()
Definition: TNamed.h:40
virtual void SendInputDataFile()
Send the input data objects to the master; the objects are taken from the dedicated list and / or the...
Definition: TProof.cxx:10179
TList * fEnabledPackagesOnCluster
Definition: TProof.h:564
Definition: TProof.h:339
static RooMathCoreReg dummy
void Detach(Option_t *opt="")
Detach this instance to its proofserv.
Definition: TProof.cxx:11085
Bool_t Contains(const char *name) const
Definition: TCollection.h:84
int nentries
Definition: THbookFile.cxx:89
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1834
void SetNWrks(Int_t n)
Definition: TProof.h:336
Bool_t IsMaster() const
Definition: TProof.h:969
EBuildPackageOpt
Definition: TProof.h:476
UInt_t What() const
Definition: TMessage.h:80
virtual TQueryResult * GetCurrentQuery() const =0
void SetRunStatus(ERunStatus rst)
Definition: TProof.h:707
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition: TProof.cxx:10609
TList * GetEnabledPackages() const
Definition: TProofServ.h:279
void ShowMissingFiles(TQueryResult *qr=0)
Show information about missing files during query described by 'qr' or the last query if qr is null (...
Definition: TProof.cxx:13090
Int_t Unlock()
Unlock the directory.
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:348
Int_t GetSandbox(TString &sb, Bool_t assert=kFALSE, const char *rc=0)
Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
Definition: TProof.cxx:1020
void ShowQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2160
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1320
Float_t fRealTime
Definition: TSlave.h:97
void SetArchived(const char *archfile)
Set (or update) query in archived state.
void ResetUrl()
Definition: TFileInfo.h:80
virtual void Remove()
Remove file event handler from system file handler list.
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job...
Definition: TProof.cxx:303
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition: TProof.cxx:5870
EQueryMode fQueryMode
Definition: TProof.h:619
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition: TPRegexp.cxx:704
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:220
#define name(a, b)
Definition: linkTestLib0.cpp:5
TString fImage
Definition: TSlave.h:84
const char * GetName() const
Returns name of object.
Definition: TProof.h:254
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition: TProof.cxx:6631
Int_t UnloadPackage(const char *package)
Unload specified package.
Definition: TProof.cxx:8530
FILE * fLogFileW
Definition: TProof.h:540
Mother of all ROOT objects.
Definition: TObject.h:58
Float_t GetCpuTime() const
Definition: TProof.h:964
Int_t fStatus
Definition: TSlave.h:100
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
const char * GetPackageDir() const
Definition: TProofServ.h:260
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
const char Int_t const char TProof * proof
Definition: TXSlave.cxx:46
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1806
char Char_t
Definition: RtypesCore.h:29
TSelector * fSelector
Definition: TProof.h:622
Int_t BufferSize() const
Definition: TBuffer.h:92
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition: TProof.cxx:3035
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition: TProof.cxx:1973
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition: TProof.cxx:9691
TString fActiveSlavesSaved
Definition: TProof.h:506
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:1023
Bool_t SendingLogToWindow() const
Definition: TProof.h:1049
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7821
Int_t GetRC(const char *RCenv, Int_t &env, const char *ord="0")
Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'.
Definition: TProof.cxx:6652
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:246
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:126
Bool_t IsIdle() const
Definition: TProof.h:973
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition: TROOT.cxx:2440
R__EXTERN TProofServ * gProofServ
Definition: TProofServ.h:359
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:11251
Bool_t IsTty() const
Definition: TProof.h:971
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
Definition: TProofMgr.cxx:229
const char * GetConfDir() const
Definition: TProof.h:937
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:103
Int_t Length() const
Definition: TBuffer.h:94
Class that contains a list of TFileInfo's and accumulated meta data information about its entries...
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:634
TMap * GetDataSetQuota(const char *optStr="")
returns a map of the quotas of all groups
Definition: TProof.cxx:11843
const char * GetMsd() const
Definition: TSlave.h:146
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:68
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition: TProof.cxx:4425
TProofOutputList fOutputList
Definition: TProof.h:569
Int_t Compare(const void *item1, const void *item2)
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition: TProof.cxx:4734
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:56
static char fgCr[4]
Definition: TProof.h:323
Int_t fSessionID
Definition: TProof.h:556
A chain is a collection of files containg TTree objects.
Definition: TChain.h:35
void WriteObject(const TObject *obj)
Write object to message buffer.
Definition: TMessage.cxx:418
void SetOptions(const char *opt)
Definition: TUrl.h:96
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2017
const TString & GetNodeName() const
Int_t fCpuSpeed
Definition: TSystem.h:166
const char *const kUNTAR3
Definition: TProof.h:169
void SetParam(Long_t l)
Add a long method parameter.
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition: TProof.cxx:1991
static Int_t SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
Save input data file from 'cachedir' into the sandbox or create a the file with input data objects...
Definition: TProof.cxx:12879
#define NULL
Definition: Rtypes.h:82
Bool_t IsTopMaster() const
Definition: TProofServ.h:307
static TList * ParseDataSetSrvMaps(const TString &srvmaps)
Create a server mapping list from the content of 'srvmaps' Return the list (owned by the caller) or 0...
Int_t fStatus
Definition: TProof.h:498
void ClearFeedback()
Clear feedback list.
Definition: TProof.cxx:10579
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7127
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1310
const char * GetDir(Bool_t raw=kFALSE) const
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition: TProof.cxx:289
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:167
Int_t GetClientProtocol() const
Definition: TProof.h:947
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
Float_t fCpuTime
Definition: TSlave.h:98
Int_t AddDynamicPath(const char *libpath, Bool_t onClient=kFALSE, TList *wrks=0, Bool_t doCollect=kTRUE)
Add 'libpath' to the lib path search.
Definition: TProof.cxx:9410
const char * GetType() const
Definition: TDSet.h:228
void Reset()
Definition: TStopwatch.h:54
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition: TProof.cxx:9675
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:3972
Int_t GetPort() const
Definition: TSlave.h:134
virtual Int_t AddOutputObject(TObject *obj)=0
Bool_t IsActive()
Definition: TProof.h:311
TList * fAvailablePackages
Definition: TProof.h:610
A TTree object has a header with a name and a title.
Definition: TTree.h:94
Int_t fCheckFileStatus
Definition: TProof.h:499
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition: TProof.cxx:10669
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:280
Long64_t fTotalBytes
Definition: TProof.h:609
double result[121]
Class describing a generic file including meta information.
Definition: TFileInfo.h:50
Int_t SendInitialState()
Transfer the initial (i.e.
Definition: TProof.cxx:6761
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition: TProof.cxx:5935
void ResetBit(UInt_t f)
Definition: TObject.h:172
TProofMgr::EServType fServType
Definition: TProof.h:617
void AttachList(TList *alist)
Attach to list 'alist'.
const AParamType & GetVal() const
Definition: TParameter.h:77
TList * GetEnabledPackages() const
Definition: TProof.h:770
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1243
virtual void ActivateAll()
Activate all de-activated sockets.
Definition: TMonitor.cxx:268
TList * fTerminatedSlaveInfos
Definition: TProof.h:604
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:2446
virtual Bool_t IsValid() const
Definition: TSlave.h:154
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition: TProof.cxx:2030
TProof * fProof
Definition: TProof.h:224
TList * FindDataSets(const char *searchString, const char *optStr="")
Find datasets, returns in a TList all found datasets.
Definition: TProof.cxx:11577
const char * GetImage() const
Definition: TProof.h:943
Bool_t Prompt(const char *p)
Prompt the question 'p' requiring an answer y,Y,n,N Return kTRUE is the answer was y or Y...
Definition: TProof.cxx:7636
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition: TProof.cxx:11683
TList * fLoadedMacros
Definition: TProof.h:575
virtual Int_t RemoveDataSet(const char *dataset, const char *optStr="")
Remove the specified dataset from the PROOF cluster.
Definition: TProof.cxx:11558
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition: TProof.cxx:4323
const Bool_t kIterBackward
Definition: TCollection.h:44
Int_t GetPerfIndex() const
static TProofMgr * Create(const char *url, Int_t loglevel=-1, const char *alias=0, Bool_t xpd=kTRUE)
Static method returning the appropriate TProofMgr object using the plugin manager.
Definition: TProofMgr.cxx:499
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
virtual Int_t Load(const char *macro, Bool_t notOnClient=kFALSE, Bool_t uniqueOnly=kTRUE, TList *wrks=0)
Load the specified macro on master, workers and, if notOnClient is kFALSE, on the client...
Definition: TProof.cxx:9198
Definition: TSlave.h:50
virtual Int_t SetDataSetTreeName(const char *dataset, const char *treename)
Set/Change the name of the default tree.
Definition: TProof.cxx:11333
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:39
const TString & GetImage() const
static TMD5 * ReadChecksum(const char *file)
Returns checksum stored in ASCII in specified file.
Definition: TMD5.cxx:420
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:901
TInetAddress GetInetAddress() const
Definition: TSocket.h:143
const Bool_t kTRUE
Definition: Rtypes.h:91
Long64_t fBytesReady
Definition: TProof.h:608
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition: TProof.cxx:10807
void ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst, Long64_t ent)
Reset progress dialog.
Definition: TProof.cxx:9866
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7862
void SetString(const char *s)
Definition: TObjString.h:49
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:459
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
Int_t SendPrint(Option_t *option="")
Send print command to master server.
Definition: TProof.cxx:7055
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:379
TString fMaster
Definition: TProof.h:494
Bool_t fTty
Definition: TProof.h:493
float value
Definition: math.cpp:443
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition: TProof.cxx:9879
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
const char * GetName() const
Returns name of object.
Definition: TMap.h:120
Int_t DeactivateWorker(const char *ord, Bool_t save=kTRUE)
Remove the worker identified by the ordinal number 'ord' from the the active list.
Definition: TProof.cxx:11937
TList * fMergers
Definition: TProof.h:584
TUrl fUrl
Definition: TProof.h:598
Int_t Nint(T x)
Definition: TMath.h:480
ESlaveType fSlaveType
Definition: TSlave.h:99
static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
Definition: civetweb.c:1917
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2299
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:181
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:12349
TMonitor * fActiveMonitor
Definition: TProof.h:512
TString fProofWorkDir
Definition: TSlave.h:85
const char * GetUser() const
Definition: TUrl.h:74
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
virtual TList * GetListOfResults() const =0
TSocket * fSocket
Definition: TProof.h:223
virtual TVirtualPacketizer * GetPacketizer() const
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition: TProof.cxx:10746
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition: TMacro.cxx:137
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:466
virtual void UpdateAutoBin(const char *name, Double_t &xmin, Double_t &xmax, Double_t &ymin, Double_t &ymax, Double_t &zmin, Double_t &zmax)=0
const char * GetFile() const
Definition: TUrl.h:78
const char * cnt
Definition: TXMLSetup.cxx:75
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:385
Int_t GetPort() const
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition: TProof.cxx:3049
virtual TDrawFeedback * CreateDrawFeedback(TProof *p)=0
Long64_t fLastPollWorkers_s
Definition: TProof.h:504
void ResetInterrupt()
Definition: TMonitor.h:76
virtual void SetIncludePath(const char *includePath)
IncludePath should contain the list of compiler flags to indicate where to find user defined header f...
Definition: TSystem.cxx:4007
Bool_t IsEndMaster() const
Definition: TProof.h:699
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:2605
Int_t fMaxDrawQueries
Definition: TProof.h:553
const char * GetDirectory() const
Return directory where to look for object.
Definition: TDSet.cxx:256
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition: TProof.cxx:12948
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:299
TProof * GetProof() const
Definition: TProofMgr.h:174
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition: TProof.cxx:4003
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898
virtual TList * GetLists() const
Definition: TEntryList.h:75
const char Int_t const char * image
Definition: TXSlave.cxx:46
void IncreaseNWrks()
Definition: TProof.h:333
void SetOrdinal(const char *ord)
Definition: TProof.h:259
const char *const kPROOF_PackDir
Definition: TProof.h:149
void SetInputHandler(TFileHandler *ih)
Adopt and register input handler for this slave.
Definition: TSlave.cxx:396
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:12582
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition: TProof.cxx:4443
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:605
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904