Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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\defgroup proof PROOF
14
15Classes defining the Parallel ROOT Facility, PROOF, a framework for parallel analysis of ROOT TTrees.
16
17\deprecated
18We keep PROOF for those who still need it for legacy use cases.
19PROOF is not developed anymore and receiving only limited support.
20%ROOT has since a few years moved to RDataFrame and related products as multi-core/multi-processing engines.
21
22*/
23
24/**
25\defgroup proofkernel PROOF kernel Libraries
26\ingroup proof
27
28The PROOF kernel libraries (libProof, libProofPlayer, libProofDraw) contain the classes defining
29the kernel of the PROOF facility, i.e. the protocol and the utilities to steer data processing
30and handling of results.
31
32*/
33
34/** \class TProof
35\ingroup proofkernel
36
37This class controls a Parallel ROOT Facility, PROOF, cluster.
38It fires the worker servers, it keeps track of how many workers are
39running, it keeps track of the workers running status, it broadcasts
40messages to all workers, it collects results, etc.
41
42*/
43
44#include <stdlib.h>
45#include <fcntl.h>
46#include <errno.h>
47#ifdef WIN32
48# include <io.h>
49# include <sys/stat.h>
50# include <sys/types.h>
51# include "snprintf.h"
52#else
53# include <unistd.h>
54#endif
55#include <vector>
56
57#include "RConfigure.h"
58#include "Riostream.h"
59#include "Getline.h"
60#include "TBrowser.h"
61#include "TChain.h"
62#include "TCondor.h"
63#include "TDSet.h"
64#include "TError.h"
65#include "TEnv.h"
66#include "TEntryList.h"
67#include "TEventList.h"
68#include "TFile.h"
69#include "TFileInfo.h"
70#include "TFTP.h"
71#include "THashList.h"
72#include "TInterpreter.h"
73#include "TKey.h"
74#include "TMap.h"
75#include "TMath.h"
76#include "TMessage.h"
77#include "TMonitor.h"
78#include "TObjArray.h"
79#include "TObjString.h"
80#include "TParameter.h"
81#include "TProof.h"
82#include "TProofNodeInfo.h"
83#include "TProofOutputFile.h"
84#include "TVirtualProofPlayer.h"
85#include "TVirtualPacketizer.h"
86#include "TProofServ.h"
87#include "TPluginManager.h"
88#include "TQueryResult.h"
89#include "TRandom.h"
90#include "TRegexp.h"
91#include "TROOT.h"
92#include "TSlave.h"
93#include "TSocket.h"
94#include "TSortedList.h"
95#include "TSystem.h"
96#include "TTree.h"
97#include "TUrl.h"
98#include "TFileCollection.h"
99#include "TDataSetManager.h"
100#include "TDataSetManagerFile.h"
101#include "TMacro.h"
102#include "TSelector.h"
103#include "TPRegexp.h"
104#include "TPackMgr.h"
105
106#include <mutex>
107
109
110// Rotating indicator
111char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
112
113TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
114TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
115
117
118//----- PROOF Interrupt signal handler -----------------------------------------
119////////////////////////////////////////////////////////////////////////////////
120/// TProof interrupt handler.
121
123{
124 if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
125
126 // Cannot ask the user : abort any remote processing
128
129 } else {
130 // Real stop or request to switch to asynchronous?
131 const char *a = 0;
132 if (fProof->GetRemoteProtocol() < 22) {
133 a = Getline("\nSwitch to asynchronous mode not supported remotely:"
134 "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
135 } else {
136 a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
137 " any other key to continue: ");
138 }
139 if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
140
141 Info("Notify","Processing interrupt signal ... %c", a[0]);
142
143 // Stop or abort any remote processing
144 Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
145 fProof->StopProcess(abort);
146
147 } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
148 // Stop any remote processing
150 }
151 }
152
153 return kTRUE;
154}
155
156//----- Input handler for messages from TProofServ -----------------------------
157////////////////////////////////////////////////////////////////////////////////
158/// Constructor
159
161 : TFileHandler(s->GetDescriptor(),1),
162 fSocket(s), fProof(p)
163{
164}
165
166////////////////////////////////////////////////////////////////////////////////
167/// Handle input
168
170{
172 return kTRUE;
173}
174
175
176//------------------------------------------------------------------------------
177
179
180////////////////////////////////////////////////////////////////////////////////
181/// Used to sort slaveinfos by ordinal.
182
184{
185 if (!obj) return 1;
186
187 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
188
189 if (!si) return fOrdinal.CompareTo(obj->GetName());
190
191 const char *myord = GetOrdinal();
192 const char *otherord = si->GetOrdinal();
193 while (myord && otherord) {
194 Int_t myval = atoi(myord);
195 Int_t otherval = atoi(otherord);
196 if (myval < otherval) return 1;
197 if (myval > otherval) return -1;
198 myord = strchr(myord, '.');
199 if (myord) myord++;
200 otherord = strchr(otherord, '.');
201 if (otherord) otherord++;
202 }
203 if (myord) return -1;
204 if (otherord) return 1;
205 return 0;
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// Used to compare slaveinfos by ordinal.
210
212{
213 if (!obj) return kFALSE;
214 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
215 if (!si) return kFALSE;
216 return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
217}
218
219////////////////////////////////////////////////////////////////////////////////
220/// Print slave info. If opt = "active" print only the active
221/// slaves, if opt="notactive" print only the not active slaves,
222/// if opt = "bad" print only the bad slaves, else
223/// print all slaves.
224
226{
227 TString stat = fStatus == kActive ? "active" :
228 fStatus == kBad ? "bad" :
229 "not active";
230
231 Bool_t newfmt = kFALSE;
232 TString oo(opt);
233 if (oo.Contains("N")) {
234 newfmt = kTRUE;
235 oo.ReplaceAll("N","");
236 }
237 if (oo == "active" && fStatus != kActive) return;
238 if (oo == "notactive" && fStatus != kNotActive) return;
239 if (oo == "bad" && fStatus != kBad) return;
240
241 if (newfmt) {
242 TString msd, si, datadir;
243 if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
244 if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
245 if (fSysInfo.fCpus > 0) {
246 si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
248 } else {
249 si.Form("| %s", fHostName.Data());
250 }
251 Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
252
253 } else {
254 TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
255
256 std::cout << "Slave: " << fOrdinal
257 << " hostname: " << fHostName
258 << " msd: " << msd
259 << " perf index: " << fPerfIndex
260 << " " << stat
261 << std::endl;
262 }
263}
264
265////////////////////////////////////////////////////////////////////////////////
266/// Setter for fSysInfo
267
269{
270 fSysInfo.fOS = si.fOS; // OS
271 fSysInfo.fModel = si.fModel; // computer model
272 fSysInfo.fCpuType = si.fCpuType; // type of cpu
273 fSysInfo.fCpus = si.fCpus; // number of cpus
274 fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
275 fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
276 fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
277 fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
278}
279
281
282//------------------------------------------------------------------------------
283
284////////////////////////////////////////////////////////////////////////////////
285/// Destructor
286
288{
289 // Just delete the list, the objects are owned by other list
290 if (fWorkers) {
293 }
294}
295////////////////////////////////////////////////////////////////////////////////
296/// Increase number of already merged workers by 1
297
299{
301 Error("SetMergedWorker", "all workers have been already merged before!");
302 else
304}
305
306////////////////////////////////////////////////////////////////////////////////
307/// Add new worker to the list of workers to be merged by this merger
308
310{
311 if (!fWorkers)
312 fWorkers = new TList();
313 if (fWorkersToMerge == fWorkers->GetSize()) {
314 Error("AddWorker", "all workers have been already assigned to this merger");
315 return;
316 }
317 fWorkers->Add(sl);
318}
319
320////////////////////////////////////////////////////////////////////////////////
321/// Return if merger has already merged all workers, i.e. if it has finished its merging job
322
324{
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Return if the determined number of workers has been already assigned to this merger
330
332{
333 if (!fWorkers)
334 return kFALSE;
335
336 return (fWorkers->GetSize() == fWorkersToMerge);
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// This a private API function.
341/// It checks whether the connection string contains a PoD cluster protocol.
342/// If it does, then the connection string will be changed to reflect
343/// a real PROOF connection string for a PROOF cluster managed by PoD.
344/// PoD: http://pod.gsi.de .
345/// Return -1 if the PoD request failed; return 0 otherwise.
346
347static Int_t PoDCheckUrl(TString *_cluster)
348{
349 if ( !_cluster )
350 return 0;
351
352 // trim spaces from both sides of the string
353 *_cluster = _cluster->Strip( TString::kBoth );
354 // PoD protocol string
355 const TString pod_prot("pod");
356
357 // URL test
358 // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
359 TUrl url( _cluster->Data() );
360 if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
361 return 0;
362
363 // PoD cluster is used
364 // call pod-info in a batch mode (-b).
365 // pod-info will find either a local PoD cluster or
366 // a remote one, manged by pod-remote.
367 *_cluster = gSystem->GetFromPipe("pod-info -c -b");
368 if( 0 == _cluster->Length() ) {
369 Error("PoDCheckUrl", "PoD server is not running");
370 return -1;
371 }
372 return 0;
373}
374
375////////////////////////////////////////////////////////////////////////////////
376/// Create a PROOF environment. Starting PROOF involves either connecting
377/// to a master server, which in turn will start a set of slave servers, or
378/// directly starting as master server (if master = ""). Masterurl is of
379/// the form: [proof[s]://]host[:port]. Conffile is the name of the config
380/// file describing the remote PROOF cluster (this argument alows you to
381/// describe different cluster configurations).
382/// The default is proof.conf. Confdir is the directory where the config
383/// file and other PROOF related files are (like motd and noproof files).
384/// Loglevel is the log level (default = 1). User specified custom config
385/// files will be first looked for in $HOME/.conffile.
386
387TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
388 Int_t loglevel, const char *alias, TProofMgr *mgr)
389 : fUrl(masterurl)
390{
391 // Default initializations
392 InitMembers();
393
394 // This may be needed during init
395 fManager = mgr;
396
397 // Default server type
399
400 // Default query mode
402
403 // Parse the main URL, adjusting the missing fields and setting the relevant
404 // bits
407
408 // Protocol and Host
409 if (!masterurl || strlen(masterurl) <= 0) {
410 fUrl.SetProtocol("proof");
411 fUrl.SetHost("__master__");
412 } else if (!(strstr(masterurl, "://"))) {
413 fUrl.SetProtocol("proof");
414 }
415 // Port
416 if (fUrl.GetPort() == TUrl(" ").GetPort())
417 fUrl.SetPort(TUrl("proof:// ").GetPort());
418
419 // Make sure to store the FQDN, so to get a solid reference for subsequent checks
420 if (!strcmp(fUrl.GetHost(), "__master__"))
421 fMaster = fUrl.GetHost();
422 else if (!strlen(fUrl.GetHost()))
424 else
426
427 // Server type
428 if (strlen(fUrl.GetOptions()) > 0) {
429 TString opts(fUrl.GetOptions());
430 if (!(strncmp(fUrl.GetOptions(),"std",3))) {
432 opts.Remove(0,3);
433 fUrl.SetOptions(opts.Data());
434 } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
436 opts.Remove(0,4);
437 fUrl.SetOptions(opts.Data());
438 }
439 }
440
441 // Instance type
445 if (fMaster == "__master__") {
449 } else if (fMaster == "prooflite") {
450 // Client and master are merged
453 }
454 // Flag that we are a client
456 if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
457
458 Init(masterurl, conffile, confdir, loglevel, alias);
459
460 // If the user was not set, get it from the master
461 if (strlen(fUrl.GetUser()) <= 0) {
462 TString usr, emsg;
463 if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
464 TObjString *os = fMacroLog.GetLineWith("const char");
465 if (os) {
466 Ssiz_t fst = os->GetString().First('\"');
467 Ssiz_t lst = os->GetString().Last('\"');
468 usr = os->GetString()(fst+1, lst-fst-1);
469 } else {
470 emsg = "could not find 'const char *' string in macro log";
471 }
472 } else {
473 emsg = "could not retrieve user info";
474 }
475 if (!emsg.IsNull()) {
476 // Get user logon name
478 if (pw) {
479 usr = pw->fUser;
480 delete pw;
481 }
482 Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
483 }
484 // Set the user name in the main URL
485 fUrl.SetUser(usr.Data());
486 }
487
488 // If called by a manager, make sure it stays in last position
489 // for cleaning
490 if (mgr) {
492 gROOT->GetListOfSockets()->Remove(mgr);
493 gROOT->GetListOfSockets()->Add(mgr);
494 }
495
496 // Old-style server type: we add this to the list and set the global pointer
498 if (!gROOT->GetListOfProofs()->FindObject(this))
499 gROOT->GetListOfProofs()->Add(this);
500
501 // Still needed by the packetizers: needs to be changed
502 gProof = this;
503}
504
505////////////////////////////////////////////////////////////////////////////////
506/// Protected constructor to be used by classes deriving from TProof
507/// (they have to call Init themselves and override StartSlaves
508/// appropriately).
509///
510/// This constructor simply closes any previous gProof and sets gProof
511/// to this instance.
512
513TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
514{
515 // Default initializations
516 InitMembers();
517
518 if (!gROOT->GetListOfProofs()->FindObject(this))
519 gROOT->GetListOfProofs()->Add(this);
520
521 gProof = this;
522}
523
524////////////////////////////////////////////////////////////////////////////////
525/// Default initializations
526
528{
529 fValid = kFALSE;
530 fTty = kFALSE;
531 fRecvMessages = 0;
532 fSlaveInfo = 0;
537 fActiveSlaves = 0;
538 fInactiveSlaves = 0;
539 fUniqueSlaves = 0;
542 fActiveMonitor = 0;
543 fUniqueMonitor = 0;
545 fCurrentMonitor = 0;
546 fBytesRead = 0;
547 fRealTime = 0;
548 fCpuTime = 0;
549 fIntHandler = 0;
550 fProgressDialog = 0;
553 fPlayer = 0;
554 fFeedback = 0;
555 fChains = 0;
556 fDSet = 0;
557 fNotIdle = 0;
558 fSync = kTRUE;
562 fLogFileW = 0;
563 fLogFileR = 0;
566 fMacroLog.SetName("ProofLogMacro");
567
568 fWaitingSlaves = 0;
569 fQueries = 0;
570 fOtherQueries = 0;
571 fDrawQueries = 0;
572 fMaxDrawQueries = 1;
573 fSeqNum = 0;
574
575 fSessionID = -1;
577
578 fPackMgr = 0;
580
581 fInputData = 0;
582
583 fPrintProgress = 0;
584
585 fLoadedMacros = 0;
586
587 fProtocol = -1;
588 fSlaves = 0;
590 fBadSlaves = 0;
591 fAllMonitor = 0;
593 fBytesReady = 0;
594 fTotalBytes = 0;
597 fRunningDSets = 0;
598
599 fCollectTimeout = -1;
600
601 fManager = 0;
604
607 fMergers = 0;
608 fMergersCount = -1;
610 fWorkersToMerge = 0;
612
613 fPerfTree = "";
614
616
617 fSelector = 0;
618
619 fPrepTime = 0.;
620
621 // Check if the user defined a list of environment variables to send over:
622 // include them into the dedicated list
623 if (gSystem->Getenv("PROOF_ENVVARS")) {
624 TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
625 Int_t from = 0;
626 while (envs.Tokenize(env, from, ",")) {
627 if (!env.IsNull()) {
628 if (!gSystem->Getenv(env)) {
629 Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
630 } else {
631 if (!envsfound.IsNull()) envsfound += ",";
632 envsfound += env;
634 TProof::AddEnvVar(env, gSystem->Getenv(env));
635 }
636 }
637 }
638 if (envsfound.IsNull()) {
639 Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
640 } else {
641 Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
642 }
643 }
644
645 // Done
646 return;
647}
648
649////////////////////////////////////////////////////////////////////////////////
650/// Clean up PROOF environment.
651
653{
654 if (fChains) {
655 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
656 // remove "chain" from list
657 chain->SetProof(0);
658 RemoveChain(chain);
659 }
660 }
661
662 // remove links to packages enabled on the client
664 // iterate over all packages
666 if (epl) {
667 TIter nxp(epl);
668 while (TObjString *pck = (TObjString *)(nxp())) {
669 FileStat_t stat;
670 if (gSystem->GetPathInfo(pck->String(), stat) == 0) {
671 // check if symlink, if so unlink
672 // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
673 // existing file or to a directory, but if fIsLink is true the symlink exists
674 if (stat.fIsLink)
675 gSystem->Unlink(pck->String());
676 }
677 }
678 epl->Delete();
679 delete epl;
680 }
681 }
682
683 Close();
710 if (fWrksOutputReady) {
712 delete fWrksOutputReady;
713 }
714 if (fQueries) {
715 fQueries->Delete();
716 delete fQueries;
717 }
718
719 // remove file with redirected logs
721 if (fLogFileR)
722 fclose(fLogFileR);
723 if (fLogFileW)
724 fclose(fLogFileW);
725 if (fLogFileName.Length() > 0)
727 }
728
729 // Remove for the global list
730 gROOT->GetListOfProofs()->Remove(this);
731 // ... and from the manager list
732 if (fManager && fManager->IsValid())
734
735 if (gProof && gProof == this) {
736 // Set previous as default
737 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
738 while ((gProof = (TProof *)pvp())) {
739 if (gProof->InheritsFrom(TProof::Class()))
740 break;
741 }
742 }
743
744 // For those interested in our destruction ...
745 Emit("~TProof()");
746 Emit("CloseWindow()");
747}
748
749////////////////////////////////////////////////////////////////////////////////
750/// Start the PROOF environment. Starting PROOF involves either connecting
751/// to a master server, which in turn will start a set of slave servers, or
752/// directly starting as master server (if master = ""). For a description
753/// of the arguments see the TProof ctor. Returns the number of started
754/// master or slave servers, returns 0 in case of error, in which case
755/// fValid remains false.
756
757Int_t TProof::Init(const char *, const char *conffile,
758 const char *confdir, Int_t loglevel, const char *alias)
759{
761
762 fValid = kFALSE;
763
764 // Connected to terminal?
765 fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
766
767 // If in attach mode, options is filled with additional info
768 Bool_t attach = kFALSE;
769 if (strlen(fUrl.GetOptions()) > 0) {
770 attach = kTRUE;
771 // A flag from the GUI
772 TString opts = fUrl.GetOptions();
773 if (opts.Contains("GUI")) {
775 opts.Remove(opts.Index("GUI"));
776 fUrl.SetOptions(opts);
777 }
778 }
779
781 // Fill default conf file and conf dir
782 if (!conffile || !conffile[0])
784 if (!confdir || !confdir[0])
786 // The group; the client receives it in the kPROOF_SESSIONTAG message
788 } else {
789 fConfDir = confdir;
790 fConfFile = conffile;
791 }
792
793 // Analysise the conffile field
794 if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
796
798 fLogLevel = loglevel;
801 fImage = fMasterServ ? "" : "<local>";
802 fIntHandler = 0;
803 fStatus = 0;
804 fRecvMessages = new TList;
806 fSlaveInfo = 0;
807 fChains = new TList;
810 fRunningDSets = 0;
812 fInputData = 0;
814 fPrintProgress = 0;
815
816 // Timeout for some collect actions
817 fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
818
819 // Should the workers be started dynamically; default: no
820 fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
821
822 // Default entry point for the data pool is the master
824 fDataPoolUrl.Form("root://%s", fMaster.Data());
825 else
826 fDataPoolUrl = "";
827
828 fProgressDialog = 0;
830
831 // Default alias is the master name
832 TString al = (alias) ? alias : fMaster.Data();
833 SetAlias(al);
834
835 // Client logging of messages from the master and slaves
838 fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
839 if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
840 Error("Init", "could not create temporary logfile");
841 if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
842 Error("Init", "could not open temp logfile for reading");
843 }
845
846 // Status of cluster
847 fNotIdle = 0;
848 // Query type
849 fSync = (attach) ? kFALSE : kTRUE;
850 // Not enqueued
852
853 // Counters
854 fBytesRead = 0;
855 fRealTime = 0;
856 fCpuTime = 0;
857
858 // List of queries
859 fQueries = 0;
860 fOtherQueries = 0;
861 fDrawQueries = 0;
862 fMaxDrawQueries = 1;
863 fSeqNum = 0;
864
865 // Remote ID of the session
866 fSessionID = -1;
867
868 // Part of active query
869 fWaitingSlaves = 0;
870
871 // Make remote PROOF player
872 fPlayer = 0;
873 MakePlayer();
874
875 fFeedback = new TList;
877 fFeedback->SetName("FeedbackList");
879
880 // sort slaves by descending performance index
882 fActiveSlaves = new TList;
884 fUniqueSlaves = new TList;
887 fBadSlaves = new TList;
888 fAllMonitor = new TMonitor;
892 fCurrentMonitor = 0;
893
896
897 fLoadedMacros = 0;
898 fPackMgr = 0;
899
900 // Enable optimized sending of streamer infos to use embedded backward/forward
901 // compatibility support between different ROOT versions and different versions of
902 // users classes
903 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
904 if (enableSchemaEvolution) {
906 } else {
907 Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
908 }
909
910 if (IsMaster()) {
911 // to make UploadPackage() method work on the master as well.
913 } else {
914
915 TString sandbox;
916 if (GetSandbox(sandbox, kTRUE) != 0) {
917 Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
918 return 0;
919 }
920
921 // Package Dir
922 TString packdir = gEnv->GetValue("Proof.PackageDir", "");
923 if (packdir.IsNull())
924 packdir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
925 if (AssertPath(packdir, kTRUE) != 0) {
926 Error("Init", "failure asserting directory %s", packdir.Data());
927 return 0;
928 }
929 fPackMgr = new TPackMgr(packdir);
930 if (gDebug > 0)
931 Info("Init", "package directory set to %s", packdir.Data());
932 }
933
934 if (!IsMaster()) {
935 // List of directories where to look for global packages
936 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
938 Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
939 if (gDebug > 0)
940 Info("Init", " %d global package directories registered", nglb);
941 }
942
943 // Master may want dynamic startup
944 if (fDynamicStartup) {
945 if (!IsMaster()) {
946 // If on client - start the master
947 if (!StartSlaves(attach))
948 return 0;
949 }
950 } else {
951
952 // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
953 // result retrieving, ...)
954 Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
955 if (!IsMaster() || !masterOnly) {
956 // Start slaves (the old, static, per-session way)
957 if (!StartSlaves(attach))
958 return 0;
959 // Client: Is Master in dynamic startup mode?
960 if (!IsMaster()) {
961 Int_t dyn = 0;
962 GetRC("Proof.DynamicStartup", dyn);
963 if (dyn != 0) fDynamicStartup = kTRUE;
964 }
965 }
966 }
967 // we are now properly initialized
968 fValid = kTRUE;
969
970 // De-activate monitor (will be activated in Collect)
972
973 // By default go into parallel mode
974 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
975 TNamed *n = 0;
976 if (TProof::GetEnvVars() &&
977 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
978 TString s(n->GetTitle());
979 if (s.IsDigit()) nwrk = s.Atoi();
980 }
981 GoParallel(nwrk, attach);
982
983 // Send relevant initial state to slaves
984 if (!attach)
986 else if (!IsIdle())
987 // redirect log
989
990 // Done at this point, the alias will be communicated to the coordinator, if any
992 SetAlias(al);
993
995
996 if (IsValid()) {
997
998 // Activate input handler
1000
1002 gROOT->GetListOfSockets()->Add(this);
1003 }
1004
1005 AskParallel();
1006
1007 return fActiveSlaves->GetSize();
1008}
1009
1010////////////////////////////////////////////////////////////////////////////////
1011/// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1012/// Use the existing setting or the default if nothing is found.
1013/// If 'assert' is kTRUE, make also sure that the path exists.
1014/// Return 0 on success, -1 on failure
1015
1016Int_t TProof::GetSandbox(TString &sb, Bool_t assert, const char *rc)
1017{
1018 // Get it from 'rc', if defined
1019 if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1020 // Or use the default 'rc'
1021 if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1022 // If nothing found , use the default
1023 if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1024 // Expand special settings
1025 if (sb == ".") {
1026 sb = gSystem->pwd();
1027 } else if (sb == "..") {
1028 sb = gSystem->GetDirName(gSystem->pwd());
1029 }
1031
1032 // Assert the path, if required
1033 if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1034 // Done
1035 return 0;
1036}
1037
1038////////////////////////////////////////////////////////////////////////////////
1039/// The config file field may contain special instructions which need to be
1040/// parsed at the beginning, e.g. for debug runs with valgrind.
1041/// Several options can be given separated by a ','
1042
1043void TProof::ParseConfigField(const char *config)
1044{
1045 TString sconf(config), opt;
1046 Ssiz_t from = 0;
1047 #ifdef R__LINUX
1048 Bool_t cpuPin = kFALSE;
1049 #endif
1050
1051 // Analysise the field
1052 const char *cq = (IsLite()) ? "\"" : "";
1053 while (sconf.Tokenize(opt, from, ",")) {
1054 if (opt.IsNull()) continue;
1055
1056 if (opt.BeginsWith("valgrind")) {
1057 // Any existing valgrind setting? User can give full settings, which we fully respect,
1058 // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1059 // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1060 // will add option "--time-stamp --leak-check=full" to our default options
1061 TString mst, top, sub, wrk, all;
1062 TList *envs = fgProofEnvList;
1063 TNamed *n = 0;
1064 if (envs) {
1065 if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1066 all = n->GetTitle();
1067 if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1068 mst = n->GetTitle();
1069 if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1070 top = n->GetTitle();
1071 if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1072 sub = n->GetTitle();
1073 if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1074 wrk = n->GetTitle();
1075 }
1076 if (all != "" && mst == "") mst = all;
1077 if (all != "" && top == "") top = all;
1078 if (all != "" && sub == "") sub = all;
1079 if (all != "" && wrk == "") wrk = all;
1080 if (all != "" && all.BeginsWith("valgrind_opts:")) {
1081 // The field is used to add an option Reset the setting
1082 Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1083 " must be set again for next run , if any");
1084 TProof::DelEnvVar("PROOF_WRAPPERCMD");
1085 }
1086 TString var, cmd;
1087 cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1088 TString mstlab("NO"), wrklab("NO");
1089 Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1090 !opt.Contains("topmaster") && !opt.Contains("submaster")))
1091 ? kTRUE : kFALSE;
1092 if (doMaster) {
1093 if (!IsLite()) {
1094 // Check if we have to add a var
1095 if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1096 mst.ReplaceAll("valgrind_opts:","");
1097 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1098 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1099 mstlab = "YES";
1100 } else if (mst != "") {
1101 mstlab = "YES";
1102 }
1103 } else {
1104 if (opt.Contains("master")) {
1105 Warning("ParseConfigField",
1106 "master valgrinding does not make sense for PROOF-Lite: ignoring");
1107 opt.ReplaceAll("master", "");
1108 if (!opt.Contains("workers")) return;
1109 }
1110 if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1111 }
1112 }
1113 if (opt.Contains("topmaster")) {
1114 // Check if we have to add a var
1115 if (top == "" || top.BeginsWith("valgrind_opts:")) {
1116 top.ReplaceAll("valgrind_opts:","");
1117 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1118 TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1119 mstlab = "YES";
1120 } else if (top != "") {
1121 mstlab = "YES";
1122 }
1123 }
1124 if (opt.Contains("submaster")) {
1125 // Check if we have to add a var
1126 if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1127 sub.ReplaceAll("valgrind_opts:","");
1128 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1129 TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1130 mstlab = "YES";
1131 } else if (sub != "") {
1132 mstlab = "YES";
1133 }
1134 }
1135 if (opt.Contains("=workers") || opt.Contains("+workers")) {
1136 // Check if we have to add a var
1137 if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1138 wrk.ReplaceAll("valgrind_opts:","");
1139 var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1140 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1141 TString nwrks("2");
1142 Int_t inw = opt.Index('#');
1143 if (inw != kNPOS) {
1144 nwrks = opt(inw+1, opt.Length());
1145 if (!nwrks.IsDigit()) nwrks = "2";
1146 }
1147 // Set the relevant variables
1148 if (!IsLite()) {
1149 TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1150 } else {
1151 gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1152 }
1153 wrklab = nwrks;
1154 // Register the additional worker log in the session file
1155 // (for the master this is done automatically)
1156 TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1157 } else if (wrk != "") {
1158 wrklab = "ALL";
1159 }
1160 }
1161 // Increase the relevant timeouts
1162 if (!IsLite()) {
1163 TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1164 gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1165 } else {
1166 gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1167 }
1168 // Warn for slowness
1169 Printf(" ");
1170 if (!IsLite()) {
1171 Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1172 } else {
1173 Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1174 }
1175 Printf(" ---> Please be patient: startup may be VERY slow ...");
1176 Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1177 Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1178 Printf(" ");
1179
1180 } else if (opt.BeginsWith("igprof-pp")) {
1181
1182 // IgProf profiling on master and worker. PROOF does not set the
1183 // environment for you: proper environment variables (like PATH and
1184 // LD_LIBRARY_PATH) should be set externally
1185
1186 Printf("*** Requested IgProf performance profiling ***");
1187 TString addLogExt = "__igprof.pp__.log";
1188 TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1189 TString tmp;
1190
1191 if (IsLite()) {
1192 addLogFmt.Append("\"");
1193 addLogFmt.Prepend("\"");
1194 }
1195
1196 tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1197 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1198
1199 tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1200 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1201
1202 TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1203
1204 } else if (opt.BeginsWith("cpupin=")) {
1205 // Enable CPU pinning. Takes as argument the list of processor IDs
1206 // that will be used in order. Processor IDs are numbered from 0,
1207 // use likwid to see how they are organized. A possible parameter
1208 // format would be:
1209 //
1210 // cpupin=3+4+0+9+10+22+7
1211 //
1212 // Only the specified processor IDs will be used in a round-robin
1213 // fashion, dealing with the fact that you can request more workers
1214 // than the number of processor IDs you have specified.
1215 //
1216 // To use all available processors in their order:
1217 //
1218 // cpupin=*
1219
1220 opt.Remove(0, 7);
1221
1222 // Remove any char which is neither a number nor a plus '+'
1223 for (Ssiz_t i=0; i<opt.Length(); i++) {
1224 Char_t c = opt[i];
1225 if ((c != '+') && ((c < '0') || (c > '9')))
1226 opt[i] = '_';
1227 }
1228 opt.ReplaceAll("_", "");
1229 TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1230 #ifdef R__LINUX
1231 cpuPin = kTRUE;
1232 #endif
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
1269Int_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
1335 if (fImage.IsNull())
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);
1382 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)
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;
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;
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()");
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
1528void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1529{
1530 TList *server_packs = gProofServ ? gProofServ->GetEnabledPackages() : nullptr;
1531 // Packages
1532 TList *packs = server_packs ? server_packs : GetEnabledPackages();
1533 if (packs && packs->GetSize() > 0) {
1534 TIter nxp(packs);
1535 TPair *pck = 0;
1536 while ((pck = (TPair *) nxp())) {
1537 // Upload and Enable methods are intelligent and avoid
1538 // re-uploading or re-enabling of a package to a node that has it.
1539 if (fDynamicStartup && increasingWorkers) {
1540 // Upload only on added workers
1541 PDB(kGlobal, 3)
1542 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1543 if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1544 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1545 } else {
1546 PDB(kGlobal, 3)
1547 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1548 if (UploadPackage(pck->GetName()) >= 0)
1549 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1550 }
1551 }
1552 }
1553
1554 if (server_packs) {
1555 server_packs->Delete();
1556 delete server_packs;
1557 }
1558
1559 // Loaded macros
1560 if (fLoadedMacros) {
1561 TIter nxp(fLoadedMacros);
1562 TObjString *os = 0;
1563 while ((os = (TObjString *) nxp())) {
1564 PDB(kGlobal, 3) {
1565 Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1566 Printf("Loading a macro : %s", os->GetName());
1567 }
1568 Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1569 }
1570 }
1571
1572 // Dynamic path
1574 dyn.ReplaceAll(":", " ");
1575 dyn.ReplaceAll("\"", " ");
1576 PDB(kGlobal, 3)
1577 Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1578 AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1579
1580 // Include path
1582 inc.ReplaceAll("-I", " ");
1583 inc.ReplaceAll("\"", " ");
1584 PDB(kGlobal, 3)
1585 Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1586 AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1587
1588 // Done
1589 return;
1590}
1591
1592////////////////////////////////////////////////////////////////////////////////
1593/// Used for shuting down the workres after a query is finished.
1594/// Sends each of the workers from the workerList, a kPROOF_STOP message.
1595/// If the workerList == 0, shutdown all the workers.
1596
1598{
1599 if (!IsMaster()) {
1600 Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1601 return -1;
1602 }
1603
1604 fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1605
1606 if (!workerList) {
1607 // shutdown all the workers
1608 TIter nxsl(fSlaves);
1609 TSlave *sl = 0;
1610 while ((sl = (TSlave *) nxsl())) {
1611 // Shut down the worker assumig that it is not processing
1612 TerminateWorker(sl);
1613 }
1614
1615 } else {
1616 if (!(workerList->GetSize())) {
1617 Error("RemoveWorkers", "The list of workers should not be empty!");
1618 return -2;
1619 }
1620
1621 // Loop over all the workers and stop them
1622 TListIter next(workerList);
1623 TObject *to;
1624 TProofNodeInfo *worker;
1625 while ((to = next())) {
1626 TSlave *sl = 0;
1627 if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1628 // Get the next worker from the list
1629 worker = (TProofNodeInfo *)to;
1630 TIter nxsl(fSlaves);
1631 while ((sl = (TSlave *) nxsl())) {
1632 // Shut down the worker assumig that it is not processing
1633 if (sl->GetName() == worker->GetNodeName())
1634 break;
1635 }
1636 } else if (to->InheritsFrom(TSlave::Class())) {
1637 sl = (TSlave *) to;
1638 } else {
1639 Warning("RemoveWorkers","unknown object type: %s - it should be"
1640 " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1641 }
1642 // Shut down the worker assumig that it is not processing
1643 if (sl) {
1644 if (gDebug > 0)
1645 Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1646 TerminateWorker(sl);
1647 }
1648 }
1649 }
1650
1651 // Update also the master counter
1652 if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1653
1654 return 0;
1655}
1656
1657////////////////////////////////////////////////////////////////////////////////
1658/// Start up PROOF slaves.
1659
1661{
1662 // If this is a master server, find the config file and start slave
1663 // servers as specified in the config file
1665
1666 Int_t pc = 0;
1667 TList *workerList = new TList;
1668 // Get list of workers
1669 if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1670 TString emsg("no resource currently available for this session: please retry later");
1671 if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1673 return kFALSE;
1674 }
1675 // Setup the workers
1676 if (AddWorkers(workerList) < 0)
1677 return kFALSE;
1678
1679 } else {
1680
1681 // create master server
1682 Printf("Starting master: opening connection ...");
1683 TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1684
1685 if (slave->IsValid()) {
1686
1687 // Notify
1688 fprintf(stderr,"Starting master:"
1689 " connection open: setting up server ... \r");
1690 StartupMessage("Connection to master opened", kTRUE, 1, 1);
1691
1692 if (!attach) {
1693
1694 // Set worker interrupt handler
1695 slave->SetInterruptHandler(kTRUE);
1696
1697 // Finalize setup of the server
1699
1700 if (slave->IsValid()) {
1701
1702 // Notify
1703 Printf("Starting master: OK ");
1704 StartupMessage("Master started", kTRUE, 1, 1);
1705
1706 // check protocol compatibility
1707 // protocol 1 is not supported anymore
1708 if (fProtocol == 1) {
1709 Error("StartSlaves",
1710 "client and remote protocols not compatible (%d and %d)",
1712 slave->Close("S");
1713 delete slave;
1714 return kFALSE;
1715 }
1716
1717 fSlaves->Add(slave);
1718 fAllMonitor->Add(slave->GetSocket());
1719
1720 // Unset worker interrupt handler
1722
1723 // Set interrupt PROOF handler from now on
1725
1726 // Give-up after 5 minutes
1727 Int_t rc = Collect(slave, 300);
1728 Int_t slStatus = slave->GetStatus();
1729 if (slStatus == -99 || slStatus == -98 || rc == 0) {
1730 fSlaves->Remove(slave);
1731 fAllMonitor->Remove(slave->GetSocket());
1732 if (slStatus == -99)
1733 Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1734 else if (slStatus == -98)
1735 Error("StartSlaves", "could not setup output redirection on master");
1736 else
1737 Error("StartSlaves", "setting up master");
1738 slave->Close("S");
1739 delete slave;
1740 return 0;
1741 }
1742
1743 if (!slave->IsValid()) {
1744 fSlaves->Remove(slave);
1745 fAllMonitor->Remove(slave->GetSocket());
1746 slave->Close("S");
1747 delete slave;
1748 Error("StartSlaves",
1749 "failed to setup connection with PROOF master server");
1750 return kFALSE;
1751 }
1752
1753 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1754 if ((fProgressDialog =
1755 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1756 if (fProgressDialog->LoadPlugin() == -1)
1757 fProgressDialog = 0;
1758 }
1759 } else {
1760 // Notify
1761 Printf("Starting master: failure");
1762 }
1763 } else {
1764
1765 // Notify
1766 Printf("Starting master: OK ");
1767 StartupMessage("Master attached", kTRUE, 1, 1);
1768
1769 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1770 if ((fProgressDialog =
1771 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1772 if (fProgressDialog->LoadPlugin() == -1)
1773 fProgressDialog = 0;
1774 }
1775
1776 fSlaves->Add(slave);
1778 }
1779
1780 } else {
1781 delete slave;
1782 // Notify only if verbosity is on: most likely the failure has already been notified
1783 if (gDebug > 0)
1784 Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1785 return kFALSE;
1786 }
1787 }
1788
1789 return kTRUE;
1790}
1791
1792////////////////////////////////////////////////////////////////////////////////
1793/// Close all open slave servers.
1794/// Client can decide to shutdown the remote session by passing option is 'S'
1795/// or 's'. Default for clients is detach, if supported. Masters always
1796/// shutdown the remote counterpart.
1797
1799{
1800 { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1801
1802 fValid = kFALSE;
1803 if (fSlaves) {
1804 if (fIntHandler)
1806
1807 TIter nxs(fSlaves);
1808 TSlave *sl = 0;
1809 while ((sl = (TSlave *)nxs()))
1810 sl->Close(opt);
1811
1812 fActiveSlaves->Clear("nodelete");
1813 fUniqueSlaves->Clear("nodelete");
1814 fAllUniqueSlaves->Clear("nodelete");
1815 fNonUniqueMasters->Clear("nodelete");
1816 fBadSlaves->Clear("nodelete");
1817 fInactiveSlaves->Clear("nodelete");
1818 fSlaves->Delete();
1819 }
1820 }
1821
1823 gROOT->GetListOfSockets()->Remove(this);
1824
1825 if (fChains) {
1826 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1827 // remove "chain" from list
1828 chain->SetProof(0);
1829 RemoveChain(chain);
1830 }
1831 }
1832
1833 if (IsProofd()) {
1834
1835 gROOT->GetListOfProofs()->Remove(this);
1836 if (gProof && gProof == this) {
1837 // Set previous proofd-related as default
1838 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1839 while ((gProof = (TProof *)pvp())) {
1840 if (gProof->IsProofd())
1841 break;
1842 }
1843 }
1844 }
1845 }
1846}
1847
1848////////////////////////////////////////////////////////////////////////////////
1849/// Create a new TSlave of type TSlave::kSlave.
1850/// Note: creation of TSlave is private with TProof as a friend.
1851/// Derived classes must use this function to create slaves.
1852
1853TSlave *TProof::CreateSlave(const char *url, const char *ord,
1854 Int_t perf, const char *image, const char *workdir)
1855{
1856 TSlave* sl = TSlave::Create(url, ord, perf, image,
1857 this, TSlave::kSlave, workdir, 0);
1858
1859 if (sl->IsValid()) {
1860 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1861 // must set fParallel to 1 for slaves since they do not
1862 // report their fParallel with a LOG_DONE message
1863 sl->fParallel = 1;
1864 }
1865
1866 return sl;
1867}
1868
1869
1870////////////////////////////////////////////////////////////////////////////////
1871/// Create a new TSlave of type TSlave::kMaster.
1872/// Note: creation of TSlave is private with TProof as a friend.
1873/// Derived classes must use this function to create slaves.
1874
1875TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1876 const char *image, const char *msd, Int_t nwk)
1877{
1878 TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1879 TSlave::kMaster, 0, msd, nwk);
1880
1881 if (sl->IsValid()) {
1882 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1883 }
1884
1885 return sl;
1886}
1887
1888////////////////////////////////////////////////////////////////////////////////
1889/// Find slave that has TSocket s. Returns 0 in case slave is not found.
1890
1892{
1893 TSlave *sl;
1894 TIter next(fSlaves);
1895
1896 while ((sl = (TSlave *)next())) {
1897 if (sl->IsValid() && sl->GetSocket() == s)
1898 return sl;
1899 }
1900 return 0;
1901}
1902
1903////////////////////////////////////////////////////////////////////////////////
1904/// Add to the fUniqueSlave list the active slaves that have a unique
1905/// (user) file system image. This information is used to transfer files
1906/// only once to nodes that share a file system (an image). Submasters
1907/// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1908/// list. That list is used to trigger the transferring of files to
1909/// the submaster's unique slaves without the need to transfer the file
1910/// to the submaster.
1911
1913{
1919
1920 TIter next(fActiveSlaves);
1921
1922 while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1923 if (fImage == sl->fImage) {
1924 if (sl->GetSlaveType() == TSlave::kMaster) {
1926 fAllUniqueSlaves->Add(sl);
1927 fAllUniqueMonitor->Add(sl->GetSocket());
1928 }
1929 continue;
1930 }
1931
1932 TIter next2(fUniqueSlaves);
1933 TSlave *replace_slave = 0;
1934 Bool_t add = kTRUE;
1935 while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1936 if (sl->fImage == sl2->fImage) {
1937 add = kFALSE;
1938 if (sl->GetSlaveType() == TSlave::kMaster) {
1939 if (sl2->GetSlaveType() == TSlave::kSlave) {
1940 // give preference to master
1941 replace_slave = sl2;
1942 add = kTRUE;
1943 } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1945 fAllUniqueSlaves->Add(sl);
1946 fAllUniqueMonitor->Add(sl->GetSocket());
1947 } else {
1948 Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1949 R__ASSERT(0);
1950 }
1951 }
1952 break;
1953 }
1954 }
1955
1956 if (add) {
1957 fUniqueSlaves->Add(sl);
1958 fAllUniqueSlaves->Add(sl);
1959 fUniqueMonitor->Add(sl->GetSocket());
1960 fAllUniqueMonitor->Add(sl->GetSocket());
1961 if (replace_slave) {
1962 fUniqueSlaves->Remove(replace_slave);
1963 fAllUniqueSlaves->Remove(replace_slave);
1964 fUniqueMonitor->Remove(replace_slave->GetSocket());
1965 fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1966 }
1967 }
1968 }
1969
1970 // will be actiavted in Collect()
1973}
1974
1975////////////////////////////////////////////////////////////////////////////////
1976/// Return number of slaves as described in the config file.
1977
1979{
1980 return fSlaves->GetSize();
1981}
1982
1983////////////////////////////////////////////////////////////////////////////////
1984/// Return number of active slaves, i.e. slaves that are valid and in
1985/// the current computing group.
1986
1988{
1989 return fActiveSlaves->GetSize();
1990}
1991
1992////////////////////////////////////////////////////////////////////////////////
1993/// Return number of inactive slaves, i.e. slaves that are valid but not in
1994/// the current computing group.
1995
1997{
1998 return fInactiveSlaves->GetSize();
1999}
2000
2001////////////////////////////////////////////////////////////////////////////////
2002/// Return number of unique slaves, i.e. active slaves that have each a
2003/// unique different user files system.
2004
2006{
2007 return fUniqueSlaves->GetSize();
2008}
2009
2010////////////////////////////////////////////////////////////////////////////////
2011/// Return number of bad slaves. This are slaves that we in the config
2012/// file, but refused to startup or that died during the PROOF session.
2013
2015{
2016 return fBadSlaves->GetSize();
2017}
2018
2019////////////////////////////////////////////////////////////////////////////////
2020/// Ask the for the statistics of the slaves.
2021
2023{
2024 if (!IsValid()) return;
2025
2028}
2029
2030////////////////////////////////////////////////////////////////////////////////
2031/// Get statistics about CPU time, real time and bytes read.
2032/// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2033/// and GetBytesRead()
2034
2036{
2037 if (fProtocol > 27) {
2038 // This returns the correct result
2039 AskStatistics();
2040 } else {
2041 // AskStatistics is buggy: parse the output of Print()
2044 Print();
2045 gSystem->RedirectOutput(0, 0, &rh);
2046 TMacro *mp = GetLastLog();
2047 if (mp) {
2048 // Look for global directories
2049 TIter nxl(mp->GetListOfLines());
2050 TObjString *os = 0;
2051 while ((os = (TObjString *) nxl())) {
2052 TString s(os->GetName());
2053 if (s.Contains("Total MB's processed:")) {
2054 s.ReplaceAll("Total MB's processed:", "");
2055 if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2056 } else if (s.Contains("Total real time used (s):")) {
2057 s.ReplaceAll("Total real time used (s):", "");
2058 if (s.IsFloat()) fRealTime = s.Atof();
2059 } else if (s.Contains("Total CPU time used (s):")) {
2060 s.ReplaceAll("Total CPU time used (s):", "");
2061 if (s.IsFloat()) fCpuTime = s.Atof();
2062 }
2063 }
2064 delete mp;
2065 }
2066 }
2067
2068 if (verbose) {
2069 Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2070 GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2071 }
2072}
2073
2074////////////////////////////////////////////////////////////////////////////////
2075/// Ask the for the number of parallel slaves.
2076
2078{
2079 if (!IsValid()) return;
2080
2083}
2084
2085////////////////////////////////////////////////////////////////////////////////
2086/// Ask the master for the list of queries.
2087
2089{
2090 if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2091
2092 Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2094 m << all;
2097
2098 // This should have been filled by now
2099 return fQueries;
2100}
2101
2102////////////////////////////////////////////////////////////////////////////////
2103/// Number of queries processed by this session
2104
2106{
2107 if (fQueries)
2108 return fQueries->GetSize() - fOtherQueries;
2109 return 0;
2110}
2111
2112////////////////////////////////////////////////////////////////////////////////
2113/// Set max number of draw queries whose results are saved
2114
2116{
2117 if (max > 0) {
2118 if (fPlayer)
2120 fMaxDrawQueries = max;
2121 }
2122}
2123
2124////////////////////////////////////////////////////////////////////////////////
2125/// Get max number of queries whose full results are kept in the
2126/// remote sandbox
2127
2129{
2131 m << kFALSE;
2134}
2135
2136////////////////////////////////////////////////////////////////////////////////
2137/// Return pointer to the list of query results in the player
2138
2140{
2141 return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2142}
2143
2144////////////////////////////////////////////////////////////////////////////////
2145/// Return pointer to the full TQueryResult instance owned by the player
2146/// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2147
2149{
2150 return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2151}
2152
2153////////////////////////////////////////////////////////////////////////////////
2154/// Ask the master for the list of queries.
2155/// Options:
2156/// "A" show information about all the queries known to the
2157/// server, i.e. even those processed by other sessions
2158/// "L" show only information about queries locally available
2159/// i.e. already retrieved. If "L" is specified, "A" is
2160/// ignored.
2161/// "F" show all details available about queries
2162/// "H" print help menu
2163/// Default ""
2164
2166{
2167 Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2168 if (help) {
2169
2170 // Help
2171
2172 Printf("+++");
2173 Printf("+++ Options: \"A\" show all queries known to server");
2174 Printf("+++ \"L\" show retrieved queries");
2175 Printf("+++ \"F\" full listing of query info");
2176 Printf("+++ \"H\" print this menu");
2177 Printf("+++");
2178 Printf("+++ (case insensitive)");
2179 Printf("+++");
2180 Printf("+++ Use Retrieve(<#>) to retrieve the full"
2181 " query results from the master");
2182 Printf("+++ e.g. Retrieve(8)");
2183
2184 Printf("+++");
2185
2186 return;
2187 }
2188
2189 if (!IsValid()) return;
2190
2191 Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2192
2193 TObject *pq = 0;
2194 if (!local) {
2195 GetListOfQueries(opt);
2196
2197 if (!fQueries) return;
2198
2199 TIter nxq(fQueries);
2200
2201 // Queries processed by other sessions
2202 if (fOtherQueries > 0) {
2203 Printf("+++");
2204 Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2205 Int_t nq = 0;
2206 while (nq++ < fOtherQueries && (pq = nxq()))
2207 pq->Print(opt);
2208 }
2209
2210 // Queries processed by this session
2211 Printf("+++");
2212 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2214 while ((pq = nxq()))
2215 pq->Print(opt);
2216
2217 } else {
2218
2219 // Queries processed by this session
2220 Printf("+++");
2221 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2223
2224 // Queries available locally
2225 TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2226 if (listlocal) {
2227 Printf("+++");
2228 Printf("+++ Queries available locally: %d", listlocal->GetSize());
2229 TIter nxlq(listlocal);
2230 while ((pq = nxlq()))
2231 pq->Print(opt);
2232 }
2233 }
2234 Printf("+++");
2235}
2236
2237////////////////////////////////////////////////////////////////////////////////
2238/// See if the data is ready to be analyzed.
2239
2241{
2242 if (!IsValid()) return kFALSE;
2243
2244 TList submasters;
2245 TIter nextSlave(GetListOfActiveSlaves());
2246 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2247 if (sl->GetSlaveType() == TSlave::kMaster) {
2248 submasters.Add(sl);
2249 }
2250 }
2251
2252 fDataReady = kTRUE; //see if any submasters set it to false
2253 fBytesReady = 0;
2254 fTotalBytes = 0;
2255 //loop over submasters and see if data is ready
2256 if (submasters.GetSize() > 0) {
2257 Broadcast(kPROOF_DATA_READY, &submasters);
2258 Collect(&submasters);
2259 }
2260
2261 bytesready = fBytesReady;
2262 totalbytes = fTotalBytes;
2263
2264 EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2265
2266 PDB(kGlobal,2)
2267 Info("IsDataReady", "%lld / %lld (%s)",
2268 bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2269
2270 return fDataReady;
2271}
2272
2273////////////////////////////////////////////////////////////////////////////////
2274/// Send interrupt to master or slave servers.
2275
2277{
2278 if (!IsValid()) return;
2279
2280 TList *slaves = 0;
2281 if (list == kAll) slaves = fSlaves;
2282 if (list == kActive) slaves = fActiveSlaves;
2283 if (list == kUnique) slaves = fUniqueSlaves;
2284 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2285
2286 if (slaves->GetSize() == 0) return;
2287
2288 TSlave *sl;
2289 TIter next(slaves);
2290
2291 while ((sl = (TSlave *)next())) {
2292 if (sl->IsValid()) {
2293
2294 // Ask slave to progate the interrupt request
2295 sl->Interrupt((Int_t)type);
2296 }
2297 }
2298}
2299
2300////////////////////////////////////////////////////////////////////////////////
2301/// Returns number of slaves active in parallel mode. Returns 0 in case
2302/// there are no active slaves. Returns -1 in case of error.
2303
2305{
2306 if (!IsValid()) return -1;
2307
2308 // iterate over active slaves and return total number of slaves
2309 TIter nextSlave(GetListOfActiveSlaves());
2310 Int_t nparallel = 0;
2311 while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2312 if (sl->GetParallel() >= 0)
2313 nparallel += sl->GetParallel();
2314
2315 return nparallel;
2316}
2317
2318////////////////////////////////////////////////////////////////////////////////
2319/// Returns list of TSlaveInfo's. In case of error return 0.
2320
2322{
2323 if (!IsValid()) return 0;
2324
2325 if (fSlaveInfo == 0) {
2328 } else {
2329 fSlaveInfo->Delete();
2330 }
2331
2332 TList masters;
2333 TIter next(GetListOfSlaves());
2334 TSlave *slave;
2335
2336 while ((slave = (TSlave *) next()) != 0) {
2337 if (slave->GetSlaveType() == TSlave::kSlave) {
2338 const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2339 TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2340 name,
2341 slave->GetPerfIdx());
2342 fSlaveInfo->Add(slaveinfo);
2343
2344 TIter nextactive(GetListOfActiveSlaves());
2345 TSlave *activeslave;
2346 while ((activeslave = (TSlave *) nextactive())) {
2347 if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2348 slaveinfo->SetStatus(TSlaveInfo::kActive);
2349 break;
2350 }
2351 }
2352
2353 TIter nextbad(GetListOfBadSlaves());
2354 TSlave *badslave;
2355 while ((badslave = (TSlave *) nextbad())) {
2356 if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2357 slaveinfo->SetStatus(TSlaveInfo::kBad);
2358 break;
2359 }
2360 }
2361 // Get system info if supported
2362 if (slave->IsValid()) {
2363 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2364 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2365 else
2366 masters.Add(slave);
2367 }
2368
2369 } else if (slave->GetSlaveType() == TSlave::kMaster) {
2370 if (slave->IsValid()) {
2371 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2372 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2373 else
2374 masters.Add(slave);
2375 }
2376 } else {
2377 Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2378 R__ASSERT(0);
2379 }
2380 }
2381 if (masters.GetSize() > 0) Collect(&masters);
2382
2383 return fSlaveInfo;
2384}
2385
2386////////////////////////////////////////////////////////////////////////////////
2387/// Activate slave server list.
2388
2390{
2391 TMonitor *mon = fAllMonitor;
2392 mon->DeActivateAll();
2393
2394 slaves = !slaves ? fActiveSlaves : slaves;
2395
2396 TIter next(slaves);
2397 TSlave *sl;
2398 while ((sl = (TSlave*) next())) {
2399 if (sl->IsValid())
2400 mon->Activate(sl->GetSocket());
2401 }
2402}
2403
2404////////////////////////////////////////////////////////////////////////////////
2405/// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2406/// monitored by 'mon'.
2407
2409{
2410 TMonitor *m = (mon) ? mon : fCurrentMonitor;
2411 if (m) {
2412 if (on)
2413 m->ActivateAll();
2414 else
2415 m->DeActivateAll();
2416 }
2417}
2418
2419////////////////////////////////////////////////////////////////////////////////
2420/// Broadcast the group priority to all workers in the specified list. Returns
2421/// the number of workers the message was successfully sent to.
2422/// Returns -1 in case of error.
2423
2424Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2425{
2426 if (!IsValid()) return -1;
2427
2428 if (workers->GetSize() == 0) return 0;
2429
2430 int nsent = 0;
2431 TIter next(workers);
2432
2433 TSlave *wrk;
2434 while ((wrk = (TSlave *)next())) {
2435 if (wrk->IsValid()) {
2436 if (wrk->SendGroupPriority(grp, priority) == -1)
2437 MarkBad(wrk, "could not send group priority");
2438 else
2439 nsent++;
2440 }
2441 }
2442
2443 return nsent;
2444}
2445
2446////////////////////////////////////////////////////////////////////////////////
2447/// Broadcast the group priority to all workers in the specified list. Returns
2448/// the number of workers the message was successfully sent to.
2449/// Returns -1 in case of error.
2450
2451Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2452{
2453 TList *workers = 0;
2454 if (list == kAll) workers = fSlaves;
2455 if (list == kActive) workers = fActiveSlaves;
2456 if (list == kUnique) workers = fUniqueSlaves;
2457 if (list == kAllUnique) workers = fAllUniqueSlaves;
2458
2459 return BroadcastGroupPriority(grp, priority, workers);
2460}
2461
2462////////////////////////////////////////////////////////////////////////////////
2463/// Reset the merge progress notificator
2464
2466{
2468}
2469
2470////////////////////////////////////////////////////////////////////////////////
2471/// Broadcast a message to all slaves in the specified list. Returns
2472/// the number of slaves the message was successfully sent to.
2473/// Returns -1 in case of error.
2474
2476{
2477 if (!IsValid()) return -1;
2478
2479 if (!slaves || slaves->GetSize() == 0) return 0;
2480
2481 int nsent = 0;
2482 TIter next(slaves);
2483
2484 TSlave *sl;
2485 while ((sl = (TSlave *)next())) {
2486 if (sl->IsValid()) {
2487 if (sl->GetSocket()->Send(mess) == -1)
2488 MarkBad(sl, "could not broadcast request");
2489 else
2490 nsent++;
2491 }
2492 }
2493
2494 return nsent;
2495}
2496
2497////////////////////////////////////////////////////////////////////////////////
2498/// Broadcast a message to all slaves in the specified list (either
2499/// all slaves or only the active slaves). Returns the number of slaves
2500/// the message was successfully sent to. Returns -1 in case of error.
2501
2503{
2504 TList *slaves = 0;
2505 if (list == kAll) slaves = fSlaves;
2506 if (list == kActive) slaves = fActiveSlaves;
2507 if (list == kUnique) slaves = fUniqueSlaves;
2508 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2509
2510 return Broadcast(mess, slaves);
2511}
2512
2513////////////////////////////////////////////////////////////////////////////////
2514/// Broadcast a character string buffer to all slaves in the specified
2515/// list. Use kind to set the TMessage what field. Returns the number of
2516/// slaves the message was sent to. Returns -1 in case of error.
2517
2518Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2519{
2520 TMessage mess(kind);
2521 if (str) mess.WriteString(str);
2522 return Broadcast(mess, slaves);
2523}
2524
2525////////////////////////////////////////////////////////////////////////////////
2526/// Broadcast a character string buffer to all slaves in the specified
2527/// list (either all slaves or only the active slaves). Use kind to
2528/// set the TMessage what field. Returns the number of slaves the message
2529/// was sent to. Returns -1 in case of error.
2530
2531Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2532{
2533 TMessage mess(kind);
2534 if (str) mess.WriteString(str);
2535 return Broadcast(mess, list);
2536}
2537
2538////////////////////////////////////////////////////////////////////////////////
2539/// Broadcast an object to all slaves in the specified list. Use kind to
2540/// set the TMEssage what field. Returns the number of slaves the message
2541/// was sent to. Returns -1 in case of error.
2542
2544{
2545 TMessage mess(kind);
2546 mess.WriteObject(obj);
2547 return Broadcast(mess, slaves);
2548}
2549
2550////////////////////////////////////////////////////////////////////////////////
2551/// Broadcast an object to all slaves in the specified list. Use kind to
2552/// set the TMEssage what field. Returns the number of slaves the message
2553/// was sent to. Returns -1 in case of error.
2554
2556{
2557 TMessage mess(kind);
2558 mess.WriteObject(obj);
2559 return Broadcast(mess, list);
2560}
2561
2562////////////////////////////////////////////////////////////////////////////////
2563/// Broadcast a raw buffer of specified length to all slaves in the
2564/// specified list. Returns the number of slaves the buffer was sent to.
2565/// Returns -1 in case of error.
2566
2567Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2568{
2569 if (!IsValid()) return -1;
2570
2571 if (slaves->GetSize() == 0) return 0;
2572
2573 int nsent = 0;
2574 TIter next(slaves);
2575
2576 TSlave *sl;
2577 while ((sl = (TSlave *)next())) {
2578 if (sl->IsValid()) {
2579 if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2580 MarkBad(sl, "could not send broadcast-raw request");
2581 else
2582 nsent++;
2583 }
2584 }
2585
2586 return nsent;
2587}
2588
2589////////////////////////////////////////////////////////////////////////////////
2590/// Broadcast a raw buffer of specified length to all slaves in the
2591/// specified list. Returns the number of slaves the buffer was sent to.
2592/// Returns -1 in case of error.
2593
2594Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2595{
2596 TList *slaves = 0;
2597 if (list == kAll) slaves = fSlaves;
2598 if (list == kActive) slaves = fActiveSlaves;
2599 if (list == kUnique) slaves = fUniqueSlaves;
2600 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2601
2602 return BroadcastRaw(buffer, length, slaves);
2603}
2604
2605////////////////////////////////////////////////////////////////////////////////
2606/// Broadcast file to all workers in the specified list. Returns the number of workers
2607/// the buffer was sent to.
2608/// Returns -1 in case of error.
2609
2610Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2611{
2612 if (!IsValid()) return -1;
2613
2614 if (wrks->GetSize() == 0) return 0;
2615
2616 int nsent = 0;
2617 TIter next(wrks);
2618
2619 TSlave *wrk;
2620 while ((wrk = (TSlave *)next())) {
2621 if (wrk->IsValid()) {
2622 if (SendFile(file, opt, rfile, wrk) < 0)
2623 Error("BroadcastFile",
2624 "problems sending file to worker %s (%s)",
2625 wrk->GetOrdinal(), wrk->GetName());
2626 else
2627 nsent++;
2628 }
2629 }
2630
2631 return nsent;
2632}
2633
2634////////////////////////////////////////////////////////////////////////////////
2635/// Broadcast file to all workers in the specified list. Returns the number of workers
2636/// the buffer was sent to.
2637/// Returns -1 in case of error.
2638
2639Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2640{
2641 TList *wrks = 0;
2642 if (list == kAll) wrks = fSlaves;
2643 if (list == kActive) wrks = fActiveSlaves;
2644 if (list == kUnique) wrks = fUniqueSlaves;
2645 if (list == kAllUnique) wrks = fAllUniqueSlaves;
2646
2647 return BroadcastFile(file, opt, rfile, wrks);
2648}
2649
2650////////////////////////////////////////////////////////////////////////////////
2651/// Release the used monitor to be used, making sure to delete newly created
2652/// monitors.
2653
2655{
2656 if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2657 && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2658 delete mon;
2659 }
2660}
2661
2662////////////////////////////////////////////////////////////////////////////////
2663/// Collect responses from slave sl. Returns the number of slaves that
2664/// responded (=1).
2665/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2666/// which means wait forever).
2667/// If defined (>= 0) endtype is the message that stops this collection.
2668
2669Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2670{
2671 Int_t rc = 0;
2672
2673 TMonitor *mon = 0;
2674 if (!sl->IsValid()) return 0;
2675
2677 mon = new TMonitor;
2678 } else {
2679 mon = fAllMonitor;
2680 mon->DeActivateAll();
2681 }
2682 mon->Activate(sl->GetSocket());
2683
2684 rc = Collect(mon, timeout, endtype, deactonfail);
2685 ReleaseMonitor(mon);
2686 return rc;
2687}
2688
2689////////////////////////////////////////////////////////////////////////////////
2690/// Collect responses from the slave servers. Returns the number of slaves
2691/// that responded.
2692/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2693/// which means wait forever).
2694/// If defined (>= 0) endtype is the message that stops this collection.
2695
2696Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2697{
2698 Int_t rc = 0;
2699
2700 TMonitor *mon = 0;
2701
2703 mon = new TMonitor;
2704 } else {
2705 mon = fAllMonitor;
2706 mon->DeActivateAll();
2707 }
2708 TIter next(slaves);
2709 TSlave *sl;
2710 while ((sl = (TSlave*) next())) {
2711 if (sl->IsValid())
2712 mon->Activate(sl->GetSocket());
2713 }
2714
2715 rc = Collect(mon, timeout, endtype, deactonfail);
2716 ReleaseMonitor(mon);
2717 return rc;
2718}
2719
2720////////////////////////////////////////////////////////////////////////////////
2721/// Collect responses from the slave servers. Returns the number of slaves
2722/// that responded.
2723/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2724/// which means wait forever).
2725/// If defined (>= 0) endtype is the message that stops this collection.
2726
2727Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2728{
2729 Int_t rc = 0;
2730 TMonitor *mon = 0;
2731
2732 if (list == kAll) mon = fAllMonitor;
2733 if (list == kActive) mon = fActiveMonitor;
2734 if (list == kUnique) mon = fUniqueMonitor;
2735 if (list == kAllUnique) mon = fAllUniqueMonitor;
2736 if (fCurrentMonitor == mon) {
2737 // Get a copy
2738 mon = new TMonitor(*mon);
2739 }
2740 mon->ActivateAll();
2741
2742 rc = Collect(mon, timeout, endtype, deactonfail);
2743 ReleaseMonitor(mon);
2744 return rc;
2745}
2746
2747////////////////////////////////////////////////////////////////////////////////
2748/// Collect responses from the slave servers. Returns the number of messages
2749/// received. Can be 0 if there are no active slaves.
2750/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2751/// which means wait forever).
2752/// If defined (>= 0) endtype is the message that stops this collection.
2753/// Collect also stops its execution from time to time to check for new
2754/// workers in Dynamic Startup mode.
2755
2756Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2757{
2758 Int_t collectId = gRandom->Integer(9999);
2759
2760 PDB(kCollect, 3)
2761 Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2762
2763 // Reset the status flag and clear the messages in the list, if any
2764 fStatus = 0;
2766
2767 Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2768
2769 if (!mon->GetActive(actto)) return 0;
2770
2772
2773 // Used by external code to know what we are monitoring
2774 TMonitor *savedMonitor = 0;
2775 if (fCurrentMonitor) {
2776 savedMonitor = fCurrentMonitor;
2777 fCurrentMonitor = mon;
2778 } else {
2779 fCurrentMonitor = mon;
2780 fBytesRead = 0;
2781 fRealTime = 0.0;
2782 fCpuTime = 0.0;
2783 }
2784
2785 // We want messages on the main window during synchronous collection,
2786 // but we save the present status to restore it at the end
2787 Bool_t saveRedirLog = fRedirLog;
2788 if (!IsIdle() && !IsSync())
2789 fRedirLog = kFALSE;
2790
2791 int cnt = 0, rc = 0;
2792
2793 // Timeout counter
2794 Long_t nto = timeout;
2795 PDB(kCollect, 2)
2796 Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2797
2798 // On clients, handle Ctrl-C during collection
2799 if (fIntHandler)
2800 fIntHandler->Add();
2801
2802 // Sockets w/o activity during the last 'sto' millisecs are deactivated
2803 Int_t nact = 0;
2804 Long_t sto = -1;
2805 Int_t nsto = 60;
2806 Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2807 mon->ResetInterrupt();
2808 while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2809
2810 // Dump last waiting sockets, if in debug mode
2811 PDB(kCollect, 2) {
2812 if (nact < 4) {
2813 TList *al = mon->GetListOfActives();
2814 if (al && al->GetSize() > 0) {
2815 Info("Collect"," %d node(s) still active:", al->GetSize());
2816 TIter nxs(al);
2817 TSocket *xs = 0;
2818 while ((xs = (TSocket *)nxs())) {
2819 TSlave *wrk = FindSlave(xs);
2820 if (wrk)
2821 Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2822 else
2823 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2824 xs->GetInetAddress().GetPort());
2825 }
2826 }
2827 delete al;
2828 }
2829 }
2830
2831 // Preemptive poll for new workers on the master only in Dynamic Mode and only
2832 // during processing (TODO: should work on Top Master only)
2834 ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2837 fLastPollWorkers_s = time(0);
2839 PDB(kCollect, 1)
2840 Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2841 }
2842
2843 // Wait for a ready socket
2844 PDB(kCollect, 3)
2845 Info("Collect", "Will invoke Select() #%04d", collectId);
2846 TSocket *s = mon->Select(1000);
2847
2848 if (s && s != (TSocket *)(-1)) {
2849 // Get and analyse the info it did receive
2850 rc = CollectInputFrom(s, endtype, deactonfail);
2851 if (rc == 1 || (rc == 2 && !savedMonitor)) {
2852 // Deactivate it if we are done with it
2853 mon->DeActivate(s);
2854 TList *al = mon->GetListOfActives();
2855 PDB(kCollect, 2)
2856 Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2857 s, mon->GetActive(),
2858 al->First());
2859 delete al;
2860 } else if (rc == 2) {
2861 // This end message was for the saved monitor
2862 // Deactivate it if we are done with it
2863 if (savedMonitor) {
2864 savedMonitor->DeActivate(s);
2865 TList *al = mon->GetListOfActives();
2866 PDB(kCollect, 2)
2867 Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2868 s, savedMonitor->GetActive(),
2869 al->First());
2870 delete al;
2871 }
2872 }
2873
2874 // Update counter (if no error occured)
2875 if (rc >= 0)
2876 cnt++;
2877 } else {
2878 // If not timed-out, exit if not stopped or not aborted
2879 // (player exits status is finished in such a case); otherwise,
2880 // we still need to collect the partial output info
2881 if (!s)
2883 mon->DeActivateAll();
2884 // Decrease the timeout counter if requested
2885 if (s == (TSocket *)(-1) && nto > 0)
2886 nto--;
2887 }
2888
2889 // Check if there are workers with ready output to be sent and ask the first to send it
2891 // Maximum number of concurrent sendings
2892 Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2893 if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2894 mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2895 TIter nxwr(fWrksOutputReady);
2896 TSlave *wrk = 0;
2897 while (mxws && (wrk = (TSlave *) nxwr())) {
2898 if (!wrk->TestBit(TSlave::kOutputRequested)) {
2899 // Ask worker for output
2900 TMessage sendoutput(kPROOF_SENDOUTPUT);
2901 PDB(kCollect, 2)
2902 Info("Collect", "worker %s was asked to send its output to master",
2903 wrk->GetOrdinal());
2904 if (wrk->GetSocket()->Send(sendoutput) != 1) {
2906 mxws--;
2907 }
2908 } else {
2909 // Count
2910 mxws--;
2911 }
2912 }
2913 }
2914
2915 // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2916 sto = -1;
2917 if (--nsto <= 0) {
2918 sto = (Long_t) actto;
2919 nsto = 60;
2920 }
2921
2922 } // end loop over active monitors
2923
2924 // If timed-out, deactivate the remaining sockets
2925 if (nto == 0) {
2926 TList *al = mon->GetListOfActives();
2927 if (al && al->GetSize() > 0) {
2928 // Notify the name of those which did timeout
2929 Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2930 TIter nxs(al);
2931 TSocket *xs = 0;
2932 while ((xs = (TSocket *)nxs())) {
2933 TSlave *wrk = FindSlave(xs);
2934 if (wrk)
2935 Info("Collect"," %s", wrk->GetName());
2936 else
2937 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2938 xs->GetInetAddress().GetPort());
2939 }
2940 }
2941 delete al;
2942 mon->DeActivateAll();
2943 }
2944
2945 // Deactivate Ctrl-C special handler
2946 if (fIntHandler)
2948
2949 // make sure group view is up to date
2950 SendGroupView();
2951
2952 // Restore redirection setting
2953 fRedirLog = saveRedirLog;
2954
2955 // Restore the monitor
2956 fCurrentMonitor = savedMonitor;
2957
2959
2960 PDB(kCollect, 3)
2961 Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2962
2963 return cnt;
2964}
2965
2966////////////////////////////////////////////////////////////////////////////////
2967/// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2968/// them. Returns the number of new workers found, or <0 on errors.
2969
2971{
2972 // Requests for worker updates
2973 Int_t dummy = 0;
2974 TList *reqWorkers = new TList();
2975 reqWorkers->SetOwner(kFALSE);
2976
2977 if (!TestBit(TProof::kIsMaster)) {
2978 Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2979 return -1;
2980 }
2981 if (!gProofServ) {
2982 Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2983 return -1;
2984 }
2985
2986 gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2987
2988 // List of new workers only (TProofNodeInfo)
2989 TList *newWorkers = new TList();
2990 newWorkers->SetOwner(kTRUE);
2991
2992 TIter next(reqWorkers);
2993 TProofNodeInfo *ni;
2994 TString fullOrd;
2995 while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2996
2997 // Form the full ordinal
2998 fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2999
3000 TIter nextInner(fSlaves);
3001 TSlave *sl;
3002 Bool_t found = kFALSE;
3003 while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
3004 if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
3005 found = kTRUE;
3006 break;
3007 }
3008 }
3009
3010 if (found) delete ni;
3011 else {
3012 newWorkers->Add(ni);
3013 PDB(kGlobal, 1)
3014 Info("PollForNewWorkers", "New worker found: %s:%s",
3015 ni->GetNodeName().Data(), fullOrd.Data());
3016 }
3017 }
3018
3019 delete reqWorkers; // not owner
3020
3021 Int_t nNewWorkers = newWorkers->GetEntries();
3022
3023 // Add the new workers
3024 if (nNewWorkers > 0) {
3025 PDB(kGlobal, 1)
3026 Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
3027 Int_t rv = AddWorkers(newWorkers);
3028 if (rv < 0) {
3029 Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3030 return -1;
3031 }
3032 // Don't delete newWorkers: AddWorkers() will do that
3033 }
3034 else {
3035 PDB(kGlobal, 2)
3036 Info("PollForNewWorkers", "No new worker found");
3037 delete newWorkers;
3038 }
3039
3040 return nNewWorkers;
3041}
3042
3043////////////////////////////////////////////////////////////////////////////////
3044/// Remove links to objects in list 'ol' from gDirectory
3045
3047{
3048 if (ol) {
3049 TIter nxo(ol);
3050 TObject *o = 0;
3051 while ((o = nxo()))
3053 }
3054}
3055
3056////////////////////////////////////////////////////////////////////////////////
3057/// Collect and analyze available input from socket s.
3058/// Returns 0 on success, -1 if any failure occurs.
3059
3061{
3062 TMessage *mess;
3063
3064 Int_t recvrc = 0;
3065 if ((recvrc = s->Recv(mess)) < 0) {
3066 PDB(kCollect,2)
3067 Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3068 Bool_t bad = kTRUE;
3069 if (recvrc == -5) {
3070 // Broken connection: try reconnection
3072 if (s->Reconnect() == 0) {
3074 bad = kFALSE;
3075 }
3076 }
3077 if (bad)
3078 MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3079 // Ignore this wake up
3080 return -1;
3081 }
3082 if (!mess) {
3083 // we get here in case the remote server died
3084 MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3085 return -1;
3086 }
3087 Int_t rc = 0;
3088
3089 Int_t what = mess->What();
3090 TSlave *sl = FindSlave(s);
3091 rc = HandleInputMessage(sl, mess, deactonfail);
3092 if (rc == 1 && (endtype >= 0) && (what != endtype))
3093 // This message was for the base monitor in recursive case
3094 rc = 2;
3095
3096 // We are done successfully
3097 return rc;
3098}
3099
3100////////////////////////////////////////////////////////////////////////////////
3101/// Analyze the received message.
3102/// Returns 0 on success (1 if this the last message from this socket), -1 if
3103/// any failure occurs.
3104
3106{
3107 char str[512];
3108 TObject *obj;
3109 Int_t rc = 0;
3110
3111 if (!mess || !sl) {
3112 Warning("HandleInputMessage", "given an empty message or undefined worker");
3113 return -1;
3114 }
3115 Bool_t delete_mess = kTRUE;
3116 TSocket *s = sl->GetSocket();
3117 if (!s) {
3118 Warning("HandleInputMessage", "worker socket is undefined");
3119 return -1;
3120 }
3121
3122 // The message type
3123 Int_t what = mess->What();
3124
3125 PDB(kCollect,3)
3126 Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3127
3128 switch (what) {
3129
3130 case kMESS_OK:
3131 // Add the message to the list
3132 fRecvMessages->Add(mess);
3133 delete_mess = kFALSE;
3134 break;
3135
3136 case kMESS_OBJECT:
3137 if (fPlayer) fPlayer->HandleRecvHisto(mess);
3138 break;
3139
3140 case kPROOF_FATAL:
3141 { TString msg;
3142 if ((mess->BufferSize() > mess->Length()))
3143 (*mess) >> msg;
3144 if (msg.IsNull()) {
3145 MarkBad(s, "received kPROOF_FATAL");
3146 } else {
3147 MarkBad(s, msg);
3148 }
3149 }
3151 // Finalize the progress dialog
3152 Emit("StopProcess(Bool_t)", kTRUE);
3153 }
3154 break;
3155
3156 case kPROOF_STOP:
3157 // Stop collection from this worker
3158 Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3159 sl->GetOrdinal());
3160 rc = 1;
3161 break;
3162
3164 // Add the message to the list
3165 fRecvMessages->Add(mess);
3166 delete_mess = kFALSE;
3167 rc = 1;
3168 break;
3169
3170 case kPROOF_TOUCH:
3171 // send a request for touching the remote admin file
3172 {
3173 sl->Touch();
3174 }
3175 break;
3176
3177 case kPROOF_GETOBJECT:
3178 // send slave object it asks for
3179 mess->ReadString(str, sizeof(str));
3180 obj = gDirectory->Get(str);
3181 if (obj)
3182 s->SendObject(obj);
3183 else
3184 s->Send(kMESS_NOTOK);
3185 break;
3186
3187 case kPROOF_GETPACKET:
3188 {
3189 PDB(kGlobal,2)
3190 Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3191 TDSetElement *elem = 0;
3192 elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3193
3194 if (elem != (TDSetElement*) -1) {
3196 answ << elem;
3197 s->Send(answ);
3198
3199 while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3200 TPair *p = (TPair*) fWaitingSlaves->First();
3201 s = (TSocket*) p->Key();
3202 TMessage *m = (TMessage*) p->Value();
3203
3204 elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3205 if (elem != (TDSetElement*) -1) {
3207 a << elem;
3208 s->Send(a);
3209 // remove has to happen via Links because TPair does not have
3210 // a Compare() function and therefore RemoveFirst() and
3211 // Remove(TObject*) do not work
3213 delete p;
3214 delete m;
3215 } else {
3216 break;
3217 }
3218 }
3219 } else {
3220 if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3221 fWaitingSlaves->Add(new TPair(s, mess));
3222 delete_mess = kFALSE;
3223 }
3224 }
3225 break;
3226
3227 case kPROOF_LOGFILE:
3228 {
3229 Int_t size;
3230 (*mess) >> size;
3231 PDB(kGlobal,2)
3232 Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3233 RecvLogFile(s, size);
3234 }
3235 break;
3236
3237 case kPROOF_LOGDONE:
3238 (*mess) >> sl->fStatus >> sl->fParallel;
3239 PDB(kCollect,2)
3240 Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3241 sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3242 if (sl->fStatus != 0) {
3243 // Return last nonzero status
3244 fStatus = sl->fStatus;
3245 // Deactivate the worker, if required
3246 if (deactonfail) DeactivateWorker(sl->fOrdinal);
3247 }
3248 // Remove from the workers-ready list
3252 }
3253 rc = 1;
3254 break;
3255
3256 case kPROOF_GETSTATS:
3257 {
3258 (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3259 >> sl->fWorkDir >> sl->fProofWorkDir;
3260 PDB(kCollect,2)
3261 Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3262 TString img;
3263 if ((mess->BufferSize() > mess->Length()))
3264 (*mess) >> img;
3265 // Set image
3266 if (img.IsNull()) {
3267 if (sl->fImage.IsNull())
3268 sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3269 sl->fProofWorkDir.Data());
3270 } else {
3271 sl->fImage = img;
3272 }
3273 PDB(kGlobal,2)
3274 Info("HandleInputMessage",
3275 "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3276
3277 fBytesRead += sl->fBytesRead;
3278 fRealTime += sl->fRealTime;
3279 fCpuTime += sl->fCpuTime;
3280 rc = 1;
3281 }
3282 break;
3283
3284 case kPROOF_GETPARALLEL:
3285 {
3286 Bool_t async = kFALSE;
3287 (*mess) >> sl->fParallel;
3288 if ((mess->BufferSize() > mess->Length()))
3289 (*mess) >> async;
3290 rc = (async) ? 0 : 1;
3291 }
3292 break;
3293
3294 case kPROOF_CHECKFILE:
3295 { // New servers (>= 5.22) send the status
3296 if ((mess->BufferSize() > mess->Length())) {
3297 (*mess) >> fCheckFileStatus;
3298 } else {
3299 // Form old servers this meant success (failure was signaled with the
3300 // dangerous kPROOF_FATAL)
3301 fCheckFileStatus = 1;
3302 }
3303 rc = 1;
3304 }
3305 break;
3306
3307 case kPROOF_SENDFILE:
3308 { // New server: signals ending of sendfile operation
3309 rc = 1;
3310 }
3311 break;
3312
3314 {
3315 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3316 Int_t type = 0;
3317 (*mess) >> type;
3318 switch (type) {
3321 fEnabledPackages = (TList *) mess->ReadObject(TList::Class());
3322 if (fEnabledPackages) {
3324 } else {
3325 Error("HandleInputMessage",
3326 "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3327 }
3328 break;
3331 fAvailablePackages = (TList *) mess->ReadObject(TList::Class());
3332 if (fAvailablePackages) {
3334 } else {
3335 Error("HandleInputMessage",
3336 "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3337 }
3338 break;
3339 default:
3340 Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3341 }
3342 }
3343 break;
3344
3345 case kPROOF_SENDOUTPUT:
3346 {
3347 // We start measuring the merging time
3349
3350 // Worker is ready to send output: make sure the relevant bit is reset
3352 PDB(kGlobal,2)
3353 Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3354 // Create the list if not yet done
3355 if (!fWrksOutputReady) {
3356 fWrksOutputReady = new TList;
3358 }
3359 fWrksOutputReady->Add(sl);
3360 }
3361 break;
3362
3364 {
3365 // We start measuring the merging time
3367
3368 PDB(kGlobal,2)
3369 Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3370 Int_t type = 0;
3371 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3373 Info("HandleInputMessage", "finalization on %s started ...", prefix);
3375 }
3376
3377 while ((mess->BufferSize() > mess->Length())) {
3378 (*mess) >> type;
3379 // If a query result header, add it to the player list
3380 if (fPlayer) {
3381 if (type == 0) {
3382 // Retrieve query result instance (output list not filled)
3383 TQueryResult *pq =
3384 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
3385 if (pq) {
3386 // Add query to the result list in TProofPlayer
3389 // And clear the output list, as we start merging a new set of results
3390 if (fPlayer->GetOutputList())
3392 // Add the unique query tag as TNamed object to the input list
3393 // so that it is available in TSelectors for monitoring
3394 TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3395 if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3396 fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3397 fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3398 } else {
3399 Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3400 }
3401 } else if (type > 0) {
3402 // Read object
3403 TObject *o = mess->ReadObject(TObject::Class());
3404 // Increment counter on the client side
3406 TString msg;
3407 Bool_t changed = kFALSE;
3408 msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3409 if (gProofServ) {
3411 } else if (IsTty() || changed) {
3412 fprintf(stderr, "%s\r", msg.Data());
3413 }
3414 // Add or merge it
3415 if ((fPlayer->AddOutputObject(o) == 1)) {
3416 // Remove the object if it has been merged
3417 SafeDelete(o);
3418 }
3419 if (type > 1) {
3420 // Update the merger progress info
3422 if (TestBit(TProof::kIsClient) && !IsLite()) {
3423 // In PROOFLite this has to be done once only in TProofLite::Process
3425 if (pq) {
3427 // Add input objects (do not override remote settings, if any)
3428 TObject *xo = 0;
3429 TIter nxin(fPlayer->GetInputList());
3430 // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3431 if (!pq->GetInputList()) pq->SetInputList(new TList());
3432 while ((xo = nxin()))
3433 if (!pq->GetInputList()->FindObject(xo->GetName()))
3434 pq->AddInput(xo->Clone());
3435 // If the last object, notify the GUI that the result arrived
3436 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3437 }
3438 // Processing is over
3439 UpdateDialog();
3440 }
3441 }
3442 }
3443 } else {
3444 Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3445 }
3446 }
3447 }
3448 break;
3449
3450 case kPROOF_OUTPUTLIST:
3451 {
3452 // We start measuring the merging time
3453
3454 PDB(kGlobal,2)
3455 Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3456 TList *out = 0;
3457 if (fPlayer) {
3459 if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3460 out = (TList *) mess->ReadObject(TList::Class());
3461 } else {
3462 TQueryResult *pq =
3463 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
3464 if (pq) {
3465 // Add query to the result list in TProofPlayer
3468 // To avoid accidental cleanups from anywhere else
3469 // remove objects from gDirectory and clone the list
3470 out = pq->GetOutputList();
3471 CleanGDirectory(out);
3472 out = (TList *) out->Clone();
3473 // Notify the GUI that the result arrived
3474 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3475 } else {
3476 PDB(kGlobal,2)
3477 Info("HandleInputMessage",
3478 "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3479 }
3480 }
3481 if (out) {
3482 out->SetOwner();
3483 fPlayer->AddOutput(out); // Incorporate the list
3484 SafeDelete(out);
3485 } else {
3486 PDB(kGlobal,2)
3487 Info("HandleInputMessage",
3488 "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3489 }
3490 } else {
3491 Warning("HandleInputMessage",
3492 "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3493 }
3494 // On clients at this point processing is over
3495 if (TestBit(TProof::kIsClient) && !IsLite())
3496 UpdateDialog();
3497 }
3498 break;
3499
3500 case kPROOF_QUERYLIST:
3501 {
3502 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3503 (*mess) >> fOtherQueries >> fDrawQueries;
3504 if (fQueries) {
3505 fQueries->Delete();
3506 delete fQueries;
3507 fQueries = 0;
3508 }
3509 fQueries = (TList *) mess->ReadObject(TList::Class());
3510 }
3511 break;
3512
3513 case kPROOF_RETRIEVE:
3514 {
3515 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3516 TQueryResult *pq =
3517 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
3518 if (pq && fPlayer) {
3520 // Notify the GUI that the result arrived
3521 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3522 } else {
3523 PDB(kGlobal,2)
3524 Info("HandleInputMessage",
3525 "kPROOF_RETRIEVE: query result missing or player undefined");
3526 }
3527 }
3528 break;
3529
3530 case kPROOF_MAXQUERIES:
3531 {
3532 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3533 Int_t max = 0;
3534
3535 (*mess) >> max;
3536 Printf("Number of queries fully kept remotely: %d", max);
3537 }
3538 break;
3539
3541 {
3542 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3543
3544 UInt_t tot = 0, done = 0;
3545 TString action;
3546 Bool_t st = kTRUE;
3547
3548 (*mess) >> action >> tot >> done >> st;
3549
3551 if (tot) {
3552 TString type = (action.Contains("submas")) ? "submasters"
3553 : "workers";
3554 Int_t frac = (Int_t) (done*100.)/tot;
3555 char msg[512] = {0};
3556 if (frac >= 100) {
3557 snprintf(msg, 512, "%s: OK (%d %s) \n",
3558 action.Data(),tot, type.Data());
3559 } else {
3560 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3561 action.Data(), done, tot, frac);
3562 }
3563 if (fSync)
3564 fprintf(stderr,"%s", msg);
3565 else
3566 NotifyLogMsg(msg, 0);
3567 }
3568 // Notify GUIs
3569 StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3570 } else {
3571
3572 // Just send the message one level up
3574 m << action << tot << done << st;
3576 }
3577 }
3578 break;
3579
3581 {
3582 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3583
3584 UInt_t tot = 0, done = 0;
3585 TString action;
3586 Bool_t st = kTRUE;
3587
3588 (*mess) >> action >> tot >> done >> st;
3589
3591 if (tot) {
3592 TString type = "files";
3593 Int_t frac = (Int_t) (done*100.)/tot;
3594 char msg[512] = {0};
3595 if (frac >= 100) {
3596 snprintf(msg, 512, "%s: OK (%d %s) \n",
3597 action.Data(),tot, type.Data());
3598 } else {
3599 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3600 action.Data(), done, tot, frac);
3601 }
3602 if (fSync)
3603 fprintf(stderr,"%s", msg);
3604 else
3605 NotifyLogMsg(msg, 0);
3606 }
3607 // Notify GUIs
3608 DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3609 } else {
3610
3611 // Just send the message one level up
3613 m << action << tot << done << st;
3615 }
3616 }
3617 break;
3618
3620 {
3621 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3622
3623 // For Proof-Lite this variable is the number of workers and is set
3624 // by the player
3625 if (!IsLite()) {
3626 fNotIdle = 1;
3628 }
3629
3630 // Redirect the output, if needed
3632
3633 // The signal is used on masters by XrdProofdProtocol to catch
3634 // the start of processing; on clients it allows to update the
3635 // progress dialog
3636 if (!TestBit(TProof::kIsMaster)) {
3637
3638 // This is the end of preparation
3639 fQuerySTW.Stop();
3641 PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3642
3643 TString selec;
3644 Int_t dsz = -1;
3645 Long64_t first = -1, nent = -1;
3646 (*mess) >> selec >> dsz >> first >> nent;
3647 // Start or reset the progress dialog
3648 if (!gROOT->IsBatch()) {
3649 if (fProgressDialog &&
3652 fProgressDialog->ExecPlugin(5, this,
3653 selec.Data(), dsz, first, nent);
3655 } else {
3656 ResetProgressDialog(selec, dsz, first, nent);
3657 }
3658 }
3660 }
3661 }
3662 }
3663 break;
3664
3665 case kPROOF_ENDINIT:
3666 {
3667 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3668
3670 if (fPlayer)
3672 }
3673 }
3674 break;
3675
3676 case kPROOF_SETIDLE:
3677 {
3678 PDB(kGlobal,2)
3679 Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3680
3681 // The session is idle
3682 if (IsLite()) {
3683 if (fNotIdle > 0) {
3684 fNotIdle--;
3685 PDB(kGlobal,2)
3686 Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3687 } else {
3688 Warning("HandleInputMessage",
3689 "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3690 sl->GetOrdinal());
3691 }
3692 } else {
3693 fNotIdle = 0;
3694 // Check if the query has been enqueued
3695 if ((mess->BufferSize() > mess->Length()))
3696 (*mess) >> fIsWaiting;
3697 }
3698 }
3699 break;
3700
3702 {
3703 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3704
3705 // We have received the sequential number
3706 (*mess) >> fSeqNum;
3707 Bool_t sync = fSync;
3708 if ((mess->BufferSize() > mess->Length()))
3709 (*mess) >> sync;
3710 if (sync != fSync && fSync) {
3711 // The server required to switch to asynchronous mode
3712 Activate();
3713 fSync = kFALSE;
3714 }
3715 DisableGoAsyn();
3716 // Check if the query has been enqueued
3717 fIsWaiting = kTRUE;
3718 // For Proof-Lite this variable is the number of workers and is set by the player
3719 if (!IsLite())
3720 fNotIdle = 1;
3721
3722 rc = 1;
3723 }
3724 break;
3725
3726 case kPROOF_SESSIONTAG:
3727 {
3728 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3729
3730 // We have received the unique tag and save it as name of this object
3731 TString stag;
3732 (*mess) >> stag;
3733 SetName(stag);
3734 // In the TSlave object
3735 sl->SetSessionTag(stag);
3736 // Server may have also sent the group
3737 if ((mess->BufferSize() > mess->Length()))
3738 (*mess) >> fGroup;
3739 // Server may have also sent the user
3740 if ((mess->BufferSize() > mess->Length())) {
3741 TString usr;
3742 (*mess) >> usr;
3743 if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3744 }
3745 }
3746 break;
3747
3748 case kPROOF_FEEDBACK:
3749 {
3750 PDB(kGlobal,2)
3751 Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3752 TList *out = (TList *) mess->ReadObject(TList::Class());
3753 out->SetOwner();
3754 if (fPlayer)
3755 fPlayer->StoreFeedback(sl, out); // Adopts the list
3756 else
3757 // Not yet ready: stop collect asap
3758 rc = 1;
3759 }
3760 break;
3761
3762 case kPROOF_AUTOBIN:
3763 {
3764 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3765
3766 TString name;
3767 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3768
3769 (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3770
3772
3774
3775 answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3776
3777 s->Send(answ);
3778 }
3779 break;
3780
3781 case kPROOF_PROGRESS:
3782 {
3783 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3784
3785 if (GetRemoteProtocol() > 25) {
3786 // New format
3787 TProofProgressInfo *pi = 0;
3788 (*mess) >> pi;
3789 fPlayer->Progress(sl,pi);
3790 } else if (GetRemoteProtocol() > 11) {
3791 Long64_t total, processed, bytesread;
3792 Float_t initTime, procTime, evtrti, mbrti;
3793 (*mess) >> total >> processed >> bytesread
3794 >> initTime >> procTime
3795 >> evtrti >> mbrti;
3796 if (fPlayer)
3797 fPlayer->Progress(sl, total, processed, bytesread,
3798 initTime, procTime, evtrti, mbrti);
3799
3800 } else {
3801 // Old format
3802 Long64_t total, processed;
3803 (*mess) >> total >> processed;
3804 if (fPlayer)
3805 fPlayer->Progress(sl, total, processed);
3806 }
3807 }
3808 break;
3809
3810 case kPROOF_STOPPROCESS:
3811 {
3812 // This message is sent from a worker that finished processing.
3813 // We determine whether it was asked to finish by the
3814 // packetizer or stopped during processing a packet
3815 // (by TProof::RemoveWorkers() or by an external signal).
3816 // In the later case call packetizer->MarkBad.
3817 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3818
3819 Long64_t events = 0;
3820 Bool_t abort = kFALSE;
3821 TProofProgressStatus *status = 0;
3822
3823 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3824 (*mess) >> status >> abort;
3825 } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3826 (*mess) >> events >> abort;
3827 } else {
3828 (*mess) >> events;
3829 }
3830 if (fPlayer) {
3831 if (fProtocol > 18) {
3832 TList *listOfMissingFiles = 0;
3833 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3834 listOfMissingFiles = new TList();
3835 listOfMissingFiles->SetName("MissingFiles");
3836 if (fPlayer)
3837 fPlayer->AddOutputObject(listOfMissingFiles);
3838 }
3839 if (fPlayer->GetPacketizer()) {
3840 Int_t ret =
3841 fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3842 if (ret > 0)
3843 fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3844 // This object is now owned by the packetizer
3845 status = 0;
3846 }
3847 if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3848 } else {
3849 fPlayer->AddEventsProcessed(events);
3850 }
3851 }
3852 SafeDelete(status);
3854 Emit("StopProcess(Bool_t)", abort);
3855 break;
3856 }
3857
3858 case kPROOF_SUBMERGER:
3859 {
3860 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3861 HandleSubmerger(mess, sl);
3862 }
3863 break;
3864
3866 {
3867 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3868
3869 Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3870 Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3871 TList* tmpinfo = 0;
3872 (*mess) >> tmpinfo;
3873 if (tmpinfo == 0) {
3874 Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3875 } else {
3876 tmpinfo->SetOwner(kFALSE);
3877 Int_t nentries = tmpinfo->GetSize();
3878 for (Int_t i=0; i<nentries; i++) {
3879 TSlaveInfo* slinfo =
3880 dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3881 if (slinfo) {
3882 // If PROOF-Lite
3883 if (IsLite()) slinfo->fHostName = gSystem->HostName();
3884 // Check if we have already a instance for this worker
3885 TIter nxw(fSlaveInfo);
3886 TSlaveInfo *ourwi = 0;
3887 while ((ourwi = (TSlaveInfo *)nxw())) {
3888 if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3889 ourwi->SetSysInfo(slinfo->GetSysInfo());
3890 ourwi->fHostName = slinfo->GetName();
3891 if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3892 ourwi->fDataDir = slinfo->GetDataDir();
3893 break;
3894 }
3895 }
3896 if (!ourwi) {
3897 fSlaveInfo->Add(slinfo);
3898 } else {
3899 slinfo = ourwi;
3900 }
3901 if (slinfo->fStatus != TSlaveInfo::kBad) {
3902 if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3903 if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3904 }
3905 if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3906 slinfo->fMsd = sl->GetMsd();
3907 }
3908 }
3909 delete tmpinfo;
3910 rc = 1;
3911 }
3912 }
3913 break;
3914
3916 {
3917 PDB(kGlobal,2)
3918 Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3919 TDSet* dset = 0;
3920 (*mess) >> dset;
3921 if (!fDSet)
3922 Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3923 else
3924 fDSet->Validate(dset);
3925 delete dset;
3926 }
3927 break;
3928
3929 case kPROOF_DATA_READY:
3930 {
3931 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3932 Bool_t dataready = kFALSE;
3933 Long64_t totalbytes, bytesready;
3934 (*mess) >> dataready >> totalbytes >> bytesready;
3935 fTotalBytes += totalbytes;
3936 fBytesReady += bytesready;
3937 if (dataready == kFALSE) fDataReady = dataready;
3938 }
3939 break;
3940
3941 case kPROOF_PING:
3942 // do nothing (ping is already acknowledged)
3943 break;
3944
3945 case kPROOF_MESSAGE:
3946 {
3947 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3948
3949 // We have received the unique tag and save it as name of this object
3950 TString msg;
3951 (*mess) >> msg;
3952 Bool_t lfeed = kTRUE;
3953 if ((mess->BufferSize() > mess->Length()))
3954 (*mess) >> lfeed;
3955
3957
3958 if (fSync) {
3959 // Notify locally
3960 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3961 } else {
3962 // Notify locally taking care of redirection, windows logs, ...
3963 NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3964 }
3965 } else {
3966
3967 // The message is logged for debugging purposes.
3968 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3969 if (gProofServ) {
3970 // We hide it during normal operations
3972
3973 // And send the message one level up
3974 gProofServ->SendAsynMessage(msg, lfeed);
3975 }
3976 }
3977 }
3978 break;
3979
3981 {
3982 TString vac;
3983 (*mess) >> vac;
3984 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3985 Int_t from = 0;
3986 TString vers, archcomp;
3987 if (vac.Tokenize(vers, from, "|"))
3988 vac.Tokenize(archcomp, from, "|");
3989 sl->SetArchCompiler(archcomp);
3990 vers.ReplaceAll(":","|");
3991 sl->SetROOTVersion(vers);
3992 }
3993 break;
3994
3995 default:
3996 {
3997 Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3998 sl->GetOrdinal(), what);
3999 }
4000 break;
4001 }
4002
4003 // Cleanup
4004 if (delete_mess)
4005 delete mess;
4006
4007 // We are done successfully
4008 return rc;
4009}
4010
4011////////////////////////////////////////////////////////////////////////////////
4012/// Process a message of type kPROOF_SUBMERGER
4013
4015{
4016 // Message sub-type
4017 Int_t type = 0;
4018 (*mess) >> type;
4019 TSocket *s = sl->GetSocket();
4020
4021 switch (type) {
4022 case kOutputSent:
4023 {
4024 if (IsEndMaster()) {
4025 Int_t merger_id = -1;
4026 (*mess) >> merger_id;
4027
4028 PDB(kSubmerger, 2)
4029 Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4030 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4031
4032 if (!fMergers || fMergers->GetSize() <= merger_id) {
4033 Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4034 break;
4035 }
4036 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4037 mi->SetMergedWorker();
4038 if (mi->AreAllWorkersMerged()) {
4039 mi->Deactivate();
4040 if (GetActiveMergersCount() == 0) {
4041 fMergers->Clear();
4042 delete fMergers;
4044 fMergersCount = -1;
4046 PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4047 }
4048 }
4049 } else {
4050 PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4051 }
4052 }
4053 break;
4054
4055 case kMergerDown:
4056 {
4057 Int_t merger_id = -1;
4058 (*mess) >> merger_id;
4059
4060 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4061
4062 if (!fMergers || fMergers->GetSize() <= merger_id) {
4063 Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4064 break;
4065 }
4066
4067 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4068 if (!mi->IsActive()) {
4069 break;
4070 } else {
4071 mi->Deactivate();
4072 }
4073
4074 // Stop the invalid merger in the case it is still listening
4076 stop << Int_t(kStopMerging);
4077 stop << 0;
4078 s->Send(stop);
4079
4080 // Ask for results from merger (only original results from this node as worker are returned)
4081 AskForOutput(mi->GetMerger());
4082
4083 // Ask for results from all workers assigned to this merger
4084 TIter nxo(mi->GetWorkers());
4085 TObject * o = 0;
4086 while ((o = nxo())) {
4087 AskForOutput((TSlave *)o);
4088 }
4089 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4090 }
4091 break;
4092
4093 case kOutputSize:
4094 {
4095 if (IsEndMaster()) {
4096 PDB(kSubmerger, 2)
4097 Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4098
4099 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4100 if (!fFinalizationRunning) {
4101 Info("HandleSubmerger", "finalization on %s started ...", prefix);
4103 }
4104
4105 Int_t output_size = 0;
4106 Int_t merging_port = 0;
4107 (*mess) >> output_size >> merging_port;
4108
4109 PDB(kSubmerger, 2) Info("HandleSubmerger",
4110 "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4111 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4112 TString msg;
4113 if (!fMergersSet) {
4114
4116
4117 // First pass - setting number of mergers according to user or dynamically
4118 fMergersCount = -1; // No mergers used if not set by user
4119 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4120 if (mc) fMergersCount = mc->GetVal(); // Value set by user
4121 TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4122 if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4123
4124 // Mergers count specified by user but not valid
4125 if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4126 msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4127 prefix, fMergersCount, activeWorkers);
4128 if (gProofServ)
4130 else
4131 Printf("%s",msg.Data());
4132 fMergersCount = 0;
4133 }
4134 // Mergers count will be set dynamically
4135 if ((fMergersCount == 0) && (!fMergersByHost)) {
4136 if (activeWorkers > 1) {
4137 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4138 if (activeWorkers / fMergersCount < 2)
4139 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4140 }
4141 if (fMergersCount > 1)
4142 msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4143 prefix, fMergersCount, activeWorkers);
4144 else {
4145 msg.Form("%s: No mergers will be used for %d workers",
4146 prefix, activeWorkers);
4147 fMergersCount = -1;
4148 }
4149 if (gProofServ)
4151 else
4152 Printf("%s",msg.Data());
4153 } else if (fMergersByHost) {
4154 // We force mergers at host level to minimize network traffic
4155 if (activeWorkers > 1) {
4156 fMergersCount = 0;
4157 THashList hosts;
4158 TIter nxwk(fSlaves);
4159 TObject *wrk = 0;
4160 while ((wrk = nxwk())) {
4161 if (!hosts.FindObject(wrk->GetName())) {
4162 hosts.Add(new TObjString(wrk->GetName()));
4163 fMergersCount++;
4164 }
4165 }
4166 }
4167 if (fMergersCount > 1)
4168 msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4169 prefix, fMergersCount, activeWorkers);
4170 else {
4171 msg.Form("%s: No mergers will be used for %d workers",
4172 prefix, activeWorkers);
4173 fMergersCount = -1;
4174 }
4175 if (gProofServ)
4177 else
4178 Printf("%s",msg.Data());
4179 } else {
4180 msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4181 prefix, fMergersCount, activeWorkers);
4182 if (gProofServ)
4184 else
4185 Printf("%s",msg.Data());
4186 }
4187
4188 // We started merging; we call it here because fMergersCount is still the original number
4189 // and can be saved internally
4191
4192 // Update merger counters (new workers are not yet active)
4194
4195 if (fMergersCount > 0) {
4196
4197 fMergers = new TList();
4199 // Total number of workers, which will not act as mergers ('pure workers')
4200 fWorkersToMerge = (activeWorkers - fMergersCount);
4201 // Establish the first merger
4202 if (!CreateMerger(sl, merging_port)) {
4203 // Cannot establish first merger
4204 AskForOutput(sl);
4206 fMergersCount--;
4207 }
4209 } else {
4210 AskForOutput(sl);
4211 }
4213 } else {
4214 // Multiple pass
4215 if (fMergersCount == -1) {
4216 // No mergers. Workers send their outputs directly to master
4217 AskForOutput(sl);
4218 } else {
4219 if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4220 RedirectWorker(s, sl, output_size);
4221 fRedirectNext--;
4222 } else {
4223 Bool_t newMerger = kTRUE;
4224 if (fMergersByHost) {
4225 TIter nxmg(fMergers);
4226 TMergerInfo *mgi = 0;
4227 while ((mgi = (TMergerInfo *) nxmg())) {
4228 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4229 newMerger = kFALSE;
4230 break;
4231 }
4232 }
4233 }
4234 if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4235 // Still not enough mergers established
4236 if (!CreateMerger(sl, merging_port)) {
4237 // Cannot establish a merger
4238 AskForOutput(sl);
4240 fMergersCount--;
4241 }
4242 } else
4243 RedirectWorker(s, sl, output_size);
4244 }
4245 }
4246 }
4247 } else {
4248 Error("HandleSubMerger","kOutputSize received not on endmaster!");
4249 }
4250 }
4251 break;
4252 }
4253}
4254
4255////////////////////////////////////////////////////////////////////////////////
4256/// Redirect output of worker sl to some merger
4257
4258void TProof::RedirectWorker(TSocket *s, TSlave * sl, Int_t output_size)
4259{
4260 Int_t merger_id = -1;
4261
4262 if (fMergersByHost) {
4263 for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4264 TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4265 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4266 merger_id = i;
4267 break;
4268 }
4269 }
4270 } else {
4271 merger_id = FindNextFreeMerger();
4272 }
4273
4274 if (merger_id == -1) {
4275 // No free merger (probably it had crashed before)
4276 AskForOutput(sl);
4277 } else {
4278 TMessage sendoutput(kPROOF_SUBMERGER);
4279 sendoutput << Int_t(kSendOutput);
4280 PDB(kSubmerger, 2)
4281 Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4282
4283 PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4284 if (!fMergers || fMergers->GetSize() <= merger_id) {
4285 Error("RedirectWorker", "#%d not in list ", merger_id);
4286 return;
4287 }
4288 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4289
4290 TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4291 sendoutput << merger_id;
4292 sendoutput << hname;
4293 sendoutput << mi->GetPort();
4294 s->Send(sendoutput);
4295 mi->AddMergedObjects(output_size);
4296 mi->AddWorker(sl);
4297 }
4298}
4299
4300////////////////////////////////////////////////////////////////////////////////
4301/// Return a merger, which is both active and still accepts some workers to be
4302/// assigned to it. It works on the 'round-robin' basis.
4303
4305{
4306 while (fLastAssignedMerger < fMergers->GetSize() &&
4307 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4308 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4310 }
4311
4314 } else {
4315 return fLastAssignedMerger++;
4316 }
4317
4318 while (fLastAssignedMerger < fMergers->GetSize() &&
4319 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4320 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4322 }
4323
4325 return -1;
4326 } else {
4327 return fLastAssignedMerger++;
4328 }
4329}
4330
4331////////////////////////////////////////////////////////////////////////////////
4332/// Master asks for output from worker sl
4333
4335{
4336 TMessage sendoutput(kPROOF_SUBMERGER);
4337 sendoutput << Int_t(kSendOutput);
4338
4339 PDB(kSubmerger, 2) Info("AskForOutput",
4340 "worker %s was asked to send its output to master",
4341 sl->GetOrdinal());
4342
4343 sendoutput << -1;
4344 sendoutput << TString("master");
4345 sendoutput << -1;
4346 sl->GetSocket()->Send(sendoutput);
4348}
4349
4350////////////////////////////////////////////////////////////////////////////////
4351/// Final update of the progress dialog
4352
4354{
4355 if (!fPlayer) return;
4356
4357 // Handle abort ...
4359 if (fSync)
4360 Info("UpdateDialog",
4361 "processing was aborted - %lld events processed",
4363
4364 if (GetRemoteProtocol() > 11) {
4365 // New format
4366 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4367 } else {
4369 }
4370 Emit("StopProcess(Bool_t)", kTRUE);
4371 }
4372
4373 // Handle stop ...
4375 if (fSync)
4376 Info("UpdateDialog",
4377 "processing was stopped - %lld events processed",
4379
4380 if (GetRemoteProtocol() > 25) {
4381 // New format
4382 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4383 } else if (GetRemoteProtocol() > 11) {
4384 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4385 } else {
4387 }
4388 Emit("StopProcess(Bool_t)", kFALSE);
4389 }
4390
4391 // Final update of the dialog box
4392 if (GetRemoteProtocol() > 25) {
4393 // New format
4394 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4395 10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4396 (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4397 } else if (GetRemoteProtocol() > 11) {
4398 // New format
4399 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4400 7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4401 (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4402 } else {
4403 EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4404 }
4405}
4406
4407////////////////////////////////////////////////////////////////////////////////
4408/// Activate the a-sync input handler.
4409
4411{
4412 TIter next(fSlaves);
4413 TSlave *sl;
4414
4415 while ((sl = (TSlave*) next()))
4416 if (sl->GetInputHandler())
4417 sl->GetInputHandler()->Add();
4418}
4419
4420////////////////////////////////////////////////////////////////////////////////
4421/// De-activate a-sync input handler.
4422
4424{
4425 TIter next(fSlaves);
4426 TSlave *sl;
4427
4428 while ((sl = (TSlave*) next()))
4429 if (sl->GetInputHandler())
4430 sl->GetInputHandler()->Remove();
4431}
4432
4433////////////////////////////////////////////////////////////////////////////////
4434/// Get the active mergers count
4435
4437{
4438 if (!fMergers) return 0;
4439
4440 Int_t active_mergers = 0;
4441
4442 TIter mergers(fMergers);
4443 TMergerInfo *mi = 0;
4444 while ((mi = (TMergerInfo *)mergers())) {
4445 if (mi->IsActive()) active_mergers++;
4446 }
4447
4448 return active_mergers;
4449}
4450
4451////////////////////////////////////////////////////////////////////////////////
4452/// Create a new merger
4453
4455{
4456 PDB(kSubmerger, 2)
4457 Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4458
4459 PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4460
4461 if (port <= 0) {
4462 PDB(kSubmerger,2)
4463 Info("CreateMerger", "cannot create merger on port %d - exit", port);
4464 return kFALSE;
4465 }
4466
4467 Int_t workers = -1;
4468 if (!fMergersByHost) {
4469 Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4470 // Number of pure workers, which are not simply divisible by mergers
4471 Int_t rest = fWorkersToMerge % mergersToCreate;
4472 // We add one more worker for each of the first 'rest' mergers being established
4473 if (rest > 0 && fMergers->GetSize() < rest) {
4474 rest = 1;
4475 } else {
4476 rest = 0;
4477 }
4478 workers = (fWorkersToMerge / mergersToCreate) + rest;
4479 } else {
4480 Int_t workersOnHost = 0;
4481 for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4482 if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4483 }
4484 workers = workersOnHost - 1;
4485 }
4486
4487 TString msg;
4488 msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4489
4490 if (gProofServ) {
4492 } else {
4493 Printf("%s",msg.Data());
4494 }
4495 TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4496
4497 TMessage bemerger(kPROOF_SUBMERGER);
4498 bemerger << Int_t(kBeMerger);
4499 bemerger << fMergers->GetSize();
4500 bemerger << workers;
4501 sl->GetSocket()->Send(bemerger);
4502
4503 PDB(kSubmerger,2) Info("CreateMerger",
4504 "merger #%d (port: %d) for %d workers started",
4505 fMergers->GetSize(), port, workers);
4506
4507 fMergers->Add(merger);
4508 fWorkersToMerge = fWorkersToMerge - workers;
4509
4510 fRedirectNext = workers / 2;
4511
4512 PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4513 return kTRUE;
4514}
4515
4516////////////////////////////////////////////////////////////////////////////////
4517/// Add a bad slave server to the bad slave list and remove it from
4518/// the active list and from the two monitor objects. Assume that the work
4519/// done by this worker was lost and ask packerizer to reassign it.
4520
4521void TProof::MarkBad(TSlave *wrk, const char *reason)
4522{
4523 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4524
4525 // We may have been invalidated in the meanwhile: nothing to do in such a case
4526 if (!IsValid()) return;
4527
4528 if (!wrk) {
4529 Error("MarkBad", "worker instance undefined: protocol error? ");
4530 return;
4531 }
4532
4533 // Local URL
4534 static TString thisurl;
4535 if (thisurl.IsNull()) {
4536 if (IsMaster()) {
4537 Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4538 thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4539 if (port > 0) thisurl += TString::Format(":%d", port);
4540 } else {
4541 thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4542 }
4543 }
4544
4545 if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4546 // Message for notification
4547 const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4548 TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4549 TString msg;
4550 msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4551 src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4552 (reason && strlen(reason)) ? reason : "unknown");
4553 Info("MarkBad", "%s", msg.Data());
4554 // Notify one level up, if the case
4555 // Add some hint for diagnostics
4556 if (gProofServ) {
4557 msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4558 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4559 } else {
4560 msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4561 }
4562 msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4563 msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4564 msg += TString::Format(" +++\n");
4565 if (gProofServ) {
4566 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4567 "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4569 } else {
4570 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4571 "Display(\"*\")\n\n", thisurl.Data());
4572 Printf("%s", msg.Data());
4573 }
4574 } else if (reason) {
4575 if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4576 Info("MarkBad", "worker %s at %s:%d asked to terminate",
4577 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4578 }
4579 }
4580
4581 if (IsMaster() && reason) {
4582 if (strcmp(reason, kPROOF_TerminateWorker)) {
4583 // if the reason was not a planned termination
4584 TList *listOfMissingFiles = 0;
4585 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4586 listOfMissingFiles = new TList();
4587 listOfMissingFiles->SetName("MissingFiles");
4588 if (fPlayer)
4589 fPlayer->AddOutputObject(listOfMissingFiles);
4590 }
4591 // If a query is being processed, assume that the work done by
4592 // the worker was lost and needs to be reassigned.
4593 TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4594 if (packetizer) {
4595 // the worker was lost so do resubmit the packets
4596 packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4597 }
4598 } else {
4599 // Tell the coordinator that we are gone
4600 if (gProofServ) {
4601 TString ord(wrk->GetOrdinal());
4602 Int_t id = ord.Last('.');
4603 if (id != kNPOS) ord.Remove(0, id+1);
4605 }
4606 }
4607 } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4608 // We are invalid after this
4609 fValid = kFALSE;
4610 }
4611
4612 fActiveSlaves->Remove(wrk);
4614
4615 fAllMonitor->Remove(wrk->GetSocket());
4617
4619
4620 if (IsMaster()) {
4621 if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4622 // if the reason was a planned termination then delete the worker and
4623 // remove it from all the lists
4624 fSlaves->Remove(wrk);
4625 fBadSlaves->Remove(wrk);
4626 fActiveSlaves->Remove(wrk);
4627 fInactiveSlaves->Remove(wrk);
4628 fUniqueSlaves->Remove(wrk);
4631
4632 // we add it to the list of terminated slave infos instead, so that it
4633 // stays available in the .workers persistent file
4634 TSlaveInfo *si = new TSlaveInfo(
4635 wrk->GetOrdinal(),
4636 Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4637 0, "", wrk->GetWorkDir());
4639 else delete si;
4640
4641 delete wrk;
4642 } else {
4643 fBadSlaves->Add(wrk);
4644 fActiveSlaves->Remove(wrk);
4645 fUniqueSlaves->Remove(wrk);
4649 wrk->Close();
4650 // Update the mergers count, if needed
4651 if (fMergersSet) {
4652 Int_t mergersCount = -1;
4653 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4654 if (mc) mergersCount = mc->GetVal(); // Value set by user
4655 // Mergers count is set dynamically: recalculate it
4656 if (mergersCount == 0) {
4658 if (activeWorkers > 1) {
4659 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4660 if (activeWorkers / fMergersCount < 2)
4661 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4662 }
4663 }
4664 }
4665 }
4666
4667 // Update session workers files
4669 } else {
4670 // On clients the proof session should be removed from the lists
4671 // and deleted, since it is not valid anymore
4672 fSlaves->Remove(wrk);
4673 if (fManager)
4674 fManager->DiscardSession(this);
4675 }
4676}
4677
4678////////////////////////////////////////////////////////////////////////////////
4679/// Add slave with socket s to the bad slave list and remove if from
4680/// the active list and from the two monitor objects.
4681
4682void TProof::MarkBad(TSocket *s, const char *reason)
4683{
4684 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4685
4686 // We may have been invalidated in the meanwhile: nothing to do in such a case
4687 if (!IsValid()) return;
4688
4689 TSlave *wrk = FindSlave(s);
4690 MarkBad(wrk, reason);
4691}
4692
4693////////////////////////////////////////////////////////////////////////////////
4694/// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4695
4697{
4698 if (!wrk) {
4699 Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4700 return;
4701 }
4702
4703 // Send stop message
4704 if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4705 TMessage mess(kPROOF_STOP);
4706 wrk->GetSocket()->Send(mess);
4707 } else {
4708 if (gDebug > 0)
4709 Info("TerminateWorker", "connection to worker is already down: cannot"
4710 " send termination message");
4711 }
4712
4713 // This is a bad worker from now on
4715}
4716
4717////////////////////////////////////////////////////////////////////////////////
4718/// Ask an active worker 'ord' to terminate, i.e. to shutdown
4719
4720void TProof::TerminateWorker(const char *ord)
4721{
4722 if (ord && strlen(ord) > 0) {
4723 Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4724 if (IsMaster()) {
4725 TIter nxw(fSlaves);
4726 TSlave *wrk = 0;
4727 while ((wrk = (TSlave *)nxw())) {
4728 if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4729 TerminateWorker(wrk);
4730 if (!all) break;
4731 }
4732 }
4733 } else {
4734 TMessage mess(kPROOF_STOP);
4735 mess << TString(ord);
4736 Broadcast(mess);
4737 }
4738 }
4739}
4740
4741////////////////////////////////////////////////////////////////////////////////
4742/// Ping PROOF. Returns 1 if master server responded.
4743
4745{
4746 return Ping(kActive);
4747}
4748
4749////////////////////////////////////////////////////////////////////////////////
4750/// Ping PROOF slaves. Returns the number of slaves that responded.
4751
4753{
4754 TList *slaves = 0;
4755 if (list == kAll) slaves = fSlaves;
4756 if (list == kActive) slaves = fActiveSlaves;
4757 if (list == kUnique) slaves = fUniqueSlaves;
4758 if (list == kAllUnique) slaves = fAllUniqueSlaves;
4759
4760 if (slaves->GetSize() == 0) return 0;
4761
4762 int nsent = 0;
4763 TIter next(slaves);
4764
4765 TSlave *sl;
4766 while ((sl = (TSlave *)next())) {
4767 if (sl->IsValid()) {
4768 if (sl->Ping() == -1) {
4769 MarkBad(sl, "ping unsuccessful");
4770 } else {
4771 nsent++;
4772 }
4773 }
4774 }
4775
4776 return nsent;
4777}
4778
4779////////////////////////////////////////////////////////////////////////////////
4780/// Ping PROOF slaves. Returns the number of slaves that responded.
4781
4783{
4784 TList *slaves = fSlaves;
4785
4786 if (slaves->GetSize() == 0) return;
4787
4788 TIter next(slaves);
4789
4790 TSlave *sl;
4791 while ((sl = (TSlave *)next())) {
4792 if (sl->IsValid()) {
4793 sl->Touch();
4794 }
4795 }
4796
4797 return;
4798}
4799
4800////////////////////////////////////////////////////////////////////////////////
4801/// Print status of PROOF cluster.
4802
4803void TProof::Print(Option_t *option) const
4804{
4805 TString secCont;
4806
4808 Printf("Connected to: %s (%s)", GetMaster(),
4809 IsValid() ? "valid" : "invalid");
4810 Printf("Port number: %d", GetPort());
4811 Printf("User: %s", GetUser());
4812 Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4813 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4815 TSlave *sl = (TSlave *)fActiveSlaves->First();
4816 if (sl) {
4817 TString sc;
4818 if (sl->GetSocket()->GetSecContext())
4819 Printf("Security context: %s",
4820 sl->GetSocket()->GetSecContext()->AsString(sc));
4821 Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4822 } else {
4823 Printf("Security context: Error - No connection");
4824 Printf("Proofd protocol version: Error - No connection");
4825 }
4826 Printf("Client protocol version: %d", GetClientProtocol());
4827 Printf("Remote protocol version: %d", GetRemoteProtocol());
4828 Printf("Log level: %d", GetLogLevel());
4829 Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4830 Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4831 if (IsValid())
4832 const_cast<TProof*>(this)->SendPrint(option);
4833 } else {
4834 const_cast<TProof*>(this)->AskStatistics();
4835 if (IsParallel())
4836 Printf("*** Master server %s (parallel mode, %d workers):",
4838 else
4839 Printf("*** Master server %s (sequential mode):",
4841
4842 Printf("Master host name: %s", gSystem->HostName());
4843 Printf("Port number: %d", GetPort());
4844 if (strlen(gProofServ->GetGroup()) > 0) {
4845 Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4846 } else {
4847 Printf("User: %s", GetUser());
4848 }
4849 TString ver;
4850 ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4851 if (gSystem->Getenv("ROOTVERSIONTAG"))
4852 ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4853 Printf("ROOT version|rev|tag: %s", ver.Data());
4854 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4856 Printf("Protocol version: %d", GetClientProtocol());
4857 Printf("Image name: %s", GetImage());
4858 Printf("Working directory: %s", gSystem->WorkingDirectory());
4859 Printf("Config directory: %s", GetConfDir());
4860 Printf("Config file: %s", GetConfFile());
4861 Printf("Log level: %d", GetLogLevel());
4862 Printf("Number of workers: %d", GetNumberOfSlaves());
4863 Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4864 Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4865 Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4866 Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4867 Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4868 Printf("Total real time used (s): %.3f", GetRealTime());
4869 Printf("Total CPU time used (s): %.3f", GetCpuTime());
4870 if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4871 Printf("List of workers:");
4872 TList masters;
4873 TIter nextslave(fSlaves);
4874 while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4875 if (!sl->IsValid()) continue;
4876
4877 if (sl->GetSlaveType() == TSlave::kSlave) {
4878 sl->Print(option);
4879 } else if (sl->GetSlaveType() == TSlave::kMaster) {
4880 TMessage mess(kPROOF_PRINT);
4881 mess.WriteString(option);
4882 if (sl->GetSocket()->Send(mess) == -1)
4883 const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4884 else
4885 masters.Add(sl);
4886 } else {
4887 Error("Print", "TSlave is neither Master nor Worker");
4888 R__ASSERT(0);
4889 }
4890 }
4891 const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4892 }
4893 }
4894}
4895
4896////////////////////////////////////////////////////////////////////////////////
4897/// Extract from opt information about output handling settings.
4898/// The understood keywords are:
4899/// of=<file>, outfile=<file> output file location
4900/// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4901/// mutually exclusive,execution stops
4902/// if both are found)
4903/// sft[=<opt>], savetofile[=<opt>] control saving to file
4904///
4905/// For 'mvf', the <opt> integer has the following meaning:
4906/// <opt> = <how>*10 + <force>
4907/// <force> = 0 save to file if memory threshold is reached
4908/// (the memory threshold is set by the cluster
4909/// admin); in case an output file is defined, the
4910/// files are merged at the end;
4911/// 1 save results to file.
4912/// <how> = 0 save at the end of the query
4913/// 1 save results after each packet (to reduce the
4914/// loss in case of crash).
4915///
4916/// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4917/// to save results after each packet.
4918///
4919/// The separator from the next option is either a ' ' or a ';'
4920///
4921/// All recognized settings are removed from the input string opt.
4922/// If action == 0, set up the output file accordingly, if action == 1 clean related
4923/// output file settings.
4924/// If the final target file is local then 'target' is set to the final local path
4925/// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4926///
4927/// Output file settings are in the form
4928///
4929/// <previous_option>of=name <next_option>
4930/// <previous_option>outfile=name,...;<next_option>
4931///
4932/// The separator from the next option is either a ' ' or a ';'
4933/// Called interanally by TProof::Process.
4934///
4935/// Returns 0 on success, -1 on error.
4936
4938{
4939 TString outfile, dsname, stfopt;
4940 if (action == 0) {
4941 TString tagf, tagd, tags, oo;
4942 Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4943 while (opt.Tokenize(oo, from, "[; ]")) {
4944 if (oo.BeginsWith("of=")) {
4945 tagf = "of=";
4946 iof = opt.Index(tagf);
4947 } else if (oo.BeginsWith("outfile=")) {
4948 tagf = "outfile=";
4949 iof = opt.Index(tagf);
4950 } else if (oo.BeginsWith("ds")) {
4951 tagd = "ds";
4952 iod = opt.Index(tagd);
4953 } else if (oo.BeginsWith("dataset")) {
4954 tagd = "dataset";
4955 iod = opt.Index(tagd);
4956 } else if (oo.BeginsWith("stf")) {
4957 tags = "stf";
4958 ios = opt.Index(tags);
4959 } else if (oo.BeginsWith("savetofile")) {
4960 tags = "savetofile";
4961 ios = opt.Index(tags);
4962 }
4963 }
4964 // Check consistency
4965 if (iof != kNPOS && iod != kNPOS) {
4966 Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4967 return -1;
4968 }
4969
4970 // Check output file first
4971 if (iof != kNPOS) {
4972 from = iof + tagf.Length();
4973 if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4974 Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4975 return -1;
4976 }
4977 // For removal from original options string
4978 tagf += outfile;
4979 }
4980 // Check dataset
4981 if (iod != kNPOS) {
4982 from = iod + tagd.Length();
4983 if (!opt.Tokenize(dsname, from, "[; ]"))
4984 if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4985 // For removal from original options string
4986 tagd += dsname;
4987 // The name may be empty or beginning with a '='
4988 if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4989 if (dsname.Contains("|V")) {
4990 target = "ds|V";
4991 dsname.ReplaceAll("|V", "");
4992 }
4993 if (dsname.IsNull()) dsname = "dataset_<qtag>";
4994 }
4995 // Check stf
4996 if (ios != kNPOS) {
4997 from = ios + tags.Length();
4998 if (!opt.Tokenize(stfopt, from, "[; ]"))
4999 if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
5000 // For removal from original options string
5001 tags += stfopt;
5002 // It must be digit
5003 if (!stfopt.IsNull()) {
5004 if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
5005 if (!stfopt.IsNull()) {
5006 if (!stfopt.IsDigit()) {
5007 Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
5008 return -1;
5009 }
5010 } else {
5011 // Default
5012 stfopt = "1";
5013 }
5014 } else {
5015 // Default
5016 stfopt = "1";
5017 }
5018 }
5019 // Remove from original options string
5020 opt.ReplaceAll(tagf, "");
5021 opt.ReplaceAll(tagd, "");
5022 opt.ReplaceAll(tags, "");
5023 }
5024
5025 // Parse now
5026 if (action == 0) {
5027 // Output file
5028 if (!outfile.IsNull()) {
5029 if (!outfile.BeginsWith("master:")) {
5031 Warning("HandleOutputOptions",
5032 "directory '%s' for the output file does not exists or is not writable:"
5033 " saving to master", gSystem->GetDirName(outfile.Data()).Data());
5034 outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5035 } else {
5036 if (!IsLite()) {
5037 // The target file is local, so we need to retrieve it
5038 target = outfile;
5039 if (!stfopt.IsNull()) {
5040 outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5041 } else {
5042 outfile = "";
5043 }
5044 }
5045 }
5046 }
5047 if (outfile.BeginsWith("master:")) {
5048 outfile.ReplaceAll("master:", "");
5049 if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5050 // Get the master data dir
5051 TString ddir, emsg;
5052 if (!IsLite()) {
5053 if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5054 TObjString *os = fMacroLog.GetLineWith("const char");
5055 if (os) {
5056 Ssiz_t fst = os->GetString().First('\"');
5057 Ssiz_t lst = os->GetString().Last('\"');
5058 ddir = os->GetString()(fst+1, lst-fst-1);
5059 } else {
5060 emsg = "could not find 'const char *' string in macro log! cannot continue";
5061 }
5062 } else {
5063 emsg = "could not retrieve master data directory info! cannot continue";
5064 }
5065 if (!emsg.IsNull()) {
5066 Error("HandleOutputOptions", "%s", emsg.Data());
5067 return -1;
5068 }
5069 }
5070 if (!ddir.IsNull()) ddir += "/";
5071 if (outfile.IsNull()) {
5072 outfile.Form("%s<file>", ddir.Data());
5073 } else {
5074 outfile.Insert(0, TString::Format("%s", ddir.Data()));
5075 }
5076 }
5077 }
5078 // Set the parameter
5079 if (!outfile.IsNull()) {
5080 if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5081 SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5082 }
5083 }
5084 // Dataset creation
5085 if (!dsname.IsNull()) {
5086 dsname.Insert(0, "ds:");
5087 // Set the parameter
5088 SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5089 // Check the Save-To-File option
5090 if (!stfopt.IsNull()) {
5091 Int_t ostf = (Int_t) stfopt.Atoi();
5092 if (ostf%10 <= 0) {
5093 Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5094 stfopt.Form("%d", ostf+1);
5095 }
5096 } else {
5097 // Minimal setting
5098 stfopt = "1";
5099 }
5100 }
5101 // Save-To-File options
5102 if (!stfopt.IsNull()) {
5103 // Set the parameter
5104 SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5105 }
5106 } else {
5107 // Retrieve the file, if required
5108 if (GetOutputList()) {
5109 if (target == "ds|V") {
5110 // Find the dataset
5111 dsname = "";
5112 TIter nxo(GetOutputList());
5113 TObject *o = 0;
5114 while ((o = nxo())) {
5115 if (o->InheritsFrom(TFileCollection::Class())) {
5116 VerifyDataSet(o->GetName());
5117 dsname = o->GetName();
5118 break;
5119 }
5120 }
5121 if (!dsname.IsNull()) {
5122 TFileCollection *fc = GetDataSet(dsname);
5123 if (fc) {
5124 fc->Print();
5125 } else {
5126 Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5127 }
5128 } else {
5129 Warning("HandleOutputOptions", "dataset not found!");
5130 }
5131 } else {
5132 Bool_t targetcopied = kFALSE;
5133 TProofOutputFile *pf = 0;
5134 if (!target.IsNull())
5136 if (pf) {
5137 // Copy the file
5138 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5139 TUrl(target, kTRUE).GetUrl())) {
5140 if (TFile::Cp(pf->GetOutputFileName(), target)) {
5141 Printf(" Output successfully copied to %s", target.Data());
5142 targetcopied = kTRUE;
5143 } else {
5144 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5145 }
5146 }
5147 }
5148 TFile *fout = 0;
5149 TObject *o = 0;
5150 TIter nxo(GetOutputList());
5151 Bool_t swapcopied = kFALSE;
5152 while ((o = nxo())) {
5153 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5154 if (pof) {
5155 if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5156 if (pof == pf && targetcopied) continue;
5157 // Copy the file
5158 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5159 TUrl(target, kTRUE).GetUrl())) {
5160 if (TFile::Cp(pof->GetOutputFileName(), target)) {
5161 Printf(" Output successfully copied to %s", target.Data());
5162 swapcopied = kTRUE;
5163 } else {
5164 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5165 }
5166 }
5167 } else if (pof->IsRetrieve()) {
5168 // Retrieve this file to the local path indicated in the title
5169 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5170 TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5171 if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5172 Printf(" Output successfully copied to %s", pof->GetTitle());
5173 } else {
5174 Warning("HandleOutputOptions",
5175 "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5176 }
5177 }
5178 }
5179 }
5180 }
5181 if (!target.IsNull() && !swapcopied) {
5182 if (!fout && !pf) {
5183 fout = TFile::Open(target, "RECREATE");
5184 if (!fout || (fout && fout->IsZombie())) {
5185 SafeDelete(fout);
5186 Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5187 }
5188 }
5189 if (fout) {
5190 nxo.Reset();
5191 while ((o = nxo())) {
5192 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5193 if (!pof) {
5194 // Write the object to the open output file
5195 o->Write();
5196 }
5197 }
5198 }
5199 }
5200 // Clean-up
5201 if (fout) {
5202 fout->Close();
5203 SafeDelete(fout);
5204 Printf(" Output saved to %s", target.Data());
5205 }
5206 }
5207 }
5208 // Remove the parameter
5209 DeleteParameters("PROOF_DefaultOutputOption");
5210 // Remove the parameter
5211 DeleteParameters("PROOF_SavePartialResults");
5212 }
5213 // Done
5214 return 0;
5215}
5216
5217////////////////////////////////////////////////////////////////////////////////
5218/// Extract from opt in optfb information about wanted feedback settings.
5219/// Feedback are removed from the input string opt.
5220/// If action == 0, set up feedback accordingly, if action == 1 clean related
5221/// feedback settings (using info in optfb, if available, or reparsing opt).
5222///
5223/// Feedback requirements are in the form
5224///
5225/// <previous_option>fb=name1,name2,name3,... <next_option>
5226/// <previous_option>feedback=name1,name2,name3,...;<next_option>
5227///
5228/// The special name 'stats' triggers feedback about events and packets.
5229/// The separator from the next option is either a ' ' or a ';'.
5230/// Called interanally by TProof::Process.
5231
5232void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5233{
5234 Ssiz_t from = 0;
5235 if (action == 0 || (action == 1 && optfb.IsNull())) {
5236 TString tag("fb=");
5237 Ssiz_t ifb = opt.Index(tag);
5238 if (ifb == kNPOS) {
5239 tag = "feedback=";
5240 ifb = opt.Index(tag);
5241 }
5242 if (ifb == kNPOS) return;
5243 from = ifb + tag.Length();
5244
5245 if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5246 Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5247 return;
5248 }
5249 // Remove from original options string
5250 tag += optfb;
5251 opt.ReplaceAll(tag, "");
5252 }
5253
5254 // Parse now
5255 TString nm, startdraw, stopdraw;
5256 from = 0;
5257 while (optfb.Tokenize(nm, from, ",")) {
5258 // Special name first
5259 if (nm == "stats") {
5260 if (action == 0) {
5261 startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5262 gROOT->ProcessLine(startdraw.Data());
5263 SetParameter("PROOF_StatsHist", "");
5264 AddFeedback("PROOF_EventsHist");
5265 AddFeedback("PROOF_PacketsHist");
5266 AddFeedback("PROOF_ProcPcktHist");
5267 } else {
5268 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5269 " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5270 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5271 gROOT->ProcessLine(stopdraw.Data());
5272 DeleteParameters("PROOF_StatsHist");
5273 RemoveFeedback("PROOF_EventsHist");
5274 RemoveFeedback("PROOF_PacketsHist");
5275 RemoveFeedback("PROOF_ProcPcktHist");
5276 }
5277 } else {
5278 if (action == 0) {
5279 // Enable or
5280 AddFeedback(nm);
5281 startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5282 gROOT->ProcessLine(startdraw.Data());
5283 } else {
5284 // ... or disable
5285 RemoveFeedback(nm);
5286 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5287 " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5288 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5289 gROOT->ProcessLine(stopdraw.Data());
5290 }
5291 }
5292 }
5293}
5294
5295////////////////////////////////////////////////////////////////////////////////
5296/// Process a data set (TDSet) using the specified selector (.C) file or
5297/// Tselector object
5298/// Entry- or event-lists should be set in the data set object using
5299/// TDSet::SetEntryList.
5300/// The return value is -1 in case of error and TSelector::GetStatus() in
5301/// in case of success.
5302
5303Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5305{
5306 if (!IsValid() || !fPlayer) return -1;
5307
5308 // Set PROOF to running state
5310
5311 TString opt(option), optfb, outfile;
5312 // Enable feedback, if required
5313 if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5314 // Define output file, either from 'opt' or the default one
5315 if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5316
5317 // Resolve query mode
5318 fSync = (GetQueryMode(opt) == kSync);
5319
5320 if (fSync && (!IsIdle() || IsWaiting())) {
5321 // Already queued or processing queries: switch to asynchronous mode
5322 Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5323 fSync = kFALSE;
5324 opt.ReplaceAll("SYNC","");
5325 opt += "ASYN";
5326 }
5327
5328 // Cleanup old temporary datasets
5329 if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5332 }
5333
5334 // deactivate the default application interrupt handler
5335 // ctrl-c's will be forwarded to PROOF to stop the processing
5336 TSignalHandler *sh = 0;
5337 if (fSync) {
5338 if (gApplication)
5340 }
5341
5342 // Make sure we get a fresh result
5344
5345 // Make sure that the workers ready list is empty
5346 if (fWrksOutputReady) {
5349 }
5350
5351 // Make sure the selector path is in the macro path
5352 TProof::AssertMacroPath(selector);
5353
5354 // Reset time measurements
5355 fQuerySTW.Reset();
5356
5357 Long64_t rv = -1;
5358 if (selector && strlen(selector)) {
5359 rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5360 } else if (fSelector) {
5361 rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5362 } else {
5363 Error("Process", "neither a selecrot file nor a selector object have"
5364 " been specified: cannot process!");
5365 }
5366
5367 // This is the end of merging
5368 fQuerySTW.Stop();
5369 Float_t rt = fQuerySTW.RealTime();
5370 // Update the query content
5372 if (qr) {
5373 qr->SetTermTime(rt);
5375 }
5376
5377 // Disable feedback, if required
5378 if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5379 // Finalise output file settings (opt is ignored in here)
5380 if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5381
5382 // Retrieve status from the output list
5383 if (rv >= 0) {
5385 (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5386 if (sst) rv = sst->GetVal();
5387 }
5388
5389 if (fSync) {
5390 // reactivate the default application interrupt handler
5391 if (sh)
5393 // Save the performance info, if required
5394 if (!fPerfTree.IsNull()) {
5395 if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5396 // Must be re-enabled each time
5397 SetPerfTree(0);
5398 }
5399 }
5400
5401 return rv;
5402}
5403
5404////////////////////////////////////////////////////////////////////////////////
5405/// Process a data set (TFileCollection) using the specified selector (.C) file
5406/// or TSelector object.
5407/// The default tree is analyzed (i.e. the first one found). To specify another
5408/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5409/// The return value is -1 in case of error and TSelector::GetStatus() in
5410/// in case of success.
5411
5414{
5415 if (!IsValid() || !fPlayer) return -1;
5416
5417 if (fProtocol < 17) {
5418 Info("Process", "server version < 5.18/00:"
5419 " processing of TFileCollection not supported");
5420 return -1;
5421 }
5422
5423 // We include the TFileCollection to the input list and we create a
5424 // fake TDSet with infor about it
5425 TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5427
5428
5429 Long64_t retval = -1;
5430 if (selector && strlen(selector)) {
5431 retval = Process(dset, selector, option, nentries, first);
5432 } else if (fSelector) {
5433 retval = Process(dset, fSelector, option, nentries, first);
5434 } else {
5435 Error("Process", "neither a selecrot file nor a selector object have"
5436 " been specified: cannot process!");
5437 }
5438 fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5439
5440 // Cleanup
5441 if (IsLite() && !fSync) {
5442 if (!fRunningDSets) fRunningDSets = new TList;
5443 fRunningDSets->Add(dset);
5444 } else {
5445 delete dset;
5446 }
5447
5448 return retval;
5449}
5450
5451////////////////////////////////////////////////////////////////////////////////
5452/// Process a dataset which is stored on the master with name 'dsetname'.
5453/// The syntax for dsetname is name[#[dir/]objname], e.g.
5454/// "mydset" analysis of the first tree in the top dir of the dataset
5455/// named "mydset"
5456/// "mydset#T" analysis tree "T" in the top dir of the dataset
5457/// named "mydset"
5458/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5459/// named "mydset"
5460/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5461/// dataset named "mydset"
5462/// The component 'name' in its more general form contains also the group and
5463/// user name following "/<group>/<user>/<dsname>". Each of these components
5464/// can contain one or more wildcards '*', in which case all the datasets matching
5465/// the expression are added together as a global dataset (wildcard support has
5466/// been added in version 5.27/02).
5467/// The last argument 'elist' specifies an entry- or event-list to be used as
5468/// event selection.
5469/// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5470/// at once in a more flexible way that the one provided by wildcarding. There
5471/// are three possibilities:
5472/// 1) specifying the dataset names separated by the OR operator '|', e.g.
5473/// dsetname = "<dset1>|<dset2>|<dset3>|..."
5474/// in this case the datasets are a seen as a global unique dataset
5475/// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5476/// dsetname = "<dset1>,<dset2> <dset3>,..."
5477/// in this case the datasets are processed one after the other and the
5478/// selector is notified when switching dataset via a bit in the current
5479/// processed element.
5480/// 3) giving the path of a textfile where the dataset names are specified
5481/// on one or multiple lines; the lines found are joined as in 1), unless
5482/// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5483/// with the dataset names listed in 'datasets.txt') in which case they are
5484/// treated as in 2); the file is open in raw mode with TFile::Open and
5485/// therefore it cane be remote, e.g. on a Web server.
5486/// Each <dsetj> has the format specified above for the single dataset processing,
5487/// included wildcarding (the name of the tree and subdirectory must be same for
5488/// all the datasets).
5489/// In the case of multiple datasets, 'elist' is treated a global entry list.
5490/// It is possible to specify per-dataset entry lists using the syntax
5491/// "mydset[#adir/[T]]?enl=entrylist"
5492/// or
5493/// "mydset[#adir/[T]]<<entrylist"
5494/// Here 'entrylist' is a tag identifying, in the order :
5495/// i. a named entry-list in the input list or in the input data list
5496/// ii. a named entry-list in memory (in gDirectory)
5497/// iii. the path of a file containing the entry-list to be used
5498/// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5499/// data list.
5500/// The return value is -1 in case of error and TSelector::GetStatus() in
5501/// in case of success.
5502
5503Long64_t TProof::Process(const char *dsetname, const char *selector,
5504 Option_t *option, Long64_t nentries,
5505 Long64_t first, TObject *elist)
5506{
5507 if (fProtocol < 13) {
5508 Info("Process", "processing 'by name' not supported by the server");
5509 return -1;
5510 }
5511
5512 TString dsname, fname(dsetname);
5513 // If the 'dsetname' corresponds to an existing and readable file we will try to
5514 // interpretate its content as names of datasets to be processed. One line can contain
5515 // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5516 // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5517 // joined with ','.
5518 const char *separator = (fname.EndsWith(",")) ? "," : "|";
5519 if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5520 if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5521 TUrl uf(fname, kTRUE);
5522 uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5523 TFile *f = TFile::Open(uf.GetUrl());
5524 if (f && !(f->IsZombie())) {
5525 const Int_t blen = 8192;
5526 char buf[blen];
5527 Long64_t rest = f->GetSize();
5528 while (rest > 0) {
5529 Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5530 if (f->ReadBuffer(buf, len)) {
5531 Error("Process", "problems reading from file '%s'", fname.Data());
5532 dsname = "";
5533 break;
5534 }
5535 buf[len] = '\0';
5536 dsname += buf;
5537 rest -= len;
5538 }
5539 f->Close();
5540 SafeDelete(f);
5541 // We fail if a failure occured
5542 if (rest > 0) return -1;
5543 } else {
5544 Error("Process", "could not open file '%s'", fname.Data());
5545 return -1;
5546 }
5547 }
5548 if (dsname.IsNull()) {
5549 dsname = dsetname;
5550 } else {
5551 // Remove trailing '\n'
5552 if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5553 // Replace all '\n' with the proper separator
5554 dsname.ReplaceAll("\n", separator);
5555 if (gDebug > 0) {
5556 Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5557 Info("Process", " '%s'", dsname.Data());
5558 }
5559 }
5560
5561 TString names(dsname), name, enl, newname;
5562 // If multi-dataset check if server supports it
5563 if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5564 Info("Process", "multi-dataset processing not supported by the server");
5565 return -1;
5566 }
5567
5568 TEntryList *el = 0;
5569 TString dsobj, dsdir;
5570 Int_t from = 0;
5571 while (names.Tokenize(name, from, "[, |]")) {
5572
5573 newname = name;
5574 // Extract the specific entry-list, if any
5575 enl = "";
5576 Int_t ienl = name.Index("?enl=");
5577 if (ienl == kNPOS) {
5578 ienl = name.Index("<<");
5579 if (ienl != kNPOS) {
5580 newname.Remove(ienl);
5581 ienl += strlen("<<");
5582 }
5583 } else {
5584 newname.Remove(ienl);
5585 ienl += strlen("?enl=");
5586 }
5587
5588 // Check the name syntax first
5589 TString obj, dir("/");
5590 Int_t idxc = newname.Index("#");
5591 if (idxc != kNPOS) {
5592 Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5593 if (idxs != kNPOS) {
5594 obj = newname(idxs+1, newname.Length());
5595 dir = newname(idxc+1, newname.Length());
5596 dir.Remove(dir.Index("/") + 1);
5597 newname.Remove(idxc);
5598 } else {
5599 obj = newname(idxc+1, newname.Length());
5600 newname.Remove(idxc);
5601 }
5602 } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5603 // protection against using ':' instead of '#'
5604 Error("Process", "bad name syntax (%s): please use"
5605 " a '#' after the dataset name", name.Data());
5606 dsname.ReplaceAll(name, "");
5607 continue;
5608 }
5609 if (dsobj.IsNull() && dsdir.IsNull()) {
5610 // The first one specifies obj and dir
5611 dsobj = obj;
5612 dsdir = dir;
5613 } else if (obj != dsobj || dir != dsdir) {
5614 // Inconsistent specification: not supported
5615 Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5616 }
5617 // Process the entry-list name, if any
5618 if (ienl != kNPOS) {
5619 // Get entrylist name or path
5620 enl = name(ienl, name.Length());
5621 el = 0;
5622 TObject *oel = 0;
5623 // If not in the input list ...
5624 TList *inpl = GetInputList();
5625 if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5626 // ... check the heap
5627 if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5628 if ((el = dynamic_cast<TEntryList *>(oel))) {
5629 // Add to the input list (input data not available on master where
5630 // this info will be processed)
5631 if (fProtocol >= 28)
5632 if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5633 }
5634 }
5635 // If not in the heap, check a file, if any
5636 if (!el) {
5637 if (!gSystem->AccessPathName(enl)) {
5638 TFile *f = TFile::Open(enl);
5639 if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5640 TIter nxk(f->GetListOfKeys());
5641 TKey *k = 0;
5642 while ((k = (TKey *) nxk())) {
5643 if (!strcmp(k->GetClassName(), "TEntryList")) {
5644 if (!el) {
5645 if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5646 // Add to the input list (input data not available on master where
5647 // this info will be processed)
5648 if (fProtocol >= 28) {
5649 if (!(inpl->FindObject(el->GetName()))) {
5650 el = (TEntryList *) el->Clone();
5651 AddInput(el);
5652 }
5653 } else {
5654 el = (TEntryList *) el->Clone();
5655 }
5656 }
5657 } else if (strcmp(el->GetName(), k->GetName())) {
5658 Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5659 "if this is not what you want, load first the content in memory"
5660 "and select it by name ", enl.Data());
5661 }
5662 }
5663 }
5664 } else {
5665 Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5666 }
5667 }
5668 }
5669 // Transmit the information
5670 if (fProtocol >= 28) {
5671 newname += "?enl=";
5672 if (el) {
5673 // An entry list object is avalaible in the input list: add its name
5674 newname += el->GetName();
5675 } else {
5676 // The entry list object was not found: send the name, the future entry list manager will
5677 // find it on the server side
5678 newname += enl;
5679 }
5680 }
5681 }
5682 // Adjust the name for this dataset
5683 dsname.ReplaceAll(name, newname);
5684 }
5685
5686 // Create the dataset object
5687 TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5688 // Set entry list
5689 if (el && fProtocol < 28) {
5690 dset->SetEntryList(el);
5691 } else {
5692 dset->SetEntryList(elist);
5693 }
5694 // Run
5695 Long64_t retval = -1;
5696 if (selector && strlen(selector)) {
5697 retval = Process(dset, selector, option, nentries, first);
5698 } else if (fSelector) {
5699 retval = Process(dset, fSelector, option, nentries, first);
5700 } else {
5701 Error("Process", "neither a selector file nor a selector object have"
5702 " been specified: cannot process!");
5703 }
5704 // Cleanup
5705 if (IsLite() && !fSync) {
5706 if (!fRunningDSets) fRunningDSets = new TList;
5707 fRunningDSets->Add(dset);
5708 } else {
5709 delete dset;
5710 }
5711
5712 return retval;
5713}
5714
5715////////////////////////////////////////////////////////////////////////////////
5716/// Generic (non-data based) selector processing: the Process() method of the
5717/// specified selector (.C) or TSelector object is called 'n' times.
5718/// The return value is -1 in case of error and TSelector::GetStatus() in
5719/// in case of success.
5720
5721Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5722{
5723 if (!IsValid()) return -1;
5724
5725 if (fProtocol < 16) {
5726 Info("Process", "server version < 5.17/04: generic processing not supported");
5727 return -1;
5728 }
5729
5730 // Fake data set
5731 TDSet *dset = new TDSet;
5732 dset->SetBit(TDSet::kEmpty);
5733
5734 Long64_t retval = -1;
5735 if (selector && strlen(selector)) {
5736 retval = Process(dset, selector, option, n);
5737 } else if (fSelector) {
5738 retval = Process(dset, fSelector, option, n);
5739 } else {
5740 Error("Process", "neither a selector file nor a selector object have"
5741 " been specified: cannot process!");
5742 }
5743
5744 // Cleanup
5745 if (IsLite() && !fSync) {
5746 if (!fRunningDSets) fRunningDSets = new TList;
5747 fRunningDSets->Add(dset);
5748 } else {
5749 delete dset;
5750 }
5751 return retval;
5752}
5753
5754////////////////////////////////////////////////////////////////////////////////
5755/// Process a data set (TDSet) using the specified selector object.
5756/// Entry- or event-lists should be set in the data set object using
5757/// TDSet::SetEntryList.
5758/// The return value is -1 in case of error and TSelector::GetStatus() in
5759/// in case of success.
5760
5763{
5764 if (fProtocol < 34) {
5765 Error("Process", "server version < 5.33/02:"
5766 "processing by object not supported");
5767 return -1;
5768 }
5769 if (!selector) {
5770 Error("Process", "selector object undefined!");
5771 return -1;
5772 }
5773 fSelector = selector;
5774 Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5775 fSelector = 0;
5776 // Done
5777 return rc;
5778}
5779
5780////////////////////////////////////////////////////////////////////////////////
5781/// Process a data set (TFileCollection) using the specified selector object
5782/// The default tree is analyzed (i.e. the first one found). To specify another
5783/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5784/// The return value is -1 in case of error and TSelector::GetStatus() in
5785/// in case of success.
5786
5789{
5790 if (fProtocol < 34) {
5791 Error("Process", "server version < 5.33/02:"
5792 "processing by object not supported");
5793 return -1;
5794 }
5795 if (!selector) {
5796 Error("Process", "selector object undefined!");
5797 return -1;
5798 }
5799 fSelector = selector;
5800 Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5801 fSelector = 0;
5802 // Done
5803 return rc;
5804}
5805
5806////////////////////////////////////////////////////////////////////////////////
5807/// Process with name of dataset and TSelector object
5808
5809Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5810 Option_t *option, Long64_t nentries,
5811 Long64_t first, TObject *elist)
5812{
5813 if (fProtocol < 34) {
5814 Error("Process", "server version < 5.33/02:"
5815 "processing by object not supported");
5816 return -1;
5817 }
5818 if (!selector) {
5819 Error("Process", "selector object undefined!");
5820 return -1;
5821 }
5822 fSelector = selector;
5823 Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5824 fSelector = 0;
5825 // Done
5826 return rc;
5827}
5828
5829////////////////////////////////////////////////////////////////////////////////
5830/// Generic (non-data based) selector processing: the Process() method of the
5831/// specified selector is called 'n' times.
5832/// The return value is -1 in case of error and TSelector::GetStatus() in
5833/// in case of success.
5834
5836{
5837 if (fProtocol < 34) {
5838 Error("Process", "server version < 5.33/02:"
5839 "processing by object not supported");
5840 return -1;
5841 }
5842 if (!selector) {
5843 Error("Process", "selector object undefined!");
5844 return -1;
5845 }
5846 fSelector = selector;
5847 Long64_t rc = Process((const char*)0, n, option);
5848 fSelector = 0;
5849 // Done
5850 return rc;
5851}
5852
5853////////////////////////////////////////////////////////////////////////////////
5854/// Get reference for the qry-th query in fQueries (as
5855/// displayed by ShowQueries).
5856
5858{
5859 ref = "";
5860 if (qry > 0) {
5861 if (!fQueries)
5863 if (fQueries) {
5864 TIter nxq(fQueries);
5865 TQueryResult *qr = 0;
5866 while ((qr = (TQueryResult *) nxq()))
5867 if (qr->GetSeqNum() == qry) {
5868 ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5869 return 0;
5870 }
5871 }
5872 }
5873 return -1;
5874}
5875
5876////////////////////////////////////////////////////////////////////////////////
5877/// Finalize the qry-th query in fQueries.
5878/// If force, force retrieval if the query is found in the local list
5879/// but has already been finalized (default kFALSE).
5880/// If query < 0, finalize current query.
5881/// Return 0 on success, -1 on error
5882
5884{
5885 if (fPlayer) {
5886 if (qry > 0) {
5887 TString ref;
5888 if (GetQueryReference(qry, ref) == 0) {
5889 return Finalize(ref, force);
5890 } else {
5891 Info("Finalize", "query #%d not found", qry);
5892 }
5893 } else {
5894 // The last query
5895 return Finalize("", force);
5896 }
5897 }
5898 return -1;
5899}
5900
5901////////////////////////////////////////////////////////////////////////////////
5902/// Finalize query with reference ref.
5903/// If force, force retrieval if the query is found in the local list
5904/// but has already been finalized (default kFALSE).
5905/// If ref = 0, finalize current query.
5906/// Return 0 on success, -1 on error
5907
5908Long64_t TProof::Finalize(const char *ref, Bool_t force)
5909{
5910 if (fPlayer) {
5911 // Get the pointer to the query
5912 TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5913 : GetQueryResult();
5915 TString xref(ref);
5916 if (!qr) {
5917 if (!xref.IsNull()) {
5918 retrieve = kTRUE;
5919 }
5920 } else {
5921 if (qr->IsFinalized()) {
5922 if (force) {
5923 retrieve = kTRUE;
5924 } else {
5925 Info("Finalize","query already finalized:"
5926 " use Finalize(<qry>,kTRUE) to force new retrieval");
5927 qr = 0;
5928 }
5929 } else {
5930 retrieve = kTRUE;
5931 xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5932 }
5933 }
5934 if (retrieve) {
5935 Retrieve(xref.Data());
5936 qr = fPlayer->GetQueryResult(xref.Data());
5937 }
5938 if (qr)
5939 return fPlayer->Finalize(qr);
5940 }
5941 return -1;
5942}
5943
5944////////////////////////////////////////////////////////////////////////////////
5945/// Send retrieve request for the qry-th query in fQueries.
5946/// If path is defined save it to path.
5947
5948Int_t TProof::Retrieve(Int_t qry, const char *path)
5949{
5950 if (qry > 0) {
5951 TString ref;
5952 if (GetQueryReference(qry, ref) == 0)
5953 return Retrieve(ref, path);
5954 else
5955 Info("Retrieve", "query #%d not found", qry);
5956 } else {
5957 Info("Retrieve","positive argument required - do nothing");
5958 }
5959 return -1;
5960}
5961
5962////////////////////////////////////////////////////////////////////////////////
5963/// Send retrieve request for the query specified by ref.
5964/// If path is defined save it to path.
5965/// Generic method working for all queries known by the server.
5966
5967Int_t TProof::Retrieve(const char *ref, const char *path)
5968{
5969 if (ref) {
5971 m << TString(ref);
5974
5975 // Archive it locally, if required
5976 if (path) {
5977
5978 // Get pointer to query
5979 TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5980
5981 if (qr) {
5982
5983 TFile *farc = TFile::Open(path,"UPDATE");
5984 if (!farc || (farc && !(farc->IsOpen()))) {
5985 Info("Retrieve", "archive file cannot be open (%s)", path);
5986 return 0;
5987 }
5988 farc->cd();
5989
5990 // Update query status
5991 qr->SetArchived(path);
5992
5993 // Write to file
5994 qr->Write();
5995
5996 farc->Close();
5997 SafeDelete(farc);
5998
5999 } else {
6000 Info("Retrieve", "query not found after retrieve");
6001 return -1;
6002 }
6003 }
6004
6005 return 0;
6006 }
6007 return -1;
6008}
6009
6010////////////////////////////////////////////////////////////////////////////////
6011/// Send remove request for the qry-th query in fQueries.
6012
6014{
6015 if (qry > 0) {
6016 TString ref;
6017 if (GetQueryReference(qry, ref) == 0)
6018 return Remove(ref, all);
6019 else
6020 Info("Remove", "query #%d not found", qry);
6021 } else {
6022 Info("Remove","positive argument required - do nothing");
6023 }
6024 return -1;
6025}
6026
6027////////////////////////////////////////////////////////////////////////////////
6028/// Send remove request for the query specified by ref.
6029/// If all = TRUE remove also local copies of the query, if any.
6030/// Generic method working for all queries known by the server.
6031/// This method can be also used to reset the list of queries
6032/// waiting to be processed: for that purpose use ref == "cleanupqueue".
6033
6034Int_t TProof::Remove(const char *ref, Bool_t all)
6035{
6036 if (all) {
6037 // Remove also local copies, if any
6038 if (fPlayer)
6040 }
6041
6042 if (IsLite()) return 0;
6043
6044 if (ref) {
6046 m << TString(ref);
6049 return 0;
6050 }
6051 return -1;
6052}
6053
6054////////////////////////////////////////////////////////////////////////////////
6055/// Send archive request for the qry-th query in fQueries.
6056
6057Int_t TProof::Archive(Int_t qry, const char *path)
6058{
6059 if (qry > 0) {
6060 TString ref;
6061 if (GetQueryReference(qry, ref) == 0)
6062 return Archive(ref, path);
6063 else
6064 Info("Archive", "query #%d not found", qry);
6065 } else {
6066 Info("Archive","positive argument required - do nothing");
6067 }
6068 return -1;
6069}
6070
6071////////////////////////////////////////////////////////////////////////////////
6072/// Send archive request for the query specified by ref.
6073/// Generic method working for all queries known by the server.
6074/// If ref == "Default", path is understood as a default path for
6075/// archiving.
6076
6077Int_t TProof::Archive(const char *ref, const char *path)
6078{
6079 if (ref) {
6081 m << TString(ref) << TString(path);
6084 return 0;
6085 }
6086 return -1;
6087}
6088
6089////////////////////////////////////////////////////////////////////////////////
6090/// Send cleanup request for the session specified by tag.
6091
6092Int_t TProof::CleanupSession(const char *sessiontag)
6093{
6094 if (sessiontag) {
6096 m << TString(sessiontag);
6099 return 0;
6100 }
6101 return -1;
6102}
6103
6104////////////////////////////////////////////////////////////////////////////////
6105/// Change query running mode to the one specified by 'mode'.
6106
6108{
6109 fQueryMode = mode;
6110
6111 if (gDebug > 0)
6112 Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6113 "Sync" : "Async");
6114}
6115
6116////////////////////////////////////////////////////////////////////////////////
6117/// Find out the query mode based on the current setting and 'mode'.
6118
6120{
6121 EQueryMode qmode = fQueryMode;
6122
6123 if (mode && (strlen(mode) > 0)) {
6124 TString m(mode);
6125 m.ToUpper();
6126 if (m.Contains("ASYN")) {
6127 qmode = kAsync;
6128 } else if (m.Contains("SYNC")) {
6129 qmode = kSync;
6130 }
6131 }
6132
6133 if (gDebug > 0)
6134 Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6135 "Sync" : "Async");
6136
6137 return qmode;
6138}
6139
6140////////////////////////////////////////////////////////////////////////////////
6141/// Execute the specified drawing action on a data set (TDSet).
6142/// Event- or Entry-lists should be set in the data set object using
6143/// TDSet::SetEntryList.
6144/// Returns -1 in case of error or number of selected events otherwise.
6145
6146Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6147 const char *selection, Option_t *option,
6149{
6150 if (!IsValid() || !fPlayer) return -1;
6151
6152 // Make sure that asynchronous processing is not active
6153 if (!IsIdle()) {
6154 Info("DrawSelect","not idle, asynchronous Draw not supported");
6155 return -1;
6156 }
6157 TString opt(option);
6158 Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6159 if (idx != kNPOS)
6160 opt.Replace(idx,4,"");
6161
6162 return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6163}
6164
6165////////////////////////////////////////////////////////////////////////////////
6166/// Execute the specified drawing action on a data set which is stored on the
6167/// master with name 'dsetname'.
6168/// The syntax for dsetname is name[#[dir/]objname], e.g.
6169/// "mydset" analysis of the first tree in the top dir of the dataset
6170/// named "mydset"
6171/// "mydset#T" analysis tree "T" in the top dir of the dataset
6172/// named "mydset"
6173/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6174/// named "mydset"
6175/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6176/// dataset named "mydset"
6177/// The last argument 'enl' specifies an entry- or event-list to be used as
6178/// event selection.
6179/// The return value is -1 in case of error and TSelector::GetStatus() in
6180/// in case of success.
6181
6182Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6183 const char *selection, Option_t *option,
6185{
6186 if (fProtocol < 13) {
6187 Info("Process", "processing 'by name' not supported by the server");
6188 return -1;
6189 }
6190
6191 TString name(dsetname);
6192 TString obj;
6193 TString dir = "/";
6194 Int_t idxc = name.Index("#");
6195 if (idxc != kNPOS) {
6196 Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6197 if (idxs != kNPOS) {
6198 obj = name(idxs+1, name.Length());
6199 dir = name(idxc+1, name.Length());
6200 dir.Remove(dir.Index("/") + 1);
6201 name.Remove(idxc);
6202 } else {
6203 obj = name(idxc+1, name.Length());
6204 name.Remove(idxc);
6205 }
6206 } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6207 // protection against using ':' instead of '#'
6208 Error("DrawSelect", "bad name syntax (%s): please use"
6209 " a '#' after the dataset name", dsetname);
6210 return -1;
6211 }
6212
6213 TDSet *dset = new TDSet(name, obj, dir);
6214 // Set entry-list, if required
6215 dset->SetEntryList(enl);
6216 Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6217 delete dset;
6218 return retval;
6219}
6220
6221////////////////////////////////////////////////////////////////////////////////
6222/// Send STOPPROCESS message to master and workers.
6223
6225{
6226 PDB(kGlobal,2)
6227 Info("StopProcess","enter %d", abort);
6228
6229 if (!IsValid())
6230 return;
6231
6232 // Flag that we have been stopped
6234 SetRunStatus(rst);
6235
6236 if (fPlayer)
6237 fPlayer->StopProcess(abort, timeout);
6238
6239 // Stop any blocking 'Collect' request; on masters we do this only if
6240 // aborting; when stopping, we still need to receive the results
6241 if (TestBit(TProof::kIsClient) || abort)
6243
6244 if (fSlaves->GetSize() == 0)
6245 return;
6246
6247 // Notify the remote counterpart
6248 TSlave *sl;
6249 TIter next(fSlaves);
6250 while ((sl = (TSlave *)next()))
6251 if (sl->IsValid())
6252 // Ask slave to progate the stop/abort request
6253 sl->StopProcess(abort, timeout);
6254}
6255
6256////////////////////////////////////////////////////////////////////////////////
6257/// Signal to disable related switches
6258
6260{
6261 Emit("DisableGoAsyn()");
6262}
6263
6264////////////////////////////////////////////////////////////////////////////////
6265/// Send GOASYNC message to the master.
6266
6268{
6269 if (!IsValid()) return;
6270
6271 if (GetRemoteProtocol() < 22) {
6272 Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6273 return;
6274 }
6275
6276 if (fSync && !IsIdle()) {
6278 Broadcast(m);
6279 } else {
6280 Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6281 }
6282}
6283
6284////////////////////////////////////////////////////////////////////////////////
6285/// Receive the log file of the slave with socket s.
6286
6288{
6289 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6290 char buf[kMAXBUF];
6291
6292 // If macro saving is enabled prepare macro
6296 }
6297
6298 // Append messages to active logging unit
6299 Int_t fdout = -1;
6300 if (!fLogToWindowOnly) {
6301 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6302 if (fdout < 0) {
6303 Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6304 " will not log msgs", fdout);
6305 return;
6306 }
6307 lseek(fdout, (off_t) 0, SEEK_END);
6308 }
6309
6310 Int_t left, rec, r;
6311 Long_t filesize = 0;
6312
6313 while (filesize < size) {
6314 left = Int_t(size - filesize);
6315 if (left >= kMAXBUF)
6316 left = kMAXBUF-1;
6317 rec = s->RecvRaw(&buf, left);
6318 filesize = (rec > 0) ? (filesize + rec) : filesize;
6320 if (rec > 0) {
6321
6322 char *p = buf;
6323 r = rec;
6324 while (r) {
6325 Int_t w;
6326
6327 w = write(fdout, p, r);
6328
6329 if (w < 0) {
6330 SysError("RecvLogFile", "error writing to unit: %d", fdout);
6331 break;
6332 }
6333 r -= w;
6334 p += w;
6335 }
6336 } else if (rec < 0) {
6337 Error("RecvLogFile", "error during receiving log file");
6338 break;
6339 }
6340 }
6341 if (rec > 0) {
6342 buf[rec] = 0;
6343 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6344 // If macro saving is enabled add to TMacro
6346 }
6347 }
6348
6349 // If idle restore logs to main session window
6351 fRedirLog = kFALSE;
6352}
6353
6354////////////////////////////////////////////////////////////////////////////////
6355/// Notify locally 'msg' to the appropriate units (file, stdout, window)
6356/// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6357
6358void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6359{
6360 // Must have somenthing to notify
6361 Int_t len = 0;
6362 if (!msg || (len = strlen(msg)) <= 0)
6363 return;
6364
6365 // Get suffix length if any
6366 Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6367
6368 // Append messages to active logging unit
6369 Int_t fdout = -1;
6370 if (!fLogToWindowOnly) {
6371 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6372 if (fdout < 0) {
6373 Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6374 " will not notify msgs", fdout);
6375 return;
6376 }
6377 lseek(fdout, (off_t) 0, SEEK_END);
6378 }
6379
6380 if (!fLogToWindowOnly) {
6381 // Write to output unit (stdout or a log file)
6382 if (len > 0) {
6383 char *p = (char *)msg;
6384 Int_t r = len;
6385 while (r) {
6386 Int_t w = write(fdout, p, r);
6387 if (w < 0) {
6388 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6389 break;
6390 }
6391 r -= w;
6392 p += w;
6393 }
6394 // Add a suffix, if requested
6395 if (lsfx > 0)
6396 if (write(fdout, sfx, lsfx) != lsfx)
6397 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6398 }
6399 }
6400 if (len > 0) {
6401 // Publish the message to the separate window (if the latter is missing
6402 // the message will just get lost)
6403 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6404 }
6405
6406 // If idle restore logs to main session window
6407 if (fRedirLog && IsIdle())
6408 fRedirLog = kFALSE;
6409}
6410
6411////////////////////////////////////////////////////////////////////////////////
6412/// Log a message into the appropriate window by emitting a signal.
6413
6414void TProof::LogMessage(const char *msg, Bool_t all)
6415{
6416 PDB(kGlobal,1)
6417 Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6418 all ? "true" : "false");
6419
6420 if (gROOT->IsBatch()) {
6421 PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6422 return;
6423 }
6424
6425 if (msg)
6426 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6427
6428 // Re-position at the beginning of the file, if requested.
6429 // This is used by the dialog when it re-opens the log window to
6430 // provide all the session messages
6431 if (all)
6432 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6433
6434 const Int_t kMAXBUF = 32768;
6435 char buf[kMAXBUF];
6436 Int_t len;
6437 do {
6438 while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6439 TSystem::GetErrno() == EINTR)
6441
6442 if (len < 0) {
6443 Error("LogMessage", "error reading log file");
6444 break;
6445 }
6446
6447 if (len > 0) {
6448 buf[len] = 0;
6449 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6450 }
6451
6452 } while (len > 0);
6453}
6454
6455////////////////////////////////////////////////////////////////////////////////
6456/// Send to all active slaves servers the current slave group size
6457/// and their unique id. Returns number of active slaves.
6458/// Returns -1 in case of error.
6459
6461{
6462 if (!IsValid()) return -1;
6463 if (TestBit(TProof::kIsClient)) return 0;
6464 if (!fSendGroupView) return 0;
6466
6467 TIter next(fActiveSlaves);
6468 TSlave *sl;
6469
6470 int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6471 char str[32];
6472
6473 while ((sl = (TSlave *)next())) {
6474 snprintf(str, 32, "%d %d", cnt, size);
6475 if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6476 MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6477 bad++;
6478 } else
6479 cnt++;
6480 }
6481
6482 // Send the group view again in case there was a change in the
6483 // group size due to a bad slave
6484
6485 if (bad) SendGroupView();
6486
6487 return GetNumberOfActiveSlaves();
6488}
6489
6490////////////////////////////////////////////////////////////////////////////////
6491/// Static method to extract the filename (if any) form a CINT command.
6492/// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6493/// appliable.
6494
6496{
6497 TString s = cmd;
6498 s = s.Strip(TString::kBoth);
6499
6500 if (s.Length() > 0 &&
6501 (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6502 TString file = s(2, s.Length());
6503 TString acm, arg, io;
6504 fn = gSystem->SplitAclicMode(file, acm, arg, io);
6505 if (!fn.IsNull())
6506 return kTRUE;
6507 }
6508
6509 // Not found
6510 return kFALSE;
6511}
6512
6513////////////////////////////////////////////////////////////////////////////////
6514/// Send command to be executed on the PROOF master and/or slaves.
6515/// If plusMaster is kTRUE then exeucte on slaves and master too.
6516/// Command can be any legal command line command. Commands like
6517/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6518/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6519/// succes.
6520
6521Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6522{
6523 return Exec(cmd, kActive, plusMaster);
6524}
6525
6526////////////////////////////////////////////////////////////////////////////////
6527/// Send command to be executed on the PROOF master and/or slaves.
6528/// Command can be any legal command line command. Commands like
6529/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6530/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6531/// succes.
6532
6533Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6534{
6535 if (!IsValid()) return -1;
6536
6537 TString s = cmd;
6538 s = s.Strip(TString::kBoth);
6539
6540 if (!s.Length()) return 0;
6541
6542 // check for macro file and make sure the file is available on all slaves
6543 TString filename;
6544 if (TProof::GetFileInCmd(s.Data(), filename)) {
6545 char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6546 if (fn) {
6547 if (GetNumberOfUniqueSlaves() > 0) {
6548 if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6549 Error("Exec", "file %s could not be transfered", fn);
6550 delete [] fn;
6551 return -1;
6552 }
6553 } else {
6554 TString scmd = s(0,3) + fn;
6555 Int_t n = SendCommand(scmd, list);
6556 delete [] fn;
6557 return n;
6558 }
6559 } else {
6560 Error("Exec", "macro %s not found", filename.Data());
6561 return -1;
6562 }
6563 delete [] fn;
6564 }
6565
6566 if (plusMaster) {
6567 if (IsLite()) {
6568 gROOT->ProcessLine(cmd);
6569 } else {
6570 DeactivateWorker("*");
6571 Int_t res = SendCommand(cmd, list);
6572 ActivateWorker("restore");
6573 if (res < 0)
6574 return res;
6575 }
6576 }
6577 return SendCommand(cmd, list);
6578}
6579
6580////////////////////////////////////////////////////////////////////////////////
6581/// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6582/// Command can be any legal command line command. Commands like
6583/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6584/// to the PROOF cluster.
6585/// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6586/// TMacro, accessible via TMacro::GetMacroLog();
6587/// Returns -1 in case of error, >=0 in case of succes.
6588
6589Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6590{
6591 if (!IsValid()) return -1;
6592
6593 TString s = cmd;
6594 s = s.Strip(TString::kBoth);
6595
6596 if (!s.Length()) return 0;
6597
6598 Int_t res = 0;
6599 if (IsLite()) {
6600 gROOT->ProcessLine(cmd);
6601 } else {
6602 Bool_t oldRedirLog = fRedirLog;
6603 fRedirLog = kTRUE;
6604 // Deactivate all workers
6605 DeactivateWorker("*");
6606 fRedirLog = kFALSE;
6607 // Reactivate the target ones, if needed
6608 if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6609 // Honour log-to-macro-saving settings
6610 Bool_t oldSaveLog = fSaveLogToMacro;
6611 fSaveLogToMacro = logtomacro;
6612 res = SendCommand(cmd, kActive);
6613 fSaveLogToMacro = oldSaveLog;
6614 fRedirLog = kTRUE;
6615 ActivateWorker("restore");
6616 fRedirLog = oldRedirLog;
6617 }
6618 // Done
6619 return res;
6620}
6621
6622////////////////////////////////////////////////////////////////////////////////
6623/// Send command to be executed on the PROOF master and/or slaves.
6624/// Command can be any legal command line command, however commands
6625/// like ".x file.C" or ".L file.C" will not cause the file.C to be
6626/// transfered to the PROOF cluster. In that case use TProof::Exec().
6627/// Returns the status send by the remote server as part of the
6628/// kPROOF_LOGDONE message. Typically this is the return code of the
6629/// command on the remote side. Returns -1 in case of error.
6630
6631Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6632{
6633 if (!IsValid()) return -1;
6634
6635 Broadcast(cmd, kMESS_CINT, list);
6636 Collect(list);
6637
6638 return fStatus;
6639}
6640
6641////////////////////////////////////////////////////////////////////////////////
6642/// Get value of environment variable 'env' on node 'ord'
6643
6644TString TProof::Getenv(const char *env, const char *ord)
6645{
6646 // The command to be executed
6647 TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6648 if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6649 // Get the line
6650 TObjString *os = fMacroLog.GetLineWith("const char");
6651 if (os) {
6652 TString info;
6653 Ssiz_t from = 0;
6654 os->GetString().Tokenize(info, from, "\"");
6655 os->GetString().Tokenize(info, from, "\"");
6656 if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6657 return info;
6658 }
6659 return TString("");
6660}
6661
6662////////////////////////////////////////////////////////////////////////////////
6663/// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6664
6665Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6666{
6667 // The command to be executed
6668 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6669 // Exectute the command saving the logs to macro
6670 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6671 // Get the line
6672 TObjString *os = fMacroLog.GetLineWith("const char");
6673 Int_t rc = -1;
6674 if (os) {
6675 Ssiz_t fst = os->GetString().First('\"');
6676 Ssiz_t lst = os->GetString().Last('\"');
6677 TString info = os->GetString()(fst+1, lst-fst-1);
6678 if (info.IsDigit()) {
6679 env = info.Atoi();
6680 rc = 0;
6681 if (gDebug > 0)
6682 Printf("%s: %d", rcenv, env);
6683 }
6684 }
6685 return rc;
6686}
6687
6688////////////////////////////////////////////////////////////////////////////////
6689/// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6690
6691Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6692{
6693 // The command to be executed
6694 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6695 // Exectute the command saving the logs to macro
6696 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6697 // Get the line
6698 TObjString *os = fMacroLog.GetLineWith("const char");
6699 Int_t rc = -1;
6700 if (os) {
6701 Ssiz_t fst = os->GetString().First('\"');
6702 Ssiz_t lst = os->GetString().Last('\"');
6703 TString info = os->GetString()(fst+1, lst-fst-1);
6704 if (info.IsFloat()) {
6705 env = info.Atof();
6706 rc = 0;
6707 if (gDebug > 0)
6708 Printf("%s: %f", rcenv, env);
6709 }
6710 }
6711 return rc;
6712}
6713
6714////////////////////////////////////////////////////////////////////////////////
6715/// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6716
6717Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6718{
6719 // The command to be executed
6720 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6721 // Exectute the command saving the logs to macro
6722 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6723 // Get the line
6724 TObjString *os = fMacroLog.GetLineWith("const char");
6725 Int_t rc = -1;
6726 if (os) {
6727 Ssiz_t fst = os->GetString().First('\"');
6728 Ssiz_t lst = os->GetString().Last('\"');
6729 env = os->GetString()(fst+1, lst-fst-1);
6730 rc = 0;
6731 if (gDebug > 0)
6732 Printf("%s: %s", rcenv, env.Data());
6733 }
6734 return rc;
6735}
6736
6737////////////////////////////////////////////////////////////////////////////////
6738/// Transfer the current state of the master to the active slave servers.
6739/// The current state includes: the current working directory, etc.
6740/// Returns the number of active slaves. Returns -1 in case of error.
6741
6743{
6744 if (!IsValid()) return -1;
6745
6746 // Go to the new directory, reset the interpreter environment and
6747 // tell slave to delete all objects from its new current directory.
6748 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6749
6750 return GetParallel();
6751}
6752
6753////////////////////////////////////////////////////////////////////////////////
6754/// Transfer the current state of the master to the active slave servers.
6755/// The current state includes: the current working directory, etc.
6756/// Returns the number of active slaves. Returns -1 in case of error.
6757
6759{
6760 if (!IsValid()) return -1;
6761
6762 // Go to the new directory, reset the interpreter environment and
6763 // tell slave to delete all objects from its new current directory.
6764 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6765
6766 return GetParallel();
6767}
6768
6769////////////////////////////////////////////////////////////////////////////////
6770/// Transfer the initial (i.e. current) state of the master to all
6771/// slave servers. Currently the initial state includes: log level.
6772/// Returns the number of active slaves. Returns -1 in case of error.
6773
6775{
6776 if (!IsValid()) return -1;
6777
6779
6780 return GetNumberOfActiveSlaves();
6781}
6782
6783////////////////////////////////////////////////////////////////////////////////
6784/// Check if a file needs to be send to the slave. Use the following
6785/// algorithm:
6786/// - check if file appears in file map
6787/// - if yes, get file's modtime and check against time in map,
6788/// if modtime not same get md5 and compare against md5 in map,
6789/// if not same return kTRUE.
6790/// - if no, get file's md5 and modtime and store in file map, ask
6791/// slave if file exists with specific md5, if yes return kFALSE,
6792/// if no return kTRUE.
6793/// The options 'cpopt' define if to copy things from cache to sandbox and what.
6794/// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6795/// must be set in cpopt; the default is copy everything.
6796/// Returns kTRUE in case file needs to be send, returns kFALSE in case
6797/// file is already on remote node.
6798
6799Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6800{
6801 Bool_t sendto = kFALSE;
6802
6803 // create worker based filename
6804 TString sn = slave->GetName();
6805 sn += ":";
6806 sn += slave->GetOrdinal();
6807 sn += ":";
6808 sn += gSystem->BaseName(file);
6809
6810 // check if file is in map
6811 FileMap_t::const_iterator it;
6812 if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6813 // file in map
6814 MD5Mod_t md = (*it).second;
6815 if (md.fModtime != modtime) {
6817 if (md5) {
6818 if ((*md5) != md.fMD5) {
6819 sendto = kTRUE;
6820 md.fMD5 = *md5;
6821 md.fModtime = modtime;
6822 fFileMap[sn] = md;
6823 // When on the master, the master and/or slaves may share
6824 // their file systems and cache. Therefore always make a
6825 // check for the file. If the file already exists with the
6826 // expected md5 the kPROOF_CHECKFILE command will cause the
6827 // file to be copied from cache to slave sandbox.
6829 sendto = kFALSE;
6831 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6832 slave->GetSocket()->Send(mess);
6833
6834 fCheckFileStatus = 0;
6836 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6837 }
6838 }
6839 delete md5;
6840 } else {
6841 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6842 return kFALSE;
6843 }
6844 }
6845 } else {
6846 // file not in map
6848 MD5Mod_t md;
6849 if (md5) {
6850 md.fMD5 = *md5;
6851 md.fModtime = modtime;
6852 fFileMap[sn] = md;
6853 delete md5;
6854 } else {
6855 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6856 return kFALSE;
6857 }
6859 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6860 slave->GetSocket()->Send(mess);
6861
6862 fCheckFileStatus = 0;
6864 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6865 }
6866
6867 return sendto;
6868}
6869
6870////////////////////////////////////////////////////////////////////////////////
6871/// Send a file to master or slave servers. Returns number of slaves
6872/// the file was sent to, maybe 0 in case master and slaves have the same
6873/// file system image, -1 in case of error.
6874/// If defined, send to worker 'wrk' only.
6875/// If defined, the full path of the remote path will be rfile.
6876/// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6877/// (to copy to the cache on a different name use rfile = "cache:newname").
6878/// The mask 'opt' is an or of ESendFileOpt:
6879///
6880/// kAscii (0x0) if set true ascii file transfer is used
6881/// kBinary (0x1) if set true binary file transfer is used
6882/// kForce (0x2) if not set an attempt is done to find out
6883/// whether the file really needs to be downloaded
6884/// (a valid copy may already exist in the cache
6885/// from a previous run); the bit is set by
6886/// UploadPackage, since the check is done elsewhere.
6887/// kForward (0x4) if set, ask server to forward the file to slave
6888/// or submaster (meaningless for slave servers).
6889/// kCpBin (0x8) Retrieve from the cache the binaries associated
6890/// with the file
6891/// kCp (0x10) Retrieve the files from the cache
6892///
6893
6894Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6895{
6896 if (!IsValid()) return -1;
6897
6898 // Use the active slaves list ...
6899 TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6900 // ... or the specified slave, if any
6901 if (wrk) {
6902 slaves = new TList();
6903 slaves->Add(wrk);
6904 }
6905
6906 if (slaves->GetSize() == 0) return 0;
6907
6908#ifndef R__WIN32
6909 Int_t fd = open(file, O_RDONLY);
6910#else
6911 Int_t fd = open(file, O_RDONLY | O_BINARY);
6912#endif
6913 if (fd < 0) {
6914 SysError("SendFile", "cannot open file %s", file);
6915 return -1;
6916 }
6917
6918 // Get info about the file
6919 Long64_t size = -1;
6920 Long_t id, flags, modtime = 0;
6921 if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6922 Error("SendFile", "cannot stat file %s", file);
6923 close(fd);
6924 return -1;
6925 }
6926 if (size == 0) {
6927 Error("SendFile", "empty file %s", file);
6928 close(fd);
6929 return -1;
6930 }
6931
6932 // Decode options
6933 Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6934 Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6935 Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6936
6937 // Copy options
6938 Int_t cpopt = 0;
6939 if ((opt & kCp)) cpopt |= kCp;
6940 if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6941
6942 const Int_t kMAXBUF = 32768; //16384 //65536;
6943 char buf[kMAXBUF];
6944 Int_t nsl = 0;
6945
6946 TIter next(slaves);
6947 TSlave *sl;
6948 TString fnam(rfile);
6949 if (fnam == "cache") {
6950 fnam += TString::Format(":%s", gSystem->BaseName(file));
6951 } else if (fnam.IsNull()) {
6952 fnam = gSystem->BaseName(file);
6953 }
6954 // List on which we will collect the results
6955 fStatus = 0;
6956 while ((sl = (TSlave *)next())) {
6957 if (!sl->IsValid())
6958 continue;
6959
6960 Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6961 // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6962 // is false. Masters might still need to send the file to newly added
6963 // slaves.
6964 PDB(kPackage,2) {
6965 const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6966 Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6967 file, sl->GetName(), sl->GetOrdinal(), sendto);
6968 }
6969 if (sl->fSlaveType == TSlave::kSlave && !sendto)
6970 continue;
6971 // The value of 'size' is used as flag remotely, so we need to
6972 // reset it to 0 if we are not going to send the file
6973 Long64_t siz = sendto ? size : 0;
6974 snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6975 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6976 MarkBad(sl, "could not send kPROOF_SENDFILE request");
6977 continue;
6978 }
6979
6980 if (sendto) {
6981
6982 lseek(fd, 0, SEEK_SET);
6983
6984 Int_t len;
6985 do {
6986 while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6988
6989 if (len < 0) {
6990 SysError("SendFile", "error reading from file %s", file);
6992 close(fd);
6993 return -1;
6994 }
6995
6996 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6997 SysError("SendFile", "error writing to slave %s:%s (now offline)",
6998 sl->GetName(), sl->GetOrdinal());
6999 MarkBad(sl, "sendraw failure");
7000 sl = 0;
7001 break;
7002 }
7003
7004 } while (len > 0);
7005
7006 nsl++;
7007 }
7008 // Wait for the operation to be done
7009 if (sl)
7011 }
7012
7013 close(fd);
7014
7015 // Cleanup temporary list, if any
7016 if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
7017 SafeDelete(slaves);
7018
7019 // We return failure is at least one unique worker failed
7020 return (fStatus != 0) ? -1 : nsl;
7021}
7022
7023////////////////////////////////////////////////////////////////////////////////
7024/// Sends an object to master and workers and expect them to send back a
7025/// message with the output of its TObject::Print(). Returns -1 on error, the
7026/// number of workers that received the objects on success.
7027
7029{
7030 if (!IsValid() || !obj) return -1;
7031 TMessage mess(kPROOF_ECHO);
7032 mess.WriteObject(obj);
7033 return Broadcast(mess);
7034}
7035
7036////////////////////////////////////////////////////////////////////////////////
7037/// Sends a string to master and workers and expect them to echo it back to
7038/// the client via a message. It is a special case of the generic Echo()
7039/// that works with TObjects. Returns -1 on error, the number of workers that
7040/// received the message on success.
7041
7042Int_t TProof::Echo(const char *str)
7043{
7044 TObjString *os = new TObjString(str);
7045 Int_t rv = Echo(os);
7046 delete os;
7047 return rv;
7048}
7049
7050////////////////////////////////////////////////////////////////////////////////
7051/// Send object to master or slave servers. Returns number of slaves object
7052/// was sent to, -1 in case of error.
7053
7055{
7056 if (!IsValid() || !obj) return -1;
7057
7058 TMessage mess(kMESS_OBJECT);
7059
7060 mess.WriteObject(obj);
7061 return Broadcast(mess, list);
7062}
7063
7064////////////////////////////////////////////////////////////////////////////////
7065/// Send print command to master server. Returns number of slaves message
7066/// was sent to. Returns -1 in case of error.
7067
7069{
7070 if (!IsValid()) return -1;
7071
7072 Broadcast(option, kPROOF_PRINT, kActive);
7074}
7075
7076////////////////////////////////////////////////////////////////////////////////
7077/// Set server logging level.
7078
7080{
7081 char str[32];
7082 fLogLevel = level;
7083 gProofDebugLevel = level;
7085 snprintf(str, 32, "%d %u", level, mask);
7087}
7088
7089////////////////////////////////////////////////////////////////////////////////
7090/// Switch ON/OFF the real-time logging facility. When this option is
7091/// ON, log messages from processing are sent back as they come, instead of
7092/// being sent back at the end in one go. This may help debugging or monitoring
7093/// in some cases, but, depending on the amount of log, it may have significant
7094/// consequencies on the load over the network, so it must be used with care.
7095
7097{
7098 if (IsValid()) {
7100 mess << on;
7101 Broadcast(mess);
7102 } else {
7103 Warning("SetRealTimeLog","session is invalid - do nothing");
7104 }
7105}
7106
7107////////////////////////////////////////////////////////////////////////////////
7108/// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7109/// selection is done (if nodes is less than the available nodes).
7110/// Returns the number of parallel slaves. Returns -1 in case of error.
7111
7113{
7114 if (!IsValid()) return -1;
7115
7117 if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7118 return SendCurrentState();
7119 } else {
7120 if (nodes < 0) {
7121 PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7122 } else {
7123 PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7124 nodes == 1 ? "" : "s");
7125 }
7127 mess << nodes << random;
7128 Broadcast(mess);
7130 Int_t n = GetParallel();
7131 PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7132 return n;
7133 }
7134}
7135
7136////////////////////////////////////////////////////////////////////////////////
7137/// Tell PROOF how many slaves to use in parallel. Returns the number of
7138/// parallel slaves. Returns -1 in case of error.
7139
7141{
7142 // If delayed startup reset settings, if required
7143 if (fDynamicStartup && nodes < 0) {
7144 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7145 }
7146
7147 Int_t n = SetParallelSilent(nodes, random);
7149 if (n < 1) {
7150 Printf("PROOF set to sequential mode");
7151 } else {
7152 TString subfix = (n == 1) ? "" : "s";
7153 if (random)
7154 subfix += ", randomly selected";
7155 Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7156 }
7157 } else if (fDynamicStartup && nodes >= 0) {
7158 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7159 gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7160 }
7161 return n;
7162}
7163
7164////////////////////////////////////////////////////////////////////////////////
7165/// Add nWorkersToAdd workers to current list of workers. This function is
7166/// works on the master only, and only when an analysis is ongoing. A message
7167/// is sent back to the client when we go "more" parallel.
7168/// Returns -1 on error, number of total (not added!) workers on success.
7169
7171{
7172 if (!IsValid() || !IsMaster() || IsIdle()) {
7173 Error("GoMoreParallel", "can't invoke here -- should not happen!");
7174 return -1;
7175 }
7176 if (!gProofServ && !IsLite()) {
7177 Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7178 return -1;
7179 }
7180
7181 TSlave *sl = 0x0;
7182 TIter next( fSlaves );
7183 Int_t nAddedWorkers = 0;
7184
7185 while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7186 (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7187
7188 // If worker is of an invalid type, break everything: it should not happen!
7189 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7190 (sl->GetSlaveType() != TSlave::kMaster)) {
7191 Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7192 sl->GetName(), sl->GetOrdinal());
7193 R__ASSERT(0);
7194 }
7195
7196 // Skip current worker if it is not a good candidate
7197 if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7198 (strcmp("IGNORE", sl->GetImage()) == 0)) {
7199 PDB(kGlobal, 2)
7200 Info("GoMoreParallel", "Worker %s:%s won't be considered",
7201 sl->GetName(), sl->GetOrdinal());
7202 continue;
7203 }
7204
7205 // Worker is good but it is already active: skip it
7206 if (fActiveSlaves->FindObject(sl)) {
7207 Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7208 sl->GetName(), sl->GetOrdinal());
7209 continue;
7210 }
7211
7212 //
7213 // From here on: worker is a good candidate
7214 //
7215
7216 if (sl->GetSlaveType() == TSlave::kSlave) {
7218 fActiveSlaves->Add(sl);
7221 nAddedWorkers++;
7222 PDB(kGlobal, 2)
7223 Info("GoMoreParallel", "Worker %s:%s marked as active!",
7224 sl->GetName(), sl->GetOrdinal());
7225 }
7226 else {
7227 // Can't add masters dynamically: this should not happen!
7228 Error("GoMoreParallel", "Dynamic addition of master is not supported");
7229 R__ASSERT(0);
7230 }
7231
7232 } // end loop over all slaves
7233
7234 // Get slave status (will set the slaves fWorkDir correctly)
7235 PDB(kGlobal, 3)
7236 Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7237 AskStatistics();
7238
7239 // Find active slaves with unique image
7240 PDB(kGlobal, 3)
7241 Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7243
7244 // Send new group-view to slaves
7245 PDB(kGlobal, 3)
7246 Info("GoMoreParallel", "Will invoke SendGroupView()");
7247 SendGroupView();
7248
7249 PDB(kGlobal, 3)
7250 Info("GoMoreParallel", "Will invoke GetParallel()");
7251 Int_t nTotalWorkers = GetParallel();
7252
7253 // Notify the client that we've got more workers, and print info on
7254 // Master's log as well
7255 TString s;
7256 s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7257 nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7258 nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7260 Info("GoMoreParallel", "%s", s.Data());
7261
7262 return nTotalWorkers;
7263}
7264
7265////////////////////////////////////////////////////////////////////////////////
7266/// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7267/// list is sorted by slave performace the active list will contain first
7268/// the most performant nodes. Returns the number of active slaves.
7269/// If random is TRUE, and nodes is less than the number of available workers,
7270/// a random selection is done.
7271/// Returns -1 in case of error.
7272
7274{
7275 if (!IsValid()) return -1;
7276
7279
7280 // Prepare the list of candidates first.
7281 // Algorithm depends on random option.
7282 TSlave *sl = 0;
7283 TList *wlst = new TList;
7284 TIter nxt(fSlaves);
7286 while ((sl = (TSlave *)nxt())) {
7287 if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7288 if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7289 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7290 (sl->GetSlaveType() != TSlave::kMaster)) {
7291 Error("GoParallel", "TSlave is neither Master nor Slave");
7292 R__ASSERT(0);
7293 }
7294 // Good candidate
7295 wlst->Add(sl);
7296 // Set it inactive
7297 fInactiveSlaves->Add(sl);
7299 }
7300 }
7301 Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7302 int cnt = 0;
7304 while (cnt < nwrks) {
7305 // Random choice, if requested
7306 if (random) {
7307 Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7308 sl = (TSlave *) wlst->At(iwrk);
7309 } else {
7310 // The first available
7311 sl = (TSlave *) wlst->First();
7312 }
7313 if (!sl) {
7314 Error("GoParallel", "attaching to candidate!");
7315 break;
7316 }
7317 // Remove from the list
7318 wlst->Remove(sl);
7319
7320 Int_t slavenodes = 0;
7321 if (sl->GetSlaveType() == TSlave::kSlave) {
7323 fActiveSlaves->Add(sl);
7326 slavenodes = 1;
7327 } else if (sl->GetSlaveType() == TSlave::kMaster) {
7330 if (!attach) {
7331 Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7332 mess << nn;
7333 } else {
7334 // To get the number of slaves
7335 mess.SetWhat(kPROOF_LOGFILE);
7336 mess << -1 << -1;
7337 }
7338 if (sl->GetSocket()->Send(mess) == -1) {
7339 MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7340 slavenodes = 0;
7341 } else {
7343 if (sl->IsValid()) {
7345 fActiveSlaves->Add(sl);
7348 if (sl->GetParallel() > 0) {
7349 slavenodes = sl->GetParallel();
7350 } else {
7351 // Sequential mode: the master acts as a worker
7352 slavenodes = 1;
7353 }
7354 } else {
7355 MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7356 slavenodes = 0;
7357 }
7358 }
7359 }
7360 // 'slavenodes' may be different than 1 in multimaster setups
7361 cnt += slavenodes;
7362 }
7363
7364 // Cleanup list
7365 wlst->SetOwner(0);
7366 SafeDelete(wlst);
7367
7368 // Get slave status (will set the slaves fWorkDir correctly)
7369 AskStatistics();
7370
7371 // Find active slaves with unique image
7373
7374 // Send new group-view to slaves
7375 if (!attach)
7376 SendGroupView();
7377
7378 Int_t n = GetParallel();
7379
7381 if (n < 1)
7382 printf("PROOF set to sequential mode\n");
7383 else
7384 printf("PROOF set to parallel mode (%d worker%s)\n",
7385 n, n == 1 ? "" : "s");
7386 }
7387
7388 PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7389 return n;
7390}
7391
7392////////////////////////////////////////////////////////////////////////////////
7393/// List contents of the data directory in the sandbox.
7394/// This is the place where files produced by the client queries are kept
7395
7397{
7398 if (!IsValid() || !fManager) return;
7399
7400 // This is run via the manager
7401 fManager->Find("~/data", "-type f", "all");
7402}
7403
7404////////////////////////////////////////////////////////////////////////////////
7405/// Remove files for the data directory.
7406/// The option 'what' can take the values:
7407/// kPurge remove all files and directories under '~/data'
7408/// kUnregistered remove only files not in registered datasets (default)
7409/// kDataset remove files belonging to dataset 'dsname'
7410/// User is prompt for confirmation, unless kForceClear is ORed with the option
7411
7412void TProof::ClearData(UInt_t what, const char *dsname)
7413{
7414 if (!IsValid() || !fManager) return;
7415
7416 // Check whether we need to prompt
7417 TString prompt, a("Y");
7418 Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7419 Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7420
7421 // If all just send the request
7422 if ((what & TProof::kPurge)) {
7423 // Prompt, if requested
7424 if (doask && !Prompt("Do you really want to remove all data files")) return;
7425 if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7426 Warning("ClearData", "problems purging data directory");
7427 return;
7428 } else if ((what & TProof::kDataset)) {
7429 // We must have got a name
7430 if (!dsname || strlen(dsname) <= 0) {
7431 Error("ClearData", "dataset name mandatory when removing a full dataset");
7432 return;
7433 }
7434 // Check if the dataset is registered
7435 if (!ExistsDataSet(dsname)) {
7436 Error("ClearData", "dataset '%s' does not exists", dsname);
7437 return;
7438 }
7439 // Get the file content
7440 TFileCollection *fc = GetDataSet(dsname);
7441 if (!fc) {
7442 Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7443 return;
7444 }
7445 // Prompt, if requested
7446 TString pmpt = TString::Format("Do you really want to remove all data files"
7447 " of dataset '%s'", dsname);
7448 if (doask && !Prompt(pmpt.Data())) return;
7449
7450 // Loop through the files
7451 Bool_t rmds = kTRUE;
7452 TIter nxf(fc->GetList());
7453 TFileInfo *fi = 0;
7454 Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7455 while ((fi = (TFileInfo *) nxf())) {
7456 // Fill the host info
7457 TString host, file;
7458 // Take info from the current url
7459 if (!(fi->GetFirstUrl())) {
7460 Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7461 fi->GetName());
7462 continue;
7463 }
7464 TUrl uf(*(fi->GetFirstUrl()));
7465 file = uf.GetFile();
7466 host = uf.GetHost();
7467 // Now search for any "file:" url
7468 Int_t nurl = fi->GetNUrls();
7469 fi->ResetUrl();
7470 TUrl *up = 0;
7471 while (nurl-- && fi->NextUrl()) {
7472 up = fi->GetCurrentUrl();
7473 if (!strcmp(up->GetProtocol(), "file")) {
7474 TString opt(up->GetOptions());
7475 if (opt.BeginsWith("node=")) {
7476 host=opt;
7477 host.ReplaceAll("node=","");
7478 file = up->GetFile();
7479 break;
7480 }
7481 }
7482 }
7483 // Issue a remove request now
7484 if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7485 Error("ClearData", "problems removing '%s'", file.Data());
7486 // Some files not removed: keep the meta info about this dataset
7487 rmds = kFALSE;
7488 }
7489 rfiles++;
7490 ClearDataProgress(rfiles, nfiles);
7491 }
7492 fprintf(stderr, "\n");
7493 if (rmds) {
7494 // All files were removed successfully: remove also the dataset meta info
7495 RemoveDataSet(dsname);
7496 }
7497 } else if (what & TProof::kUnregistered) {
7498
7499 // Get the existing files
7500 TString outtmp("ProofClearData_");
7501 FILE *ftmp = gSystem->TempFileName(outtmp);
7502 if (!ftmp) {
7503 Error("ClearData", "cannot create temp file for logs");
7504 return;
7505 }
7506 fclose(ftmp);
7508 gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7509 ShowData();
7510 gSystem->RedirectOutput(0, 0, &h);
7511 // Parse the output file now
7512 std::ifstream in;
7513 in.open(outtmp.Data());
7514 if (!in.is_open()) {
7515 Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7516 gSystem->Unlink(outtmp);
7517 return;
7518 }
7519 // Go through
7520 Int_t nfiles = 0;
7521 TMap *afmap = new TMap;
7522 TString line, host, file;
7523 Int_t from = 0;
7524 while (in.good()) {
7525 line.ReadLine(in);
7526 if (line.IsNull()) continue;
7527 while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7528 from = 0;
7529 host = "";
7530 if (!line.Tokenize(host, from, "| ")) continue;
7531 file = "";
7532 if (!line.Tokenize(file, from, "| ")) continue;
7533 if (!host.IsNull() && !file.IsNull()) {
7534 TList *fl = (TList *) afmap->GetValue(host.Data());
7535 if (!fl) {
7536 fl = new TList();
7537 fl->SetName(host);
7538 afmap->Add(new TObjString(host), fl);
7539 }
7540 fl->Add(new TObjString(file));
7541 nfiles++;
7542 PDB(kDataset,2)
7543 Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7544 } else {
7545 Warning("ClearData", "found incomplete line: '%s'", line.Data());
7546 }
7547 }
7548 // Close and remove the file
7549 in.close();
7550 gSystem->Unlink(outtmp);
7551
7552 // Get registered data files
7553 TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7554 TMap *fcmap = GetDataSets(sel);
7555 if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7556 PDB(kDataset,1)
7557 Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7558 SafeDelete(fcmap);
7559 }
7560
7561 // Go thorugh and prepare the lists per node
7562 TString opt;
7563 TObjString *os = 0;
7564 if (fcmap) {
7565 TIter nxfc(fcmap);
7566 while ((os = (TObjString *) nxfc())) {
7567 TFileCollection *fc = 0;
7568 if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7569 TFileInfo *fi = 0;
7570 TIter nxfi(fc->GetList());
7571 while ((fi = (TFileInfo *) nxfi())) {
7572 // Get special "file:" url
7573 fi->ResetUrl();
7574 Int_t nurl = fi->GetNUrls();
7575 TUrl *up = 0;
7576 while (nurl-- && fi->NextUrl()) {
7577 up = fi->GetCurrentUrl();
7578 if (!strcmp(up->GetProtocol(), "file")) {
7579 opt = up->GetOptions();
7580 if (opt.BeginsWith("node=")) {
7581 host=opt;
7582 host.ReplaceAll("node=","");
7583 file = up->GetFile();
7584 PDB(kDataset,2)
7585 Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7586 // Remove this from the full list, if there
7587 TList *fl = (TList *) afmap->GetValue(host.Data());
7588 if (fl) {
7589 TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7590 if (fn) {
7591 fl->Remove(fn);
7592 SafeDelete(fn);
7593 nfiles--;
7594 } else {
7595 Warning("ClearData",
7596 "registered file '%s' not found in the full list!",
7597 file.Data());
7598 }
7599 }
7600 break;
7601 }
7602 }
7603 }
7604 }
7605 }
7606 }
7607 // Clean up the the received map
7608 if (fcmap) fcmap->SetOwner(kTRUE);
7609 SafeDelete(fcmap);
7610 }
7611 // List of the files to be removed
7612 Info("ClearData", "%d unregistered files to be removed:", nfiles);
7613 afmap->Print();
7614 // Prompt, if requested
7615 TString pmpt = TString::Format("Do you really want to remove all %d"
7616 " unregistered data files", nfiles);
7617 if (doask && !Prompt(pmpt.Data())) return;
7618
7619 // Remove one by one; we may implement a bloc remove in the future
7620 Int_t rfiles = 0;
7621 TIter nxls(afmap);
7622 while ((os = (TObjString *) nxls())) {
7623 TList *fl = 0;
7624 if ((fl = (TList *) afmap->GetValue(os))) {
7625 TIter nxf(fl);
7626 TObjString *fn = 0;
7627 while ((fn = (TObjString *) nxf())) {
7628 // Issue a remove request now
7629 if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7630 Error("ClearData", "problems removing '%s' on host '%s'",
7631 fn->GetName(), os->GetName());
7632 }
7633 rfiles++;
7634 ClearDataProgress(rfiles, nfiles);
7635 }
7636 }
7637 }
7638 fprintf(stderr, "\n");
7639 // Final cleanup
7640 afmap->SetOwner(kTRUE);
7641 SafeDelete(afmap);
7642 }
7643}
7644
7645////////////////////////////////////////////////////////////////////////////////
7646/// Prompt the question 'p' requiring an answer y,Y,n,N
7647/// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7648
7650{
7651 TString pp(p);
7652 if (!pp.Contains("?")) pp += "?";
7653 if (!pp.Contains("[y/N]")) pp += " [y/N]";
7654 TString a = Getline(pp.Data());
7655 if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7656 Printf("Please answer y, Y, n or N");
7657 // Unclear answer: assume negative
7658 return kFALSE;
7659 } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7660 // Explicitly Negative answer
7661 return kFALSE;
7662 }
7663 // Explicitly Positive answer
7664 return kTRUE;
7665}
7666
7667////////////////////////////////////////////////////////////////////////////////
7668/// Progress bar for clear data
7669
7671{
7672 fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7673 for (Int_t l = 0; l < 20; l++) {
7674 if (r > 0 && t > 0) {
7675 if (l < 20*r/t)
7676 fprintf(stderr, "=");
7677 else if (l == 20*r/t)
7678 fprintf(stderr, ">");
7679 else if (l > 20*r/t)
7680 fprintf(stderr, ".");
7681 } else
7682 fprintf(stderr, "=");
7683 }
7684 fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7685}
7686
7687////////////////////////////////////////////////////////////////////////////////
7688/// List contents of file cache. If all is true show all caches also on
7689/// slaves. If everything is ok all caches are to be the same.
7690
7692{
7693 if (!IsValid()) return;
7694
7695 TMessage mess(kPROOF_CACHE);
7696 mess << Int_t(kShowCache) << all;
7697 Broadcast(mess, kUnique);
7698
7699 if (all) {
7700 TMessage mess2(kPROOF_CACHE);
7701 mess2 << Int_t(kShowSubCache) << all;
7703
7705 } else {
7707 }
7708}
7709
7710////////////////////////////////////////////////////////////////////////////////
7711/// Remove file from all file caches. If file is 0 or "" or "*", remove all
7712/// the files
7713
7714void TProof::ClearCache(const char *file)
7715{
7716 if (!IsValid()) return;
7717
7718 TMessage mess(kPROOF_CACHE);
7719 mess << Int_t(kClearCache) << TString(file);
7720 Broadcast(mess, kUnique);
7721
7722 TMessage mess2(kPROOF_CACHE);
7723 mess2 << Int_t(kClearSubCache) << TString(file);
7725
7727
7728 // clear file map so files get send again to remote nodes
7729 fFileMap.clear();
7730}
7731
7732////////////////////////////////////////////////////////////////////////////////
7733/// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7734
7735void TProof::SystemCmd(const char *cmd, Int_t fdout)
7736{
7737 if (fdout < 0) {
7738 // Exec directly the command
7739 gSystem->Exec(cmd);
7740 } else {
7741 // Exec via a pipe
7742 FILE *fin = gSystem->OpenPipe(cmd, "r");
7743 if (fin) {
7744 // Now we go
7745 char line[2048];
7746 while (fgets(line, 2048, fin)) {
7747 Int_t r = strlen(line);
7748 if (r > 0) {
7749 if (write(fdout, line, r) < 0) {
7750 ::Warning("TProof::SystemCmd",
7751 "errno %d writing to file descriptor %d",
7752 TSystem::GetErrno(), fdout);
7753 }
7754 } else {
7755 // Done
7756 break;
7757 }
7758 }
7759 gSystem->ClosePipe(fin);
7760 }
7761 }
7762}
7763
7764////////////////////////////////////////////////////////////////////////////////
7765/// List contents of package directory. If all is true show all package
7766/// directories also on slaves. If everything is ok all package directories
7767/// should be the same. If redir is kTRUE the result is redirected to the log
7768/// file (option available for internal actions).
7769
7771{
7772 if (!IsValid()) return;
7773
7774 Bool_t oldredir = fRedirLog;
7775 if (redirlog) fRedirLog = kTRUE;
7776
7777 // Active logging unit
7778 FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7779 if (!fout) {
7780 Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7781 " will not log msgs", fout);
7782 return;
7783 }
7784 lseek(fileno(fout), (off_t) 0, SEEK_END);
7785
7787 fPackMgr->Show();
7788 }
7789
7790 // Nothing more to do if we are a Lite-session
7791 if (IsLite()) {
7792 fRedirLog = oldredir;
7793 return;
7794 }
7795
7796 TMessage mess(kPROOF_CACHE);
7797 mess << Int_t(kShowPackages) << all;
7798 Broadcast(mess, kUnique);
7799
7800 if (all) {
7801 TMessage mess2(kPROOF_CACHE);
7802 mess2 << Int_t(kShowSubPackages) << all;
7804
7806 } else {
7808 }
7809 // Restore logging option
7810 fRedirLog = oldredir;
7811}
7812
7813////////////////////////////////////////////////////////////////////////////////
7814/// List which packages are enabled. If all is true show enabled packages
7815/// for all active slaves. If everything is ok all active slaves should
7816/// have the same packages enabled.
7817
7819{
7820 if (!IsValid()) return;
7821
7823 fPackMgr->ShowEnabled(TString::Format("*** Enabled packages on client on %s\n",
7824 gSystem->HostName()));
7825 }
7826
7827 // Nothing more to do if we are a Lite-session
7828 if (IsLite()) return;
7829
7830 TMessage mess(kPROOF_CACHE);
7831 mess << Int_t(kShowEnabledPackages) << all;
7832 Broadcast(mess);
7834}
7835
7836////////////////////////////////////////////////////////////////////////////////
7837/// Remove all packages.
7838/// Returns 0 in case of success and -1 in case of error.
7839
7841{
7842 if (!IsValid()) return -1;
7843
7844 if (UnloadPackages() == -1)
7845 return -1;
7846
7847 if (DisablePackages() == -1)
7848 return -1;
7849
7850 return fStatus;
7851}
7852
7853////////////////////////////////////////////////////////////////////////////////
7854/// Remove a specific package.
7855/// Returns 0 in case of success and -1 in case of error.
7856
7857Int_t TProof::ClearPackage(const char *package)
7858{
7859 if (!IsValid()) return -1;
7860
7861 if (!package || !package[0]) {
7862 Error("ClearPackage", "need to specify a package name");
7863 return -1;
7864 }
7865
7866 // if name, erroneously, is a par pathname strip off .par and path
7867 TString pac = package;
7868 if (pac.EndsWith(".par"))
7869 pac.Remove(pac.Length()-4);
7870 pac = gSystem->BaseName(pac);
7871
7872 if (UnloadPackage(pac) == -1)
7873 return -1;
7874
7875 if (DisablePackage(pac) == -1)
7876 return -1;
7877
7878 return fStatus;
7879}
7880
7881////////////////////////////////////////////////////////////////////////////////
7882/// Remove a specific package.
7883/// Returns 0 in case of success and -1 in case of error.
7884
7886{
7887 if (!IsValid()) return -1;
7888
7889 if (!pack || strlen(pack) <= 0) {
7890 Error("DisablePackage", "need to specify a package name");
7891 return -1;
7892 }
7893
7894 // if name, erroneously, is a par pathname strip off .par and path
7895 TString pac = pack;
7896 if (pac.EndsWith(".par"))
7897 pac.Remove(pac.Length()-4);
7898 pac = gSystem->BaseName(pac);
7899
7900 if (fPackMgr->Remove(pack) < 0)
7901 Warning("DisablePackage", "problem removing locally package '%s'", pack);
7902
7903 // Nothing more to do if we are a Lite-session
7904 if (IsLite()) return 0;
7905
7906 Int_t st = -1;
7907 Bool_t done = kFALSE;
7908 if (fManager) {
7909 // Try to do it via XROOTD (new way)
7910 TString path;
7911 path.Form("~/packages/%s", pack);
7912 if (fManager->Rm(path, "-rf", "all") != -1) {
7913 path.Append(".par");
7914 if (fManager->Rm(path, "-f", "all") != -1) {
7915 done = kTRUE;
7916 st = 0;
7917 }
7918 }
7919 }
7920 if (!done) {
7921 // Try via TProofServ (old way)
7922 TMessage mess(kPROOF_CACHE);
7923 mess << Int_t(kDisablePackage) << pac;
7924 Broadcast(mess, kUnique);
7925
7926 TMessage mess2(kPROOF_CACHE);
7927 mess2 << Int_t(kDisableSubPackage) << pac;
7929
7931 st = fStatus;
7932 }
7933
7934 // Done
7935 return st;
7936}
7937
7938////////////////////////////////////////////////////////////////////////////////
7939/// Remove all packages.
7940/// Returns 0 in case of success and -1 in case of error.
7941
7943{
7944 if (!IsValid()) return -1;
7945
7946 // remove all packages on client
7947 if (fPackMgr->Remove(nullptr) < 0)
7948 Warning("DisablePackages", "problem removing packages locally");
7949
7950 // Nothing more to do if we are a Lite-session
7951 if (IsLite()) return 0;
7952
7953 Int_t st = -1;
7954 Bool_t done = kFALSE;
7955 if (fManager) {
7956 // Try to do it via XROOTD (new way)
7957 if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
7958 done = kTRUE;
7959 st = 0;
7960 }
7961 }
7962 if (!done) {
7963
7964 TMessage mess(kPROOF_CACHE);
7965 mess << Int_t(kDisablePackages);
7966 Broadcast(mess, kUnique);
7967
7968 TMessage mess2(kPROOF_CACHE);
7969 mess2 << Int_t(kDisableSubPackages);
7971
7973 st = fStatus;
7974 }
7975
7976 // Done
7977 return st;
7978}
7979
7980////////////////////////////////////////////////////////////////////////////////
7981/// Build specified package. Executes the PROOF-INF/BUILD.sh
7982/// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
7983/// then submit build command to slaves, but don't wait
7984/// for results. If opt is kCollectBuildResults then collect result
7985/// from slaves. To be used on the master.
7986/// If opt = kBuildAll (default) then submit and wait for results
7987/// (to be used on the client).
7988/// Returns 0 in case of success and -1 in case of error.
7989
7990Int_t TProof::BuildPackage(const char *package,
7991 EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
7992{
7993 if (!IsValid()) return -1;
7994
7995 if (!package || !package[0]) {
7996 Error("BuildPackage", "need to specify a package name");
7997 return -1;
7998 }
7999
8000 // if name, erroneously, is a par pathname strip off .par and path
8001 TString pac = package;
8002 if (pac.EndsWith(".par"))
8003 pac.Remove(pac.Length()-4);
8004 pac = gSystem->BaseName(pac);
8005
8006 Bool_t buildOnClient = kTRUE;
8007 if (opt == kDontBuildOnClient) {
8008 buildOnClient = kFALSE;
8009 opt = kBuildAll;
8010 }
8011 // Prepare the local package
8012 TString pdir;
8013 Int_t st = 0;
8014
8015 if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
8016 if (workers) {
8017 TMessage mess(kPROOF_CACHE);
8018 mess << Int_t(kBuildPackage) << pac << chkveropt;
8019 Broadcast(mess, workers);
8020
8021 } else {
8022 TMessage mess(kPROOF_CACHE);
8023 mess << Int_t(kBuildPackage) << pac << chkveropt;
8024 Broadcast(mess, kUnique);
8025
8026 TMessage mess2(kPROOF_CACHE);
8027 mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8029 }
8030 }
8031
8032 if (opt >= kBuildAll) {
8033 // by first forwarding the build commands to the master and slaves
8034 // and only then building locally we build in parallel
8035 if (buildOnClient) {
8036 st = fPackMgr->Build(pac, chkveropt);
8037 }
8038
8039
8040 fStatus = 0;
8041 if (!IsLite() || !buildOnClient) {
8042
8043 // On the master, workers that fail are deactivated
8044 // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8045 if (workers) {
8046// Collect(workers, -1, -1, deactivateOnFailure);
8047 Collect(workers);
8048 } else {
8050 }
8051 }
8052
8053 if (fStatus < 0 || st < 0)
8054 return -1;
8055 }
8056
8057 return 0;
8058}
8059
8060////////////////////////////////////////////////////////////////////////////////
8061/// Load specified package. Executes the PROOF-INF/SETUP.C script
8062/// on all active nodes. If notOnClient = true, don't load package
8063/// on the client. The default is to load the package also on the client.
8064/// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8065/// The objects in the list must be streamable; the SETUP macro will be executed
8066/// like this: SETUP.C(loadopts).
8067/// Returns 0 in case of success and -1 in case of error.
8068
8069Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8070 TList *loadopts, TList *workers)
8071{
8072 if (!IsValid()) return -1;
8073
8074 if (!package || !package[0]) {
8075 Error("LoadPackage", "need to specify a package name");
8076 return -1;
8077 }
8078
8079 // if name, erroneously, is a par pathname strip off .par and path
8080 TString pac = package;
8081 if (pac.EndsWith(".par"))
8082 pac.Remove(pac.Length()-4);
8083 pac = gSystem->BaseName(pac);
8084
8085 if (!notOnClient && TestBit(TProof::kIsClient))
8086 if (fPackMgr->Load(package, loadopts) == -1) return -1;
8087
8088 TMessage mess(kPROOF_CACHE);
8089 mess << Int_t(kLoadPackage) << pac;
8090 if (loadopts) mess << loadopts;
8091
8092 // On the master, workers that fail are deactivated
8093 Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8094
8095 Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8096
8097 if (workers) {
8098 PDB(kPackage, 3)
8099 Info("LoadPackage", "Sending load message to selected workers only");
8100 Broadcast(mess, workers);
8101 if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8102 } else {
8103 Broadcast(mess);
8104 Collect(kActive, -1, -1, deactivateOnFailure);
8105 }
8106
8107 return fStatus;
8108}
8109
8110////////////////////////////////////////////////////////////////////////////////
8111/// Unload specified package.
8112/// Returns 0 in case of success and -1 in case of error.
8113
8114Int_t TProof::UnloadPackage(const char *package)
8115{
8116 if (!IsValid()) return -1;
8117
8118 if (!package || !package[0]) {
8119 Error("UnloadPackage", "need to specify a package name");
8120 return -1;
8121 }
8122
8123 // if name, erroneously, is a par pathname strip off .par and path
8124 TString pac = package;
8125 if (pac.EndsWith(".par"))
8126 pac.Remove(pac.Length()-4);
8127 pac = gSystem->BaseName(pac);
8128
8129 if (fPackMgr->Unload(package) < 0)
8130 Warning("UnloadPackage", "unable to remove symlink to %s", package);
8131
8132 // Nothing more to do if we are a Lite-session
8133 if (IsLite()) return 0;
8134
8135 TMessage mess(kPROOF_CACHE);
8136 mess << Int_t(kUnloadPackage) << pac;
8137 Broadcast(mess);
8138 Collect();
8139
8140 return fStatus;
8141}
8142
8143////////////////////////////////////////////////////////////////////////////////
8144/// Unload all packages.
8145/// Returns 0 in case of success and -1 in case of error.
8146
8148{
8149 if (!IsValid()) return -1;
8150
8152 if (fPackMgr->Unload(0) < 0) return -1;
8153 }
8154
8155 // Nothing more to do if we are a Lite-session
8156 if (IsLite()) return 0;
8157
8158 TMessage mess(kPROOF_CACHE);
8159 mess << Int_t(kUnloadPackages);
8160 Broadcast(mess);
8161 Collect();
8162
8163 return fStatus;
8164}
8165
8166////////////////////////////////////////////////////////////////////////////////
8167/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8168/// script if it exists followed by the PROOF-INF/SETUP.C script.
8169/// In case notOnClient = true, don't enable the package on the client.
8170/// The default is to enable packages also on the client.
8171/// If specified, enables packages only on the specified workers.
8172/// Returns 0 in case of success and -1 in case of error.
8173/// Provided for backward compatibility.
8174
8175Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8176 TList *workers)
8177{
8178 return EnablePackage(package, (TList *)0, notOnClient, workers);
8179}
8180
8181////////////////////////////////////////////////////////////////////////////////
8182/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8183/// script if it exists followed by the PROOF-INF/SETUP.C script.
8184/// In case notOnClient = true, don't enable the package on the client.
8185/// The default is to enable packages also on the client.
8186/// It is is possible to specify options for the loading step via 'loadopts';
8187/// the string will be passed passed as argument to SETUP.
8188/// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8189/// plugin version checking during building: possible choices are:
8190/// off no check; failure may occur at loading
8191/// on check ROOT version [default]
8192/// svn check ROOT version and Git commit SHA1.
8193/// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8194/// If specified, enables packages only on the specified workers.
8195/// Returns 0 in case of success and -1 in case of error.
8196
8197Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8198 Bool_t notOnClient, TList *workers)
8199{
8200 TList *optls = 0;
8201 if (loadopts && strlen(loadopts)) {
8202 if (fProtocol > 28) {
8203 TObjString *os = new TObjString(loadopts);
8204 // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8205 os->String().ReplaceAll("checkversion=", "chkv=");
8206 Ssiz_t fcv = kNPOS, lcv = kNPOS;
8207 if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8208 TRegexp re("[; |]");
8209 if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8210 lcv = os->String().Length();
8211 }
8212 TString ocv = os->String()(fcv, lcv - fcv);
8213 Int_t cvopt = -1;
8214 if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8215 cvopt = (Int_t) TPackMgr::kDontCheck;
8216 else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8217 cvopt = (Int_t) TPackMgr::kCheckROOT;
8218 else
8219 Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8220 if (cvopt > -1) {
8221 if (gDebug > 0)
8222 Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8223 optls = new TList;
8224 optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8225 // Remove the special option from; we leave a separator if there were two (one before and one after)
8226 if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8227 if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8228 os->String().ReplaceAll(ocv.Data(), "");
8229 }
8230 }
8231 if (!os->String().IsNull()) {
8232 if (!optls) optls = new TList;
8233 optls->Add(new TObjString(os->String().Data()));
8234 }
8235 if (optls) optls->SetOwner(kTRUE);
8236 } else {
8237 // Notify
8238 Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8239 }
8240 }
8241 // Run
8242 Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8243 // Clean up
8244 SafeDelete(optls);
8245 // Done
8246 return rc;
8247}
8248
8249////////////////////////////////////////////////////////////////////////////////
8250/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8251/// script if it exists followed by the PROOF-INF/SETUP.C script.
8252/// In case notOnClient = true, don't enable the package on the client.
8253/// The default is to enable packages also on the client.
8254/// It is is possible to specify a list of objects to be passed to the SETUP
8255/// functions via 'loadopts'; the objects must be streamable.
8256/// Returns 0 in case of success and -1 in case of error.
8257
8258Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8259 Bool_t notOnClient, TList *workers)
8260{
8261 if (!IsValid()) return -1;
8262
8263 if (!package || !package[0]) {
8264 Error("EnablePackage", "need to specify a package name");
8265 return -1;
8266 }
8267
8268 // if name, erroneously, is a par pathname strip off .par and path
8269 TString pac = package;
8270 if (pac.EndsWith(".par"))
8271 pac.Remove(pac.Length()-4);
8272 pac = gSystem->BaseName(pac);
8273
8275 if (notOnClient)
8276 opt = kDontBuildOnClient;
8277
8278 // Get check version option; user settings have priority
8279 Int_t chkveropt = TPackMgr::kCheckROOT;
8280 TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8281 if (!ocv.IsNull()) {
8282 if (ocv == "off" || ocv == "0")
8283 chkveropt = (Int_t) TPackMgr::kDontCheck;
8284 else if (ocv == "on" || ocv == "1")
8285 chkveropt = (Int_t) TPackMgr::kCheckROOT;
8286 else
8287 Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8288 }
8289 if (loadopts) {
8290 TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8291 if (pcv) {
8292 chkveropt = pcv->GetVal();
8293 loadopts->Remove(pcv);
8294 delete pcv;
8295 }
8296 }
8297 if (gDebug > 0)
8298 Info("EnablePackage", "using check version option: %d", chkveropt);
8299
8300 if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8301 return -1;
8302
8303 TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8304 if (optls && fProtocol <= 28) {
8305 Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8306 optls = 0;
8307 }
8308
8309 if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8310 return -1;
8311
8312 // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8316 }
8318 TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8319 : new TPair(new TObjString(pac), 0);
8321 }
8322
8323 return 0;
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327/// Download a PROOF archive (PAR file) from the master package repository.
8328/// The PAR file is downloaded in the current directory or in the directory
8329/// specified by 'dstdir'. If a package with the same name already exists
8330/// at destination, a check on the MD5 sum is done and the user warned or
8331/// prompted for action, depending is the file is equal or different.
8332/// Returns 0 in case of success and -1 in case of error.
8333
8334Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8335{
8336 if (!fManager || !(fManager->IsValid())) {
8337 Error("DownloadPackage", "the manager is undefined!");
8338 return -1;
8339 }
8340
8341 // Create the default source and destination paths
8342 TString parname(gSystem->BaseName(pack)), src, dst;
8343 if (!parname.EndsWith(".par")) parname += ".par";
8344 src.Form("packages/%s", parname.Data());
8345 if (!dstdir || strlen(dstdir) <= 0) {
8346 dst.Form("./%s", parname.Data());
8347 } else {
8348 // Check the destination directory
8349 FileStat_t st;
8350 if (gSystem->GetPathInfo(dstdir, st) != 0) {
8351 // Directory does not exit: create it
8352 if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8353 Error("DownloadPackage",
8354 "could not create the destination directory '%s' (errno: %d)",
8355 dstdir, TSystem::GetErrno());
8356 return -1;
8357 }
8358 } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8359 Error("DownloadPackage",
8360 "destination path '%s' exist but is not a directory!", dstdir);
8361 return -1;
8362 }
8363 dst.Form("%s/%s", dstdir, parname.Data());
8364 }
8365
8366 // Make sure the source file exists
8367 FileStat_t stsrc;
8369 if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8370 Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8371 Int_t rc = fManager->Stat(src, stsrc);
8372 if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8373 Warning("DownloadPackage", "problems restoring output");
8374 if (rc != 0) {
8375 // Check if there is another possible source
8377 TMacro *mp = GetLastLog();
8378 if (mp) {
8379 // Look for global directories
8380 Bool_t isGlobal = kFALSE;
8381 TIter nxl(mp->GetListOfLines());
8382 TObjString *os = 0;
8383 TString globaldir;
8384 while ((os = (TObjString *) nxl())) {
8385 TString s(os->GetName());
8386 if (s.Contains("*** Global Package cache")) {
8387 // Get the directory
8388 s.Remove(0, s.Last(':') + 1);
8389 s.Remove(s.Last(' '));
8390 globaldir = s;
8391 isGlobal = kTRUE;
8392 } else if (s.Contains("*** Package cache")) {
8393 isGlobal = kFALSE;
8394 globaldir = "";
8395 }
8396 // Check for the package
8397 if (isGlobal && s.Contains(parname)) {
8398 src.Form("%s/%s", globaldir.Data(), parname.Data());
8399 break;
8400 }
8401 }
8402 // Cleanup
8403 delete mp;
8404 }
8405 }
8406
8407 // Do it via the manager
8408 if (fManager->GetFile(src, dst, "silent") != 0) {
8409 Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8410 pack, src.Data(), dst.Data());
8411 return -1;
8412 } else {
8413 Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8414 pack, dst.Data());
8415 }
8416 // Done
8417 return 0;
8418}
8419
8420////////////////////////////////////////////////////////////////////////////////
8421/// Upload a PROOF archive (PAR file). A PAR file is a compressed
8422/// tar file with one special additional directory, PROOF-INF
8423/// (blatantly copied from Java's jar format). It must have the extension
8424/// .par. A PAR file can be directly a binary or a source with a build
8425/// procedure. In the PROOF-INF directory there can be a build script:
8426/// BUILD.sh to be called to build the package, in case of a binary PAR
8427/// file don't specify a build script or make it a no-op. Then there is
8428/// SETUP.C which sets the right environment variables to use the package,
8429/// like LD_LIBRARY_PATH, etc.
8430/// The 'opt' allows to specify whether the .PAR should be just unpacked
8431/// in the existing dir (opt = kUntar, default) or a remove of the existing
8432/// directory should be executed (opt = kRemoveOld), so triggering a full
8433/// re-build. The option if effective only for PROOF protocol > 8 .
8434/// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8435/// an alternative global directory for global usage. This may require special
8436/// privileges.
8437/// If download is kTRUE and the package is not found locally, then it is downloaded
8438/// from the master repository.
8439/// Returns 0 in case of success and -1 in case of error.
8440
8442 TList *workers)
8443{
8444 if (!IsValid()) return -1;
8445
8446 // Remote PAR ?
8448 Bool_t remotepar = (ft == TFile::kWeb || ft == TFile::kNet) ? kTRUE : kFALSE;
8449
8450 TString par(pack), base, name;
8451 if (par.EndsWith(".par")) {
8452 base = gSystem->BaseName(par);
8453 name = base(0, base.Length() - strlen(".par"));
8454 } else {
8455 name = gSystem->BaseName(par);
8456 base.Form("%s.par", name.Data());
8457 par += ".par";
8458 }
8459
8460 // Default location is the local working dir; then the package dir
8461 gSystem->ExpandPathName(par);
8463 Int_t xrc = -1;
8464 if (!remotepar) xrc = TPackMgr::FindParPath(fPackMgr, name, par);
8465 if (xrc == 0) {
8466 // Package is in the global dirs
8467 if (gDebug > 0)
8468 Info("UploadPackage", "global package found (%s): no upload needed",
8469 par.Data());
8470 return 0;
8471 } else if (xrc < 0) {
8472 Error("UploadPackage", "PAR file '%s' not found", par.Data());
8473 return -1;
8474 }
8475 }
8476
8477 // Strategy:
8478 // On the client:
8479 // get md5 of package and check if it is different
8480 // from the one stored in the local package directory. If it is lock
8481 // the package directory and copy the package, unlock the directory.
8482 // On the masters:
8483 // get md5 of package and check if it is different from the
8484 // one stored on the remote node. If it is different lock the remote
8485 // package directory and use TFTP or SendFile to ftp the package to the
8486 // remote node, unlock the directory.
8487
8488
8490 Bool_t rmold = (opt == TProof::kRemoveOld) ? kTRUE : kFALSE;
8491 if (fPackMgr->Install(par, rmold) < 0) {
8492 Error("UploadPackage", "installing '%s' failed", gSystem->BaseName(par));
8493 return -1;
8494 }
8495 }
8496
8497 // Nothing more to do if we are a Lite-session
8498 if (IsLite()) return 0;
8499
8500 TMD5 *md5 = fPackMgr->ReadMD5(name);
8501
8502 TString smsg;
8503 if (remotepar && GetRemoteProtocol() > 36) {
8504 smsg.Form("+%s", par.Data());
8505 } else {
8506 smsg.Form("+%s", base.Data());
8507 }
8508
8510 mess << smsg << (*md5);
8512 smsg.Replace(0, 1, "-");
8513 mess2 << smsg << (*md5);
8515 smsg.Replace(0, 1, "=");
8516 mess3 << smsg << (*md5);
8517
8518 delete md5;
8519
8520 if (fProtocol > 8) {
8521 // Send also the option
8522 mess << (UInt_t) opt;
8523 mess2 << (UInt_t) opt;
8524 mess3 << (UInt_t) opt;
8525 }
8526
8527 // Loop over all slaves with unique fs image, or to a selected
8528 // list of workers, if specified
8529 if (!workers)
8530 workers = fUniqueSlaves;
8531 TIter next(workers);
8532 TSlave *sl = 0;
8533 while ((sl = (TSlave *) next())) {
8534 if (!sl->IsValid())
8535 continue;
8536
8537 sl->GetSocket()->Send(mess);
8538
8539 fCheckFileStatus = 0;
8541 if (fCheckFileStatus == 0) {
8542
8543 if (fProtocol > 5) {
8544 // remote directory is locked, upload file over the open channel
8545 smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
8546 if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
8547 Error("UploadPackage", "%s: problems uploading file %s",
8548 sl->GetOrdinal(), par.Data());
8549 return -1;
8550 }
8551 } else {
8552 // old servers receive it via TFTP
8553 TFTP ftp(TString("root://")+sl->GetName(), 1);
8554 if (!ftp.IsZombie()) {
8555 smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
8556 ftp.cd(smsg.Data());
8557 ftp.put(par, base.Data());
8558 }
8559 }
8560
8561 // install package and unlock dir
8562 sl->GetSocket()->Send(mess2);
8563 fCheckFileStatus = 0;
8565 if (fCheckFileStatus == 0) {
8566 Error("UploadPackage", "%s: unpacking of package %s failed",
8567 sl->GetOrdinal(), base.Data());
8568 return -1;
8569 }
8570 }
8571 }
8572
8573 // loop over all other master nodes
8574 TIter nextmaster(fNonUniqueMasters);
8575 TSlave *ma;
8576 while ((ma = (TSlave *) nextmaster())) {
8577 if (!ma->IsValid())
8578 continue;
8579
8580 ma->GetSocket()->Send(mess3);
8581
8582 fCheckFileStatus = 0;
8584 if (fCheckFileStatus == 0) {
8585 // error -> package should have been found
8586 Error("UploadPackage", "package %s did not exist on submaster %s",
8587 base.Data(), ma->GetOrdinal());
8588 return -1;
8589 }
8590 }
8591
8592 return 0;
8593}
8594
8595
8596////////////////////////////////////////////////////////////////////////////////
8597/// Make sure that the directory path contained by macro is in the macro path
8598
8599void TProof::AssertMacroPath(const char *macro)
8600{
8601 static TString macrop(gROOT->GetMacroPath());
8602 if (macro && strlen(macro) > 0) {
8603 TString dirn = gSystem->GetDirName(macro);
8604 if (!macrop.Contains(dirn)) {
8605 macrop += TString::Format("%s:", dirn.Data());
8606 gROOT->SetMacroPath(macrop);
8607 }
8608 }
8609}
8610
8611
8612////////////////////////////////////////////////////////////////////////////////
8613/// Load the specified macro on master, workers and, if notOnClient is
8614/// kFALSE, on the client. The macro file is uploaded if new or updated.
8615/// Additional files to be uploaded (or updated, if needed) can be specified
8616/// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
8617/// If existing in the same directory, a header basename(macro).h or .hh, is also
8618/// uploaded.
8619/// The default is to load the macro also on the client; notOnClient can be used
8620/// to avoid loading on the client.
8621/// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
8622/// only, and collection is not done; if uniqueWorkers is kFALSE, collection
8623/// from the previous request is done, and broadcasting + collection from the
8624/// other workers is done.
8625/// The wrks arg can be used on the master to limit the set of workers.
8626/// Returns 0 in case of success and -1 in case of error.
8627
8628Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
8629 TList *wrks)
8630{
8631 if (!IsValid()) return -1;
8632
8633 if (!macro || !macro[0]) {
8634 Error("Load", "need to specify a macro name");
8635 return -1;
8636 }
8637
8638 // Make sure the path is in the macro path
8640
8641 if (TestBit(TProof::kIsClient) && !wrks) {
8642
8643 // Extract the file implementation name first
8644 TString addsname, implname = macro;
8645 Ssiz_t icom = implname.Index(",");
8646 if (icom != kNPOS) {
8647 addsname = implname(icom + 1, implname.Length());
8648 implname.Remove(icom);
8649 }
8650 TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
8651 TString bmsg(basemacro), acmode, args, io;
8652 implname = gSystem->SplitAclicMode(implname, acmode, args, io);
8653
8654 // Macro names must have a standard format
8655 Int_t dot = implname.Last('.');
8656 if (dot == kNPOS) {
8657 Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
8658 return -1;
8659 }
8660
8661 // Is there any associated header file
8662 Bool_t hasHeader = kTRUE;
8663 TString headname = implname;
8664 headname.Remove(dot);
8665 headname += ".h";
8666 if (gSystem->AccessPathName(headname, kReadPermission)) {
8667 TString h = headname;
8668 headname.Remove(dot);
8669 headname += ".hh";
8670 if (gSystem->AccessPathName(headname, kReadPermission)) {
8671 hasHeader = kFALSE;
8672 if (gDebug > 0)
8673 Info("Load", "no associated header file found: tried: %s %s",
8674 h.Data(), headname.Data());
8675 }
8676 }
8677
8678 // Is there any additional file ?
8679 TString addincs;
8680 TList addfiles;
8681 if (!addsname.IsNull()) {
8682 TString fn;
8683 Int_t from = 0;
8684 while (addsname.Tokenize(fn, from, ",")) {
8686 Error("Load", "additional file '%s' not found", fn.Data());
8687 return -1;
8688 }
8689 // Create the additional include statement
8690 if (!notOnClient) {
8691 TString dirn = gSystem->GetDirName(fn);
8692 if (addincs.IsNull()) {
8693 addincs.Form("-I%s", dirn.Data());
8694 } else if (!addincs.Contains(dirn)) {
8695 addincs += TString::Format(" -I%s", dirn.Data());
8696 }
8697 }
8698 // Remember these files ...
8699 addfiles.Add(new TObjString(fn));
8700 }
8701 }
8702
8703 // Send files now; the md5 check is run here; see SendFile for more
8704 // details.
8705 if (SendFile(implname, kAscii | kForward , "cache") == -1) {
8706 Error("Load", "problems sending implementation file %s", implname.Data());
8707 return -1;
8708 }
8709 if (hasHeader)
8710 if (SendFile(headname, kAscii | kForward , "cache") == -1) {
8711 Error("Load", "problems sending header file %s", headname.Data());
8712 return -1;
8713 }
8714 // Additional files
8715 if (addfiles.GetSize() > 0) {
8716 TIter nxfn(&addfiles);
8717 TObjString *os = 0;
8718 while ((os = (TObjString *) nxfn())) {
8719 // These files need to be available everywhere, cache and sandbox
8720 if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
8721 Error("Load", "problems sending additional file %s", os->GetName());
8722 return -1;
8723 }
8724 // Add the base names to the message broadcasted
8725 bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
8726 }
8727 addfiles.SetOwner(kTRUE);
8728 }
8729
8730 // The files are now on the workers: now we send the loading request
8731 TMessage mess(kPROOF_CACHE);
8732 if (GetRemoteProtocol() < 34) {
8733 mess << Int_t(kLoadMacro) << basemacro;
8734 // This may be needed
8735 AddIncludePath("../../cache");
8736 } else {
8737 mess << Int_t(kLoadMacro) << bmsg;
8738 }
8739 Broadcast(mess, kActive);
8740
8741 // Load locally, if required
8742 if (!notOnClient) {
8743 // Mofify the include path
8744 TString oldincs = gSystem->GetIncludePath();
8745 if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
8746
8747 // By first forwarding the load command to the master and workers
8748 // and only then loading locally we load/build in parallel
8749 gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
8750
8751 // Restore include path
8752 if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
8753
8754 // Update the macro path
8756 TString np = gSystem->GetDirName(macro);
8757 if (!np.IsNull()) {
8758 np += ":";
8759 if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
8760 Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
8761 mp.Insert(ip, np);
8763 if (gDebug > 0)
8764 Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
8765 }
8766 }
8767 }
8768
8769 // Wait for master and workers to be done
8771
8772 if (IsLite()) {
8773 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8774 if (!fLoadedMacros) {
8775 fLoadedMacros = new TList();
8777 }
8778 // if wrks is specified the macro should already be loaded on the master.
8779 fLoadedMacros->Add(new TObjString(macro));
8780 }
8781
8782 } else {
8783 // On master
8784
8785 // The files are now on the workers: now we send the loading request first
8786 // to the unique workers, so that the eventual compilation occurs only once.
8787 TString basemacro = gSystem->BaseName(macro);
8788 TMessage mess(kPROOF_CACHE);
8789
8790 if (uniqueWorkers) {
8791 mess << Int_t(kLoadMacro) << basemacro;
8792 if (wrks) {
8793 Broadcast(mess, wrks);
8794 Collect(wrks);
8795 } else {
8796 Broadcast(mess, kUnique);
8797 }
8798 } else {
8799 // Wait for the result of the previous sending
8801
8802 // We then send a tuned loading request to the other workers
8803 TList others;
8804 TSlave *wrk = 0;
8805 TIter nxw(fActiveSlaves);
8806 while ((wrk = (TSlave *)nxw())) {
8807 if (!fUniqueSlaves->FindObject(wrk)) {
8808 others.Add(wrk);
8809 }
8810 }
8811
8812 // Do not force compilation, if it was requested
8813 Int_t ld = basemacro.Last('.');
8814 if (ld != kNPOS) {
8815 Int_t lpp = basemacro.Index("++", ld);
8816 if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
8817 }
8818 mess << Int_t(kLoadMacro) << basemacro;
8819 Broadcast(mess, &others);
8820 Collect(&others);
8821 }
8822
8823 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8824 if (!fLoadedMacros) {
8825 fLoadedMacros = new TList();
8827 }
8828 // if wrks is specified the macro should already be loaded on the master.
8829 if (!wrks)
8830 fLoadedMacros->Add(new TObjString(macro));
8831 }
8832
8833 // Done
8834 return 0;
8835}
8836
8837////////////////////////////////////////////////////////////////////////////////
8838/// Add 'libpath' to the lib path search.
8839/// Multiple paths can be specified at once separating them with a comma or
8840/// a blank.
8841/// Return 0 on success, -1 otherwise
8842
8843Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
8844 Bool_t doCollect)
8845{
8846 if ((!libpath || !libpath[0])) {
8847 if (gDebug > 0)
8848 Info("AddDynamicPath", "list is empty - nothing to do");
8849 return 0;
8850 }
8851
8852 // Do it also on clients, if required
8853 if (onClient)
8854 HandleLibIncPath("lib", kTRUE, libpath);
8855
8857 m << TString("lib") << (Bool_t)kTRUE;
8858
8859 // Add paths
8860 if (libpath && strlen(libpath)) {
8861 m << TString(libpath);
8862 } else {
8863 m << TString("-");
8864 }
8865
8866 // Tell the server to send back or not
8867 m << (Int_t)doCollect;
8868
8869 // Forward the request
8870 if (wrks) {
8871 Broadcast(m, wrks);
8872 if (doCollect)
8873 Collect(wrks, fCollectTimeout);
8874 } else {
8875 Broadcast(m);
8877 }
8878
8879 return 0;
8880}
8881
8882////////////////////////////////////////////////////////////////////////////////
8883/// Add 'incpath' to the inc path search.
8884/// Multiple paths can be specified at once separating them with a comma or
8885/// a blank.
8886/// Return 0 on success, -1 otherwise
8887
8888Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
8889 Bool_t doCollect)
8890{
8891 if ((!incpath || !incpath[0])) {
8892 if (gDebug > 0)
8893 Info("AddIncludePath", "list is empty - nothing to do");
8894 return 0;
8895 }
8896
8897 // Do it also on clients, if required
8898 if (onClient)
8899 HandleLibIncPath("inc", kTRUE, incpath);
8900
8902 m << TString("inc") << (Bool_t)kTRUE;
8903
8904 // Add paths
8905 if (incpath && strlen(incpath)) {
8906 m << TString(incpath);
8907 } else {
8908 m << TString("-");
8909 }
8910
8911 // Tell the server to send back or not
8912 m << (Int_t)doCollect;
8913
8914 // Forward the request
8915 if (wrks) {
8916 Broadcast(m, wrks);
8917 if (doCollect)
8918 Collect(wrks, fCollectTimeout);
8919 } else {
8920 Broadcast(m);
8922 }
8923
8924 return 0;
8925}
8926
8927////////////////////////////////////////////////////////////////////////////////
8928/// Remove 'libpath' from the lib path search.
8929/// Multiple paths can be specified at once separating them with a comma or
8930/// a blank.
8931/// Return 0 on success, -1 otherwise
8932
8933Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
8934{
8935 if ((!libpath || !libpath[0])) {
8936 if (gDebug > 0)
8937 Info("RemoveDynamicPath", "list is empty - nothing to do");
8938 return 0;
8939 }
8940
8941 // Do it also on clients, if required
8942 if (onClient)
8943 HandleLibIncPath("lib", kFALSE, libpath);
8944
8946 m << TString("lib") <<(Bool_t)kFALSE;
8947
8948 // Add paths
8949 if (libpath && strlen(libpath))
8950 m << TString(libpath);
8951 else
8952 m << TString("-");
8953
8954 // Forward the request
8955 Broadcast(m);
8957
8958 return 0;
8959}
8960
8961////////////////////////////////////////////////////////////////////////////////
8962/// Remove 'incpath' from the inc path search.
8963/// Multiple paths can be specified at once separating them with a comma or
8964/// a blank.
8965/// Return 0 on success, -1 otherwise
8966
8967Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
8968{
8969 if ((!incpath || !incpath[0])) {
8970 if (gDebug > 0)
8971 Info("RemoveIncludePath", "list is empty - nothing to do");
8972 return 0;
8973 }
8974
8975 // Do it also on clients, if required
8976 if (onClient)
8977 HandleLibIncPath("in", kFALSE, incpath);
8978
8980 m << TString("inc") << (Bool_t)kFALSE;
8981
8982 // Add paths
8983 if (incpath && strlen(incpath))
8984 m << TString(incpath);
8985 else
8986 m << TString("-");
8987
8988 // Forward the request
8989 Broadcast(m);
8991
8992 return 0;
8993}
8994
8995////////////////////////////////////////////////////////////////////////////////
8996/// Handle lib, inc search paths modification request
8997
8998void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
8999{
9000 TString type(what);
9001 TString path(dirs);
9002
9003 // Check type of action
9004 if ((type != "lib") && (type != "inc")) {
9005 Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
9006 return;
9007 }
9008
9009 // Separators can be either commas or blanks
9010 path.ReplaceAll(","," ");
9011
9012 // Decompose lists
9013 TObjArray *op = 0;
9014 if (path.Length() > 0 && path != "-") {
9015 if (!(op = path.Tokenize(" "))) {
9016 Warning("HandleLibIncPath","decomposing path %s", path.Data());
9017 return;
9018 }
9019 }
9020
9021 if (add) {
9022
9023 if (type == "lib") {
9024
9025 // Add libs
9026 TIter nxl(op, kIterBackward);
9027 TObjString *lib = 0;
9028 while ((lib = (TObjString *) nxl())) {
9029 // Expand path
9030 TString xlib = lib->GetName();
9031 gSystem->ExpandPathName(xlib);
9032 // Add to the dynamic lib search path if it exists and can be read
9033 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9034 TString newlibpath = gSystem->GetDynamicPath();
9035 // In the first position after the working dir
9036 Int_t pos = 0;
9037 if (newlibpath.BeginsWith(".:"))
9038 pos = 2;
9039 if (newlibpath.Index(xlib) == kNPOS) {
9040 newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9041 gSystem->SetDynamicPath(newlibpath);
9042 }
9043 } else {
9044 if (gDebug > 0)
9045 Info("HandleLibIncPath",
9046 "libpath %s does not exist or cannot be read - not added", xlib.Data());
9047 }
9048 }
9049
9050 } else {
9051
9052 // Add incs
9053 TIter nxi(op);
9054 TObjString *inc = 0;
9055 while ((inc = (TObjString *) nxi())) {
9056 // Expand path
9057 TString xinc = inc->GetName();
9058 gSystem->ExpandPathName(xinc);
9059 // Add to the dynamic lib search path if it exists and can be read
9060 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9061 TString curincpath = gSystem->GetIncludePath();
9062 if (curincpath.Index(xinc) == kNPOS)
9063 gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9064 } else
9065 if (gDebug > 0)
9066 Info("HandleLibIncPath",
9067 "incpath %s does not exist or cannot be read - not added", xinc.Data());
9068 }
9069 }
9070
9071
9072 } else {
9073
9074 if (type == "lib") {
9075
9076 // Remove libs
9077 TIter nxl(op);
9078 TObjString *lib = 0;
9079 while ((lib = (TObjString *) nxl())) {
9080 // Expand path
9081 TString xlib = lib->GetName();
9082 gSystem->ExpandPathName(xlib);
9083 // Remove from the dynamic lib search path
9084 TString newlibpath = gSystem->GetDynamicPath();
9085 newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9086 gSystem->SetDynamicPath(newlibpath);
9087 }
9088
9089 } else {
9090
9091 // Remove incs
9092 TIter nxi(op);
9093 TObjString *inc = 0;
9094 while ((inc = (TObjString *) nxi())) {
9095 TString newincpath = gSystem->GetIncludePath();
9096 newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9097 // Remove the interpreter path (added anyhow internally)
9098 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9099 gSystem->SetIncludePath(newincpath);
9100 }
9101 }
9102 }
9103}
9104
9105////////////////////////////////////////////////////////////////////////////////
9106/// Get from the master the list of names of the packages available.
9107
9109{
9110 if (!IsValid())
9111 return (TList *)0;
9112
9113 TMessage mess(kPROOF_CACHE);
9114 mess << Int_t(kListPackages);
9115 Broadcast(mess);
9117
9118 return fAvailablePackages;
9119}
9120
9121////////////////////////////////////////////////////////////////////////////////
9122/// Get from the master the list of names of the packages enabled.
9123
9125{
9126 if (!IsValid())
9127 return (TList *)0;
9128
9129 TMessage mess(kPROOF_CACHE);
9130 mess << Int_t(kListEnabledPackages);
9131 Broadcast(mess);
9133
9134 return fEnabledPackages;
9135}
9136
9137////////////////////////////////////////////////////////////////////////////////
9138/// Print a progress bar on stderr. Used in batch mode.
9139
9141 Float_t procTime, Long64_t bytesread)
9142{
9143 if (fPrintProgress) {
9144 Bool_t redirlog = fRedirLog;
9145 fRedirLog = kFALSE;
9146 // Call the external function
9147 (*fPrintProgress)(total, processed, procTime, bytesread);
9148 fRedirLog = redirlog;
9149 return;
9150 }
9151
9152 fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9153
9154 for (int l = 0; l < 20; l++) {
9155 if (total > 0) {
9156 if (l < 20*processed/total)
9157 fprintf(stderr, "=");
9158 else if (l == 20*processed/total)
9159 fprintf(stderr, ">");
9160 else if (l > 20*processed/total)
9161 fprintf(stderr, ".");
9162 } else
9163 fprintf(stderr, "=");
9164 }
9165 Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9166 Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9167 TString sunit("B/s");
9168 if (evtrti > 0.) {
9169 Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9170 if (mbsrti > 0.) {
9171 const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9172 if (mbsrti >= toG) {
9173 mbsrti /= toG;
9174 sunit = "GB/s";
9175 } else if (mbsrti >= toM) {
9176 mbsrti /= toM;
9177 sunit = "MB/s";
9178 } else if (mbsrti >= toK) {
9179 mbsrti /= toK;
9180 sunit = "kB/s";
9181 }
9182 fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9183 (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9184 } else {
9185 fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9186 (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9187 }
9188 } else {
9189 fprintf(stderr, "| %.02f %%\r",
9190 (total ? ((100.0*processed)/total) : 100.0));
9191 }
9192 if (processed >= total) {
9193 fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9194 }
9195}
9196
9197////////////////////////////////////////////////////////////////////////////////
9198/// Get query progress information. Connect a slot to this signal
9199/// to track progress.
9200
9202{
9203 if (fPrintProgress) {
9204 // Call the external function
9205 return (*fPrintProgress)(total, processed, -1., -1);
9206 }
9207
9208 PDB(kGlobal,1)
9209 Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9210
9211 if (gROOT->IsBatch()) {
9212 // Simple progress bar
9213 if (total > 0)
9214 PrintProgress(total, processed);
9215 } else {
9216 EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9217 }
9218}
9219
9220////////////////////////////////////////////////////////////////////////////////
9221/// Get query progress information. Connect a slot to this signal
9222/// to track progress.
9223
9225 Float_t initTime, Float_t procTime,
9226 Float_t evtrti, Float_t mbrti)
9227{
9228 PDB(kGlobal,1)
9229 Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9230 initTime, procTime, evtrti, mbrti);
9231
9232 if (gROOT->IsBatch()) {
9233 // Simple progress bar
9234 if (total > 0)
9235 PrintProgress(total, processed, procTime, bytesread);
9236 } else {
9237 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9238 7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9239 }
9240}
9241
9242////////////////////////////////////////////////////////////////////////////////
9243/// Get query progress information. Connect a slot to this signal
9244/// to track progress.
9245
9247 Float_t initTime, Float_t procTime,
9248 Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9249{
9250 PDB(kGlobal,1)
9251 Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9252 initTime, procTime, evtrti, mbrti, actw, eses);
9253
9254 if (gROOT->IsBatch()) {
9255 // Simple progress bar
9256 if (total > 0)
9257 PrintProgress(total, processed, procTime, bytesread);
9258 } else {
9259 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9260 10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9261 }
9262}
9263
9264////////////////////////////////////////////////////////////////////////////////
9265/// Get list of feedback objects. Connect a slot to this signal
9266/// to monitor the feedback object.
9267
9269{
9270 PDB(kGlobal,1)
9271 Info("Feedback","%d objects", objs->GetSize());
9272 PDB(kFeedback,1) {
9273 Info("Feedback","%d objects", objs->GetSize());
9274 objs->ls();
9275 }
9276
9277 Emit("Feedback(TList *objs)", (Longptr_t) objs);
9278}
9279
9280////////////////////////////////////////////////////////////////////////////////
9281/// Close progress dialog.
9282
9284{
9285 PDB(kGlobal,1)
9286 Info("CloseProgressDialog",
9287 "called: have progress dialog: %d", fProgressDialogStarted);
9288
9289 // Nothing to do if not there
9291 return;
9292
9293 Emit("CloseProgressDialog()");
9294}
9295
9296////////////////////////////////////////////////////////////////////////////////
9297/// Reset progress dialog.
9298
9299void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9300 Long64_t ent)
9301{
9302 PDB(kGlobal,1)
9303 Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9304
9305 EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9306 4, sel, sz, fst, ent);
9307}
9308
9309////////////////////////////////////////////////////////////////////////////////
9310/// Send startup message.
9311
9312void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9313{
9314 PDB(kGlobal,1)
9315 Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9316
9317 EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9318 4, msg, st, done, total);
9319}
9320
9321////////////////////////////////////////////////////////////////////////////////
9322/// Send dataset preparation status.
9323
9324void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9325{
9326 PDB(kGlobal,1)
9327 Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9328
9329 EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9330 4, msg, st, done, total);
9331}
9332
9333////////////////////////////////////////////////////////////////////////////////
9334/// Send or notify data set status
9335
9336void TProof::SendDataSetStatus(const char *action, UInt_t done,
9337 UInt_t tot, Bool_t st)
9338{
9339 if (IsLite()) {
9340 if (tot) {
9341 TString type = "files";
9342 Int_t frac = (Int_t) (done*100.)/tot;
9343 char msg[512] = {0};
9344 if (frac >= 100) {
9345 snprintf(msg, 512, "%s: OK (%d %s) \n",
9346 action,tot, type.Data());
9347 } else {
9348 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9349 action, done, tot, frac);
9350 }
9351 if (fSync)
9352 fprintf(stderr,"%s", msg);
9353 else
9354 NotifyLogMsg(msg, 0);
9355 }
9356 return;
9357 }
9358
9361 mess << TString(action) << tot << done << st;
9362 gProofServ->GetSocket()->Send(mess);
9363 }
9364}
9365
9366////////////////////////////////////////////////////////////////////////////////
9367/// Notify availability of a query result.
9368
9369void TProof::QueryResultReady(const char *ref)
9370{
9371 PDB(kGlobal,1)
9372 Info("QueryResultReady","ref: %s", ref);
9373
9374 Emit("QueryResultReady(const char*)",ref);
9375}
9376
9377////////////////////////////////////////////////////////////////////////////////
9378/// Validate a TDSet.
9379
9381{
9382 if (dset->ElementsValid()) return;
9383
9384 TList nodes;
9385 nodes.SetOwner();
9386
9387 TList slholder;
9388 slholder.SetOwner();
9389 TList elemholder;
9390 elemholder.SetOwner();
9391
9392 // build nodelist with slaves and elements
9393 TIter nextSlave(GetListOfActiveSlaves());
9394 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9395 TList *sllist = 0;
9396 TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9397 if (!p) {
9398 sllist = new TList;
9399 sllist->SetName(sl->GetName());
9400 slholder.Add(sllist);
9401 TList *elemlist = new TList;
9402 elemlist->SetName(TString(sl->GetName())+"_elem");
9403 elemholder.Add(elemlist);
9404 nodes.Add(new TPair(sllist, elemlist));
9405 } else {
9406 sllist = dynamic_cast<TList*>(p->Key());
9407 }
9408 if (sllist) sllist->Add(sl);
9409 }
9410
9411 // add local elements to nodes
9412 TList nonLocal; // list of nonlocal elements
9413 // make two iterations - first add local elements - then distribute nonlocals
9414 for (Int_t i = 0; i < 2; i++) {
9415 Bool_t local = i>0?kFALSE:kTRUE;
9416 TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9417 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9418 if (elem->GetValid()) continue;
9419 TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9420 if (p) {
9421 TList *eli = dynamic_cast<TList*>(p->Value());
9422 TList *sli = dynamic_cast<TList*>(p->Key());
9423 if (eli && sli) {
9424 eli->Add(elem);
9425
9426 // order list by elements/slave
9427 TPair *p2 = p;
9428 Bool_t stop = kFALSE;
9429 while (!stop) {
9430 TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9431 if (p3) {
9432 TList *p3v = dynamic_cast<TList*>(p3->Value());
9433 TList *p3k = dynamic_cast<TList*>(p3->Key());
9434 if (p3v && p3k) {
9435 Int_t nelem = p3v->GetSize();
9436 Int_t nsl = p3k->GetSize();
9437 if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
9438 else stop = kTRUE;
9439 }
9440 } else {
9441 stop = kTRUE;
9442 }
9443 }
9444
9445 if (p2!=p) {
9446 nodes.Remove(p->Key());
9447 nodes.AddAfter(p2->Key(), p);
9448 }
9449 } else {
9450 Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
9451 continue;
9452 }
9453
9454 } else {
9455 if (local) {
9456 nonLocal.Add(elem);
9457 } else {
9458 Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
9459 }
9460 }
9461 }
9462 }
9463
9464 // send to slaves
9465 TList usedslaves;
9466 TIter nextNode(&nodes);
9467 SetDSet(dset); // set dset to be validated in Collect()
9468 while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
9469 TList *slaves = dynamic_cast<TList*>(node->Key());
9470 TList *setelements = dynamic_cast<TList*>(node->Value());
9471 if (!slaves || !setelements) continue;
9472 // distribute elements over the slaves
9473 Int_t nslaves = slaves->GetSize();
9474 Int_t nelements = setelements->GetSize();
9475 for (Int_t i=0; i<nslaves; i++) {
9476
9477 TDSet copyset(dset->GetType(), dset->GetObjName(),
9478 dset->GetDirectory());
9479 for (Int_t j = (i*nelements)/nslaves;
9480 j < ((i+1)*nelements)/nslaves;
9481 j++) {
9482 TDSetElement *elem =
9483 dynamic_cast<TDSetElement*>(setelements->At(j));
9484 if (elem) {
9485 copyset.Add(elem->GetFileName(), elem->GetObjName(),
9486 elem->GetDirectory(), elem->GetFirst(),
9487 elem->GetNum(), elem->GetMsd());
9488 }
9489 }
9490
9491 if (copyset.GetListOfElements()->GetSize()>0) {
9493 mesg << &copyset;
9494
9495 TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
9496 if (sl) {
9497 PDB(kGlobal,1) Info("ValidateDSet",
9498 "Sending TDSet with %d elements to slave %s"
9499 " to be validated",
9500 copyset.GetListOfElements()->GetSize(),
9501 sl->GetOrdinal());
9502 sl->GetSocket()->Send(mesg);
9503 usedslaves.Add(sl);
9504 }
9505 }
9506 }
9507 }
9508
9509 PDB(kGlobal,1)
9510 Info("ValidateDSet","Calling Collect");
9511 Collect(&usedslaves);
9512 SetDSet(0);
9513}
9514
9515////////////////////////////////////////////////////////////////////////////////
9516/// Add data objects that might be needed during the processing of
9517/// the selector (see Process()). This object can be very large, so they
9518/// are distributed in an optimized way using a dedicated file.
9519/// If push is TRUE the input data are sent over even if no apparent change
9520/// occured to the list.
9521
9523{
9524 if (obj) {
9525 if (!fInputData) fInputData = new TList;
9526 if (!fInputData->FindObject(obj)) {
9527 fInputData->Add(obj);
9529 }
9530 }
9531 if (push) SetBit(TProof::kNewInputData);
9532}
9533
9534////////////////////////////////////////////////////////////////////////////////
9535/// Remove obj form the input data list; if obj is null (default), clear the
9536/// input data info.
9537
9539{
9540 if (!obj) {
9541 if (fInputData) {
9544 }
9546
9547 // Also remove any info about input data in the input list
9548 TObject *o = 0;
9549 TList *in = GetInputList();
9550 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9551 in->Remove(o);
9552 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9553 in->Remove(o);
9554
9555 // ... and reset the file
9556 fInputDataFile = "";
9558
9559 } else if (fInputData) {
9560 Int_t sz = fInputData->GetSize();
9561 while (fInputData->FindObject(obj))
9562 fInputData->Remove(obj);
9563 // Flag for update, if anything changed
9564 if (sz != fInputData->GetSize())
9566 }
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570/// Remove obj 'name' form the input data list;
9571
9573{
9574 TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
9575 if (obj) ClearInputData(obj);
9576}
9577
9578////////////////////////////////////////////////////////////////////////////////
9579/// Set the file to be used to optimally distribute the input data objects.
9580/// If the file exists the object in the file are added to those in the
9581/// fInputData list. If the file path is null, a default file will be created
9582/// at the moment of sending the processing request with the content of
9583/// the fInputData list. See also SendInputDataFile.
9584
9585void TProof::SetInputDataFile(const char *datafile)
9586{
9587 if (datafile && strlen(datafile) > 0) {
9588 if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
9590 fInputDataFile = datafile;
9591 } else {
9592 if (!fInputDataFile.IsNull())
9594 fInputDataFile = "";
9595 }
9596 // Make sure that the chosen file is readable
9599 fInputDataFile = "";
9600 }
9601}
9602
9603////////////////////////////////////////////////////////////////////////////////
9604/// Send the input data objects to the master; the objects are taken from the
9605/// dedicated list and / or the specified file.
9606/// If the fInputData is empty the specified file is sent over.
9607/// If there is no specified file, a file named "inputdata.root" is created locally
9608/// with the content of fInputData and sent over to the master.
9609/// If both fInputData and the specified file are not empty, a copy of the file
9610/// is made locally and augmented with the content of fInputData.
9611
9613{
9614 // Prepare the file
9615 TString dataFile;
9616 PrepareInputDataFile(dataFile);
9617
9618 // Send it, if not empty
9619 if (dataFile.Length() > 0) {
9620
9621 Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
9622 BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
9623
9624 // Set the name in the input list
9625 TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
9626 AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
9627 }
9628}
9629
9630////////////////////////////////////////////////////////////////////////////////
9631/// Prepare the file with the input data objects to be sent the master; the
9632/// objects are taken from the dedicated list and / or the specified file.
9633/// If the fInputData is empty the specified file is sent over.
9634/// If there is no specified file, a file named "inputdata.root" is created locally
9635/// with the content of fInputData and sent over to the master.
9636/// If both fInputData and the specified file are not empty, a copy of the file
9637/// is made locally and augmented with the content of fInputData.
9638
9640{
9641 // Save info about new data for usage in this call;
9643 // Next time we need some change
9645
9646 // Check the list
9647 Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
9648 // Check the file
9649 Bool_t file_ok = kFALSE;
9652 // It must contain something
9654 if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
9655 file_ok = kTRUE;
9656 }
9657
9658 // Remove any info about input data in the input list
9659 TObject *o = 0;
9660 TList *in = GetInputList();
9661 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9662 in->Remove(o);
9663 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9664 in->Remove(o);
9665
9666 // We must have something to send
9667 dataFile = "";
9668 if (!list_ok && !file_ok) return;
9669
9670 // Three cases:
9671 if (file_ok && !list_ok) {
9672 // Just send the file
9673 dataFile = fInputDataFile;
9674 } else if (!file_ok && list_ok) {
9676 // Nothing to do, if no new data
9677 if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
9678 // Create the file first
9679 TFile *f = TFile::Open(fInputDataFile, "RECREATE");
9680 if (f) {
9681 f->cd();
9682 TIter next(fInputData);
9683 TObject *obj;
9684 while ((obj = next())) {
9685 obj->Write(0, TObject::kSingleKey, 0);
9686 }
9687 f->Close();
9688 SafeDelete(f);
9689 } else {
9690 Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
9691 return;
9692 }
9693 dataFile = fInputDataFile;
9694 } else if (file_ok && list_ok) {
9695 dataFile = kPROOF_InputDataFile;
9696 // Create the file if not existing or there are new data
9697 if (newdata || gSystem->AccessPathName(dataFile)) {
9698 // Cleanup previous file if obsolete
9699 if (!gSystem->AccessPathName(dataFile))
9700 gSystem->Unlink(dataFile);
9701 if (dataFile != fInputDataFile) {
9702 // Make a local copy first
9703 if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
9704 Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
9705 return;
9706 }
9707 }
9708 // Add the input data list
9709 TFile *f = TFile::Open(dataFile, "UPDATE");
9710 if (f) {
9711 f->cd();
9712 TIter next(fInputData);
9713 TObject *obj = 0;
9714 while ((obj = next())) {
9715 obj->Write(0, TObject::kSingleKey, 0);
9716 }
9717 f->Close();
9718 SafeDelete(f);
9719 } else {
9720 Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
9721 return;
9722 }
9723 }
9724 }
9725
9726 // Done
9727 return;
9728}
9729
9730////////////////////////////////////////////////////////////////////////////////
9731/// Add objects that might be needed during the processing of
9732/// the selector (see Process()).
9733
9735{
9736 if (fPlayer) fPlayer->AddInput(obj);
9737}
9738
9739////////////////////////////////////////////////////////////////////////////////
9740/// Clear input object list.
9741
9743{
9744 if (fPlayer) fPlayer->ClearInput();
9745
9746 // the system feedback list is always in the input list
9748}
9749
9750////////////////////////////////////////////////////////////////////////////////
9751/// Get input list.
9752
9754{
9755 return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
9756}
9757
9758////////////////////////////////////////////////////////////////////////////////
9759/// Get specified object that has been produced during the processing
9760/// (see Process()).
9761
9763{
9764
9766 // Can be called by MarkBad on the master before the player is initialized
9767 return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
9768
9769 // This checks also associated output files
9770 return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
9771}
9772
9773////////////////////////////////////////////////////////////////////////////////
9774/// Find object 'name' in list 'out' or in the files specified in there
9775
9777{
9778 TObject *o = 0;
9779 if (!name || (name && strlen(name) <= 0) ||
9780 !out || (out && out->GetSize() <= 0)) return o;
9781 if ((o = out->FindObject(name))) return o;
9782
9783 // For the time being we always check for all the files; this may require
9784 // some caching
9785 TProofOutputFile *pf = 0;
9786 TIter nxo(out);
9787 while ((o = nxo())) {
9788 if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
9789 TFile *f = 0;
9790 if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
9791 TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
9792 f = TFile::Open(fn.Data());
9793 if (!f || (f && f->IsZombie())) {
9794 ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
9795 }
9796 }
9797 if (f && (o = f->Get(name))) return o;
9798 }
9799 }
9800
9801 // Done, unsuccessfully
9802 return o;
9803}
9804
9805////////////////////////////////////////////////////////////////////////////////
9806/// Get list with all object created during processing (see Process()).
9807
9809{
9810 if (fOutputList.GetSize() > 0) return &fOutputList;
9811 if (fPlayer) {
9813 return &fOutputList;
9814 }
9815 return (TList *)0;
9816}
9817
9818////////////////////////////////////////////////////////////////////////////////
9819/// Set input list parameter. If the parameter is already
9820/// set it will be set to the new value.
9821
9822void TProof::SetParameter(const char *par, const char *value)
9823{
9824 if (!fPlayer) {
9825 Warning("SetParameter", "player undefined! Ignoring");
9826 return;
9827 }
9828
9829 TList *il = fPlayer->GetInputList();
9830 TObject *item = il->FindObject(par);
9831 if (item) {
9832 il->Remove(item);
9833 delete item;
9834 }
9835 il->Add(new TNamed(par, value));
9836}
9837
9838////////////////////////////////////////////////////////////////////////////////
9839/// Set an input list parameter.
9840
9841void TProof::SetParameter(const char *par, Int_t value)
9842{
9843 if (!fPlayer) {
9844 Warning("SetParameter", "player undefined! Ignoring");
9845 return;
9846 }
9847
9848 TList *il = fPlayer->GetInputList();
9849 TObject *item = il->FindObject(par);
9850 if (item) {
9851 il->Remove(item);
9852 delete item;
9853 }
9854 il->Add(new TParameter<Int_t>(par, value));
9855}
9856
9857////////////////////////////////////////////////////////////////////////////////
9858/// Set an input list parameter.
9859
9860void TProof::SetParameter(const char *par, Long_t value)
9861{
9862 if (!fPlayer) {
9863 Warning("SetParameter", "player undefined! Ignoring");
9864 return;
9865 }
9866
9867 TList *il = fPlayer->GetInputList();
9868 TObject *item = il->FindObject(par);
9869 if (item) {
9870 il->Remove(item);
9871 delete item;
9872 }
9873 il->Add(new TParameter<Long_t>(par, value));
9874}
9875
9876////////////////////////////////////////////////////////////////////////////////
9877/// Set an input list parameter.
9878
9879void TProof::SetParameter(const char *par, Long64_t value)
9880{
9881 if (!fPlayer) {
9882 Warning("SetParameter", "player undefined! Ignoring");
9883 return;
9884 }
9885
9886 TList *il = fPlayer->GetInputList();
9887 TObject *item = il->FindObject(par);
9888 if (item) {
9889 il->Remove(item);
9890 delete item;
9891 }
9892 il->Add(new TParameter<Long64_t>(par, value));
9893}
9894
9895////////////////////////////////////////////////////////////////////////////////
9896/// Set an input list parameter.
9897
9898void TProof::SetParameter(const char *par, Double_t value)
9899{
9900 if (!fPlayer) {
9901 Warning("SetParameter", "player undefined! Ignoring");
9902 return;
9903 }
9904
9905 TList *il = fPlayer->GetInputList();
9906 TObject *item = il->FindObject(par);
9907 if (item) {
9908 il->Remove(item);
9909 delete item;
9910 }
9911 il->Add(new TParameter<Double_t>(par, value));
9912}
9913
9914////////////////////////////////////////////////////////////////////////////////
9915/// Get specified parameter. A parameter set via SetParameter() is either
9916/// a TParameter or a TNamed or 0 in case par is not defined.
9917
9918TObject *TProof::GetParameter(const char *par) const
9919{
9920 if (!fPlayer) {
9921 Warning("GetParameter", "player undefined! Ignoring");
9922 return (TObject *)0;
9923 }
9924
9925 TList *il = fPlayer->GetInputList();
9926 return il->FindObject(par);
9927}
9928
9929////////////////////////////////////////////////////////////////////////////////
9930/// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
9931/// or exact name (e.g. PROOF_MaxSlavesPerNode).
9932
9933void TProof::DeleteParameters(const char *wildcard)
9934{
9935 if (!fPlayer) return;
9936
9937 if (!wildcard) wildcard = "";
9938 TRegexp re(wildcard, kTRUE);
9939 Int_t nch = strlen(wildcard);
9940
9941 TList *il = fPlayer->GetInputList();
9942 if (il) {
9943 TObject *p = 0;
9944 TIter next(il);
9945 while ((p = next())) {
9946 TString s = p->GetName();
9947 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9948 il->Remove(p);
9949 delete p;
9950 }
9951 }
9952}
9953
9954////////////////////////////////////////////////////////////////////////////////
9955/// Show the input list parameters specified by the wildcard.
9956/// Default is the special PROOF control parameters (PROOF_*).
9957
9958void TProof::ShowParameters(const char *wildcard) const
9959{
9960 if (!fPlayer) return;
9961
9962 if (!wildcard) wildcard = "";
9963 TRegexp re(wildcard, kTRUE);
9964 Int_t nch = strlen(wildcard);
9965
9966 TList *il = fPlayer->GetInputList();
9967 TObject *p;
9968 TIter next(il);
9969 while ((p = next())) {
9970 TString s = p->GetName();
9971 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9972 if (p->IsA() == TNamed::Class()) {
9973 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9974 } else if (p->IsA() == TParameter<Long_t>::Class()) {
9975 Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
9976 } else if (p->IsA() == TParameter<Long64_t>::Class()) {
9977 Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
9978 } else if (p->IsA() == TParameter<Double_t>::Class()) {
9979 Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
9980 } else {
9981 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9982 }
9983 }
9984}
9985
9986////////////////////////////////////////////////////////////////////////////////
9987/// Add object to feedback list.
9988
9989void TProof::AddFeedback(const char *name)
9990{
9991 PDB(kFeedback, 3)
9992 Info("AddFeedback", "Adding object \"%s\" to feedback", name);
9993 if (fFeedback->FindObject(name) == 0)
9995}
9996
9997////////////////////////////////////////////////////////////////////////////////
9998/// Remove object from feedback list.
9999
10001{
10003 if (obj != 0) {
10004 fFeedback->Remove(obj);
10005 delete obj;
10006 }
10007}
10008
10009////////////////////////////////////////////////////////////////////////////////
10010/// Clear feedback list.
10011
10013{
10014 fFeedback->Delete();
10015}
10016
10017////////////////////////////////////////////////////////////////////////////////
10018/// Show items in feedback list.
10019
10021{
10022 if (fFeedback->GetSize() == 0) {
10023 Info("","no feedback requested");
10024 return;
10025 }
10026
10027 fFeedback->Print();
10028}
10029
10030////////////////////////////////////////////////////////////////////////////////
10031/// Return feedback list.
10032
10034{
10035 return fFeedback;
10036}
10037
10038////////////////////////////////////////////////////////////////////////////////
10039/// Creates a tree header (a tree with nonexisting files) object for
10040/// the DataSet.
10041
10043{
10045 TSlave *sl = (TSlave*) l->First();
10046 if (sl == 0) {
10047 Error("GetTreeHeader", "No connection");
10048 return 0;
10049 }
10050
10051 TSocket *soc = sl->GetSocket();
10053
10054 msg << dset;
10055
10056 soc->Send(msg);
10057
10058 TMessage *reply;
10059 Int_t d = -1;
10060 if (fProtocol >= 20) {
10062 reply = (TMessage *) fRecvMessages->First();
10063 } else {
10064 d = soc->Recv(reply);
10065 }
10066 if (!reply) {
10067 Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10068 return 0;
10069 }
10070
10071 TString s1;
10072 TTree *t = 0;
10073 (*reply) >> s1;
10074 if (s1 == "Success")
10075 (*reply) >> t;
10076
10077 PDB(kGlobal, 1) {
10078 if (t) {
10079 Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10080 s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10081 } else {
10082 Info("GetTreeHeader", "tree header retrieval failed");
10083 }
10084 }
10085 delete reply;
10086
10087 return t;
10088}
10089
10090////////////////////////////////////////////////////////////////////////////////
10091/// Draw feedback creation proxy. When accessed via TProof avoids
10092/// link dependency on libProofPlayer.
10093
10095{
10096 return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10097}
10098
10099////////////////////////////////////////////////////////////////////////////////
10100/// Set draw feedback option.
10101
10103{
10105}
10106
10107////////////////////////////////////////////////////////////////////////////////
10108/// Delete draw feedback object.
10109
10111{
10113}
10114
10115////////////////////////////////////////////////////////////////////////////////
10116/// FIXME: to be written
10117
10119{
10120 return 0;
10121/*
10122 TMessage msg(kPROOF_GETOUTPUTLIST);
10123 TList* slaves = fActiveSlaves;
10124 Broadcast(msg, slaves);
10125 TMonitor mon;
10126 TList* outputList = new TList();
10127
10128 TIter si(slaves);
10129 TSlave *slave;
10130 while ((slave = (TSlave*)si.Next()) != 0) {
10131 PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10132 slave->GetSocket(), slave->GetName());
10133 mon.Add(slave->GetSocket());
10134 }
10135 mon.ActivateAll();
10136 ((TProof*)gProof)->DeActivateAsyncInput();
10137 ((TProof*)gProof)->fCurrentMonitor = &mon;
10138
10139 while (mon.GetActive() != 0) {
10140 TSocket *sock = mon.Select();
10141 if (!sock) {
10142 Error("GetOutputList","TMonitor::.Select failed!");
10143 break;
10144 }
10145 mon.DeActivate(sock);
10146 TMessage *reply;
10147 if (sock->Recv(reply) <= 0) {
10148 MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10149// Error("GetOutputList","Recv failed! for slave-%d (%s)",
10150// slave->GetOrdinal(), slave->GetName());
10151 continue;
10152 }
10153 if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10154// Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10155// slave->GetOrdinal(), slave->GetName());
10156 MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10157 continue;
10158 }
10159 TList* l;
10160
10161 (*reply) >> l;
10162 TIter next(l);
10163 TNamed *n;
10164 while ( (n = dynamic_cast<TNamed*> (next())) ) {
10165 if (!outputList->FindObject(n->GetName()))
10166 outputList->Add(n);
10167 }
10168 delete reply;
10169 }
10170 ((TProof*)gProof)->fCurrentMonitor = 0;
10171
10172 return outputList;
10173*/
10174}
10175
10176////////////////////////////////////////////////////////////////////////////////
10177/// Build the PROOF's structure in the browser.
10178
10180{
10181 b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10182 b->Add(&fMaster, fMaster.Class(), "fMaster");
10183 b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10184 b->Add(fChains, fChains->Class(), "fChains");
10185
10186 if (fPlayer) {
10187 b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10188 if (fPlayer->GetOutputList())
10189 b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10191 b->Add(fPlayer->GetListOfResults(),
10192 fPlayer->GetListOfResults()->Class(), "ListOfResults");
10193 }
10194}
10195
10196////////////////////////////////////////////////////////////////////////////////
10197/// Set a new PROOF player.
10198
10200{
10201 if (fPlayer)
10202 delete fPlayer;
10203 fPlayer = player;
10204};
10205
10206////////////////////////////////////////////////////////////////////////////////
10207/// Construct a TProofPlayer object. The player string specifies which
10208/// player should be created: remote, slave, sm (supermaster) or base.
10209/// Default is remote. Socket is needed in case a slave player is created.
10210
10212{
10213 if (!player)
10214 player = "remote";
10215
10216 SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10217 return GetPlayer();
10218}
10219
10220////////////////////////////////////////////////////////////////////////////////
10221/// Add chain to data set
10222
10224{
10225 fChains->Add(chain);
10226}
10227
10228////////////////////////////////////////////////////////////////////////////////
10229/// Remove chain from data set
10230
10232{
10233 fChains->Remove(chain);
10234}
10235
10236////////////////////////////////////////////////////////////////////////////////
10237/// Ask for remote logs in the range [start, end]. If start == -1 all the
10238/// messages not yet received are sent back.
10239
10241{
10242 if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10243
10245
10246 msg << start << end;
10247
10248 Broadcast(msg, kActive);
10250}
10251
10252////////////////////////////////////////////////////////////////////////////////
10253/// Fill a TMacro with the log lines since the last reading (fLogFileR)
10254/// Return (TMacro *)0 if no line was logged.
10255/// The returned TMacro must be deleted by the caller.
10256
10258{
10259 TMacro *maclog = 0;
10260
10261 // Save present offset
10262 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10263 if (nowlog < 0) {
10264 SysError("GetLastLog",
10265 "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10266 return maclog;
10267 }
10268
10269 // Get extremes
10270 off_t startlog = nowlog;
10271 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10272 if (endlog < 0) {
10273 SysError("GetLastLog",
10274 "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10275 return maclog;
10276 }
10277
10278 // Perhaps nothing to log
10279 UInt_t tolog = (UInt_t)(endlog - startlog);
10280 if (tolog <= 0) return maclog;
10281
10282 // Set starting point
10283 if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10284 SysError("GetLastLog",
10285 "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10286 return maclog;
10287 }
10288
10289 // Create the output object
10290 maclog = new TMacro;
10291
10292 // Now we go
10293 char line[2048];
10294 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10295 while (fgets(line, wanted, fLogFileR)) {
10296 Int_t r = strlen(line);
10297 if (r > 0) {
10298 if (line[r-1] == '\n') line[r-1] = '\0';
10299 maclog->AddLine(line);
10300 } else {
10301 // Done
10302 break;
10303 }
10304 tolog -= r;
10305 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10306 }
10307
10308 // Restore original pointer
10309 if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10310 Warning("GetLastLog",
10311 "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10312 }
10313
10314 // Done
10315 return maclog;
10316}
10317
10318////////////////////////////////////////////////////////////////////////////////
10319/// Display log of query pq into the log window frame
10320
10322{
10323 if (!pq) return;
10324
10325 TList *lines = pq->GetLogFile()->GetListOfLines();
10326 if (lines) {
10327 TIter nxl(lines);
10328 TObjString *l = 0;
10329 while ((l = (TObjString *)nxl()))
10330 EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10331 }
10332}
10333
10334////////////////////////////////////////////////////////////////////////////////
10335/// Display on screen the content of the temporary log file for query
10336/// in reference
10337
10338void TProof::ShowLog(const char *queryref)
10339{
10340 // Make sure we have all info (GetListOfQueries retrieves the
10341 // head info only)
10342 Retrieve(queryref);
10343
10344 if (fPlayer) {
10345 if (queryref) {
10346 if (fPlayer->GetListOfResults()) {
10348 TQueryResult *qr = 0;
10349 while ((qr = (TQueryResult *) nxq()))
10350 if (strstr(queryref, qr->GetTitle()) &&
10351 strstr(queryref, qr->GetName()))
10352 break;
10353 if (qr) {
10354 PutLog(qr);
10355 return;
10356 }
10357
10358 }
10359 }
10360 }
10361}
10362
10363////////////////////////////////////////////////////////////////////////////////
10364/// Display on screen the content of the temporary log file.
10365/// If qry == -2 show messages from the last (current) query.
10366/// If qry == -1 all the messages not yet displayed are shown (default).
10367/// If qry == 0, all the messages in the file are shown.
10368/// If qry > 0, only the messages related to query 'qry' are shown.
10369/// For qry != -1 the original file offset is restored at the end
10370
10372{
10373 // Save present offset
10374 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10375 if (nowlog < 0) {
10376 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10377 return;
10378 }
10379
10380 // Get extremes
10381 off_t startlog = nowlog;
10382 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10383 if (endlog < 0) {
10384 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10385 return;
10386 }
10387
10388 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10389 if (qry == 0) {
10390 startlog = 0;
10391 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10392 } else if (qry != -1) {
10393
10394 TQueryResult *pq = 0;
10395 if (qry == -2) {
10396 // Pickup the last one
10397 pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10398 if (!pq) {
10400 if (fQueries)
10401 pq = (TQueryResult *)(fQueries->Last());
10402 }
10403 } else if (qry > 0) {
10404 TList *queries = GetQueryResults();
10405 if (queries) {
10406 TIter nxq(queries);
10407 while ((pq = (TQueryResult *)nxq()))
10408 if (qry == pq->GetSeqNum())
10409 break;
10410 }
10411 if (!pq) {
10412 queries = GetListOfQueries();
10413 TIter nxq(queries);
10414 while ((pq = (TQueryResult *)nxq()))
10415 if (qry == pq->GetSeqNum())
10416 break;
10417 }
10418 }
10419 if (pq) {
10420 PutLog(pq);
10421 return;
10422 } else {
10423 if (gDebug > 0)
10424 Info("ShowLog","query %d not found in list", qry);
10425 qry = -1;
10426 }
10427 }
10428
10429 // Number of bytes to log
10430 UInt_t tolog = (UInt_t)(endlog - startlog);
10431
10432 // Perhaps nothing
10433 if (tolog <= 0) {
10434 // Set starting point
10435 lseek(fileno(fLogFileR), startlog, SEEK_SET);
10436 }
10437
10438 // Now we go
10439 Int_t np = 0;
10440 char line[2048];
10441 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10442 while (fgets(line, wanted, fLogFileR)) {
10443
10444 Int_t r = strlen(line);
10445 if (!SendingLogToWindow()) {
10446 if (line[r-1] != '\n') line[r-1] = '\n';
10447 if (r > 0) {
10448 char *p = line;
10449 while (r) {
10450 Int_t w = write(fileno(stdout), p, r);
10451 if (w < 0) {
10452 SysError("ShowLog", "error writing to stdout");
10453 break;
10454 }
10455 r -= w;
10456 p += w;
10457 }
10458 }
10459 tolog -= strlen(line);
10460 np++;
10461
10462 // Ask if more is wanted
10463 if (!(np%10)) {
10464 const char *opt = Getline("More (y/n)? [y]");
10465 if (opt[0] == 'n')
10466 break;
10467 }
10468
10469 // We may be over
10470 if (tolog <= 0)
10471 break;
10472
10473 // Update wanted bytes
10474 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10475 } else {
10476 // Log to window
10477 if (line[r-1] == '\n') line[r-1] = 0;
10479 }
10480 }
10481 if (!SendingLogToWindow()) {
10482 // Avoid screwing up the prompt
10483 if (write(fileno(stdout), "\n", 1) != 1)
10484 SysError("ShowLog", "error writing to stdout");
10485 }
10486
10487 // Restore original pointer
10488 if (qry > -1)
10489 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10490}
10491
10492////////////////////////////////////////////////////////////////////////////////
10493/// Set session with 'id' the default one. If 'id' is not found in the list,
10494/// the current session is set as default
10495
10497{
10498 if (GetManager()) {
10500 if (d) {
10501 if (d->GetProof()) {
10502 gProof = d->GetProof();
10503 return;
10504 }
10505 }
10506
10507 // Id not found or undefined: set as default this session
10508 gProof = this;
10509 }
10510
10511 return;
10512}
10513
10514////////////////////////////////////////////////////////////////////////////////
10515/// Detach this instance to its proofserv.
10516/// If opt is 'S' or 's' the remote server is shutdown
10517
10519{
10520 // Nothing to do if not in contact with proofserv
10521 if (!IsValid()) return;
10522
10523 // Get worker and socket instances
10524 TSlave *sl = (TSlave *) fActiveSlaves->First();
10525 TSocket *s = 0;
10526 if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
10527 Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
10528 return;
10529 }
10530
10531 Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
10532
10533 // If processing, try to stop processing first
10534 if (shutdown && !IsIdle()) {
10535 // Remove pending requests
10536 Remove("cleanupqueue");
10537 // Do not wait for ever, but al least 20 seconds
10538 Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
10539 timeout = (timeout > 20) ? timeout : 20;
10540 // Send stop signal
10541 StopProcess(kFALSE, (Long_t) (timeout / 2));
10542 // Receive results
10543 Collect(kActive, timeout);
10544 }
10545
10546 // Avoid spurious messages: deactivate new inputs ...
10548
10549 // ... and discard existing ones
10550 sl->FlushSocket();
10551
10552 // Close session (we always close the connection)
10553 Close(opt);
10554
10555 // Close the progress dialog, if any
10558
10559 // Update info in the table of our manager, if any
10560 if (GetManager() && GetManager()->QuerySessions("L")) {
10561 TIter nxd(GetManager()->QuerySessions("L"));
10562 TProofDesc *d = 0;
10563 while ((d = (TProofDesc *)nxd())) {
10564 if (d->GetProof() == this) {
10565 d->SetProof(0);
10566 GetManager()->QuerySessions("L")->Remove(d);
10567 break;
10568 }
10569 }
10570 }
10571
10572 // Invalidate this instance
10573 fValid = kFALSE;
10574
10575 return;
10576}
10577
10578////////////////////////////////////////////////////////////////////////////////
10579/// Set an alias for this session. If reconnection is supported, the alias
10580/// will be communicated to the remote coordinator so that it can be recovered
10581/// when reconnecting
10582
10583void TProof::SetAlias(const char *alias)
10584{
10585 // Set it locally
10586 TNamed::SetTitle(alias);
10588 // Set the name at the same value
10589 TNamed::SetName(alias);
10590
10591 // Nothing to do if not in contact with coordinator
10592 if (!IsValid()) return;
10593
10594 if (!IsProofd() && TestBit(TProof::kIsClient)) {
10595 TSlave *sl = (TSlave *) fActiveSlaves->First();
10596 if (sl)
10597 sl->SetAlias(alias);
10598 }
10599
10600 return;
10601}
10602
10603////////////////////////////////////////////////////////////////////////////////
10604/// *** This function is deprecated and will disappear in future versions ***
10605/// *** It is just a wrapper around TFile::Cp.
10606/// *** Please use TProofMgr::UploadFiles.
10607///
10608/// Upload a set of files and save the list of files by name dataSetName.
10609/// The 'files' argument is a list of TFileInfo objects describing the files
10610/// as first url.
10611/// The mask 'opt' is a combination of EUploadOpt:
10612/// kAppend (0x1) if set true files will be appended to
10613/// the dataset existing by given name
10614/// kOverwriteDataSet (0x2) if dataset with given name exited it
10615/// would be overwritten
10616/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10617/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10618/// kOverwriteNoFiles (0x10) overwrite none
10619/// kAskUser (0x0) ask user before overwriteng dataset/files
10620/// The default value is kAskUser.
10621/// The user will be asked to confirm overwriting dataset or files unless
10622/// specified opt provides the answer!
10623/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10624/// skippedFiles argument. The function will add to this list TFileInfo
10625/// objects describing all files that existed on the cluster and were
10626/// not uploaded.
10627///
10628/// Communication Summary
10629/// Client Master
10630/// |------------>DataSetName----------->|
10631/// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
10632/// (*)|-------> call RegisterDataSet ------->|
10633/// (*) - optional
10634
10635Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
10636{
10637 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10638
10639 return -1;
10640}
10641
10642////////////////////////////////////////////////////////////////////////////////
10643/// *** This function is deprecated and will disappear in future versions ***
10644/// *** It is just a wrapper around TFile::Cp.
10645/// *** Please use TProofMgr::UploadFiles.
10646///
10647/// Upload a set of files and save the list of files by name dataSetName.
10648/// The mask 'opt' is a combination of EUploadOpt:
10649/// kAppend (0x1) if set true files will be appended to
10650/// the dataset existing by given name
10651/// kOverwriteDataSet (0x2) if dataset with given name exited it
10652/// would be overwritten
10653/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10654/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10655/// kOverwriteNoFiles (0x10) overwrite none
10656/// kAskUser (0x0) ask user before overwriteng dataset/files
10657/// The default value is kAskUser.
10658/// The user will be asked to confirm overwriting dataset or files unless
10659/// specified opt provides the answer!
10660/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10661/// skippedFiles argument. The function will add to this list TFileInfo
10662/// objects describing all files that existed on the cluster and were
10663/// not uploaded.
10664///
10665
10666Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
10667{
10668 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10669
10670 return -1;
10671}
10672
10673////////////////////////////////////////////////////////////////////////////////
10674/// *** This function is deprecated and will disappear in future versions ***
10675/// *** It is just a wrapper around TFile::Cp.
10676/// *** Please use TProofMgr::UploadFiles.
10677///
10678/// Upload files listed in "file" to PROOF cluster.
10679/// Where file = name of file containing list of files and
10680/// dataset = dataset name and opt is a combination of EUploadOpt bits.
10681/// Each file description (line) can include wildcards.
10682/// Check TFileInfo compatibility
10683
10684Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
10685{
10686 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10687
10688 // Done
10689 return -1;
10690}
10691
10692////////////////////////////////////////////////////////////////////////////////
10693/// Register the 'dataSet' on the cluster under the current
10694/// user, group and the given 'dataSetName'.
10695/// If a dataset with the same name already exists the action fails unless 'opts'
10696/// contains 'O', in which case the old dataset is overwritten, or contains 'U',
10697/// in which case 'newDataSet' is added to the existing dataset (duplications are
10698/// ignored, if any).
10699/// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
10700/// is configured to allow so). By default the dataset is not verified.
10701/// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
10702/// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
10703/// If 'opts' contains 'S' validation would be run serially (meaningful only if
10704/// validation is required).
10705/// Returns kTRUE on success.
10706
10707Bool_t TProof::RegisterDataSet(const char *dataSetName,
10708 TFileCollection *dataSet, const char *optStr)
10709{
10710 // Check TFileInfo compatibility
10711 if (fProtocol < 17) {
10712 Info("RegisterDataSet",
10713 "functionality not available: the server does not have dataset support");
10714 return kFALSE;
10715 }
10716
10717 if (!dataSetName || strlen(dataSetName) <= 0) {
10718 Info("RegisterDataSet", "specifying a dataset name is mandatory");
10719 return kFALSE;
10720 }
10721
10722 Bool_t parallelverify = kFALSE;
10723 TString sopt(optStr);
10724 if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
10725 // We do verification in parallel later on; just register for now
10726 parallelverify = kTRUE;
10727 sopt.ReplaceAll("V", "");
10728 }
10729 // This would screw up things remotely, make sure is not there
10730 sopt.ReplaceAll("S", "");
10731
10733 mess << Int_t(kRegisterDataSet);
10734 mess << TString(dataSetName);
10735 mess << sopt;
10736 mess.WriteObject(dataSet);
10737 Broadcast(mess);
10738
10739 Bool_t result = kTRUE;
10740 Collect();
10741 if (fStatus != 0) {
10742 Error("RegisterDataSet", "dataset was not saved");
10743 result = kFALSE;
10744 return result;
10745 }
10746
10747 // If old server or not verifying in parallel we are done
10748 if (!parallelverify) return result;
10749
10750 // If we are here it means that we will verify in parallel
10751 sopt += "V";
10752 if (VerifyDataSet(dataSetName, sopt) < 0){
10753 Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
10754 return kFALSE;
10755 }
10756
10757 // We are done
10758 return kTRUE;
10759}
10760
10761////////////////////////////////////////////////////////////////////////////////
10762/// Set/Change the name of the default tree. The tree name may contain
10763/// subdir specification in the form "subdir/name".
10764/// Returns 0 on success, -1 otherwise.
10765
10766Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
10767{
10768 // Check TFileInfo compatibility
10769 if (fProtocol < 23) {
10770 Info("SetDataSetTreeName", "functionality not supported by the server");
10771 return -1;
10772 }
10773
10774 if (!dataset || strlen(dataset) <= 0) {
10775 Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
10776 return -1;
10777 }
10778
10779 if (!treename || strlen(treename) <= 0) {
10780 Info("SetDataSetTreeName", "specifying a tree name is mandatory");
10781 return -1;
10782 }
10783
10784 TUri uri(dataset);
10785 TString fragment(treename);
10786 if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
10787 uri.SetFragment(fragment);
10788
10790 mess << Int_t(kSetDefaultTreeName);
10791 mess << uri.GetUri();
10792 Broadcast(mess);
10793
10794 Collect();
10795 if (fStatus != 0) {
10796 Error("SetDataSetTreeName", "some error occured: default tree name not changed");
10797 return -1;
10798 }
10799 return 0;
10800}
10801
10802////////////////////////////////////////////////////////////////////////////////
10803/// Lists all datasets that match given uri.
10804/// The 'optStr' can contain a comma-separated list of servers for which the
10805/// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
10806/// only the global information in the TFileCollection is retrieved; useful to only
10807/// get the list of available datasets.
10808
10809TMap *TProof::GetDataSets(const char *uri, const char *optStr)
10810{
10811 if (fProtocol < 15) {
10812 Info("GetDataSets",
10813 "functionality not available: the server does not have dataset support");
10814 return 0;
10815 }
10816 if (fProtocol < 31 && strstr(optStr, ":lite:"))
10817 Warning("GetDataSets", "'lite' option not supported by the server");
10818
10820 mess << Int_t(kGetDataSets);
10821 mess << TString(uri ? uri : "");
10822 mess << TString(optStr ? optStr : "");
10823 Broadcast(mess);
10825
10826 TMap *dataSetMap = 0;
10827 if (fStatus != 0) {
10828 Error("GetDataSets", "error receiving datasets information");
10829 } else {
10830 // Look in the list
10831 TMessage *retMess = (TMessage *) fRecvMessages->First();
10832 if (retMess && retMess->What() == kMESS_OK) {
10833 if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
10834 Error("GetDataSets", "error receiving datasets");
10835 } else
10836 Error("GetDataSets", "message not found or wrong type (%p)", retMess);
10837 }
10838
10839 return dataSetMap;
10840}
10841
10842////////////////////////////////////////////////////////////////////////////////
10843/// Shows datasets in locations that match the uri.
10844/// By default shows the user's datasets and global ones
10845
10846void TProof::ShowDataSets(const char *uri, const char* optStr)
10847{
10848 if (fProtocol < 15) {
10849 Info("ShowDataSets",
10850 "functionality not available: the server does not have dataset support");
10851 return;
10852 }
10853
10855 mess << Int_t(kShowDataSets);
10856 mess << TString(uri ? uri : "");
10857 mess << TString(optStr ? optStr : "");
10858 Broadcast(mess);
10859
10861 if (fStatus != 0)
10862 Error("ShowDataSets", "error receiving datasets information");
10863}
10864
10865////////////////////////////////////////////////////////////////////////////////
10866/// Returns kTRUE if 'dataset' exists, kFALSE otherwise
10867
10868Bool_t TProof::ExistsDataSet(const char *dataset)
10869{
10870 if (fProtocol < 15) {
10871 Info("ExistsDataSet", "functionality not available: the server has an"
10872 " incompatible version of TFileInfo");
10873 return kFALSE;
10874 }
10875
10876 if (!dataset || strlen(dataset) <= 0) {
10877 Error("ExistsDataSet", "dataset name missing");
10878 return kFALSE;
10879 }
10880
10882 msg << Int_t(kCheckDataSetName) << TString(dataset);
10883 Broadcast(msg);
10885 if (fStatus == -1) {
10886 // The dataset exists
10887 return kTRUE;
10888 }
10889 // The dataset does not exists
10890 return kFALSE;
10891}
10892
10893////////////////////////////////////////////////////////////////////////////////
10894/// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
10895
10896void TProof::ClearDataSetCache(const char *dataset)
10897{
10898 if (fProtocol < 28) {
10899 Info("ClearDataSetCache", "functionality not available on server");
10900 return;
10901 }
10902
10904 msg << Int_t(kCache) << TString(dataset) << TString("clear");
10905 Broadcast(msg);
10907 // Done
10908 return;
10909}
10910
10911////////////////////////////////////////////////////////////////////////////////
10912/// Display the content of the dataset cache, if any (matching 'dataset', if defined).
10913
10914void TProof::ShowDataSetCache(const char *dataset)
10915{
10916 if (fProtocol < 28) {
10917 Info("ShowDataSetCache", "functionality not available on server");
10918 return;
10919 }
10920
10922 msg << Int_t(kCache) << TString(dataset) << TString("show");
10923 Broadcast(msg);
10925 // Done
10926 return;
10927}
10928
10929////////////////////////////////////////////////////////////////////////////////
10930/// Get a list of TFileInfo objects describing the files of the specified
10931/// dataset.
10932/// To get the short version (containing only the global meta information)
10933/// specify optStr = "S:" or optStr = "short:".
10934/// To get the sub-dataset of files located on a given server(s) specify
10935/// the list of servers (comma-separated) in the 'optStr' field.
10936
10937TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10938{
10939 if (fProtocol < 15) {
10940 Info("GetDataSet", "functionality not available: the server has an"
10941 " incompatible version of TFileInfo");
10942 return 0;
10943 }
10944
10945 if (!uri || strlen(uri) <= 0) {
10946 Info("GetDataSet", "specifying a dataset name is mandatory");
10947 return 0;
10948 }
10949
10950 TMessage nameMess(kPROOF_DATASETS);
10951 nameMess << Int_t(kGetDataSet);
10952 nameMess << TString(uri);
10953 nameMess << TString(optStr ? optStr: "");
10954 if (Broadcast(nameMess) < 0)
10955 Error("GetDataSet", "sending request failed");
10956
10958 TFileCollection *fileList = 0;
10959 if (fStatus != 0) {
10960 Error("GetDataSet", "error receiving datasets information");
10961 } else {
10962 // Look in the list
10963 TMessage *retMess = (TMessage *) fRecvMessages->First();
10964 if (retMess && retMess->What() == kMESS_OK) {
10965 if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10966 Error("GetDataSet", "error reading list of files");
10967 } else
10968 Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10969 }
10970
10971 return fileList;
10972}
10973
10974////////////////////////////////////////////////////////////////////////////////
10975/// display meta-info for given dataset usi
10976
10977void TProof::ShowDataSet(const char *uri, const char* opt)
10978{
10979 TFileCollection *fileList = 0;
10980 if ((fileList = GetDataSet(uri))) {
10981 fileList->Print(opt);
10982 delete fileList;
10983 } else
10984 Warning("ShowDataSet","no such dataset: %s", uri);
10985}
10986
10987////////////////////////////////////////////////////////////////////////////////
10988/// Remove the specified dataset from the PROOF cluster.
10989/// Files are not deleted.
10990
10991Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10992{
10993 TMessage nameMess(kPROOF_DATASETS);
10994 nameMess << Int_t(kRemoveDataSet);
10995 nameMess << TString(uri?uri:"");
10996 nameMess << TString(optStr?optStr:"");
10997 if (Broadcast(nameMess) < 0)
10998 Error("RemoveDataSet", "sending request failed");
11000
11001 if (fStatus != 0)
11002 return -1;
11003 else
11004 return 0;
11005}
11006
11007////////////////////////////////////////////////////////////////////////////////
11008/// Find datasets, returns in a TList all found datasets.
11009
11010TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
11011{
11012 Error ("FindDataSets", "not yet implemented");
11013 return (TList *) 0;
11014}
11015
11016////////////////////////////////////////////////////////////////////////////////
11017/// Allows users to request staging of a particular dataset. Requests are
11018/// saved in a special dataset repository and must be honored by the endpoint.
11019
11021{
11022 if (fProtocol < 35) {
11023 Error("RequestStagingDataSet",
11024 "functionality not supported by the server");
11025 return kFALSE;
11026 }
11027
11029 mess << Int_t(kRequestStaging);
11030 mess << TString(dataset);
11031 Broadcast(mess);
11032
11033 Collect();
11034 if (fStatus != 0) {
11035 Error("RequestStagingDataSet", "staging request was unsuccessful");
11036 return kFALSE;
11037 }
11038
11039 return kTRUE;
11040}
11041
11042////////////////////////////////////////////////////////////////////////////////
11043/// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11044/// failure. Dataset not found equals to a failure.
11045
11047{
11048 if (fProtocol < 36) {
11049 Error("CancelStagingDataSet",
11050 "functionality not supported by the server");
11051 return kFALSE;
11052 }
11053
11055 mess << Int_t(kCancelStaging);
11056 mess << TString(dataset);
11057 Broadcast(mess);
11058
11059 Collect();
11060 if (fStatus != 0) {
11061 Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11062 return kFALSE;
11063 }
11064
11065 return kTRUE;
11066}
11067
11068////////////////////////////////////////////////////////////////////////////////
11069/// Obtains a TFileCollection showing the staging status of the specified
11070/// dataset. A valid dataset manager and dataset staging requests repository
11071/// must be present on the endpoint.
11072
11074{
11075 if (fProtocol < 35) {
11076 Error("GetStagingStatusDataSet",
11077 "functionality not supported by the server");
11078 return NULL;
11079 }
11080
11081 TMessage nameMess(kPROOF_DATASETS);
11082 nameMess << Int_t(kStagingStatus);
11083 nameMess << TString(dataset);
11084 if (Broadcast(nameMess) < 0) {
11085 Error("GetStagingStatusDataSet", "sending request failed");
11086 return NULL;
11087 }
11088
11090 TFileCollection *fc = NULL;
11091
11092 if (fStatus < 0) {
11093 Error("GetStagingStatusDataSet", "problem processing the request");
11094 }
11095 else if (fStatus == 0) {
11096 TMessage *retMess = (TMessage *)fRecvMessages->First();
11097 if (retMess && (retMess->What() == kMESS_OK)) {
11098 fc = (TFileCollection *)(
11099 retMess->ReadObject(TFileCollection::Class()) );
11100 if (!fc)
11101 Error("GetStagingStatusDataSet", "error reading list of files");
11102 }
11103 else {
11104 Error("GetStagingStatusDataSet",
11105 "response message not found or wrong type (%p)", retMess);
11106 }
11107 }
11108 //else {}
11109
11110 return fc;
11111}
11112
11113////////////////////////////////////////////////////////////////////////////////
11114/// Like GetStagingStatusDataSet, but displays results immediately.
11115
11116void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11117{
11119 if (fc) {
11120 fc->Print(opt);
11121 delete fc;
11122 }
11123}
11124
11125////////////////////////////////////////////////////////////////////////////////
11126/// Verify if all files in the specified dataset are available.
11127/// Print a list and return the number of missing files.
11128/// Returns -1 in case of error.
11129
11130Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11131{
11132 if (fProtocol < 15) {
11133 Info("VerifyDataSet", "functionality not available: the server has an"
11134 " incompatible version of TFileInfo");
11135 return -1;
11136 }
11137
11138 // Sanity check
11139 if (!uri || (uri && strlen(uri) <= 0)) {
11140 Error("VerifyDataSet", "dataset name is is mandatory");
11141 return -1;
11142 }
11143
11144 Int_t nmissingfiles = 0;
11145
11146 TString sopt(optStr);
11147 if (fProtocol < 34 || sopt.Contains("S")) {
11148 sopt.ReplaceAll("S", "");
11149 Info("VerifyDataSet", "Master-only verification");
11150 TMessage nameMess(kPROOF_DATASETS);
11151 nameMess << Int_t(kVerifyDataSet);
11152 nameMess << TString(uri);
11153 nameMess << sopt;
11154 Broadcast(nameMess);
11155
11157
11158 if (fStatus < 0) {
11159 Info("VerifyDataSet", "no such dataset %s", uri);
11160 return -1;
11161 } else
11162 nmissingfiles = fStatus;
11163 return nmissingfiles;
11164 }
11165
11166 // Request for parallel verification: can only be done if we have workers
11167 if (!IsParallel() && !fDynamicStartup) {
11168 Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11169 Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11170 return -1;
11171 }
11172
11173 // Do parallel verification
11174 return VerifyDataSetParallel(uri, optStr);
11175}
11176
11177////////////////////////////////////////////////////////////////////////////////
11178/// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11179/// TProofLite::VerifyDataSet
11180
11181Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11182{
11183 Int_t nmissingfiles = 0;
11184
11185 // Let PROOF master prepare node-files map
11186 SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11187
11188 // Use TPacketizerFile
11189 TString oldpack;
11190 if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11191 SetParameter("PROOF_Packetizer", "TPacketizerFile");
11192
11193 // Add dataset name
11194 SetParameter("PROOF_VerifyDataSet", uri);
11195 // Add options
11196 SetParameter("PROOF_VerifyDataSetOption", optStr);
11197 SetParameter("PROOF_SavePartialResults", (Int_t)0);
11198 Int_t oldifiip = -1;
11199 if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11200 SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11201
11202 // TO DO : figure out mss and stageoption
11203 const char* mss="";
11204 SetParameter("PROOF_MSS", mss);
11205 const char* stageoption="";
11206 SetParameter("PROOF_StageOption", stageoption);
11207
11208 // Process verification in parallel
11209 Process("TSelVerifyDataSet", (Long64_t) 1);
11210
11211 // Restore packetizer
11212 if (!oldpack.IsNull())
11213 SetParameter("PROOF_Packetizer", oldpack);
11214 else
11215 DeleteParameters("PROOF_Packetizer");
11216
11217 // Delete or restore parameters
11218 DeleteParameters("PROOF_FilesToProcess");
11219 DeleteParameters("PROOF_VerifyDataSet");
11220 DeleteParameters("PROOF_VerifyDataSetOption");
11221 DeleteParameters("PROOF_MSS");
11222 DeleteParameters("PROOF_StageOption");
11223 if (oldifiip > -1) {
11224 SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11225 } else {
11226 DeleteParameters("PROOF_IncludeFileInfoInPacket");
11227 }
11228 DeleteParameters("PROOF_SavePartialResults");
11229
11230 // Merge outputs
11231 Int_t nopened = 0;
11232 Int_t ntouched = 0;
11233 Bool_t changed_ds = kFALSE;
11234
11235 TIter nxtout(GetOutputList());
11236 TObject* obj;
11237 TList *lfiindout = new TList;
11238 while ((obj = nxtout())) {
11239 TList *l = dynamic_cast<TList *>(obj);
11240 if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11241 TIter nxt(l);
11242 TFileInfo *fiindout = 0;
11243 while ((fiindout = (TFileInfo*) nxt())) {
11244 lfiindout->Add(fiindout);
11245 }
11246 }
11247 // Add up number of disppeared files
11248 TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11249 if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11250 nmissingfiles += pdisappeared->GetVal();
11251 }
11252 TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11253 if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11254 nopened += pnopened->GetVal();
11255 }
11256 TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11257 if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11258 ntouched += pntouched->GetVal();
11259 }
11260 TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11261 if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11262 if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11263 }
11264 }
11265
11266 Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11267 " # missing files = %d)",
11268 uri, changed_ds, nopened, ntouched, nmissingfiles);
11269 // Done
11270 return nmissingfiles;
11271}
11272
11273////////////////////////////////////////////////////////////////////////////////
11274/// returns a map of the quotas of all groups
11275
11276TMap *TProof::GetDataSetQuota(const char* optStr)
11277{
11278 if (IsLite()) {
11279 Info("UploadDataSet", "Lite-session: functionality not implemented");
11280 return (TMap *)0;
11281 }
11282
11284 mess << Int_t(kGetQuota);
11285 mess << TString(optStr?optStr:"");
11286 Broadcast(mess);
11287
11289 TMap *groupQuotaMap = 0;
11290 if (fStatus < 0) {
11291 Info("GetDataSetQuota", "could not receive quota");
11292 } else {
11293 // Look in the list
11294 TMessage *retMess = (TMessage *) fRecvMessages->First();
11295 if (retMess && retMess->What() == kMESS_OK) {
11296 if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11297 Error("GetDataSetQuota", "error getting quotas");
11298 } else
11299 Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11300 }
11301
11302 return groupQuotaMap;
11303}
11304
11305////////////////////////////////////////////////////////////////////////////////
11306/// shows the quota and usage of all groups
11307/// if opt contains "U" shows also distribution of usage on user-level
11308
11310{
11311 if (fProtocol < 15) {
11312 Info("ShowDataSetQuota",
11313 "functionality not available: the server does not have dataset support");
11314 return;
11315 }
11316
11317 if (IsLite()) {
11318 Info("UploadDataSet", "Lite-session: functionality not implemented");
11319 return;
11320 }
11321
11323 mess << Int_t(kShowQuota);
11324 mess << TString(opt?opt:"");
11325 Broadcast(mess);
11326
11327 Collect();
11328 if (fStatus != 0)
11329 Error("ShowDataSetQuota", "error receiving quota information");
11330}
11331
11332////////////////////////////////////////////////////////////////////////////////
11333/// If in active in a monitor set ready state
11334
11336{
11337 if (fCurrentMonitor)
11339}
11340
11341////////////////////////////////////////////////////////////////////////////////
11342/// Make sure that the worker identified by the ordinal number 'ord' is
11343/// in the active list. The request will be forwarded to the master
11344/// in direct contact with the worker. If needed, this master will move
11345/// the worker from the inactive to the active list and rebuild the list
11346/// of unique workers.
11347/// Use ord = "*" to activate all inactive workers.
11348/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11349/// status of which will be modified at once.
11350/// Return <0 if something went wrong (-2 if at least one worker was not found)
11351/// or the number of workers with status change (on master; 0 on client).
11352
11354{
11355 return ModifyWorkerLists(ord, kTRUE, save);
11356}
11357
11358////////////////////////////////////////////////////////////////////////////////
11359/// Remove the worker identified by the ordinal number 'ord' from the
11360/// the active list. The request will be forwarded to the master
11361/// in direct contact with the worker. If needed, this master will move
11362/// the worker from the active to the inactive list and rebuild the list
11363/// of unique workers.
11364/// Use ord = "*" to deactivate all active workers.
11365/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11366/// status of which will be modified at once.
11367/// Return <0 if something went wrong (-2 if at least one worker was not found)
11368/// or the number of workers with status change (on master; 0 on client).
11369
11371{
11372 return ModifyWorkerLists(ord, kFALSE, save);
11373}
11374
11375////////////////////////////////////////////////////////////////////////////////
11376/// Modify the worker active/inactive list by making the worker identified by
11377/// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11378/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11379/// status of which will be modified at once.
11380/// If needed, the request will be forwarded to the master in direct contact
11381/// with the worker. The end-master will move the worker from one list to the
11382/// other active and rebuild the list of unique active workers.
11383/// Use ord = "*" to deactivate all active workers.
11384/// If save is TRUE the current active list is saved before any modification is
11385/// done; re-running with ord = "restore" restores the saved list
11386/// Return <0 if something went wrong (-2 if at least one worker was not found)
11387/// or the number of workers with status change (on master; 0 on client).
11388
11390{
11391 // Make sure the input make sense
11392 if (!ord || strlen(ord) <= 0) {
11393 Info("ModifyWorkerLists",
11394 "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11395 return -1;
11396 }
11397 if (gDebug > 0)
11398 Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11399
11400 Int_t nwc = 0;
11401 Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11402 if (IsEndMaster()) {
11403 if (restoring) {
11404 // We are asked to restore the previous settings
11405 nwc = RestoreActiveList();
11406 } else {
11407 if (save) SaveActiveList();
11408 }
11409 }
11410
11411 Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11412
11413 // Check if this is for us
11415 if (!allord &&
11416 strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11417 return 0;
11418 }
11419
11420 Bool_t fw = kTRUE; // Whether to forward one step down
11421 Bool_t rs = kFALSE; // Whether to rescan for unique workers
11422
11423 // Appropriate list pointing
11424 TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11425 TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11426
11427 if (IsEndMaster() && !restoring) {
11428 // Create the hash list of ordinal numbers
11429 THashList *ords = 0;
11430 if (!allord) {
11431 ords = new THashList();
11432 const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
11433 TString oo(ord), o;
11434 Int_t from = 0;
11435 while(oo.Tokenize(o, from, ","))
11436 if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
11437 }
11438 // We do not need to send forward
11439 fw = kFALSE;
11440 // Look for the worker in the initial list
11441 TObject *os = 0;
11442 TSlave *wrk = 0;
11443 if (in->GetSize() > 0) {
11444 TIter nxw(in);
11445 while ((wrk = (TSlave *) nxw())) {
11446 os = 0;
11447 if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
11448 // Add it to the final list
11449 if (!out->FindObject(wrk)) {
11450 out->Add(wrk);
11451 if (add)
11452 fActiveMonitor->Add(wrk->GetSocket());
11453 }
11454 // Remove it from the initial list
11455 in->Remove(wrk);
11456 if (!add) {
11459 } else
11461 // Count
11462 nwc++;
11463 // Nothing to forward (ord is unique)
11464 fw = kFALSE;
11465 // Rescan for unique workers (active list modified)
11466 rs = kTRUE;
11467 // We may be done, if not option 'all'
11468 if (!allord && ords) {
11469 if (os) ords->Remove(os);
11470 if (ords->GetSize() == 0) break;
11471 SafeDelete(os);
11472 }
11473 }
11474 }
11475 }
11476 // If some worker not found, notify it if at the end
11477 if (!fw && ords && ords->GetSize() > 0) {
11478 TString oo;
11479 TIter nxo(ords);
11480 while ((os = nxo())) {
11481 TIter nxw(out);
11482 while ((wrk = (TSlave *) nxw()))
11483 if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
11484 if (!wrk) {
11485 if (!oo.IsNull()) oo += ",";
11486 oo += os->GetName();
11487 }
11488 }
11489 if (!oo.IsNull()) {
11490 Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
11491 nwc = -2;
11492 }
11493 }
11494 // Cleanup hash list
11495 if (ords) {
11496 ords->Delete();
11497 SafeDelete(ords);
11498 }
11499 }
11500
11501 // Rescan for unique workers
11502 if (rs)
11504
11505 // Forward the request one step down, if needed
11506 Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
11507 if (fw) {
11508 if (fProtocol > 32) {
11510 mess << action << TString(ord);
11511 Broadcast(mess);
11513 if (fStatus != 0) {
11514 nwc = (fStatus < nwc) ? fStatus : nwc;
11515 if (fStatus == -2) {
11516 if (gDebug > 0)
11517 Warning("ModifyWorkerLists", "request not completely full filled");
11518 } else {
11519 Error("ModifyWorkerLists", "request failed");
11520 }
11521 }
11522 } else {
11523 TString oo(ord), o;
11524 if (oo.Contains(","))
11525 Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
11526 Int_t from = 0;
11527 while(oo.Tokenize(o, from, ",")) {
11529 mess << action << o;
11530 Broadcast(mess);
11532 }
11533 }
11534 }
11535 // Done
11536 return nwc;
11537}
11538
11539////////////////////////////////////////////////////////////////////////////////
11540/// Save current list of active workers
11541
11543{
11545 if (fInactiveSlaves->GetSize() == 0) {
11546 fActiveSlavesSaved = "*";
11547 } else {
11548 TIter nxw(fActiveSlaves);
11549 TSlave *wk = 0;
11550 while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
11551 }
11552}
11553
11554////////////////////////////////////////////////////////////////////////////////
11555/// Restore saved list of active workers
11556
11558{
11559 // Clear the current active list
11561 // Restore the previous active list
11564
11565 return 0;
11566}
11567
11568////////////////////////////////////////////////////////////////////////////////
11569/// Start a PROOF session on a specific cluster. If cluster is 0 (the
11570/// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
11571/// If cluster is "lite://" we start a PROOF-lite session.
11572/// If cluster is "" (empty string) then we connect to the cluster specified
11573/// by 'Proof.LocalDefault', defaulting to "lite://".
11574/// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
11575/// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
11576/// Via conffile a specific PROOF config file in the confir directory can be specified.
11577/// Use loglevel to set the default loging level for debugging.
11578/// The appropriate instance of TProofMgr is created, if not
11579/// yet existing. The instantiated TProof object is returned.
11580/// Use TProof::cd() to switch between PROOF sessions.
11581/// For more info on PROOF see the TProof ctor.
11582
11583TProof *TProof::Open(const char *cluster, const char *conffile,
11584 const char *confdir, Int_t loglevel)
11585{
11586 const char *pn = "TProof::Open";
11587
11588 // Make sure libProof and dependents are loaded and TProof can be created,
11589 // dependents are loaded via the information in the [system].rootmap file
11590 if (!cluster) {
11591
11592 TPluginManager *pm = gROOT->GetPluginManager();
11593 if (!pm) {
11594 ::Error(pn, "plugin manager not found");
11595 return 0;
11596 }
11597
11598 if (gROOT->IsBatch()) {
11599 ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
11600 return 0;
11601 }
11602 // start PROOF Session Viewer
11603 TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
11604 if (!sv) {
11605 ::Error(pn, "no plugin found for TSessionViewer");
11606 return 0;
11607 }
11608 if (sv->LoadPlugin() == -1) {
11609 ::Error(pn, "plugin for TSessionViewer could not be loaded");
11610 return 0;
11611 }
11612 sv->ExecPlugin(0);
11613 return 0;
11614
11615 } else {
11616
11617 TString clst(cluster);
11618
11619 // Check for PoD cluster
11620 if (PoDCheckUrl( &clst ) < 0) return 0;
11621
11622 if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
11623 if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
11624
11625 // Parse input URL
11626 TUrl u(clst);
11627
11628 // *** GG, 060711: this does not seem to work any more (at XrdClient level)
11629 // *** to be investigated (it is not really needed; static tunnels work).
11630 // Dynamic tunnel:
11631 // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
11632 TString opts(u.GetOptions());
11633 if (!opts.IsNull()) {
11634 Int_t it = opts.Index("tunnel=");
11635 if (it != kNPOS) {
11636 TString sport = opts(it + strlen("tunnel="), opts.Length());
11637 TString host("127.0.0.1");
11638 Int_t port = -1;
11639 Int_t ic = sport.Index(":");
11640 if (ic != kNPOS) {
11641 // Isolate the host
11642 host = sport(0, ic);
11643 sport.Remove(0, ic + 1);
11644 }
11645 if (!sport.IsDigit()) {
11646 // Remove the non digit part
11647 TRegexp re("[^0-9]");
11648 Int_t ind = sport.Index(re);
11649 if (ind != kNPOS)
11650 sport.Remove(ind);
11651 }
11652 // Set the port
11653 if (sport.IsDigit())
11654 port = sport.Atoi();
11655 if (port > 0) {
11656 // Set the relevant variables
11657 ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
11658 gEnv->SetValue("XNet.SOCKS4Host", host);
11659 gEnv->SetValue("XNet.SOCKS4Port", port);
11660 } else {
11661 // Warn parsing problems
11662 ::Warning("TProof::Open",
11663 "problems parsing tunnelling info from options: %s", opts.Data());
11664 }
11665 }
11666 }
11667
11668 // Find out if we are required to attach to a specific session
11669 Int_t locid = -1;
11670 Bool_t create = kFALSE;
11671 if (opts.Length() > 0) {
11672 if (opts.BeginsWith("N",TString::kIgnoreCase)) {
11673 create = kTRUE;
11674 opts.Remove(0,1);
11675 u.SetOptions(opts);
11676 } else if (opts.IsDigit()) {
11677 locid = opts.Atoi();
11678 }
11679 }
11680
11681 // Attach-to or create the appropriate manager
11683
11684 TProof *proof = 0;
11685 if (mgr && mgr->IsValid()) {
11686
11687 // If XProofd we always attempt an attach first (unless
11688 // explicitly not requested).
11689 Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
11690 if (attach) {
11691 TProofDesc *d = 0;
11692 if (locid < 0)
11693 // Get the list of sessions
11694 d = (TProofDesc *) mgr->QuerySessions("")->First();
11695 else
11696 d = (TProofDesc *) mgr->GetProofDesc(locid);
11697 if (d) {
11698 proof = (TProof*) mgr->AttachSession(d);
11699 if (!proof || !proof->IsValid()) {
11700 if (locid)
11701 ::Error(pn, "new session could not be attached");
11702 SafeDelete(proof);
11703 }
11704 }
11705 }
11706
11707 // start the PROOF session
11708 if (!proof) {
11709 proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
11710 if (!proof || !proof->IsValid()) {
11711 ::Error(pn, "new session could not be created");
11712 SafeDelete(proof);
11713 }
11714 }
11715 }
11716 return proof;
11717 }
11718}
11719
11720////////////////////////////////////////////////////////////////////////////////
11721/// Get instance of the effective manager for 'url'
11722/// Return 0 on failure.
11723
11724TProofMgr *TProof::Mgr(const char *url)
11725{
11726 if (!url)
11727 return (TProofMgr *)0;
11728
11729 // Attach or create the relevant instance
11730 return TProofMgr::Create(url);
11731}
11732
11733////////////////////////////////////////////////////////////////////////////////
11734/// Wrapper around TProofMgr::Reset(...).
11735
11736void TProof::Reset(const char *url, Bool_t hard)
11737{
11738 if (url) {
11739 TProofMgr *mgr = TProof::Mgr(url);
11740 if (mgr && mgr->IsValid())
11741 mgr->Reset(hard);
11742 else
11743 ::Error("TProof::Reset",
11744 "unable to initialize a valid manager instance");
11745 }
11746}
11747
11748////////////////////////////////////////////////////////////////////////////////
11749/// Get environemnt variables.
11750
11752{
11753 return fgProofEnvList;
11754}
11755
11756////////////////////////////////////////////////////////////////////////////////
11757/// Add an variable to the list of environment variables passed to proofserv
11758/// on the master and slaves
11759
11760void TProof::AddEnvVar(const char *name, const char *value)
11761{
11762 if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
11763
11764 if (fgProofEnvList == 0) {
11765 // initialize the list if needed
11766 fgProofEnvList = new TList;
11768 } else {
11769 // replace old entries with the same name
11771 if (o != 0) {
11773 }
11774 }
11775 fgProofEnvList->Add(new TNamed(name, value));
11776}
11777
11778////////////////////////////////////////////////////////////////////////////////
11779/// Remove an variable from the list of environment variables passed to proofserv
11780/// on the master and slaves
11781
11782void TProof::DelEnvVar(const char *name)
11783{
11784 if (fgProofEnvList == 0) return;
11785
11787 if (o != 0) {
11789 }
11790}
11791
11792////////////////////////////////////////////////////////////////////////////////
11793/// Clear the list of environment variables passed to proofserv
11794/// on the master and slaves
11795
11797{
11798 if (fgProofEnvList == 0) return;
11799
11801}
11802
11803////////////////////////////////////////////////////////////////////////////////
11804/// Save information about the worker set in the file .workers in the working
11805/// dir. Called each time there is a change in the worker setup, e.g. by
11806/// TProof::MarkBad().
11807
11809{
11810 // We must be masters
11812 return;
11813
11814 // We must have a server defined
11815 if (!gProofServ) {
11816 Error("SaveWorkerInfo","gProofServ undefined");
11817 return;
11818 }
11819
11820 // The relevant lists must be defined
11821 if (!fSlaves && !fBadSlaves) {
11822 Warning("SaveWorkerInfo","all relevant worker lists is undefined");
11823 return;
11824 }
11825
11826 // Create or truncate the file first
11827 TString fnwrk = gSystem->GetDirName(gProofServ->GetSessionDir())+"/.workers";
11828 FILE *fwrk = fopen(fnwrk.Data(),"w");
11829 if (!fwrk) {
11830 Error("SaveWorkerInfo",
11831 "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
11832 return;
11833 }
11834
11835 // Do we need to register an additional line for another log?
11836 TString addlogext;
11837 TString addLogTag;
11838 if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
11839 addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
11840 TPMERegexp reLogTag("^__(.*)__\\.log"); // $
11841 if (reLogTag.Match(addlogext) == 2) {
11842 addLogTag = reLogTag[1];
11843 }
11844 else {
11845 addLogTag = "+++";
11846 }
11847 if (gDebug > 0)
11848 Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
11849 }
11850
11851 // Used to eliminate datetime and PID from workdir to obtain log file name
11852 TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
11853
11854 // Loop over the list of workers (active is any worker not flagged as bad)
11855 TIter nxa(fSlaves);
11856 TSlave *wrk = 0;
11857 TString logfile;
11858 while ((wrk = (TSlave *) nxa())) {
11859 Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
11860 logfile = wrk->GetWorkDir();
11861 if (re.Match(logfile) == 2) logfile = re[1];
11862 else continue; // invalid (should not happen)
11863 // Write out record for this worker
11864 fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
11865 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11866 wrk->GetOrdinal(), logfile.Data());
11867 // Additional line, if required
11868 if (addlogext.Length() > 0) {
11869 fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
11870 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11871 wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
11872 }
11873
11874 }
11875
11876 // Loop also over the list of bad workers (if they failed to startup they are not in
11877 // the overall list
11878 TIter nxb(fBadSlaves);
11879 while ((wrk = (TSlave *) nxb())) {
11880 logfile = wrk->GetWorkDir();
11881 if (re.Match(logfile) == 2) logfile = re[1];
11882 else continue; // invalid (should not happen)
11883 if (!fSlaves->FindObject(wrk)) {
11884 // Write out record for this worker
11885 fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
11886 wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
11887 wrk->GetOrdinal(), logfile.Data());
11888 }
11889 }
11890
11891 // Eventually loop over the list of gracefully terminated workers: we'll get
11892 // logfiles from those workers as well. They'll be shown with a special
11893 // status of "2"
11895 TSlaveInfo *sli;
11896 while (( sli = (TSlaveInfo *)nxt() )) {
11897 logfile = sli->GetDataDir();
11898 if (re.Match(logfile) == 2) logfile = re[1];
11899 else continue; // invalid (should not happen)
11900 fprintf(fwrk, "%s 2 %s %s.log\n",
11901 sli->GetName(), sli->GetOrdinal(), logfile.Data());
11902 // Additional line, if required
11903 if (addlogext.Length() > 0) {
11904 fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
11905 sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
11906 logfile.Data(), addlogext.Data());
11907 }
11908 }
11909
11910 // Close file
11911 fclose(fwrk);
11912
11913 // We are done
11914 return;
11915}
11916
11917////////////////////////////////////////////////////////////////////////////////
11918/// Get the value from the specified parameter from the specified collection.
11919/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11920/// or value type does not match), 0 otherwise.
11921
11923{
11924 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11925 if (obj) {
11926 TNamed *p = dynamic_cast<TNamed*>(obj);
11927 if (p) {
11928 value = p->GetTitle();
11929 return 0;
11930 }
11931 }
11932 return -1;
11933
11934}
11935
11936////////////////////////////////////////////////////////////////////////////////
11937/// Get the value from the specified parameter from the specified collection.
11938/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11939/// or value type does not match), 0 otherwise.
11940
11942{
11943 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11944 if (obj) {
11945 TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
11946 if (p) {
11947 value = p->GetVal();
11948 return 0;
11949 }
11950 }
11951 return -1;
11952}
11953
11954////////////////////////////////////////////////////////////////////////////////
11955/// Get the value from the specified parameter from the specified collection.
11956/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11957/// or value type does not match), 0 otherwise.
11958
11960{
11961 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11962 if (obj) {
11963 TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
11964 if (p) {
11965 value = p->GetVal();
11966 return 0;
11967 }
11968 }
11969 return -1;
11970}
11971
11972////////////////////////////////////////////////////////////////////////////////
11973/// Get the value from the specified parameter from the specified collection.
11974/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11975/// or value type does not match), 0 otherwise.
11976
11978{
11979 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11980 if (obj) {
11981 TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
11982 if (p) {
11983 value = p->GetVal();
11984 return 0;
11985 }
11986 }
11987 return -1;
11988}
11989
11990////////////////////////////////////////////////////////////////////////////////
11991/// Get the value from the specified parameter from the specified collection.
11992/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11993/// or value type does not match), 0 otherwise.
11994
11996{
11997 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11998 if (obj) {
11999 TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
12000 if (p) {
12001 value = p->GetVal();
12002 return 0;
12003 }
12004 }
12005 return -1;
12006}
12007
12008////////////////////////////////////////////////////////////////////////////////
12009/// Make sure that dataset is in the form to be processed. This may mean
12010/// retrieving the relevant info from the dataset manager or from the
12011/// attached input list.
12012/// Returns 0 on success, -1 on error
12013
12015 TDataSetManager *mgr, TString &emsg)
12016{
12017 emsg = "";
12018
12019 // We must have something to process
12020 if (!dset || !input || !mgr) {
12021 emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
12022 return -1;
12023 }
12024
12025 TList *datasets = new TList;
12026 TFileCollection *dataset = 0;
12027 TString lookupopt;
12028 TString dsname(dset->GetName());
12029
12030 // First extract the "entry list" part on the global name, if any
12031 TString dsns(dsname), enlname;
12032 Ssiz_t eli = dsns.Index("?enl=");
12033 if (eli != kNPOS) {
12034 enlname = dsns(eli + strlen("?enl="), dsns.Length());
12035 dsns.Remove(eli, dsns.Length()-eli);
12036 }
12037
12038 // The dataset maybe in the form of a TFileCollection in the input list
12039 if (dsname.BeginsWith("TFileCollection:")) {
12040 // Isolate the real name
12041 dsname.ReplaceAll("TFileCollection:", "");
12042 // Get the object
12043 dataset = (TFileCollection *) input->FindObject(dsname);
12044 if (!dataset) {
12045 emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12046 return -1;
12047 }
12048 // Remove from everywhere
12049 input->RecursiveRemove(dataset);
12050 // Add it to the local list
12051 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12052 // Make sure we lookup everything (unless the client or the administrator
12053 // required something else)
12054 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12055 lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12056 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12057 }
12058 }
12059
12060 // This is the name we parse for additional specifications, such directory
12061 // and object name; for multiple datasets we assume that the directory and
12062 // and object name are the same for all datasets
12063 TString dsnparse;
12064 // The received message included an empty dataset, with only the name
12065 // defined: assume that a dataset, stored on the PROOF master by that
12066 // name, should be processed.
12067 if (!dataset) {
12068
12069 TFileCollection *fc = nullptr;
12070
12071 // Check if the entry list and dataset name are valid. If they have spaces,
12072 // commas, or pipes, they are not considered as valid and we revert to the
12073 // "multiple datasets" case
12074 TRegexp rg("[, |]");
12075 Bool_t validEnl = (enlname.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12076 Bool_t validSdsn = (dsns.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12077
12078 if (validEnl && validSdsn && (( fc = mgr->GetDataSet(dsns) ))) {
12079
12080 //
12081 // String corresponds to ONE dataset only
12082 //
12083
12084 TIter nxfi(fc->GetList());
12085 TFileInfo *fi;
12086 while (( fi = (TFileInfo *)nxfi() ))
12087 fi->SetTitle(dsns.Data());
12088 dataset = fc;
12089 dsnparse = dsns; // without entry list
12090
12091 // Adds the entry list (or empty string if not specified)
12092 datasets->Add( new TPair(dataset, new TObjString( enlname.Data() )) );
12093
12094 } else {
12095
12096 //
12097 // String does NOT correspond to one dataset: check if many datasets
12098 // were specified instead
12099 //
12100
12101 dsns = dsname.Data();
12102 TString dsn1;
12103 Int_t from1 = 0;
12104 while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12105 TString dsn2;
12106 Int_t from2 = 0;
12107 while (dsn1.Tokenize(dsn2, from2, "|")) {
12108 enlname = "";
12109 Int_t ienl = dsn2.Index("?enl=");
12110 if (ienl != kNPOS) {
12111 enlname = dsn2(ienl + 5, dsn2.Length());
12112 dsn2.Remove(ienl);
12113 }
12114 if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12115 // Save dataset name in TFileInfo's title to use it in TDset
12116 TIter nxfi(fc->GetList());
12117 TFileInfo *fi;
12118 while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12119 dsnparse = dsn2;
12120 if (!dataset) {
12121 // This is our dataset
12122 dataset = fc;
12123 } else {
12124 // Add it to the dataset
12125 dataset->Add(fc);
12126 SafeDelete(fc);
12127 }
12128 }
12129 }
12130 // The dataset name(s) in the first element
12131 if (dataset) {
12132 if (dataset->GetList()->First())
12133 ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12134 // Add it to the local list
12135 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12136 }
12137 // Reset the pointer
12138 dataset = 0;
12139 }
12140
12141 }
12142
12143 //
12144 // At this point the dataset(s) to be processed, if any, are found in the
12145 // "datasets" variable
12146 //
12147
12148 if (!datasets || datasets->GetSize() <= 0) {
12149 emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12150 return -1;
12151 } else {
12152 // Make 'dataset' to point to the first one in the list
12153 if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12154 emsg.Form("dataset pointer is null: corruption? - aborting");
12155 return -1;
12156 }
12157 }
12158 // Apply the lookup option requested by the client or the administartor
12159 // (by default we trust the information in the dataset)
12160 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12161 lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12162 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12163 }
12164 } else {
12165 // We were given a named, single, TFileCollection
12166 dsnparse = dsname;
12167 }
12168
12169 // Logic for the subdir/obj names: try first to see if the dataset name contains
12170 // some info; if not check the settings in the TDSet object itself; if still empty
12171 // check the default tree name / path in the TFileCollection object; if still empty
12172 // use the default as the flow will determine
12173 TString dsTree;
12174 // Get the [subdir/]tree, if any
12175 mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12176 if (dsTree.IsNull()) {
12177 // Use what we have in the original dataset; we need this to locate the
12178 // meta data information
12179 dsTree += dset->GetDirectory();
12180 dsTree += dset->GetObjName();
12181 }
12182 if (!dsTree.IsNull() && dsTree != "/") {
12183 TString tree(dsTree);
12184 Int_t idx = tree.Index("/");
12185 if (idx != kNPOS) {
12186 TString dir = tree(0, idx+1);
12187 tree.Remove(0, idx);
12188 dset->SetDirectory(dir);
12189 }
12190 dset->SetObjName(tree);
12191 } else {
12192 // Use the default obj name from the TFileCollection
12193 dsTree = dataset->GetDefaultTreeName();
12194 }
12195
12196 // Pass dataset server mapping instructions, if any
12198 TList *srvmapslist = srvmapsref;
12199 TString srvmaps;
12200 if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12201 srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12202 if (gProofServ) {
12203 TString msg;
12204 if (srvmapsref && !srvmapslist) {
12205 msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12206 } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12207 msg.Form("+++ Info: dataset server mapping(s) modified by user");
12208 } else if (!srvmapsref && srvmapslist) {
12209 msg.Form("+++ Info: dataset server mapping(s) added by user");
12210 }
12212 }
12213 }
12214
12215 // Flag multi-datasets
12216 if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12217 // Loop over the list of datasets
12218 TList *listOfMissingFiles = new TList;
12219 TEntryList *entrylist = 0;
12220 TPair *pair = 0;
12221 TIter nxds(datasets);
12222 while ((pair = (TPair *) nxds())) {
12223 // File Collection
12224 dataset = (TFileCollection *) pair->Key();
12225 // Entry list, if any
12226 TEntryList *enl = 0;
12227 TObjString *os = (TObjString *) pair->Value();
12228 if (strlen(os->GetName())) {
12229 if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12230 if (gProofServ)
12232 " entry list %s not found", os->GetName()));
12233 }
12234 if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12235 if (gProofServ)
12237 " no sub-lists in entry-list!"));
12238 }
12239 }
12240 TList *missingFiles = new TList;
12241 TSeqCollection* files = dataset->GetList();
12242 if (gDebug > 0) files->Print();
12243 Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12244 if (dset->TestBit(TDSet::kMultiDSet)) {
12245 TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12246 ds->SetSrvMaps(srvmapslist);
12247 if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12248 emsg.Form("error integrating dataset %s", dataset->GetName());
12249 continue;
12250 }
12251 // Add the TDSet object to the multi-dataset
12252 dset->Add(ds);
12253 // Add entry list if any
12254 if (enl) ds->SetEntryList(enl);
12255 } else {
12256 dset->SetSrvMaps(srvmapslist);
12257 if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12258 emsg.Form("error integrating dataset %s", dataset->GetName());
12259 continue;
12260 }
12261 if (enl) entrylist = enl;
12262 }
12263 if (missingFiles) {
12264 // The missing files objects have to be removed from the dataset
12265 // before delete.
12266 TIter next(missingFiles);
12267 TObject *file;
12268 while ((file = next())) {
12269 dataset->GetList()->Remove(file);
12270 listOfMissingFiles->Add(file);
12271 }
12272 missingFiles->SetOwner(kFALSE);
12273 missingFiles->Clear();
12274 }
12275 SafeDelete(missingFiles);
12276 }
12277 // Cleanup; we need to do this because pairs do no delete their content
12278 nxds.Reset();
12279 while ((pair = (TPair *) nxds())) {
12280 if (pair->Key()) delete pair->Key();
12281 if (pair->Value()) delete pair->Value();
12282 }
12283 datasets->SetOwner(kTRUE);
12284 SafeDelete(datasets);
12285
12286 // Cleanup the server mapping list, if created by the user
12287 if (srvmapslist && srvmapslist != srvmapsref) {
12288 srvmapslist->SetOwner(kTRUE);
12289 SafeDelete(srvmapslist);
12290 }
12291
12292 // Set the global entrylist, if required
12293 if (entrylist) dset->SetEntryList(entrylist);
12294
12295 // Make sure it will be sent back merged with other similar lists created
12296 // during processing; this list will be transferred by the player to the
12297 // output list, once the latter has been created (see TProofPlayerRemote::Process)
12298 if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12299 listOfMissingFiles->SetName("MissingFiles");
12300 input->Add(listOfMissingFiles);
12301 }
12302
12303 // Done
12304 return 0;
12305}
12306
12307////////////////////////////////////////////////////////////////////////////////
12308/// Save input data file from 'cachedir' into the sandbox or create a the file
12309/// with input data objects
12310
12311Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12312{
12313 TList *input = 0;
12314
12315 // We must have got something to process
12316 if (!qr || !(input = qr->GetInputList()) ||
12317 !cachedir || strlen(cachedir) <= 0) return 0;
12318
12319 // There must be some input data or input data file
12320 TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12321 TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12322 if (!data && !inputdata) return 0;
12323 // Default dstination filename
12324 if (!data)
12325 input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12326
12327 TString dstname(data->GetTitle()), srcname;
12328 Bool_t fromcache = kFALSE;
12329 if (dstname.BeginsWith("cache:")) {
12330 fromcache = kTRUE;
12331 dstname.ReplaceAll("cache:", "");
12332 srcname.Form("%s/%s", cachedir, dstname.Data());
12333 if (gSystem->AccessPathName(srcname)) {
12334 emsg.Form("input data file not found in cache (%s)", srcname.Data());
12335 return -1;
12336 }
12337 }
12338
12339 // If from cache, just move the cache file
12340 if (fromcache) {
12341 if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12342 emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12343 return -1;
12344 }
12345 } else {
12346 // Create the file
12347 if (inputdata && inputdata->GetSize() > 0) {
12348 TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12349 if (f) {
12350 f->cd();
12351 inputdata->Write();
12352 f->Close();
12353 delete f;
12354 } else {
12355 emsg.Form("could not create %s", dstname.Data());
12356 return -1;
12357 }
12358 } else {
12359 emsg.Form("no input data!");
12360 return -1;
12361 }
12362 }
12363 ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12364
12365 // Save the file name and clean up the data list
12366 data->SetTitle(dstname);
12367 if (inputdata) {
12368 input->Remove(inputdata);
12369 inputdata->SetOwner();
12370 delete inputdata;
12371 }
12372
12373 // Done
12374 return 0;
12375}
12376
12377////////////////////////////////////////////////////////////////////////////////
12378/// Send the input data file to the workers
12379
12381{
12382 TList *input = 0;
12383
12384 // We must have got something to process
12385 if (!qr || !(input = qr->GetInputList())) return 0;
12386
12387 // There must be some input data or input data file
12388 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12389 if (!inputdata) return 0;
12390
12391 TString fname(inputdata->GetTitle());
12392 if (gSystem->AccessPathName(fname)) {
12393 emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12394 return -1;
12395 }
12396
12397 // PROOF session must available
12398 if (!p || !p->IsValid()) {
12399 emsg.Form("TProof object undefined or invalid: protocol error!");
12400 return -1;
12401 }
12402
12403 // Send to unique workers and submasters
12404 p->BroadcastFile(fname, TProof::kBinary, "cache");
12405
12406 // Done
12407 return 0;
12408}
12409
12410////////////////////////////////////////////////////////////////////////////////
12411/// Get the input data from the file defined in the input list
12412
12413Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12414{
12415 // We must have got something to process
12416 if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12417
12418 // There must be some input data or input data file
12419 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12420 if (!inputdata) return 0;
12421
12422 TString fname;
12423 fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12424 if (gSystem->AccessPathName(fname)) {
12425 emsg.Form("input data file not found in cache (%s)", fname.Data());
12426 return -1;
12427 }
12428
12429 // List of added objects (for proper cleaning ...)
12430 TList *added = new TList;
12431 added->SetName("PROOF_InputObjsFromFile");
12432 // Read the input data into the input list
12433 TFile *f = TFile::Open(fname.Data());
12434 if (f) {
12435 TList *keys = (TList *) f->GetListOfKeys();
12436 if (!keys) {
12437 emsg.Form("could not get list of object keys from file");
12438 return -1;
12439 }
12440 TIter nxk(keys);
12441 TKey *k = 0;
12442 while ((k = (TKey *)nxk())) {
12443 TObject *o = f->Get(k->GetName());
12444 if (o) {
12445 input->Add(o);
12446 added->Add(o);
12447 }
12448 }
12449 // Add the file as last one
12450 if (added->GetSize() > 0) {
12451 added->Add(f);
12452 input->Add(added);
12453 } else {
12454 // Cleanup the file now
12455 f->Close();
12456 delete f;
12457 }
12458 } else {
12459 emsg.Form("could not open %s", fname.Data());
12460 return -1;
12461 }
12462
12463 // Done
12464 return 0;
12465}
12466
12467////////////////////////////////////////////////////////////////////////////////
12468/// Start the log viewer window usign the plugin manager
12469
12470void TProof::LogViewer(const char *url, Int_t idx)
12471{
12472 if (!gROOT->IsBatch()) {
12473 // Get the handler, if not yet done
12474 if (!fgLogViewer) {
12475 if ((fgLogViewer =
12476 gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
12477 if (fgLogViewer->LoadPlugin() == -1) {
12478 fgLogViewer = 0;
12479 ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
12480 return;
12481 }
12482 }
12483 }
12484 if (fgLogViewer) {
12485 // Execute the plug-in
12486 TString u = (url && strlen(url) <= 0) ? "lite" : url;
12487 fgLogViewer->ExecPlugin(2, u.Data(), idx);
12488 }
12489 } else {
12490 if (url && strlen(url) > 0) {
12491 ::Info("TProof::LogViewer",
12492 "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
12493 } else if (url && strlen(url) <= 0) {
12494 ::Info("TProof::LogViewer",
12495 "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
12496 } else {
12497 ::Info("TProof::LogViewer",
12498 "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
12499 }
12500 }
12501 // Done
12502 return;
12503}
12504
12505////////////////////////////////////////////////////////////////////////////////
12506/// Enable/Disable the graphic progress dialog.
12507/// By default the dialog is enabled
12508
12510{
12511 if (on)
12513 else
12515}
12516
12517////////////////////////////////////////////////////////////////////////////////
12518/// Show information about missing files during query described by 'qr' or the
12519/// last query if qr is null (default).
12520/// A short summary is printed in the end.
12521
12523{
12524 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12525 if (!xqr) {
12526 Warning("ShowMissingFiles", "no (last) query found: do nothing");
12527 return;
12528 }
12529
12530 // Get the list, if any
12531 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12532 if (!missing) {
12533 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12534 return;
12535 }
12536
12537 Int_t nmf = 0, ncf = 0;
12538 Long64_t msz = 0, mszzip = 0, mev = 0;
12539 // Scan the list
12540 TFileInfo *fi = 0;
12541 TIter nxf(missing);
12542 while ((fi = (TFileInfo *) nxf())) {
12543 char status = 'M';
12544 if (fi->TestBit(TFileInfo::kCorrupted)) {
12545 ncf++;
12546 status = 'C';
12547 } else {
12548 nmf++;
12549 }
12550 TFileInfoMeta *im = fi->GetMetaData();
12551 if (im) {
12552 if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
12553 if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
12554 mev += im->GetEntries();
12555 Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
12556 } else {
12557 Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
12558 }
12559 }
12560
12561 // Final notification
12562 if (msz <= 0) msz = -1;
12563 if (mszzip <= 0) mszzip = -1;
12564 Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
12565 if (msz > 0. || mszzip > 0.) {
12566 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12567 " about %.2f%% of the total (%lld bytes, %lld zipped)",
12568 nmf, ncf, mev, xf * 100., msz, mszzip);
12569 } else {
12570 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12571 " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
12572 }
12573}
12574
12575////////////////////////////////////////////////////////////////////////////////
12576/// Get a TFileCollection with the files missing in the query described by 'qr'
12577/// or the last query if qr is null (default).
12578/// Return a null pointer if none were found, for whatever reason.
12579/// The caller is responsible for the returned object.
12580
12582{
12583 TFileCollection *fc = 0;
12584
12585 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12586 if (!xqr) {
12587 Warning("GetMissingFiles", "no (last) query found: do nothing");
12588 return fc;
12589 }
12590
12591 // Get the list, if any
12592 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12593 if (!missing) {
12594 if (gDebug > 0)
12595 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12596 return fc;
12597 }
12598
12599 // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
12600 TString fcname("unknown");
12601 TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
12602 if (ds) {
12603 fcname.Form("%s.m0", ds->GetName());
12604 Int_t j = 1;
12605 while (gDirectory->FindObject(fcname) && j < 1000)
12606 fcname.Form("%s.m%d", ds->GetName(), j++);
12607 }
12608 fc = new TFileCollection(fcname, "Missing Files");
12609 if (ds) fc->SetDefaultTreeName(ds->GetObjName());
12610 // Scan the list
12611 TFileInfo *fi = 0;
12612 TIter nxf(missing);
12613 while ((fi = (TFileInfo *) nxf())) {
12614 fc->Add((TFileInfo *) fi->Clone());
12615 }
12616 fc->Update();
12617 // Done
12618 return fc;
12619}
12620
12621////////////////////////////////////////////////////////////////////////////////
12622/// Enable/Disable saving of the performance tree
12623
12624void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
12625{
12626 if (pf && strlen(pf) > 0) {
12627 fPerfTree = pf;
12628 SetParameter("PROOF_StatsHist", "");
12629 SetParameter("PROOF_StatsTrace", "");
12630 if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
12631 Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
12632 } else {
12633 fPerfTree = "";
12634 DeleteParameters("PROOF_StatsHist");
12635 DeleteParameters("PROOF_StatsTrace");
12636 DeleteParameters("PROOF_SlaveStatsTrace");
12637 Info("SetPerfTree", "saving of the performance tree disabled");
12638 }
12639}
12640
12641////////////////////////////////////////////////////////////////////////////////
12642/// Save performance information from TPerfStats to file 'pf'.
12643/// If 'ref' is defined, do it for query 'ref'.
12644/// Return 0 on sucecss, -1 in case of any error
12645
12646Int_t TProof::SavePerfTree(const char *pf, const char *ref)
12647{
12648 if (!IsValid()) {
12649 Error("SafePerfTree", "this TProof instance is invalid!");
12650 return -1;
12651 }
12652
12653 TList *outls = GetOutputList();
12654 TString sref;
12655 if (ref && strlen(ref) > 0) {
12656 if (!fPlayer) {
12657 Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
12658 return -1;
12659 }
12661 if (!qr) {
12662 Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
12663 return -1;
12664 }
12665 outls = qr->GetOutputList();
12666 sref.Form(" for requested query '%s'", ref);
12667 }
12668 if (!outls || (outls && outls->GetSize() <= 0)) {
12669 Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
12670 return -1;
12671 }
12672
12673 TString fn = fPerfTree;
12674 if (pf && strlen(pf)) fn = pf;
12675 if (fn.IsNull()) fn = "perftree.root";
12676
12677 TFile f(fn, "RECREATE");
12678 if (f.IsZombie()) {
12679 Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
12680 } else {
12681 f.cd();
12682 TIter nxo(outls);
12683 TObject* obj = 0;
12684 while ((obj = nxo())) {
12685 TString objname(obj->GetName());
12686 if (objname.BeginsWith("PROOF_")) {
12687 // Must list the objects since other PROOF_ objects exist
12688 // besides timing objects
12689 if (objname == "PROOF_PerfStats" ||
12690 objname == "PROOF_PacketsHist" ||
12691 objname == "PROOF_EventsHist" ||
12692 objname == "PROOF_NodeHist" ||
12693 objname == "PROOF_LatencyHist" ||
12694 objname == "PROOF_ProcTimeHist" ||
12695 objname == "PROOF_CpuTimeHist")
12696 obj->Write();
12697 }
12698 }
12699 f.Close();
12700 }
12701 Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
12702
12703 // Done
12704 return 0;
12705}
@ kPROOF_VALIDATE_DSET
@ kPROOF_PING
@ kMESS_OK
@ kPROOF_DATA_READY
@ kPROOF_GETSTATS
@ kPROOF_GETTREEHEADER
@ kPROOF_PROGRESS
@ kPROOF_QUERYLIST
@ kPROOF_CHECKFILE
@ kPROOF_GOASYNC
@ kPROOF_PARALLEL
@ kPROOF_LOGLEVEL
@ kMESS_NOTOK
@ kPROOF_SENDOUTPUT
@ kPROOF_SESSIONTAG
@ kPROOF_RETRIEVE
@ kPROOF_AUTOBIN
@ kPROOF_TOUCH
@ kPROOF_GETOBJECT
@ kMESS_OBJECT
@ kPROOF_STOPPROCESS
@ kPROOF_VERSARCHCOMP
@ kPROOF_LOGFILE
@ kPROOF_REMOVE
@ kPROOF_FATAL
@ kPROOF_OUTPUTOBJECT
@ kPROOF_REALTIMELOG
@ kPROOF_SUBMERGER
@ kPROOF_QUERYSUBMITTED
@ kPROOF_ARCHIVE
@ kPROOF_SENDFILE
@ kPROOF_ECHO
@ kPROOF_GETPACKET
@ kPROOF_WORKERLISTS
@ kPROOF_OUTPUTLIST
@ kPROOF_RESET
@ kPROOF_GETPARALLEL
@ kPROOF_PRINT
@ kPROOF_FEEDBACK
@ kPROOF_SERVERSTARTED
@ kPROOF_DATASET_STATUS
@ kPROOF_LIB_INC_PATH
@ kPROOF_CACHE
@ kPROOF_MESSAGE
@ kPROOF_LOGDONE
@ kPROOF_DATASETS
@ kMESS_CINT
@ kPROOF_ENDINIT
@ kPROOF_PACKAGE_LIST
@ kPROOF_SETIDLE
@ kPROOF_STARTPROCESS
@ kPROOF_GETSLAVEINFO
@ kPROOF_MAXQUERIES
@ kPROOF_CLEANUPSESSION
@ kPROOF_STOP
@ kPROOF_GROUPVIEW
ROOT::R::TRInterface & r
Definition Object.C:4
#define SafeDelete(p)
Definition RConfig.hxx:537
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
static void retrieve(const gsl_integration_workspace *workspace, double *a, double *b, double *r, double *e)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
const Ssiz_t kNPOS
Definition RtypesCore.h:124
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
char Char_t
Definition RtypesCore.h:37
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
R__EXTERN TApplication * gApplication
const Bool_t kIterBackward
Definition TCollection.h:43
#define gDirectory
Definition TDirectory.h:385
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define R__ASSERT(e)
Definition TError.h:118
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
static unsigned int total
XFontStruct * id
Definition TGX11.cxx:109
char name[80]
Definition TGX11.cxx:110
int type
Definition TGX11.cxx:121
float xmin
int nentries
float ymin
float xmax
float ymax
#define gInterpreter
const Bool_t kSortDescending
Definition TList.h:32
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition TProofDebug.h:53
#define PDB(mask, level)
Definition TProofDebug.h:56
R__EXTERN Int_t gProofDebugLevel
Definition TProofDebug.h:54
R__EXTERN TProofServ * gProofServ
Definition TProofServ.h:347
static Int_t PoDCheckUrl(TString *_cluster)
This a private API function.
Definition TProof.cxx:347
TProof * gProof
Definition TProof.cxx:108
const char *const kPROOF_WorkerIdleTO
Definition TProof.h:135
const char *const kPROOF_PackDir
Definition TProof.h:126
const char *const kPROOF_ConfFile
Definition TProof.h:122
const char *const kPROOF_WorkDir
Definition TProof.h:124
const Long64_t kPROOF_DynWrkPollInt_s
Definition TProof.h:138
const char *const kPROOF_InputDataFile
Definition TProof.h:136
R__EXTERN TProof * gProof
Definition TProof.h:1077
const char *const kPROOF_ConfDir
Definition TProof.h:123
const Int_t kPROOF_Protocol
Definition TProof.h:120
const char *const kPROOF_TerminateWorker
Definition TProof.h:134
Int_t gDebug
Definition TROOT.cxx:592
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:404
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
@ kFileExists
Definition TSystem.h:44
@ kReadPermission
Definition TSystem.h:47
@ kWritePermission
Definition TSystem.h:46
Bool_t R_ISLNK(Int_t mode)
Definition TSystem.h:119
Bool_t R_ISDIR(Int_t mode)
Definition TSystem.h:115
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
#define R__LOCKGUARD(mutex)
#define O_BINARY
Definition civetweb.c:799
#define snprintf
Definition civetweb.c:1540
static struct mg_connection * fc(struct mg_context *ctx)
Definition civetweb.c:3728
TSignalHandler * GetSignalHandler() const
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
TObject * ReadObject(const TClass *cl) override
Read object from I/O buffer.
void WriteString(const char *s) override
Write string to I/O buffer.
char * ReadString(char *s, Int_t max) override
Read string from I/O buffer.
void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
Int_t BufferSize() const
Definition TBuffer.h:98
Int_t Length() const
Definition TBuffer.h:100
A chain is a collection of files containing TTree objects.
Definition TChain.h:33
Collection abstract base class.
Definition TCollection.h:65
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
Bool_t Contains(const char *name) const
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
Manages an element of a TDSet.
Definition TDSet.h:66
const char * GetObjName() const
Definition TDSet.h:120
Long64_t GetNum() const
Definition TDSet.h:114
const char * GetDirectory() const
Return directory where to look for object.
Definition TDSet.cxx:253
const char * GetMsd() const
Definition TDSet.h:117
const char * GetFileName() const
Definition TDSet.h:111
Long64_t GetFirst() const
Definition TDSet.h:112
This class implements a data set to be used for PROOF processing.
Definition TDSet.h:153
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition TDSet.cxx:1894
virtual Bool_t Add(const char *file, const char *objname=0, const char *dir=0, Long64_t first=0, Long64_t num=-1, const char *msd=0)
Add file to list of files to be analyzed.
Definition TDSet.cxx:1052
Bool_t ElementsValid()
Check if all elements are valid.
Definition TDSet.cxx:1556
void SetSrvMaps(TList *srvmaps=0)
Set (or unset) the list for mapping servers coordinate for files.
Definition TDSet.cxx:1172
void Validate()
Validate the TDSet by opening files.
Definition TDSet.cxx:1590
const char * GetType() const
Definition TDSet.h:228
TList * GetListOfElements() const
Definition TDSet.h:231
void SetDirectory(const char *dir)
Set/change directory.
Definition TDSet.cxx:1041
void SetObjName(const char *objname)
Set/change object name.
Definition TDSet.cxx:1026
const char * GetDirectory() const
Definition TDSet.h:230
const char * GetObjName() const
Definition TDSet.h:229
@ kEmpty
Definition TDSet.h:159
@ kMultiDSet
Definition TDSet.h:162
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
static TList * GetDataSetSrvMaps()
Static getter for server mapping list.
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...
Bool_t ParseUri(const char *uri, TString *dsGroup=0, TString *dsUser=0, TString *dsName=0, TString *dsTree=0, Bool_t onlyCurrent=kFALSE, Bool_t wildcards=kFALSE)
Parses a (relative) URI that describes a DataSet on the cluster.
Bool_t cd() override
Change current directory to "this" directory.
Utility class to draw objects in the feedback list during queries.
A List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
virtual TList * GetLists() const
Definition TEntryList.h:75
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:736
Definition TFTP.h:34
void cd(const char *dir) const
Definition TFTP.h:113
void put(const char *file, const char *remoteName=0)
Definition TFTP.h:111
Class that contains a list of TFileInfo's and accumulated meta data information about its entries.
THashList * GetList()
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
const char * GetDefaultTreeName() const
Returns the tree set with SetDefaultTreeName if set Returns the name of the first tree in the meta da...
Int_t Add(TFileInfo *info)
Add TFileInfo to the collection.
virtual void Remove()
Remove file event handler from system file handler list.
virtual void Add()
Add file event handler to system file handler list.
Long64_t GetZipBytes() const
Definition TFileInfo.h:145
Long64_t GetTotBytes() const
Definition TFileInfo.h:144
Long64_t GetEntries() const
Definition TFileInfo.h:140
Class describing a generic file including meta information.
Definition TFileInfo.h:39
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
TUrl * GetFirstUrl() const
Definition TFileInfo.h:72
Int_t GetNUrls() const
Definition TFileInfo.h:75
void ResetUrl()
Definition TFileInfo.h:69
TUrl * GetCurrentUrl() const
Return the current url.
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition TFile.cxx:1407
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=nullptr)
Resolve the file type as a function of the protocol field in 'name'.
Definition TFile.cxx:4739
EFileType
File type.
Definition TFile.h:196
@ kWeb
Definition TFile.h:196
@ kNet
Definition TFile.h:196
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:4922
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:4025
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:899
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * FindObject(const char *name) const
Find object using its name.
TObject * Remove(TObject *obj)
Remove object from the list.
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Int_t GetPort() const
const char * GetHostName() const
void Reset()
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual const char * GetClassName() const
Definition TKey.h:76
Iterator of linked list.
Definition TList.h:191
A doubly linked list.
Definition TList.h:38
virtual void Add(TObject *obj)
Definition TList.h:81
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition TList.cxx:330
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition TList.cxx:822
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
virtual TObjLink * FirstLink() const
Definition TList.h:102
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:357
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition TList.cxx:693
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition TList.cxx:250
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:764
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition TList.cxx:402
This code implements the MD5 message-digest algorithm.
Definition TMD5.h:44
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition TMD5.cxx:474
Class supporting a collection of lines with C++ code.
Definition TMacro.h:31
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition TMacro.cxx:141
TList * GetListOfLines() const
Definition TMacro.h:51
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition TMacro.cxx:303
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition TMap.h:40
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:54
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition TMap.cxx:236
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition TProof.cxx:331
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job.
Definition TProof.cxx:323
TSlave * GetMerger()
Definition TProof.h:274
virtual ~TMergerInfo()
Destructor.
Definition TProof.cxx:287
Int_t fWorkersToMerge
Definition TProof.h:254
Bool_t IsActive()
Definition TProof.h:288
TList * fWorkers
Definition TProof.h:259
void SetMergedWorker()
Increase number of already merged workers by 1.
Definition TProof.cxx:298
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition TProof.cxx:309
void Deactivate()
Definition TProof.h:287
Int_t fMergedWorkers
Definition TProof.h:256
TList * GetWorkers()
Definition TProof.h:272
Int_t GetPort()
Definition TProof.h:275
void AddMergedObjects(Int_t objects)
Definition TProof.h:282
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition TMessage.cxx:116
UInt_t What() const
Definition TMessage.h:75
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriori In case you OR "what" with kMESS_ACK,...
Definition TMessage.cxx:222
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition TMonitor.cxx:241
virtual void ActivateAll()
Activate all de-activated sockets.
Definition TMonitor.cxx:268
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition TMonitor.cxx:322
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition TMonitor.cxx:250
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition TMonitor.cxx:168
void ResetInterrupt()
Definition TMonitor.h:72
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition TMonitor.cxx:438
virtual void DeActivateAll()
De-activate all activated sockets.
Definition TMonitor.cxx:302
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition TMonitor.cxx:284
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition TMonitor.cxx:498
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition TMonitor.cxx:214
void Interrupt()
Definition TMonitor.h:71
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
TNamed()
Definition TNamed.h:36
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:31
Collectable string class.
Definition TObjString.h:28
const char * GetName() const
Returns name of object.
Definition TObjString.h:38
const TString & GetString() const
Definition TObjString.h:46
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
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:868
@ kSingleKey
write collection with single key
Definition TObject.h:91
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:429
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition TObject.cxx:644
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TObject.cxx:216
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition TObject.cxx:977
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:393
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:515
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:473
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:622
void ResetBit(UInt_t f)
Definition TObject.h:200
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition TPRegexp.h:97
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:706
The PROOF package manager contains tools to manage packages.
Definition TPackMgr.h:37
@ kDontCheck
Definition TPackMgr.h:39
@ kCheckROOT
Definition TPackMgr.h:39
void Show(const char *title=0)
Show available packages.
Definition TPackMgr.cxx:548
Int_t Build(const char *pack, Int_t opt=TPackMgr::kCheckROOT)
Method to build a package.
Definition TPackMgr.cxx:87
Int_t Install(const char *par, Bool_t rmold=kFALSE)
Install package from par (unpack the file in the directory); par can be an URL for remote retrieval.
Definition TPackMgr.cxx:766
void ShowEnabled(const char *title=0)
Show enabled packages.
Definition TPackMgr.cxx:662
static Int_t FindParPath(TPackMgr *packmgr, const char *pack, TString &par)
Get the full path to PAR, looking also in the global dirs.
Definition TPackMgr.cxx:934
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition TPackMgr.cxx:872
Int_t Load(const char *pack, TList *optls=0)
Method to load a package taking an option list Return -1 on error, 0 otherwise.
Definition TPackMgr.cxx:220
Int_t Unload(const char *pack)
Method to unload a package.
Definition TPackMgr.cxx:411
TList * GetListOfEnabled() const
Get list of enabled packages Returns a pointer to a TList object, transferring ownership to the calle...
Definition TPackMgr.cxx:644
Int_t Remove(const char *pack=0, Bool_t dolock=kTRUE)
Remove package 'pack' If 'pack' is null or empty all packages are cleared.
Definition TPackMgr.cxx:593
TMD5 * ReadMD5(const char *pack)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition TPackMgr.cxx:708
Class used by TMap to store (key,value) pairs.
Definition TMap.h:102
TObject * Value() const
Definition TMap.h:121
const char * GetName() const
Returns name of object.
Definition TMap.h:116
TObject * Key() const
Definition TMap.h:120
Named parameter, streamable and storable.
Definition TParameter.h:35
const AParamType & GetVal() const
Definition TParameter.h:67
const char * GetName() const
Returns name of object.
Definition TParameter.h:66
Longptr_t ExecPlugin(int nargs, const T &... params)
Int_t LoadPlugin()
Load the plugin library for this handler.
This class implements a plugin library manager.
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
void SetProof(TProof *p)
Definition TProofMgr.h:179
TProofInputHandler(const TProofInputHandler &)
TProof * fProof
Definition TProof.h:201
Bool_t Notify()
Handle input.
Definition TProof.cxx:169
TSocket * fSocket
Definition TProof.h:200
Bool_t Notify()
TProof interrupt handler.
Definition TProof.cxx:122
void IncreaseIdx()
Definition TProof.h:311
void DecreaseNWrks()
Definition TProof.h:309
void Reset(Int_t n=-1)
Definition TProof.h:312
const char * Export(Bool_t &changed)
Definition TProof.h:304
static char fgCr[4]
Definition TProof.h:300
void IncreaseNWrks()
Definition TProof.h:310
void SetNWrks(Int_t n)
Definition TProof.h:313
The PROOF manager interacts with the PROOF server coordinator to create or destroy a PROOF session,...
Definition TProofMgr.h:43
virtual Int_t Reset(Bool_t hard=kFALSE, const char *usr=0)
Send a cleanup request for the sessions associated with the current user.
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
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.
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 .
virtual void Find(const char *="~/", const char *=0, const char *=0)
Definition TProofMgr.h:113
virtual TProof * CreateSession(const char *=0, const char *=0, Int_t=-1)
Create a new remote session (master and associated workers).
virtual Bool_t IsValid() const
Definition TProofMgr.h:77
virtual Int_t GetFile(const char *, const char *, const char *=0)
Definition TProofMgr.h:122
virtual TProof * AttachSession(Int_t, Bool_t=kFALSE)
Dummy version provided for completeness.
virtual Bool_t IsProofd() const
Definition TProofMgr.h:76
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to 'id'.
virtual Int_t Stat(const char *, FileStat_t &, const char *=0)
Definition TProofMgr.h:120
virtual Bool_t IsLite() const
Definition TProofMgr.h:75
virtual void DiscardSession(TProof *p)
Discard TProofDesc of session 'p' from the internal list.
The purpose of this class is to provide a complete node description for masters, submasters and worke...
const TString & GetMsd() const
Int_t GetNWrks() const
const TString & GetImage() const
Bool_t IsWorker() const
const TString & GetOrdinal() const
const TString & GetWorkDir() const
Int_t GetPerfIndex() const
const TString & GetNodeName() const
Int_t GetPort() const
const char * GetName() const
Returns name of object.
Class to steer the merging of files produced on the workers.
const char * GetDir(Bool_t raw=kFALSE) const
const char * GetOutputFileName() const
const char * GetFileName() const
Bool_t IsRetrieve() const
void AttachList(TList *alist)
Attach to list 'alist'.
Container class for processing statistics.
Long64_t GetEntries() const
const char * GetOrdinal() const
Definition TProofServ.h:253
const char * GetImage() const
Definition TProofServ.h:244
TList * GetEnabledPackages() const
Definition TProofServ.h:267
virtual EQueryAction GetWorkers(TList *workers, Int_t &prioritychange, Bool_t resume=kFALSE)
Get list of workers to be used from now on.
virtual void ReleaseWorker(const char *)
Definition TProofServ.h:305
const char * GetUser() const
Definition TProofServ.h:241
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
TSocket * GetSocket() const
Definition TProofServ.h:257
const char * GetGroup() const
Definition TProofServ.h:242
void SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
static void ResolveKeywords(TString &fname, const char *path=0)
Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and <build> placeholders in fname...
TPackMgr * GetPackMgr() const
Definition TProofServ.h:249
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
const char * GetSessionDir() const
Definition TProofServ.h:247
const char * GetWorkDir() const
Definition TProofServ.h:243
const char * GetPrefix() const
Definition TProofServ.h:276
Bool_t IsTopMaster() const
Definition TProofServ.h:295
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition TProof.h:316
void HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
Handle lib, inc search paths modification request.
Definition TProof.cxx:8998
const char * GetSessionTag() const
Definition TProof.h:909
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:6533
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition TProof.cxx:1996
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition TProof.cxx:7770
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition TProof.cxx:7396
Bool_t fRedirLog
Definition TProof.h:510
Bool_t fMergersByHost
Definition TProof.h:549
Int_t SendPrint(Option_t *option="")
Send print command to master server.
Definition TProof.cxx:7068
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition TProof.cxx:11724
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition TProof.cxx:4454
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:2451
EUrgent
Definition TProof.h:393
@ kSoftInterrupt
Definition TProof.h:397
Bool_t fValid
Definition TProof.h:464
Int_t GetNumberOfQueries()
Number of queries processed by this session.
Definition TProof.cxx:2105
TProofMgr * fManager
Definition TProof.h:587
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition TProof.cxx:4410
TList * GetOutputNames()
FIXME: to be written.
Definition TProof.cxx:10118
Bool_t IsEndMaster() const
Definition TProof.h:664
TList * fUniqueSlaves
Definition TProof.h:481
Int_t fMergersCount
Definition TProof.h:550
void DisableGoAsyn()
Signal to disable related switches.
Definition TProof.cxx:6259
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition TProof.cxx:10321
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:6358
void Activate(TList *slaves=0)
Activate slave server list.
Definition TProof.cxx:2389
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition TProof.cxx:8441
TMonitor * fCurrentMonitor
Definition TProof.h:487
TMonitor * fAllUniqueMonitor
Definition TProof.h:486
void SetFeedback(TString &opt, TString &optfb, Int_t action)
Extract from opt in optfb information about wanted feedback settings.
Definition TProof.cxx:5232
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition TProof.cxx:6758
void Close(Option_t *option="")
Close all open slave servers.
Definition TProof.cxx:1798
TList * fTerminatedSlaveInfos
Definition TProof.h:573
TString fWorkDir
Definition TProof.h:467
TList * GetListOfSlaves() const
Definition TProof.h:654
TMonitor * fUniqueMonitor
Definition TProof.h:485
Int_t SetParallelSilent(Int_t nodes, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition TProof.cxx:7112
Int_t fSessionID
Definition TProof.h:528
@ kDeactivateWorker
Definition TProof.h:451
@ kActivateWorker
Definition TProof.h:450
Int_t DisablePackages()
Remove all packages.
Definition TProof.cxx:7942
Bool_t fProgressDialogStarted
Definition TProof.h:493
Int_t DownloadPackage(const char *par, const char *dstdir=0)
Download a PROOF archive (PAR file) from the master package repository.
Definition TProof.cxx:8334
EBuildPackageOpt
Definition TProof.h:453
@ kDontBuildOnClient
Definition TProof.h:454
@ kBuildAll
Definition TProof.h:456
TMap * GetDataSetQuota(const char *optStr="")
returns a map of the quotas of all groups
Definition TProof.cxx:11276
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:12311
Int_t fLogLevel
Definition TProof.h:469
FILE * fLogFileW
Definition TProof.h:512
void ShowQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition TProof.cxx:2165
Int_t fDrawQueries
Definition TProof.h:524
Int_t BuildPackage(const char *package, EBuildPackageOpt opt=kBuildAll, Int_t chkveropt=TPackMgr::kCheckROOT, TList *workers=0)
Build specified package.
Definition TProof.cxx:7990
Bool_t IsTty() const
Definition TProof.h:938
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition TProof.cxx:4803
Int_t GetClientProtocol() const
Definition TProof.h:914
Int_t fCollectTimeout
Definition TProof.h:583
virtual ~TProof()
Clean up PROOF environment.
Definition TProof.cxx:652
EQueryMode fQueryMode
Definition TProof.h:588
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition TProof.cxx:10231
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition TProof.cxx:1528
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:12413
TList * fNonUniqueMasters
Definition TProof.h:483
Int_t SendObject(const TObject *obj, ESlaves list=kActive)
Send object to master or slave servers.
Definition TProof.cxx:7054
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition TProof.cxx:4937
TVirtualProofPlayer * fPlayer
Definition TProof.h:494
Bool_t fIsWaiting
Definition TProof.h:508
void AddFeedback(const char *name)
Add object to feedback list.
Definition TProof.cxx:9989
TList * fSlaveInfo
Definition TProof.h:473
Bool_t IsParallel() const
Definition TProof.h:939
static void LogViewer(const char *url=0, Int_t sessionidx=0)
Start the log viewer window usign the plugin manager.
Definition TProof.cxx:12470
TVirtualProofPlayer * GetPlayer() const
Definition TProof.h:716
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition TProof.cxx:3046
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition TProof.cxx:4423
TString fMaster
Definition TProof.h:466
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:2567
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition TProof.cxx:11796
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:9522
void AskParallel()
Ask the for the number of parallel slaves.
Definition TProof.cxx:2077
FileMap_t fFileMap
Definition TProof.h:502
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition TProof.cxx:7714
TList * fInactiveSlaves
Definition TProof.h:480
virtual void ClearDataSetCache(const char *dataset=0)
Clear the content of the dataset cache, if any (matching 'dataset', if defined).
Definition TProof.cxx:10896
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:11353
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition TProof.cxx:6092
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition TProof.cxx:11046
TList * fChains
Definition TProof.h:496
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition TProof.cxx:9918
void SetRunStatus(ERunStatus rst)
Definition TProof.h:672
TList * fActiveSlaves
Definition TProof.h:477
TString fInputDataFile
Definition TProof.h:536
Long64_t fLastPollWorkers_s
Definition TProof.h:476
TUrl fUrl
Definition TProof.h:567
Int_t Archive(Int_t query, const char *url)
Send archive request for the qry-th query in fQueries.
Definition TProof.cxx:6057
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition TProof.cxx:4334
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition TProof.cxx:9108
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'.
Definition TProof.cxx:2148
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition TProof.cxx:1978
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition TProof.cxx:9312
TList * fLoadedMacros
Definition TProof.h:544
Long64_t fTotalBytes
Definition TProof.h:578
static void AssertMacroPath(const char *macro)
Make sure that the directory path contained by macro is in the macro path.
Definition TProof.cxx:8599
ERunStatus
Definition TProof.h:370
@ kStopped
Definition TProof.h:372
@ kAborted
Definition TProof.h:373
@ kRunning
Definition TProof.h:371
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:8888
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition TProof.cxx:10809
Int_t fWorkersToMerge
Definition TProof.h:551
PrintProgress_t fPrintProgress
Definition TProof.h:540
virtual void ShowCache(Bool_t all=kFALSE)
List contents of file cache.
Definition TProof.cxx:7691
void ClearFeedback()
Clear feedback list.
Definition TProof.cxx:10012
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:11583
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition TProof.cxx:10179
Int_t GetPort() const
Definition TProof.h:912
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition TProof.cxx:11335
void ResetMergePrg()
Reset the merge progress notificator.
Definition TProof.cxx:2465
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition TProof.cxx:12624
void ClearData(UInt_t what=kUnregistered, const char *dsname=0)
Remove files for the data directory.
Definition TProof.cxx:7412
Bool_t IsValid() const
Definition TProof.h:937
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition TProof.cxx:4782
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 void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition TProof.cxx:11116
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition TProof.cxx:11181
const char * GetConfFile() const
Definition TProof.h:905
Int_t fMaxDrawQueries
Definition TProof.h:525
Int_t GetRemoteProtocol() const
Definition TProof.h:913
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:11389
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition TProof.cxx:7140
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition TProof.cxx:7170
Int_t fSeqNum
Definition TProof.h:526
TList * fAllUniqueSlaves
Definition TProof.h:482
virtual void ShowDataSetCache(const char *dataset=0)
Display the content of the dataset cache, if any (matching 'dataset', if defined).
Definition TProof.cxx:10914
const char * GetImage() const
Definition TProof.h:910
Int_t FindNextFreeMerger()
Return a merger, which is both active and still accepts some workers to be assigned to it.
Definition TProof.cxx:4304
@ kStopMerging
Definition TProof.h:381
@ kOutputSent
Definition TProof.h:382
@ kMergerDown
Definition TProof.h:380
@ kSendOutput
Definition TProof.h:378
@ kOutputSize
Definition TProof.h:377
@ kBeMerger
Definition TProof.h:379
Float_t fPrepTime
Definition TProof.h:594
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:6665
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:11760
Bool_t fSaveLogToMacro
Definition TProof.h:516
static Bool_t GetFileInCmd(const char *cmd, TString &fn)
Static method to extract the filename (if any) form a CINT command.
Definition TProof.cxx:6495
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition TProof.cxx:10846
Int_t fOtherQueries
Definition TProof.h:523
@ kUnregistered
Definition TProof.h:387
@ kPurge
Definition TProof.h:386
@ kForceClear
Definition TProof.h:389
@ kDataset
Definition TProof.h:388
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:2669
Float_t GetCpuTime() const
Definition TProof.h:931
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition TProof.cxx:7670
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition TProof.cxx:12380
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition TProof.cxx:10199
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition TProof.cxx:7857
Int_t SendInitialState()
Transfer the initial (i.e.
Definition TProof.cxx:6774
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition TProof.cxx:1320
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition TProof.cxx:2035
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:10707
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition TProof.cxx:2475
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition TProof.cxx:9933
Bool_t IsWaiting() const
Definition TProof.h:941
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:9639
void InitMembers()
Default initializations.
Definition TProof.cxx:527
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition TProof.cxx:4258
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition TProof.cxx:4014
TString fDataPoolUrl
Definition TProof.h:585
Bool_t fEndMaster
Definition TProof.h:530
Bool_t fLogToWindowOnly
Definition TProof.h:514
Bool_t IsSync() const
Definition TProof.h:669
void SetInputDataFile(const char *datafile)
Set the file to be used to optimally distribute the input data objects.
Definition TProof.cxx:9585
Int_t fStatus
Definition TProof.h:470
TList * fRunningDSets
Definition TProof.h:581
Int_t ClearPackages()
Remove all packages.
Definition TProof.cxx:7840
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition TProof.cxx:9822
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition TProof.cxx:1660
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition TProof.cxx:4744
TList * fQueries
Definition TProof.h:522
void SetActive(Bool_t=kTRUE)
Definition TProof.h:988
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:1875
void SaveActiveList()
Save current list of active workers.
Definition TProof.cxx:11542
Bool_t fMasterServ
Definition TProof.h:566
const char * GetDataPoolUrl() const
Definition TProof.h:1043
TList * fFeedback
Definition TProof.h:495
virtual Int_t SetDataSetTreeName(const char *dataset, const char *treename)
Set/Change the name of the default tree.
Definition TProof.cxx:10766
Bool_t IsIdle() const
Definition TProof.h:940
TList * fBadSlaves
Definition TProof.h:574
EUploadPackageOpt
Definition TProof.h:366
@ kUntar
Definition TProof.h:367
@ kRemoveOld
Definition TProof.h:368
Bool_t fMergersSet
Definition TProof.h:548
Int_t fRedirectNext
Definition TProof.h:555
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:12522
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition TProof.cxx:8967
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'.
Definition TProof.cxx:2408
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition TProof.cxx:2304
ESlaves
Definition TProof.h:564
@ kUnique
Definition TProof.h:564
@ kAllUnique
Definition TProof.h:564
@ kActive
Definition TProof.h:564
@ kAll
Definition TProof.h:564
Int_t UnloadPackage(const char *package)
Unload specified package.
Definition TProof.cxx:8114
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition TProof.cxx:10000
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition TProof.cxx:6013
TList * fWrksOutputReady
Definition TProof.h:559
std::recursive_mutex fCloseMutex
Definition TProof.h:542
Bool_t SendingLogToWindow() const
Definition TProof.h:1016
static TPluginHandler * fgLogViewer
Definition TProof.h:561
TList * fMergers
Definition TProof.h:553
Long64_t GetBytesRead() const
Definition TProof.h:929
void UpdateDialog()
Final update of the progress dialog.
Definition TProof.cxx:4353
void AskStatistics()
Ask the for the statistics of the slaves.
Definition TProof.cxx:2022
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition TProof.cxx:10583
Float_t fCpuTime
Definition TProof.h:490
Bool_t fFinalizationRunning
Definition TProof.h:554
void Detach(Option_t *opt="")
Detach this instance to its proofserv.
Definition TProof.cxx:10518
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:9140
TPluginHandler * fProgressDialog
Definition TProof.h:492
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:757
const char * GetConfDir() const
Definition TProof.h:904
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:6146
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:11370
@ kRemoveDataSet
Definition TProof.h:430
@ kRegisterDataSet
Definition TProof.h:427
@ kShowQuota
Definition TProof.h:434
@ kGetQuota
Definition TProof.h:433
@ kStagingStatus
Definition TProof.h:438
@ kShowDataSets
Definition TProof.h:432
@ kCache
Definition TProof.h:436
@ kSetDefaultTreeName
Definition TProof.h:435
@ kRequestStaging
Definition TProof.h:437
@ kGetDataSets
Definition TProof.h:426
@ kCheckDataSetName
Definition TProof.h:425
@ kVerifyDataSet
Definition TProof.h:429
@ kCancelStaging
Definition TProof.h:439
@ kGetDataSet
Definition TProof.h:428
TProofMergePrg fMergePrg
Definition TProof.h:519
void SetRealTimeLog(Bool_t on=kTRUE)
Switch ON/OFF the real-time logging facility.
Definition TProof.cxx:7096
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition TProof.cxx:10496
TMacro fMacroLog
Definition TProof.h:517
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:12581
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning,...
Definition TProof.cxx:1043
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition TProof.cxx:2014
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition TProof.cxx:5948
Long64_t fBytesRead
Definition TProof.h:488
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:2610
TList * fInputData
Definition TProof.h:535
TString fPerfTree
Definition TProof.h:557
void ShowParameters(const char *wildcard="PROOF_*") const
Show the input list parameters specified by the wildcard.
Definition TProof.cxx:9958
TMonitor * fActiveMonitor
Definition TProof.h:484
void SendDataSetStatus(const char *msg, UInt_t n, UInt_t tot, Bool_t st)
Send or notify data set status.
Definition TProof.cxx:9336
Bool_t fTty
Definition TProof.h:465
virtual Int_t RemoveDataSet(const char *dataset, const char *optStr="")
Remove the specified dataset from the PROOF cluster.
Definition TProof.cxx:10991
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition TProof.cxx:6414
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition TProof.cxx:11736
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition TProof.cxx:2970
Int_t fLastAssignedMerger
Definition TProof.h:552
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition TProof.cxx:2139
void ShowFeedback() const
Show items in feedback list.
Definition TProof.cxx:10020
TString fConfDir
Definition TProof.h:569
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:7273
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition TProof.cxx:6107
Int_t UnloadPackages()
Unload all packages.
Definition TProof.cxx:8147
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition TProof.cxx:10211
TList * GetListOfActiveSlaves() const
Definition TProof.h:723
TSignalHandler * fIntHandler
Definition TProof.h:491
TList * FindDataSets(const char *searchString, const char *optStr="")
Find datasets, returns in a TList all found datasets.
Definition TProof.cxx:11010
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition TProof.cxx:12646
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:8628
@ kIsClient
Definition TProof.h:344
@ kNewInputData
Definition TProof.h:343
@ kIsMaster
Definition TProof.h:345
@ kUseProgressDialog
Definition TProof.h:347
@ kUsingSessionGui
Definition TProof.h:342
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:8843
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition TProof.cxx:513
Bool_t fDynamicStartup
Definition TProof.h:589
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition TProof.cxx:1597
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition TProof.cxx:9201
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition TProof.cxx:5883
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition TProof.cxx:8933
TSelector * fSelector
Definition TProof.h:591
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:11309
Bool_t fIsPollingWorkers
Definition TProof.h:475
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition TProof.cxx:10110
Bool_t IsLite() const
Definition TProof.h:933
virtual TFileCollection * GetStagingStatusDataSet(const char *dataset)
Obtains a TFileCollection showing the staging status of the specified dataset.
Definition TProof.cxx:11073
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:6799
Float_t fRealTime
Definition TProof.h:489
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:7649
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition TProof.cxx:12509
TString fLogFileName
Definition TProof.h:511
void GoAsynchronous()
Send GOASYNC message to the master.
Definition TProof.cxx:6267
Int_t fCheckFileStatus
Definition TProof.h:471
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition TProof.cxx:9808
TList * fAvailablePackages
Definition TProof.h:579
TList * fRecvMessages
Definition TProof.h:472
void SetManager(TProofMgr *mgr)
Set manager and schedule its destruction after this for clean operations.
Definition TProof.cxx:1301
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition TProof.cxx:6644
Int_t fProtocol
Definition TProof.h:571
void StopProcess(Bool_t abort, Int_t timeout=-1)
Send STOPPROCESS message to master and workers.
Definition TProof.cxx:6224
TList * GetEnabledPackages() const
Definition TProof.h:735
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition TProof.cxx:1987
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:1853
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition TProof.cxx:2128
ERunStatus fRunStatus
Definition TProof.h:507
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:6894
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:12014
friend class TProofInputHandler
Definition TProof.h:324
FILE * fLogFileR
Definition TProof.h:513
void Interrupt(EUrgent type, ESlaves list=kActive)
Send interrupt to master or slave servers.
Definition TProof.cxx:2276
Float_t GetRealTime() const
Definition TProof.h:930
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:10635
TList * fWaitingSlaves
Definition TProof.h:521
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:4521
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition TProof.cxx:6460
Bool_t IsProofd() const
Definition TProof.h:934
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition TProof.cxx:11557
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:7028
void ShowLog(Int_t qry=-1)
Display on screen the content of the temporary log file.
Definition TProof.cxx:10371
TString fConfFile
Definition TProof.h:568
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:9538
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition TProof.cxx:6631
void Feedback(TList *objs)
Get list of feedback objects.
Definition TProof.cxx:9268
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition TProof.cxx:11020
Int_t GetLogLevel() const
Definition TProof.h:916
TObject * GetOutput(const char *name)
Get specified object that has been produced during the processing (see Process()).
Definition TProof.cxx:9762
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition TProof.cxx:2321
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition TProof.cxx:10042
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition TProof.cxx:9380
TProofMgr::EServType fServType
Definition TProof.h:586
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:10684
@ kDisableSubPackage
Definition TProof.h:413
@ kShowSubPackages
Definition TProof.h:411
@ kShowEnabledPackages
Definition TProof.h:408
@ kListEnabledPackages
Definition TProof.h:420
@ kLoadMacro
Definition TProof.h:421
@ kShowSubCache
Definition TProof.h:409
@ kDisablePackage
Definition TProof.h:416
@ kDisablePackages
Definition TProof.h:418
@ kLoadPackage
Definition TProof.h:407
@ kBuildPackage
Definition TProof.h:406
@ kListPackages
Definition TProof.h:419
@ kUnloadPackages
Definition TProof.h:417
@ kUnloadPackage
Definition TProof.h:415
@ kShowCache
Definition TProof.h:401
@ kClearSubCache
Definition TProof.h:410
@ kBuildSubPackage
Definition TProof.h:414
@ kClearCache
Definition TProof.h:402
@ kShowPackages
Definition TProof.h:403
@ kDisableSubPackages
Definition TProof.h:412
static TList * fgProofEnvList
Definition TProof.h:545
virtual void FindUniqueSlaves()
Add to the fUniqueSlave list the active slaves that have a unique (user) file system image.
Definition TProof.cxx:1912
const char * GetUser() const
Definition TProof.h:906
TPackMgr * fPackMgr
Definition TProof.h:532
void TerminateWorker(TSlave *wrk)
Ask an active worker 'wrk' to terminate, i.e. to shutdown.
Definition TProof.cxx:4696
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition TProof.cxx:7735
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition TProof.cxx:6119
TString fActiveSlavesSaved
Definition TProof.h:478
Int_t LoadPackage(const char *package, Bool_t notOnClient=kFALSE, TList *loadopts=0, TList *workers=0)
Load specified package.
Definition TProof.cxx:8069
Bool_t fSendGroupView
list returned by kPROOF_GETSLAVEINFO
Definition TProof.h:474
TDSet * fDSet
Definition TProof.h:503
void ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst, Long64_t ent)
Reset progress dialog.
Definition TProof.cxx:9299
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition TProof.cxx:10102
friend class TProofInterruptHandler
Definition TProof.h:325
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:10937
Bool_t fSync
Definition TProof.h:506
Bool_t fDataReady
Definition TProof.h:576
@ kBinary
Definition TProof.h:443
@ kCp
Definition TProof.h:447
@ kAscii
Definition TProof.h:442
@ kForce
Definition TProof.h:444
@ kCpBin
Definition TProof.h:446
@ kForward
Definition TProof.h:445
Long64_t fBytesReady
Definition TProof.h:577
TDrawFeedback * CreateDrawFeedback()
Draw feedback creation proxy.
Definition TProof.cxx:10094
void AddChain(TChain *chain)
Add chain to data set.
Definition TProof.cxx:10223
static const TList * GetEnvVars()
Get environemnt variables.
Definition TProof.cxx:11751
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition TProof.cxx:1891
TString fGroup
Definition TProof.h:468
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition TProof.cxx:9124
TList * GetFeedbackList() const
Return feedback list.
Definition TProof.cxx:10033
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:9612
TList * fEnabledPackages
Definition TProof.h:580
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition TProof.cxx:2088
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:11782
Int_t BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
Broadcast an object to all slaves in the specified list.
Definition TProof.cxx:2543
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition TProof.cxx:7079
TList * fEnabledPackagesOnCluster
Definition TProof.h:533
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:5303
void ClearInput()
Clear input object list.
Definition TProof.cxx:9742
TList * GetListOfBadSlaves() const
Definition TProof.h:657
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:1016
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition TProof.cxx:7885
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition TProof.cxx:5857
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition TProof.cxx:2005
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition TProof.cxx:10868
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition TProof.cxx:10977
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition TProof.cxx:3105
void SetDSet(TDSet *dset)
Definition TProof.h:737
void AddInput(TObject *obj)
Add objects that might be needed during the processing of the selector (see Process()).
Definition TProof.cxx:9734
Int_t fNotIdle
Definition TProof.h:505
void RecvLogFile(TSocket *s, Int_t size)
Receive the log file of the slave with socket s.
Definition TProof.cxx:6287
Bool_t IsMaster() const
Definition TProof.h:936
void CloseProgressDialog()
Close progress dialog.
Definition TProof.cxx:9283
TProofOutputList fOutputList
Definition TProof.h:538
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition TProof.cxx:4436
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition TProof.cxx:9324
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition TProof.cxx:10257
TList * GetInputList()
Get input list.
Definition TProof.cxx:9753
TStopwatch fQuerySTW
Definition TProof.h:593
const char * GetUrl()
Definition TProof.h:911
void ReleaseMonitor(TMonitor *mon)
Release the used monitor to be used, making sure to delete newly created monitors.
Definition TProof.cxx:2654
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition TProof.cxx:7818
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition TProof.cxx:2115
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition TProof.cxx:10240
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition TProof.cxx:3060
EQueryMode
Definition TProof.h:349
@ kAsync
Definition TProof.h:351
@ kSync
Definition TProof.h:350
const char * GetMaster() const
Definition TProof.h:903
void QueryResultReady(const char *ref)
Notify availability of a query result.
Definition TProof.cxx:9369
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition TProof.cxx:11808
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition TProof.cxx:8175
TList * fSlaves
Definition TProof.h:572
Bool_t IsDataReady(Long64_t &totalbytes, Long64_t &bytesready)
See if the data is ready to be analyzed.
Definition TProof.cxx:2240
TProofMgr * GetManager()
Definition TProof.h:1037
TMonitor * fAllMonitor
Definition TProof.h:575
const char * GetGroup() const
Definition TProof.h:907
virtual Int_t VerifyDataSet(const char *dataset, const char *optStr="")
Verify if all files in the specified dataset are available.
Definition TProof.cxx:11130
TString fImage
Definition TProof.h:570
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition TQObject.h:164
void EmitVA(const char *signal_name, Int_t, const T &... params)
Emit a signal with a varying number of arguments.
Definition TQObject.h:100
A container class for query results.
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
Long64_t GetEntries() const
Int_t GetSeqNum() const
void SetTermTime(Float_t termtime)
void SetArchived(const char *archfile)
Set (or update) query in archived state.
TList * GetOutputList()
void SetPrepTime(Float_t preptime)
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
void AddInput(TObject *obj)
Add obj to the input list.
TList * GetInputList()
TMacro * GetLogFile() const
Bool_t IsFinalized() const
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2720
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition TROOT.cxx:2746
virtual Double_t Rndm()
Machine independent random number generator.
Definition TRandom.cxx:552
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition TRandom.cxx:360
Regular expression class.
Definition TRegexp.h:31
virtual const char * AsString(TString &out)
Returns short string with relevant information about this security context.
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition TSelector.h:31
Sequenceable collection abstract base class.
virtual void Add()
Add signal handler to system signal handler list.
virtual void Remove()
Remove signal handler from system signal handler list.
ESlaveStatus fStatus
Definition TProof.h:222
Int_t Compare(const TObject *obj) const
Used to sort slaveinfos by ordinal.
Definition TProof.cxx:183
TString fMsd
Definition TProof.h:218
SysInfo_t GetSysInfo() const
Definition TProof.h:233
TString fDataDir
Definition TProof.h:219
Int_t fPerfIndex
Definition TProof.h:220
void SetStatus(ESlaveStatus stat)
Definition TProof.h:234
@ kNotActive
Definition TProof.h:214
TString fOrdinal
Definition TProof.h:216
const char * GetOrdinal() const
Definition TProof.h:232
TString fHostName
Definition TProof.h:217
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition TProof.cxx:268
void SetOrdinal(const char *ord)
Definition TProof.h:236
SysInfo_t fSysInfo
Definition TProof.h:221
const char * GetName() const
Returns name of object.
Definition TProof.h:231
Bool_t IsEqual(const TObject *obj) const
Used to compare slaveinfos by ordinal.
Definition TProof.cxx:211
const char * GetDataDir() const
Definition TProof.h:229
void Print(Option_t *option="") const
Print slave info.
Definition TProof.cxx:225
Class describing a PROOF worker server.
Definition TSlave.h:46
Int_t fStatus
Definition TSlave.h:96
Int_t fParallel
Definition TSlave.h:97
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition TSlave.cxx:655
TString fImage
Definition TSlave.h:80
Float_t fRealTime
Definition TSlave.h:93
const char * GetWorkDir() const
Definition TSlave.h:127
ESlaveType fSlaveType
Definition TSlave.h:95
Int_t GetSlaveType() const
Definition TSlave.h:139
Int_t GetParallel() const
Definition TSlave.h:141
Float_t fCpuTime
Definition TSlave.h:94
const char * GetImage() const
Definition TSlave.h:125
void SetArchCompiler(const char *ac)
Definition TSlave.h:158
Int_t GetPort() const
Definition TSlave.h:130
@ kSlave
Definition TSlave.h:55
@ kMaster
Definition TSlave.h:55
TSocket * GetSocket() const
Definition TSlave.h:134
@ kOutputRequested
Definition TSlave.h:58
virtual void SetStatus(Int_t st)
Definition TSlave.h:113
virtual void StopProcess(Bool_t abort, Int_t timeout)
Sent stop/abort request to PROOF server.
Definition TSlave.cxx:629
virtual void FlushSocket()
Definition TSlave.h:105
const char * GetUser() const
Definition TSlave.h:128
TFileHandler * GetInputHandler() const
Definition TSlave.h:144
TString fWorkDir
Definition TSlave.h:82
const char * GetMsd() const
Definition TSlave.h:142
@ kActive
Definition TSlave.h:56
@ kInactive
Definition TSlave.h:56
TString fOrdinal
Definition TSlave.h:86
Long64_t fBytesRead
Definition TSlave.h:92
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:441
virtual void Touch()
Definition TSlave.h:165
TString fProofWorkDir
Definition TSlave.h:81
void SetInputHandler(TFileHandler *ih)
Adopt and register input handler for this slave.
Definition TSlave.cxx:393
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition TSlave.cxx:510
Int_t GetStatus() const
Definition TSlave.h:140
virtual void SetInterruptHandler(Bool_t)
Definition TSlave.h:156
virtual Int_t SetupServ(Int_t stype, const char *conffile)
Init a PROOF slave object.
Definition TSlave.cxx:178
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition TSlave.cxx:493
virtual Int_t SendGroupPriority(const char *, Int_t)
Definition TSlave.h:110
const char * GetName() const
Returns name of object.
Definition TSlave.h:124
TString fName
Definition TSlave.h:79
virtual Bool_t IsValid() const
Definition TSlave.h:150
void SetSessionTag(const char *st)
Definition TSlave.h:161
const char * GetOrdinal() const
Definition TSlave.h:131
const char * GetProofWorkDir() const
Definition TSlave.h:126
void SetROOTVersion(const char *rv)
Definition TSlave.h:159
virtual void Close(Option_t *opt="")
Close slave socket.
Definition TSlave.cxx:276
Int_t GetPerfIdx() const
Definition TSlave.h:132
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition TSocket.cxx:818
Int_t GetRemoteProtocol() const
Definition TSocket.h:126
TInetAddress GetInetAddress() const
Definition TSocket.h:113
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition TSocket.cxx:898
TSecContext * GetSecContext() const
Definition TSocket.h:127
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition TSocket.cxx:620
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition TSocket.cxx:600
virtual Bool_t IsValid() const
Definition TSocket.h:132
virtual Int_t Reconnect()
Definition TSocket.h:138
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition TSocket.cxx:522
A sorted doubly linked list.
Definition TSortedList.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Stop()
Stop the stopwatch.
void Reset()
Definition TStopwatch.h:52
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:442
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:649
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1946
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2202
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1131
Double_t Atof() const
Return floating-point value contained in string.
Definition TString.cxx:2012
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition TString.cxx:1816
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:682
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:523
const char * Data() const
Definition TString.h:369
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition TString.cxx:1788
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
@ kTrailing
Definition TString.h:267
@ kBoth
Definition TString.h:267
@ kIgnoreCase
Definition TString.h:268
@ kExact
Definition TString.h:268
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:916
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2222
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:615
TString & Prepend(const char *cs)
Definition TString.h:661
Bool_t IsNull() const
Definition TString.h:407
TString & Remove(Ssiz_t pos)
Definition TString.h:673
TString & Append(const char *cs)
Definition TString.h:564
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:2336
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2314
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
Definition TSystem.cxx:1713
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition TSystem.cxx:3889
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:279
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
const char * pwd()
Definition TSystem.h:422
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:263
virtual void AddIncludePath(const char *includePath)
Add a directory to the already set include path.
Definition TSystem.cxx:4153
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:1506
virtual int GetPid()
Get process id.
Definition TSystem.cxx:710
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition TSystem.cxx:1341
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1663
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3971
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4252
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition TSystem.cxx:907
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:656
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:4188
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition TSystem.cxx:665
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:1398
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:1296
virtual FILE * TempFileName(TString &base, const char *dir=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition TSystem.cxx:1497
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition TSystem.cxx:674
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:935
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition TSystem.cxx:535
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1793
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition TSystem.cxx:683
virtual const char * HostName()
Return the system's host name.
Definition TSystem.cxx:306
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition TSystem.cxx:1655
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition TSystem.cxx:952
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition TSystem.cxx:1804
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:872
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1546
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition TSystem.cxx:2297
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition TSystem.cxx:545
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1647
virtual const char * GetBuildArch() const
Return the build architecture.
Definition TSystem.cxx:3873
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1381
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition TSystem.cxx:1599
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition TSystem.cxx:1482
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Long64_t GetMaxEntryLoop() const
Definition TTree.h:494
This class represents a RFC 3986 compatible URI.
Definition TUri.h:35
Bool_t SetFragment(const TString &fragment)
Set fragment component of URI:
Definition TUri.cxx:498
const TString GetUri() const
Returns the whole URI - an implementation of chapter 5.3 component recomposition.
Definition TUri.cxx:140
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:389
const char * GetFile() const
Definition TUrl.h:69
void SetUser(const char *user)
Definition TUrl.h:82
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition TUrl.cxx:522
const char * GetUser() const
Definition TUrl.h:65
const char * GetHost() const
Definition TUrl.h:67
void SetOptions(const char *opt)
Definition TUrl.h:87
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition TUrl.cxx:471
const char * GetOptions() const
Definition TUrl.h:71
void SetHost(const char *host)
Definition TUrl.h:84
const char * GetProtocol() const
Definition TUrl.h:64
void SetPort(Int_t port)
Definition TUrl.h:88
Int_t GetPort() const
Definition TUrl.h:78
void SetPasswd(const char *pw)
Definition TUrl.h:83
The packetizer is a load balancing object created for each query.
virtual Int_t AddProcessed(TSlave *, TProofProgressStatus *, Double_t, TList **)
virtual void MarkBad(TSlave *, TProofProgressStatus *, TList **)
Abstract interface for the PROOF player.
virtual TDSetElement * GetNextPacket(TSlave *slave, TMessage *r)=0
virtual void AddEventsProcessed(Long64_t ev)=0
virtual void AddInput(TObject *inp)=0
virtual TQueryResult * GetCurrentQuery() const =0
virtual void AddOutput(TList *out)=0
virtual TList * GetInputList() const =0
virtual TObject * GetOutput(const char *name) const =0
virtual void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)=0
virtual void SetMaxDrawQueries(Int_t max)=0
virtual Long64_t GetEventsProcessed() const =0
virtual Long64_t DrawSelect(TDSet *set, const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual TQueryResult * GetQueryResult(const char *ref)=0
virtual void SetMerging(Bool_t on=kTRUE)=0
virtual EExitStatus GetExitStatus() const =0
virtual void Progress(Long64_t total, Long64_t processed)=0
virtual void AddQueryResult(TQueryResult *q)=0
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
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
virtual Int_t AddOutputObject(TObject *obj)=0
virtual Bool_t JoinProcess(TList *workers)=0
virtual TList * GetListOfResults() const =0
virtual void ClearInput()=0
virtual void HandleRecvHisto(TMessage *mess)=0
virtual void RemoveQueryResult(const char *ref)=0
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual Long64_t Finalize(Bool_t force=kFALSE, Bool_t sync=kFALSE)=0
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual void StoreFeedback(TObject *slave, TList *out)=0
virtual TDrawFeedback * CreateDrawFeedback(TProof *p)=0
virtual TVirtualPacketizer * GetPacketizer() const
virtual void DeleteDrawFeedback(TDrawFeedback *f)=0
virtual TList * GetOutputList() const =0
virtual void SetInitTime()=0
virtual void SetCurrentQuery(TQueryResult *q)=0
TLine * line
const Int_t n
Definition legend1.C:16
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:663
Double_t Sqrt(Double_t x)
Definition TMath.h:641
Definition file.py:1
Definition first.py:1
Definition tree.py:1
static const char * what
Definition stlLoader.cc:6
Int_t fMode
Definition TSystem.h:127
Bool_t fIsLink
Definition TSystem.h:132
Int_t fCpuSpeed
Definition TSystem.h:155
Int_t fL2Cache
Definition TSystem.h:157
Int_t fBusSpeed
Definition TSystem.h:156
TString fCpuType
Definition TSystem.h:153
Int_t fCpus
Definition TSystem.h:154
Int_t fPhysRam
Definition TSystem.h:158
TString fOS
Definition TSystem.h:151
TString fModel
Definition TSystem.h:152
Long_t fModtime
Definition TProof.h:499
TString fUser
Definition TSystem.h:141
auto * m
Definition textangle.C:8
auto * l
Definition textangle.C:4