Logo ROOT   6.16/01
Reference Guide
TProof.cxx
Go to the documentation of this file.
1// @(#)root/proof:$Id: a2a50e759072c37ccbc65ecbcce735a76de86e95 $
2// Author: Fons Rademakers 13/02/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11/**
12 \defgroup proof PROOF
13
14 Classes defining the Parallel ROOT Facility, PROOF, a framework for parallel analysis of ROOT TTrees.
15
16*/
17
18/**
19 \defgroup proofkernel PROOF kernel Libraries
20 \ingroup proof
21
22 The PROOF kernel libraries (libProof, libProofPlayer, libProofDraw) contain the classes defining
23 the kernel of the PROOF facility, i.e. the protocol and the utilities to steer data processing
24 and handling of results.
25
26*/
27
28/** \class TProof
29\ingroup proofkernel
30
31This class controls a Parallel ROOT Facility, PROOF, cluster.
32It fires the worker servers, it keeps track of how many workers are
33running, it keeps track of the workers running status, it broadcasts
34messages to all workers, it collects results, etc.
35
36*/
37
38#include <stdlib.h>
39#include <fcntl.h>
40#include <errno.h>
41#ifdef WIN32
42# include <io.h>
43# include <sys/stat.h>
44# include <sys/types.h>
45# include "snprintf.h"
46#else
47# include <unistd.h>
48#endif
49#include <vector>
50
51#include "RConfigure.h"
52#include "Riostream.h"
53#include "Getline.h"
54#include "TBrowser.h"
55#include "TChain.h"
56#include "TCondor.h"
57#include "TDSet.h"
58#include "TError.h"
59#include "TEnv.h"
60#include "TEntryList.h"
61#include "TEventList.h"
62#include "TFile.h"
63#include "TFileInfo.h"
64#include "TFunction.h"
65#include "TFTP.h"
66#include "THashList.h"
67#include "TInterpreter.h"
68#include "TKey.h"
69#include "TMap.h"
70#include "TMath.h"
71#include "TMessage.h"
72#include "TMethodArg.h"
73#include "TMethodCall.h"
74#include "TMonitor.h"
75#include "TObjArray.h"
76#include "TObjString.h"
77#include "TParameter.h"
78#include "TProof.h"
79#include "TProofNodeInfo.h"
80#include "TProofOutputFile.h"
81#include "TVirtualProofPlayer.h"
82#include "TVirtualPacketizer.h"
83#include "TProofServ.h"
84#include "TPluginManager.h"
85#include "TQueryResult.h"
86#include "TRandom.h"
87#include "TRegexp.h"
88#include "TROOT.h"
89#include "TSlave.h"
90#include "TSocket.h"
91#include "TSortedList.h"
92#include "TSystem.h"
93#include "TTree.h"
94#include "TUrl.h"
95#include "TFileCollection.h"
96#include "TDataSetManager.h"
97#include "TDataSetManagerFile.h"
98#include "TMacro.h"
99#include "TSelector.h"
100#include "TPRegexp.h"
101#include "TPackMgr.h"
102
103#include <mutex>
104
106
107// Rotating indicator
108char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
109
110TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
111TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
112
114
115//----- PROOF Interrupt signal handler -----------------------------------------
116////////////////////////////////////////////////////////////////////////////////
117/// TProof interrupt handler.
118
120{
121 if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
122
123 // Cannot ask the user : abort any remote processing
125
126 } else {
127 // Real stop or request to switch to asynchronous?
128 const char *a = 0;
129 if (fProof->GetRemoteProtocol() < 22) {
130 a = Getline("\nSwitch to asynchronous mode not supported remotely:"
131 "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
132 } else {
133 a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
134 " any other key to continue: ");
135 }
136 if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
137
138 Info("Notify","Processing interrupt signal ... %c", a[0]);
139
140 // Stop or abort any remote processing
141 Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
142 fProof->StopProcess(abort);
143
144 } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
145 // Stop any remote processing
147 }
148 }
149
150 return kTRUE;
151}
152
153//----- Input handler for messages from TProofServ -----------------------------
154////////////////////////////////////////////////////////////////////////////////
155/// Constructor
156
158 : TFileHandler(s->GetDescriptor(),1),
159 fSocket(s), fProof(p)
160{
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Handle input
165
167{
169 return kTRUE;
170}
171
172
173//------------------------------------------------------------------------------
174
176
177////////////////////////////////////////////////////////////////////////////////
178/// Used to sort slaveinfos by ordinal.
179
181{
182 if (!obj) return 1;
183
184 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
185
186 if (!si) return fOrdinal.CompareTo(obj->GetName());
187
188 const char *myord = GetOrdinal();
189 const char *otherord = si->GetOrdinal();
190 while (myord && otherord) {
191 Int_t myval = atoi(myord);
192 Int_t otherval = atoi(otherord);
193 if (myval < otherval) return 1;
194 if (myval > otherval) return -1;
195 myord = strchr(myord, '.');
196 if (myord) myord++;
197 otherord = strchr(otherord, '.');
198 if (otherord) otherord++;
199 }
200 if (myord) return -1;
201 if (otherord) return 1;
202 return 0;
203}
204
205////////////////////////////////////////////////////////////////////////////////
206/// Used to compare slaveinfos by ordinal.
207
209{
210 if (!obj) return kFALSE;
211 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
212 if (!si) return kFALSE;
213 return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Print slave info. If opt = "active" print only the active
218/// slaves, if opt="notactive" print only the not active slaves,
219/// if opt = "bad" print only the bad slaves, else
220/// print all slaves.
221
223{
224 TString stat = fStatus == kActive ? "active" :
225 fStatus == kBad ? "bad" :
226 "not active";
227
228 Bool_t newfmt = kFALSE;
229 TString oo(opt);
230 if (oo.Contains("N")) {
231 newfmt = kTRUE;
232 oo.ReplaceAll("N","");
233 }
234 if (oo == "active" && fStatus != kActive) return;
235 if (oo == "notactive" && fStatus != kNotActive) return;
236 if (oo == "bad" && fStatus != kBad) return;
237
238 if (newfmt) {
239 TString msd, si, datadir;
240 if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
241 if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
242 if (fSysInfo.fCpus > 0) {
243 si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
245 } else {
246 si.Form("| %s", fHostName.Data());
247 }
248 Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
249
250 } else {
251 TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
252
253 std::cout << "Slave: " << fOrdinal
254 << " hostname: " << fHostName
255 << " msd: " << msd
256 << " perf index: " << fPerfIndex
257 << " " << stat
258 << std::endl;
259 }
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Setter for fSysInfo
264
266{
267 fSysInfo.fOS = si.fOS; // OS
268 fSysInfo.fModel = si.fModel; // computer model
269 fSysInfo.fCpuType = si.fCpuType; // type of cpu
270 fSysInfo.fCpus = si.fCpus; // number of cpus
271 fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
272 fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
273 fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
274 fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
275}
276
278
279//------------------------------------------------------------------------------
280
281////////////////////////////////////////////////////////////////////////////////
282/// Destructor
283
285{
286 // Just delete the list, the objects are owned by other list
287 if (fWorkers) {
290 }
291}
292////////////////////////////////////////////////////////////////////////////////
293/// Increase number of already merged workers by 1
294
296{
298 Error("SetMergedWorker", "all workers have been already merged before!");
299 else
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Add new worker to the list of workers to be merged by this merger
305
307{
308 if (!fWorkers)
309 fWorkers = new TList();
310 if (fWorkersToMerge == fWorkers->GetSize()) {
311 Error("AddWorker", "all workers have been already assigned to this merger");
312 return;
313 }
314 fWorkers->Add(sl);
315}
316
317////////////////////////////////////////////////////////////////////////////////
318/// Return if merger has already merged all workers, i.e. if it has finished its merging job
319
321{
323}
324
325////////////////////////////////////////////////////////////////////////////////
326/// Return if the determined number of workers has been already assigned to this merger
327
329{
330 if (!fWorkers)
331 return kFALSE;
332
333 return (fWorkers->GetSize() == fWorkersToMerge);
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// This a private API function.
338/// It checks whether the connection string contains a PoD cluster protocol.
339/// If it does, then the connection string will be changed to reflect
340/// a real PROOF connection string for a PROOF cluster managed by PoD.
341/// PoD: http://pod.gsi.de .
342/// Return -1 if the PoD request failed; return 0 otherwise.
343
344static Int_t PoDCheckUrl(TString *_cluster)
345{
346 if ( !_cluster )
347 return 0;
348
349 // trim spaces from both sides of the string
350 *_cluster = _cluster->Strip( TString::kBoth );
351 // PoD protocol string
352 const TString pod_prot("pod");
353
354 // URL test
355 // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
356 TUrl url( _cluster->Data() );
357 if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
358 return 0;
359
360 // PoD cluster is used
361 // call pod-info in a batch mode (-b).
362 // pod-info will find either a local PoD cluster or
363 // a remote one, manged by pod-remote.
364 *_cluster = gSystem->GetFromPipe("pod-info -c -b");
365 if( 0 == _cluster->Length() ) {
366 Error("PoDCheckUrl", "PoD server is not running");
367 return -1;
368 }
369 return 0;
370}
371
372////////////////////////////////////////////////////////////////////////////////
373/// Create a PROOF environment. Starting PROOF involves either connecting
374/// to a master server, which in turn will start a set of slave servers, or
375/// directly starting as master server (if master = ""). Masterurl is of
376/// the form: [proof[s]://]host[:port]. Conffile is the name of the config
377/// file describing the remote PROOF cluster (this argument alows you to
378/// describe different cluster configurations).
379/// The default is proof.conf. Confdir is the directory where the config
380/// file and other PROOF related files are (like motd and noproof files).
381/// Loglevel is the log level (default = 1). User specified custom config
382/// files will be first looked for in $HOME/.conffile.
383
384TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
385 Int_t loglevel, const char *alias, TProofMgr *mgr)
386 : fUrl(masterurl)
387{
388 // Default initializations
389 InitMembers();
390
391 // This may be needed during init
392 fManager = mgr;
393
394 // Default server type
396
397 // Default query mode
399
400 // Parse the main URL, adjusting the missing fields and setting the relevant
401 // bits
404
405 // Protocol and Host
406 if (!masterurl || strlen(masterurl) <= 0) {
407 fUrl.SetProtocol("proof");
408 fUrl.SetHost("__master__");
409 } else if (!(strstr(masterurl, "://"))) {
410 fUrl.SetProtocol("proof");
411 }
412 // Port
413 if (fUrl.GetPort() == TUrl(" ").GetPort())
414 fUrl.SetPort(TUrl("proof:// ").GetPort());
415
416 // Make sure to store the FQDN, so to get a solid reference for subsequent checks
417 if (!strcmp(fUrl.GetHost(), "__master__"))
418 fMaster = fUrl.GetHost();
419 else if (!strlen(fUrl.GetHost()))
421 else
423
424 // Server type
425 if (strlen(fUrl.GetOptions()) > 0) {
426 TString opts(fUrl.GetOptions());
427 if (!(strncmp(fUrl.GetOptions(),"std",3))) {
429 opts.Remove(0,3);
430 fUrl.SetOptions(opts.Data());
431 } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
433 opts.Remove(0,4);
434 fUrl.SetOptions(opts.Data());
435 }
436 }
437
438 // Instance type
442 if (fMaster == "__master__") {
446 } else if (fMaster == "prooflite") {
447 // Client and master are merged
450 }
451 // Flag that we are a client
453 if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
454
455 Init(masterurl, conffile, confdir, loglevel, alias);
456
457 // If the user was not set, get it from the master
458 if (strlen(fUrl.GetUser()) <= 0) {
459 TString usr, emsg;
460 if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
461 TObjString *os = fMacroLog.GetLineWith("const char");
462 if (os) {
463 Ssiz_t fst = os->GetString().First('\"');
464 Ssiz_t lst = os->GetString().Last('\"');
465 usr = os->GetString()(fst+1, lst-fst-1);
466 } else {
467 emsg = "could not find 'const char *' string in macro log";
468 }
469 } else {
470 emsg = "could not retrieve user info";
471 }
472 if (!emsg.IsNull()) {
473 // Get user logon name
475 if (pw) {
476 usr = pw->fUser;
477 delete pw;
478 }
479 Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
480 }
481 // Set the user name in the main URL
482 fUrl.SetUser(usr.Data());
483 }
484
485 // If called by a manager, make sure it stays in last position
486 // for cleaning
487 if (mgr) {
489 gROOT->GetListOfSockets()->Remove(mgr);
490 gROOT->GetListOfSockets()->Add(mgr);
491 }
492
493 // Old-style server type: we add this to the list and set the global pointer
495 if (!gROOT->GetListOfProofs()->FindObject(this))
496 gROOT->GetListOfProofs()->Add(this);
497
498 // Still needed by the packetizers: needs to be changed
499 gProof = this;
500}
501
502////////////////////////////////////////////////////////////////////////////////
503/// Protected constructor to be used by classes deriving from TProof
504/// (they have to call Init themselves and override StartSlaves
505/// appropriately).
506///
507/// This constructor simply closes any previous gProof and sets gProof
508/// to this instance.
509
510TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
511{
512 // Default initializations
513 InitMembers();
514
515 if (!gROOT->GetListOfProofs()->FindObject(this))
516 gROOT->GetListOfProofs()->Add(this);
517
518 gProof = this;
519}
520
521////////////////////////////////////////////////////////////////////////////////
522/// Default initializations
523
525{
526 fValid = kFALSE;
527 fTty = kFALSE;
528 fRecvMessages = 0;
529 fSlaveInfo = 0;
534 fActiveSlaves = 0;
535 fInactiveSlaves = 0;
536 fUniqueSlaves = 0;
539 fActiveMonitor = 0;
540 fUniqueMonitor = 0;
542 fCurrentMonitor = 0;
543 fBytesRead = 0;
544 fRealTime = 0;
545 fCpuTime = 0;
546 fIntHandler = 0;
547 fProgressDialog = 0;
550 fPlayer = 0;
551 fFeedback = 0;
552 fChains = 0;
553 fDSet = 0;
554 fNotIdle = 0;
555 fSync = kTRUE;
559 fLogFileW = 0;
560 fLogFileR = 0;
563 fMacroLog.SetName("ProofLogMacro");
564
565 fWaitingSlaves = 0;
566 fQueries = 0;
567 fOtherQueries = 0;
568 fDrawQueries = 0;
569 fMaxDrawQueries = 1;
570 fSeqNum = 0;
571
572 fSessionID = -1;
574
575 fPackMgr = 0;
577
578 fInputData = 0;
579
580 fPrintProgress = 0;
581
582 fLoadedMacros = 0;
583
584 fProtocol = -1;
585 fSlaves = 0;
587 fBadSlaves = 0;
588 fAllMonitor = 0;
590 fBytesReady = 0;
591 fTotalBytes = 0;
594 fRunningDSets = 0;
595
596 fCollectTimeout = -1;
597
598 fManager = 0;
601
604 fMergers = 0;
605 fMergersCount = -1;
607 fWorkersToMerge = 0;
609
610 fPerfTree = "";
611
613
614 fSelector = 0;
615
616 fPrepTime = 0.;
617
618 // Check if the user defined a list of environment variables to send over:
619 // include them into the dedicated list
620 if (gSystem->Getenv("PROOF_ENVVARS")) {
621 TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
622 Int_t from = 0;
623 while (envs.Tokenize(env, from, ",")) {
624 if (!env.IsNull()) {
625 if (!gSystem->Getenv(env)) {
626 Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
627 } else {
628 if (!envsfound.IsNull()) envsfound += ",";
629 envsfound += env;
631 TProof::AddEnvVar(env, gSystem->Getenv(env));
632 }
633 }
634 }
635 if (envsfound.IsNull()) {
636 Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
637 } else {
638 Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
639 }
640 }
641
642 // Done
643 return;
644}
645
646////////////////////////////////////////////////////////////////////////////////
647/// Clean up PROOF environment.
648
650{
651 if (fChains) {
652 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
653 // remove "chain" from list
654 chain->SetProof(0);
655 RemoveChain(chain);
656 }
657 }
658
659 // remove links to packages enabled on the client
661 // iterate over all packages
663 TIter nxp(epl);
664 while (TObjString *pck = (TObjString *)(nxp())) {
665 FileStat_t stat;
666 if (gSystem->GetPathInfo(pck->String(), stat) == 0) {
667 // check if symlink, if so unlink
668 // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
669 // existing file or to a directory, but if fIsLink is true the symlink exists
670 if (stat.fIsLink)
671 gSystem->Unlink(pck->String());
672 }
673 }
674 }
675
676 Close();
702 if (fWrksOutputReady) {
704 delete fWrksOutputReady;
705 }
706
707 // remove file with redirected logs
709 if (fLogFileR)
710 fclose(fLogFileR);
711 if (fLogFileW)
712 fclose(fLogFileW);
713 if (fLogFileName.Length() > 0)
715 }
716
717 // Remove for the global list
718 gROOT->GetListOfProofs()->Remove(this);
719 // ... and from the manager list
720 if (fManager && fManager->IsValid())
722
723 if (gProof && gProof == this) {
724 // Set previous as default
725 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
726 while ((gProof = (TProof *)pvp())) {
728 break;
729 }
730 }
731
732 // For those interested in our destruction ...
733 Emit("~TProof()");
734 Emit("CloseWindow()");
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// Start the PROOF environment. Starting PROOF involves either connecting
739/// to a master server, which in turn will start a set of slave servers, or
740/// directly starting as master server (if master = ""). For a description
741/// of the arguments see the TProof ctor. Returns the number of started
742/// master or slave servers, returns 0 in case of error, in which case
743/// fValid remains false.
744
745Int_t TProof::Init(const char *, const char *conffile,
746 const char *confdir, Int_t loglevel, const char *alias)
747{
749
750 fValid = kFALSE;
751
752 // Connected to terminal?
753 fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
754
755 // If in attach mode, options is filled with additional info
756 Bool_t attach = kFALSE;
757 if (strlen(fUrl.GetOptions()) > 0) {
758 attach = kTRUE;
759 // A flag from the GUI
760 TString opts = fUrl.GetOptions();
761 if (opts.Contains("GUI")) {
763 opts.Remove(opts.Index("GUI"));
764 fUrl.SetOptions(opts);
765 }
766 }
767
769 // Fill default conf file and conf dir
770 if (!conffile || !conffile[0])
772 if (!confdir || !confdir[0])
774 // The group; the client receives it in the kPROOF_SESSIONTAG message
776 } else {
777 fConfDir = confdir;
778 fConfFile = conffile;
779 }
780
781 // Analysise the conffile field
782 if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
784
786 fLogLevel = loglevel;
789 fImage = fMasterServ ? "" : "<local>";
790 fIntHandler = 0;
791 fStatus = 0;
792 fRecvMessages = new TList;
794 fSlaveInfo = 0;
795 fChains = new TList;
798 fRunningDSets = 0;
800 fInputData = 0;
802 fPrintProgress = 0;
803
804 // Timeout for some collect actions
805 fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
806
807 // Should the workers be started dynamically; default: no
808 fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
809
810 // Default entry point for the data pool is the master
812 fDataPoolUrl.Form("root://%s", fMaster.Data());
813 else
814 fDataPoolUrl = "";
815
816 fProgressDialog = 0;
818
819 // Default alias is the master name
820 TString al = (alias) ? alias : fMaster.Data();
821 SetAlias(al);
822
823 // Client logging of messages from the master and slaves
826 fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
827 if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
828 Error("Init", "could not create temporary logfile");
829 if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
830 Error("Init", "could not open temp logfile for reading");
831 }
833
834 // Status of cluster
835 fNotIdle = 0;
836 // Query type
837 fSync = (attach) ? kFALSE : kTRUE;
838 // Not enqueued
840
841 // Counters
842 fBytesRead = 0;
843 fRealTime = 0;
844 fCpuTime = 0;
845
846 // List of queries
847 fQueries = 0;
848 fOtherQueries = 0;
849 fDrawQueries = 0;
850 fMaxDrawQueries = 1;
851 fSeqNum = 0;
852
853 // Remote ID of the session
854 fSessionID = -1;
855
856 // Part of active query
857 fWaitingSlaves = 0;
858
859 // Make remote PROOF player
860 fPlayer = 0;
861 MakePlayer();
862
863 fFeedback = new TList;
865 fFeedback->SetName("FeedbackList");
867
868 // sort slaves by descending performance index
870 fActiveSlaves = new TList;
872 fUniqueSlaves = new TList;
875 fBadSlaves = new TList;
876 fAllMonitor = new TMonitor;
880 fCurrentMonitor = 0;
881
884
885 fLoadedMacros = 0;
886 fPackMgr = 0;
887
888 // Enable optimized sending of streamer infos to use embedded backward/forward
889 // compatibility support between different ROOT versions and different versions of
890 // users classes
891 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
892 if (enableSchemaEvolution) {
894 } else {
895 Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
896 }
897
898 if (IsMaster()) {
899 // to make UploadPackage() method work on the master as well.
901 } else {
902
903 TString sandbox;
904 if (GetSandbox(sandbox, kTRUE) != 0) {
905 Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
906 return 0;
907 }
908
909 // Package Dir
910 TString packdir = gEnv->GetValue("Proof.PackageDir", "");
911 if (packdir.IsNull())
912 packdir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
913 if (AssertPath(packdir, kTRUE) != 0) {
914 Error("Init", "failure asserting directory %s", packdir.Data());
915 return 0;
916 }
917 fPackMgr = new TPackMgr(packdir);
918 if (gDebug > 0)
919 Info("Init", "package directory set to %s", packdir.Data());
920 }
921
922 if (!IsMaster()) {
923 // List of directories where to look for global packages
924 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
926 Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
927 if (gDebug > 0)
928 Info("Init", " %d global package directories registered", nglb);
929 }
930
931 // Master may want dynamic startup
932 if (fDynamicStartup) {
933 if (!IsMaster()) {
934 // If on client - start the master
935 if (!StartSlaves(attach))
936 return 0;
937 }
938 } else {
939
940 // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
941 // result retrieving, ...)
942 Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
943 if (!IsMaster() || !masterOnly) {
944 // Start slaves (the old, static, per-session way)
945 if (!StartSlaves(attach))
946 return 0;
947 // Client: Is Master in dynamic startup mode?
948 if (!IsMaster()) {
949 Int_t dyn = 0;
950 GetRC("Proof.DynamicStartup", dyn);
951 if (dyn != 0) fDynamicStartup = kTRUE;
952 }
953 }
954 }
955 // we are now properly initialized
956 fValid = kTRUE;
957
958 // De-activate monitor (will be activated in Collect)
960
961 // By default go into parallel mode
962 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
963 TNamed *n = 0;
964 if (TProof::GetEnvVars() &&
965 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
966 TString s(n->GetTitle());
967 if (s.IsDigit()) nwrk = s.Atoi();
968 }
969 GoParallel(nwrk, attach);
970
971 // Send relevant initial state to slaves
972 if (!attach)
974 else if (!IsIdle())
975 // redirect log
977
978 // Done at this point, the alias will be communicated to the coordinator, if any
980 SetAlias(al);
981
983
984 if (IsValid()) {
985
986 // Activate input handler
988
990 gROOT->GetListOfSockets()->Add(this);
991 }
992
993 AskParallel();
994
995 return fActiveSlaves->GetSize();
996}
997
998////////////////////////////////////////////////////////////////////////////////
999/// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1000/// Use the existing setting or the default if nothing is found.
1001/// If 'assert' is kTRUE, make also sure that the path exists.
1002/// Return 0 on success, -1 on failure
1003
1004Int_t TProof::GetSandbox(TString &sb, Bool_t assert, const char *rc)
1005{
1006 // Get it from 'rc', if defined
1007 if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1008 // Or use the default 'rc'
1009 if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1010 // If nothing found , use the default
1011 if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1012 // Expand special settings
1013 if (sb == ".") {
1014 sb = gSystem->pwd();
1015 } else if (sb == "..") {
1016 sb = gSystem->DirName(gSystem->pwd());
1017 }
1019
1020 // Assert the path, if required
1021 if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1022 // Done
1023 return 0;
1024}
1025
1026////////////////////////////////////////////////////////////////////////////////
1027/// The config file field may contain special instructions which need to be
1028/// parsed at the beginning, e.g. for debug runs with valgrind.
1029/// Several options can be given separated by a ','
1030
1031void TProof::ParseConfigField(const char *config)
1032{
1033 TString sconf(config), opt;
1034 Ssiz_t from = 0;
1035 Bool_t cpuPin = kFALSE;
1036
1037 // Analysise the field
1038 const char *cq = (IsLite()) ? "\"" : "";
1039 while (sconf.Tokenize(opt, from, ",")) {
1040 if (opt.IsNull()) continue;
1041
1042 if (opt.BeginsWith("valgrind")) {
1043 // Any existing valgrind setting? User can give full settings, which we fully respect,
1044 // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1045 // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1046 // will add option "--time-stamp --leak-check=full" to our default options
1047 TString mst, top, sub, wrk, all;
1048 TList *envs = fgProofEnvList;
1049 TNamed *n = 0;
1050 if (envs) {
1051 if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1052 all = n->GetTitle();
1053 if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1054 mst = n->GetTitle();
1055 if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1056 top = n->GetTitle();
1057 if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1058 sub = n->GetTitle();
1059 if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1060 wrk = n->GetTitle();
1061 }
1062 if (all != "" && mst == "") mst = all;
1063 if (all != "" && top == "") top = all;
1064 if (all != "" && sub == "") sub = all;
1065 if (all != "" && wrk == "") wrk = all;
1066 if (all != "" && all.BeginsWith("valgrind_opts:")) {
1067 // The field is used to add an option Reset the setting
1068 Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1069 " must be set again for next run , if any");
1070 TProof::DelEnvVar("PROOF_WRAPPERCMD");
1071 }
1072 TString var, cmd;
1073 cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1074 TString mstlab("NO"), wrklab("NO");
1075 Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1076 !opt.Contains("topmaster") && !opt.Contains("submaster")))
1077 ? kTRUE : kFALSE;
1078 if (doMaster) {
1079 if (!IsLite()) {
1080 // Check if we have to add a var
1081 if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1082 mst.ReplaceAll("valgrind_opts:","");
1083 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1084 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1085 mstlab = "YES";
1086 } else if (mst != "") {
1087 mstlab = "YES";
1088 }
1089 } else {
1090 if (opt.Contains("master")) {
1091 Warning("ParseConfigField",
1092 "master valgrinding does not make sense for PROOF-Lite: ignoring");
1093 opt.ReplaceAll("master", "");
1094 if (!opt.Contains("workers")) return;
1095 }
1096 if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1097 }
1098 }
1099 if (opt.Contains("topmaster")) {
1100 // Check if we have to add a var
1101 if (top == "" || top.BeginsWith("valgrind_opts:")) {
1102 top.ReplaceAll("valgrind_opts:","");
1103 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1104 TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1105 mstlab = "YES";
1106 } else if (top != "") {
1107 mstlab = "YES";
1108 }
1109 }
1110 if (opt.Contains("submaster")) {
1111 // Check if we have to add a var
1112 if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1113 sub.ReplaceAll("valgrind_opts:","");
1114 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1115 TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1116 mstlab = "YES";
1117 } else if (sub != "") {
1118 mstlab = "YES";
1119 }
1120 }
1121 if (opt.Contains("=workers") || opt.Contains("+workers")) {
1122 // Check if we have to add a var
1123 if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1124 wrk.ReplaceAll("valgrind_opts:","");
1125 var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1126 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1127 TString nwrks("2");
1128 Int_t inw = opt.Index('#');
1129 if (inw != kNPOS) {
1130 nwrks = opt(inw+1, opt.Length());
1131 if (!nwrks.IsDigit()) nwrks = "2";
1132 }
1133 // Set the relevant variables
1134 if (!IsLite()) {
1135 TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1136 } else {
1137 gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1138 }
1139 wrklab = nwrks;
1140 // Register the additional worker log in the session file
1141 // (for the master this is done automatically)
1142 TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1143 } else if (wrk != "") {
1144 wrklab = "ALL";
1145 }
1146 }
1147 // Increase the relevant timeouts
1148 if (!IsLite()) {
1149 TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1150 gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1151 } else {
1152 gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1153 }
1154 // Warn for slowness
1155 Printf(" ");
1156 if (!IsLite()) {
1157 Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1158 } else {
1159 Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1160 }
1161 Printf(" ---> Please be patient: startup may be VERY slow ...");
1162 Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1163 Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1164 Printf(" ");
1165
1166 } else if (opt.BeginsWith("igprof-pp")) {
1167
1168 // IgProf profiling on master and worker. PROOF does not set the
1169 // environment for you: proper environment variables (like PATH and
1170 // LD_LIBRARY_PATH) should be set externally
1171
1172 Printf("*** Requested IgProf performance profiling ***");
1173 TString addLogExt = "__igprof.pp__.log";
1174 TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1175 TString tmp;
1176
1177 if (IsLite()) {
1178 addLogFmt.Append("\"");
1179 addLogFmt.Prepend("\"");
1180 }
1181
1182 tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1183 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1184
1185 tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1186 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1187
1188 TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1189
1190 } else if (opt.BeginsWith("cpupin=")) {
1191 // Enable CPU pinning. Takes as argument the list of processor IDs
1192 // that will be used in order. Processor IDs are numbered from 0,
1193 // use likwid to see how they are organized. A possible parameter
1194 // format would be:
1195 //
1196 // cpupin=3+4+0+9+10+22+7
1197 //
1198 // Only the specified processor IDs will be used in a round-robin
1199 // fashion, dealing with the fact that you can request more workers
1200 // than the number of processor IDs you have specified.
1201 //
1202 // To use all available processors in their order:
1203 //
1204 // cpupin=*
1205
1206 opt.Remove(0, 7);
1207
1208 // Remove any char which is neither a number nor a plus '+'
1209 for (Ssiz_t i=0; i<opt.Length(); i++) {
1210 Char_t c = opt[i];
1211 if ((c != '+') && ((c < '0') || (c > '9')))
1212 opt[i] = '_';
1213 }
1214 opt.ReplaceAll("_", "");
1215 TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1216 cpuPin = kTRUE;
1217 } else if (opt.BeginsWith("workers=")) {
1218
1219 // Request for a given number of workers (within the max) or worker
1220 // startup combination:
1221 // workers=5 start max 5 workers (or less, if less are assigned)
1222 // workers=2x start max 2 workers per node (or less, if less are assigned)
1223 opt.ReplaceAll("workers=","");
1224 TProof::AddEnvVar("PROOF_NWORKERS", opt);
1225 }
1226 }
1227
1228 // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1229 #ifdef R__LINUX
1230 if (IsLite() && cpuPin) {
1231 Printf("*** Requested CPU pinning ***");
1232 const TList *ev = GetEnvVars();
1233 const char *pinCmd = "taskset -c <cpupin>";
1234 TString val;
1235 TNamed *p;
1236 if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1237 val = p->GetTitle();
1238 val.Insert(val.Length()-1, " ");
1239 val.Insert(val.Length()-1, pinCmd);
1240 }
1241 else {
1242 val.Form("\"%s\"", pinCmd);
1243 }
1244 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1245 }
1246 #endif
1247}
1248
1249////////////////////////////////////////////////////////////////////////////////
1250/// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1251/// that the path is writable
1252
1253Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1254{
1255 if (!inpath || strlen(inpath) <= 0) {
1256 Error("AssertPath", "undefined input path");
1257 return -1;
1258 }
1259
1260 TString path(inpath);
1261 gSystem->ExpandPathName(path);
1262
1263 if (gSystem->AccessPathName(path, kFileExists)) {
1264 if (gSystem->mkdir(path, kTRUE) != 0) {
1265 Error("AssertPath", "could not create path %s", path.Data());
1266 return -1;
1267 }
1268 }
1269 // It must be writable
1270 if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1271 if (gSystem->Chmod(path, 0666) != 0) {
1272 Error("AssertPath", "could not make path %s writable", path.Data());
1273 return -1;
1274 }
1275 }
1276
1277 // Done
1278 return 0;
1279}
1280
1281////////////////////////////////////////////////////////////////////////////////
1282/// Set manager and schedule its destruction after this for clean
1283/// operations.
1284
1286{
1287 fManager = mgr;
1288
1289 if (mgr) {
1291 gROOT->GetListOfSockets()->Remove(mgr);
1292 gROOT->GetListOfSockets()->Add(mgr);
1293 }
1294}
1295
1296////////////////////////////////////////////////////////////////////////////////
1297/// Works on the master node only.
1298/// It starts workers on the machines in workerList and sets the paths,
1299/// packages and macros as on the master.
1300/// It is a subbstitute for StartSlaves(...)
1301/// The code is mostly the master part of StartSlaves,
1302/// with the parallel startup removed.
1303
1305{
1306 if (!IsMaster()) {
1307 Error("AddWorkers", "AddWorkers can only be called on the master!");
1308 return -1;
1309 }
1310
1311 if (!workerList || !(workerList->GetSize())) {
1312 Error("AddWorkers", "empty list of workers!");
1313 return -2;
1314 }
1315
1316 // Code taken from master part of StartSlaves with the parllel part removed
1317
1319 if (fImage.IsNull())
1321
1322 // Get all workers
1323 UInt_t nSlaves = workerList->GetSize();
1324 UInt_t nSlavesDone = 0;
1325 Int_t ord = 0;
1326
1327 // Loop over all new workers and start them (if we had already workers it means we are
1328 // increasing parallelism or that is not the first time we are called)
1329 Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1330
1331 // A list of TSlave objects for workers that are being added
1332 TList *addedWorkers = new TList();
1333 if (!addedWorkers) {
1334 // This is needed to silence Coverity ...
1335 Error("AddWorkers", "cannot create new list for the workers to be added");
1336 return -2;
1337 }
1338 addedWorkers->SetOwner(kFALSE);
1339 TListIter next(workerList);
1340 TObject *to;
1341 TProofNodeInfo *worker;
1342 TSlaveInfo *dummysi = new TSlaveInfo();
1343 while ((to = next())) {
1344 // Get the next worker from the list
1345 worker = (TProofNodeInfo *)to;
1346
1347 // Read back worker node info
1348 const Char_t *image = worker->GetImage().Data();
1349 const Char_t *workdir = worker->GetWorkDir().Data();
1350 Int_t perfidx = worker->GetPerfIndex();
1351 Int_t sport = worker->GetPort();
1352 if (sport == -1)
1353 sport = fUrl.GetPort();
1354
1355 // Create worker server
1356 TString fullord;
1357 if (worker->GetOrdinal().Length() > 0) {
1358 fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1359 } else {
1360 fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1361 }
1362
1363 // Remove worker from the list of workers terminated gracefully
1364 dummysi->SetOrdinal(fullord);
1366 SafeDelete(rmsi);
1367
1368 // Create worker server
1369 TString wn(worker->GetNodeName());
1370 if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1371 TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1372 // Add group info in the password firdl, if any
1373 if (strlen(gProofServ->GetGroup()) > 0) {
1374 // Set also the user, otherwise the password is not exported
1375 if (strlen(u.GetUser()) <= 0)
1378 }
1379 TSlave *slave = 0;
1380 if (worker->IsWorker()) {
1381 slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1382 } else {
1383 slave = CreateSubmaster(u.GetUrl(), fullord,
1384 image, worker->GetMsd(), worker->GetNWrks());
1385 }
1386
1387 // Add to global list (we will add to the monitor list after
1388 // finalizing the server startup)
1389 Bool_t slaveOk = kTRUE;
1390 fSlaves->Add(slave);
1391 if (slave->IsValid()) {
1392 addedWorkers->Add(slave);
1393 } else {
1394 slaveOk = kFALSE;
1395 fBadSlaves->Add(slave);
1396 Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1397 }
1398
1399 PDB(kGlobal,3)
1400 Info("AddWorkers", "worker on host %s created"
1401 " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1402
1403 // Notify opening of connection
1404 nSlavesDone++;
1406 m << TString("Opening connections to workers") << nSlaves
1407 << nSlavesDone << slaveOk;
1409
1410 ord++;
1411 } //end of the worker loop
1412 SafeDelete(dummysi);
1413
1414 // Cleanup
1415 SafeDelete(workerList);
1416
1417 nSlavesDone = 0;
1418
1419 // Here we finalize the server startup: in this way the bulk
1420 // of remote operations are almost parallelized
1421 TIter nxsl(addedWorkers);
1422 TSlave *sl = 0;
1423 while ((sl = (TSlave *) nxsl())) {
1424
1425 // Finalize setup of the server
1426 if (sl->IsValid())
1427 sl->SetupServ(TSlave::kSlave, 0);
1428
1429 // Monitor good slaves
1430 Bool_t slaveOk = kTRUE;
1431 if (sl->IsValid()) {
1432 fAllMonitor->Add(sl->GetSocket());
1433 PDB(kGlobal,3)
1434 Info("AddWorkers", "worker on host %s finalized"
1435 " and added to list", sl->GetOrdinal());
1436 } else {
1437 slaveOk = kFALSE;
1438 fBadSlaves->Add(sl);
1439 }
1440
1441 // Notify end of startup operations
1442 nSlavesDone++;
1444 m << TString("Setting up worker servers") << nSlaves
1445 << nSlavesDone << slaveOk;
1447 }
1448
1449 // Now set new state on the added workers (on all workers for simplicity)
1450 // use fEnabledPackages, fLoadedMacros,
1451 // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1452 // no need to load packages that are only loaded and not enabled (dyn mode)
1453 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1454 TNamed *n = 0;
1455 if (TProof::GetEnvVars() &&
1456 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1457 TString s(n->GetTitle());
1458 if (s.IsDigit()) nwrk = s.Atoi();
1459 }
1460
1461 if (fDynamicStartup && goMoreParallel) {
1462
1463 PDB(kGlobal, 3)
1464 Info("AddWorkers", "will invoke GoMoreParallel()");
1465 Int_t nw = GoMoreParallel(nwrk);
1466 PDB(kGlobal, 3)
1467 Info("AddWorkers", "GoMoreParallel()=%d", nw);
1468
1469 }
1470 else {
1471 // Not in Dynamic Workers mode
1472 PDB(kGlobal, 3)
1473 Info("AddWorkers", "will invoke GoParallel()");
1474 GoParallel(nwrk, kFALSE, 0);
1475 }
1476
1477 // Set worker processing environment
1478 SetupWorkersEnv(addedWorkers, goMoreParallel);
1479
1480 // Update list of current workers
1481 PDB(kGlobal, 3)
1482 Info("AddWorkers", "will invoke SaveWorkerInfo()");
1484
1485 // Inform the client that the number of workers has changed
1486 if (fDynamicStartup && gProofServ) {
1487 PDB(kGlobal, 3)
1488 Info("AddWorkers", "will invoke SendParallel()");
1490
1491 if (goMoreParallel && fPlayer) {
1492 // In case we are adding workers dynamically to an existing process, we
1493 // should invoke a special player's Process() to set only added workers
1494 // to the proper state
1495 PDB(kGlobal, 3)
1496 Info("AddWorkers", "will send the PROCESS message to selected workers");
1497 fPlayer->JoinProcess(addedWorkers);
1498 // Update merger counters (new workers are not yet active)
1499 fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1500 }
1501 }
1502
1503 // Cleanup
1504 delete addedWorkers;
1505
1506 return 0;
1507}
1508
1509////////////////////////////////////////////////////////////////////////////////
1510/// Set up packages, loaded macros, include and lib paths ...
1511
1512void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1513{
1514 // Packages
1516 if (packs && packs->GetSize() > 0) {
1517 TIter nxp(packs);
1518 TPair *pck = 0;
1519 while ((pck = (TPair *) nxp())) {
1520 // Upload and Enable methods are intelligent and avoid
1521 // re-uploading or re-enabling of a package to a node that has it.
1522 if (fDynamicStartup && increasingWorkers) {
1523 // Upload only on added workers
1524 PDB(kGlobal, 3)
1525 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1526 if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1527 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1528 } else {
1529 PDB(kGlobal, 3)
1530 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1531 if (UploadPackage(pck->GetName()) >= 0)
1532 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1533 }
1534 }
1535 }
1536
1537 // Loaded macros
1538 if (fLoadedMacros) {
1539 TIter nxp(fLoadedMacros);
1540 TObjString *os = 0;
1541 while ((os = (TObjString *) nxp())) {
1542 PDB(kGlobal, 3) {
1543 Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1544 Printf("Loading a macro : %s", os->GetName());
1545 }
1546 Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1547 }
1548 }
1549
1550 // Dynamic path
1552 dyn.ReplaceAll(":", " ");
1553 dyn.ReplaceAll("\"", " ");
1554 PDB(kGlobal, 3)
1555 Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1556 AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1557
1558 // Include path
1560 inc.ReplaceAll("-I", " ");
1561 inc.ReplaceAll("\"", " ");
1562 PDB(kGlobal, 3)
1563 Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1564 AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1565
1566 // Done
1567 return;
1568}
1569
1570////////////////////////////////////////////////////////////////////////////////
1571/// Used for shuting down the workres after a query is finished.
1572/// Sends each of the workers from the workerList, a kPROOF_STOP message.
1573/// If the workerList == 0, shutdown all the workers.
1574
1576{
1577 if (!IsMaster()) {
1578 Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1579 return -1;
1580 }
1581
1582 fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1583
1584 if (!workerList) {
1585 // shutdown all the workers
1586 TIter nxsl(fSlaves);
1587 TSlave *sl = 0;
1588 while ((sl = (TSlave *) nxsl())) {
1589 // Shut down the worker assumig that it is not processing
1590 TerminateWorker(sl);
1591 }
1592
1593 } else {
1594 if (!(workerList->GetSize())) {
1595 Error("RemoveWorkers", "The list of workers should not be empty!");
1596 return -2;
1597 }
1598
1599 // Loop over all the workers and stop them
1600 TListIter next(workerList);
1601 TObject *to;
1602 TProofNodeInfo *worker;
1603 while ((to = next())) {
1604 TSlave *sl = 0;
1605 if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1606 // Get the next worker from the list
1607 worker = (TProofNodeInfo *)to;
1608 TIter nxsl(fSlaves);
1609 while ((sl = (TSlave *) nxsl())) {
1610 // Shut down the worker assumig that it is not processing
1611 if (sl->GetName() == worker->GetNodeName())
1612 break;
1613 }
1614 } else if (to->InheritsFrom(TSlave::Class())) {
1615 sl = (TSlave *) to;
1616 } else {
1617 Warning("RemoveWorkers","unknown object type: %s - it should be"
1618 " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1619 }
1620 // Shut down the worker assumig that it is not processing
1621 if (sl) {
1622 if (gDebug > 0)
1623 Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1624 TerminateWorker(sl);
1625 }
1626 }
1627 }
1628
1629 // Update also the master counter
1630 if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1631
1632 return 0;
1633}
1634
1635////////////////////////////////////////////////////////////////////////////////
1636/// Start up PROOF slaves.
1637
1639{
1640 // If this is a master server, find the config file and start slave
1641 // servers as specified in the config file
1643
1644 Int_t pc = 0;
1645 TList *workerList = new TList;
1646 // Get list of workers
1647 if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1648 TString emsg("no resource currently available for this session: please retry later");
1649 if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1651 return kFALSE;
1652 }
1653 // Setup the workers
1654 if (AddWorkers(workerList) < 0)
1655 return kFALSE;
1656
1657 } else {
1658
1659 // create master server
1660 Printf("Starting master: opening connection ...");
1661 TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1662
1663 if (slave->IsValid()) {
1664
1665 // Notify
1666 fprintf(stderr,"Starting master:"
1667 " connection open: setting up server ... \r");
1668 StartupMessage("Connection to master opened", kTRUE, 1, 1);
1669
1670 if (!attach) {
1671
1672 // Set worker interrupt handler
1673 slave->SetInterruptHandler(kTRUE);
1674
1675 // Finalize setup of the server
1677
1678 if (slave->IsValid()) {
1679
1680 // Notify
1681 Printf("Starting master: OK ");
1682 StartupMessage("Master started", kTRUE, 1, 1);
1683
1684 // check protocol compatibility
1685 // protocol 1 is not supported anymore
1686 if (fProtocol == 1) {
1687 Error("StartSlaves",
1688 "client and remote protocols not compatible (%d and %d)",
1690 slave->Close("S");
1691 delete slave;
1692 return kFALSE;
1693 }
1694
1695 fSlaves->Add(slave);
1696 fAllMonitor->Add(slave->GetSocket());
1697
1698 // Unset worker interrupt handler
1700
1701 // Set interrupt PROOF handler from now on
1703
1704 // Give-up after 5 minutes
1705 Int_t rc = Collect(slave, 300);
1706 Int_t slStatus = slave->GetStatus();
1707 if (slStatus == -99 || slStatus == -98 || rc == 0) {
1708 fSlaves->Remove(slave);
1709 fAllMonitor->Remove(slave->GetSocket());
1710 if (slStatus == -99)
1711 Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1712 else if (slStatus == -98)
1713 Error("StartSlaves", "could not setup output redirection on master");
1714 else
1715 Error("StartSlaves", "setting up master");
1716 slave->Close("S");
1717 delete slave;
1718 return 0;
1719 }
1720
1721 if (!slave->IsValid()) {
1722 fSlaves->Remove(slave);
1723 fAllMonitor->Remove(slave->GetSocket());
1724 slave->Close("S");
1725 delete slave;
1726 Error("StartSlaves",
1727 "failed to setup connection with PROOF master server");
1728 return kFALSE;
1729 }
1730
1731 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1732 if ((fProgressDialog =
1733 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1734 if (fProgressDialog->LoadPlugin() == -1)
1735 fProgressDialog = 0;
1736 }
1737 } else {
1738 // Notify
1739 Printf("Starting master: failure");
1740 }
1741 } else {
1742
1743 // Notify
1744 Printf("Starting master: OK ");
1745 StartupMessage("Master attached", kTRUE, 1, 1);
1746
1747 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1748 if ((fProgressDialog =
1749 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1750 if (fProgressDialog->LoadPlugin() == -1)
1751 fProgressDialog = 0;
1752 }
1753
1754 fSlaves->Add(slave);
1756 }
1757
1758 } else {
1759 delete slave;
1760 // Notify only if verbosity is on: most likely the failure has already been notified
1761 if (gDebug > 0)
1762 Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1763 return kFALSE;
1764 }
1765 }
1766
1767 return kTRUE;
1768}
1769
1770////////////////////////////////////////////////////////////////////////////////
1771/// Close all open slave servers.
1772/// Client can decide to shutdown the remote session by passing option is 'S'
1773/// or 's'. Default for clients is detach, if supported. Masters always
1774/// shutdown the remote counterpart.
1775
1777{
1778 { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1779
1780 fValid = kFALSE;
1781 if (fSlaves) {
1782 if (fIntHandler)
1784
1785 TIter nxs(fSlaves);
1786 TSlave *sl = 0;
1787 while ((sl = (TSlave *)nxs()))
1788 sl->Close(opt);
1789
1790 fActiveSlaves->Clear("nodelete");
1791 fUniqueSlaves->Clear("nodelete");
1792 fAllUniqueSlaves->Clear("nodelete");
1793 fNonUniqueMasters->Clear("nodelete");
1794 fBadSlaves->Clear("nodelete");
1795 fInactiveSlaves->Clear("nodelete");
1796 fSlaves->Delete();
1797 }
1798 }
1799
1801 gROOT->GetListOfSockets()->Remove(this);
1802
1803 if (fChains) {
1804 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1805 // remove "chain" from list
1806 chain->SetProof(0);
1807 RemoveChain(chain);
1808 }
1809 }
1810
1811 if (IsProofd()) {
1812
1813 gROOT->GetListOfProofs()->Remove(this);
1814 if (gProof && gProof == this) {
1815 // Set previous proofd-related as default
1816 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1817 while ((gProof = (TProof *)pvp())) {
1818 if (gProof->IsProofd())
1819 break;
1820 }
1821 }
1822 }
1823 }
1824}
1825
1826////////////////////////////////////////////////////////////////////////////////
1827/// Create a new TSlave of type TSlave::kSlave.
1828/// Note: creation of TSlave is private with TProof as a friend.
1829/// Derived classes must use this function to create slaves.
1830
1831TSlave *TProof::CreateSlave(const char *url, const char *ord,
1832 Int_t perf, const char *image, const char *workdir)
1833{
1834 TSlave* sl = TSlave::Create(url, ord, perf, image,
1835 this, TSlave::kSlave, workdir, 0);
1836
1837 if (sl->IsValid()) {
1838 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1839 // must set fParallel to 1 for slaves since they do not
1840 // report their fParallel with a LOG_DONE message
1841 sl->fParallel = 1;
1842 }
1843
1844 return sl;
1845}
1846
1847
1848////////////////////////////////////////////////////////////////////////////////
1849/// Create a new TSlave of type TSlave::kMaster.
1850/// Note: creation of TSlave is private with TProof as a friend.
1851/// Derived classes must use this function to create slaves.
1852
1853TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1854 const char *image, const char *msd, Int_t nwk)
1855{
1856 TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1857 TSlave::kMaster, 0, msd, nwk);
1858
1859 if (sl->IsValid()) {
1860 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1861 }
1862
1863 return sl;
1864}
1865
1866////////////////////////////////////////////////////////////////////////////////
1867/// Find slave that has TSocket s. Returns 0 in case slave is not found.
1868
1870{
1871 TSlave *sl;
1872 TIter next(fSlaves);
1873
1874 while ((sl = (TSlave *)next())) {
1875 if (sl->IsValid() && sl->GetSocket() == s)
1876 return sl;
1877 }
1878 return 0;
1879}
1880
1881////////////////////////////////////////////////////////////////////////////////
1882/// Add to the fUniqueSlave list the active slaves that have a unique
1883/// (user) file system image. This information is used to transfer files
1884/// only once to nodes that share a file system (an image). Submasters
1885/// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1886/// list. That list is used to trigger the transferring of files to
1887/// the submaster's unique slaves without the need to transfer the file
1888/// to the submaster.
1889
1891{
1897
1898 TIter next(fActiveSlaves);
1899
1900 while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1901 if (fImage == sl->fImage) {
1902 if (sl->GetSlaveType() == TSlave::kMaster) {
1904 fAllUniqueSlaves->Add(sl);
1905 fAllUniqueMonitor->Add(sl->GetSocket());
1906 }
1907 continue;
1908 }
1909
1910 TIter next2(fUniqueSlaves);
1911 TSlave *replace_slave = 0;
1912 Bool_t add = kTRUE;
1913 while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1914 if (sl->fImage == sl2->fImage) {
1915 add = kFALSE;
1916 if (sl->GetSlaveType() == TSlave::kMaster) {
1917 if (sl2->GetSlaveType() == TSlave::kSlave) {
1918 // give preference to master
1919 replace_slave = sl2;
1920 add = kTRUE;
1921 } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1923 fAllUniqueSlaves->Add(sl);
1924 fAllUniqueMonitor->Add(sl->GetSocket());
1925 } else {
1926 Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1927 R__ASSERT(0);
1928 }
1929 }
1930 break;
1931 }
1932 }
1933
1934 if (add) {
1935 fUniqueSlaves->Add(sl);
1936 fAllUniqueSlaves->Add(sl);
1937 fUniqueMonitor->Add(sl->GetSocket());
1938 fAllUniqueMonitor->Add(sl->GetSocket());
1939 if (replace_slave) {
1940 fUniqueSlaves->Remove(replace_slave);
1941 fAllUniqueSlaves->Remove(replace_slave);
1942 fUniqueMonitor->Remove(replace_slave->GetSocket());
1943 fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1944 }
1945 }
1946 }
1947
1948 // will be actiavted in Collect()
1951}
1952
1953////////////////////////////////////////////////////////////////////////////////
1954/// Return number of slaves as described in the config file.
1955
1957{
1958 return fSlaves->GetSize();
1959}
1960
1961////////////////////////////////////////////////////////////////////////////////
1962/// Return number of active slaves, i.e. slaves that are valid and in
1963/// the current computing group.
1964
1966{
1967 return fActiveSlaves->GetSize();
1968}
1969
1970////////////////////////////////////////////////////////////////////////////////
1971/// Return number of inactive slaves, i.e. slaves that are valid but not in
1972/// the current computing group.
1973
1975{
1976 return fInactiveSlaves->GetSize();
1977}
1978
1979////////////////////////////////////////////////////////////////////////////////
1980/// Return number of unique slaves, i.e. active slaves that have each a
1981/// unique different user files system.
1982
1984{
1985 return fUniqueSlaves->GetSize();
1986}
1987
1988////////////////////////////////////////////////////////////////////////////////
1989/// Return number of bad slaves. This are slaves that we in the config
1990/// file, but refused to startup or that died during the PROOF session.
1991
1993{
1994 return fBadSlaves->GetSize();
1995}
1996
1997////////////////////////////////////////////////////////////////////////////////
1998/// Ask the for the statistics of the slaves.
1999
2001{
2002 if (!IsValid()) return;
2003
2006}
2007
2008////////////////////////////////////////////////////////////////////////////////
2009/// Get statistics about CPU time, real time and bytes read.
2010/// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2011/// and GetBytesRead()
2012
2014{
2015 if (fProtocol > 27) {
2016 // This returns the correct result
2017 AskStatistics();
2018 } else {
2019 // AskStatistics is buggy: parse the output of Print()
2022 Print();
2023 gSystem->RedirectOutput(0, 0, &rh);
2024 TMacro *mp = GetLastLog();
2025 if (mp) {
2026 // Look for global directories
2027 TIter nxl(mp->GetListOfLines());
2028 TObjString *os = 0;
2029 while ((os = (TObjString *) nxl())) {
2030 TString s(os->GetName());
2031 if (s.Contains("Total MB's processed:")) {
2032 s.ReplaceAll("Total MB's processed:", "");
2033 if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2034 } else if (s.Contains("Total real time used (s):")) {
2035 s.ReplaceAll("Total real time used (s):", "");
2036 if (s.IsFloat()) fRealTime = s.Atof();
2037 } else if (s.Contains("Total CPU time used (s):")) {
2038 s.ReplaceAll("Total CPU time used (s):", "");
2039 if (s.IsFloat()) fCpuTime = s.Atof();
2040 }
2041 }
2042 delete mp;
2043 }
2044 }
2045
2046 if (verbose) {
2047 Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2048 GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2049 }
2050}
2051
2052////////////////////////////////////////////////////////////////////////////////
2053/// Ask the for the number of parallel slaves.
2054
2056{
2057 if (!IsValid()) return;
2058
2061}
2062
2063////////////////////////////////////////////////////////////////////////////////
2064/// Ask the master for the list of queries.
2065
2067{
2068 if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2069
2070 Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2072 m << all;
2075
2076 // This should have been filled by now
2077 return fQueries;
2078}
2079
2080////////////////////////////////////////////////////////////////////////////////
2081/// Number of queries processed by this session
2082
2084{
2085 if (fQueries)
2086 return fQueries->GetSize() - fOtherQueries;
2087 return 0;
2088}
2089
2090////////////////////////////////////////////////////////////////////////////////
2091/// Set max number of draw queries whose results are saved
2092
2094{
2095 if (max > 0) {
2096 if (fPlayer)
2098 fMaxDrawQueries = max;
2099 }
2100}
2101
2102////////////////////////////////////////////////////////////////////////////////
2103/// Get max number of queries whose full results are kept in the
2104/// remote sandbox
2105
2107{
2109 m << kFALSE;
2112}
2113
2114////////////////////////////////////////////////////////////////////////////////
2115/// Return pointer to the list of query results in the player
2116
2118{
2119 return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2120}
2121
2122////////////////////////////////////////////////////////////////////////////////
2123/// Return pointer to the full TQueryResult instance owned by the player
2124/// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2125
2127{
2128 return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2129}
2130
2131////////////////////////////////////////////////////////////////////////////////
2132/// Ask the master for the list of queries.
2133/// Options:
2134/// "A" show information about all the queries known to the
2135/// server, i.e. even those processed by other sessions
2136/// "L" show only information about queries locally available
2137/// i.e. already retrieved. If "L" is specified, "A" is
2138/// ignored.
2139/// "F" show all details available about queries
2140/// "H" print help menu
2141/// Default ""
2142
2144{
2145 Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2146 if (help) {
2147
2148 // Help
2149
2150 Printf("+++");
2151 Printf("+++ Options: \"A\" show all queries known to server");
2152 Printf("+++ \"L\" show retrieved queries");
2153 Printf("+++ \"F\" full listing of query info");
2154 Printf("+++ \"H\" print this menu");
2155 Printf("+++");
2156 Printf("+++ (case insensitive)");
2157 Printf("+++");
2158 Printf("+++ Use Retrieve(<#>) to retrieve the full"
2159 " query results from the master");
2160 Printf("+++ e.g. Retrieve(8)");
2161
2162 Printf("+++");
2163
2164 return;
2165 }
2166
2167 if (!IsValid()) return;
2168
2169 Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2170
2171 TObject *pq = 0;
2172 if (!local) {
2173 GetListOfQueries(opt);
2174
2175 if (!fQueries) return;
2176
2177 TIter nxq(fQueries);
2178
2179 // Queries processed by other sessions
2180 if (fOtherQueries > 0) {
2181 Printf("+++");
2182 Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2183 Int_t nq = 0;
2184 while (nq++ < fOtherQueries && (pq = nxq()))
2185 pq->Print(opt);
2186 }
2187
2188 // Queries processed by this session
2189 Printf("+++");
2190 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2192 while ((pq = nxq()))
2193 pq->Print(opt);
2194
2195 } else {
2196
2197 // Queries processed by this session
2198 Printf("+++");
2199 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2201
2202 // Queries available locally
2203 TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2204 if (listlocal) {
2205 Printf("+++");
2206 Printf("+++ Queries available locally: %d", listlocal->GetSize());
2207 TIter nxlq(listlocal);
2208 while ((pq = nxlq()))
2209 pq->Print(opt);
2210 }
2211 }
2212 Printf("+++");
2213}
2214
2215////////////////////////////////////////////////////////////////////////////////
2216/// See if the data is ready to be analyzed.
2217
2219{
2220 if (!IsValid()) return kFALSE;
2221
2222 TList submasters;
2223 TIter nextSlave(GetListOfActiveSlaves());
2224 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2225 if (sl->GetSlaveType() == TSlave::kMaster) {
2226 submasters.Add(sl);
2227 }
2228 }
2229
2230 fDataReady = kTRUE; //see if any submasters set it to false
2231 fBytesReady = 0;
2232 fTotalBytes = 0;
2233 //loop over submasters and see if data is ready
2234 if (submasters.GetSize() > 0) {
2235 Broadcast(kPROOF_DATA_READY, &submasters);
2236 Collect(&submasters);
2237 }
2238
2239 bytesready = fBytesReady;
2240 totalbytes = fTotalBytes;
2241
2242 EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2243
2244 PDB(kGlobal,2)
2245 Info("IsDataReady", "%lld / %lld (%s)",
2246 bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2247
2248 return fDataReady;
2249}
2250
2251////////////////////////////////////////////////////////////////////////////////
2252/// Send interrupt to master or slave servers.
2253
2255{
2256 if (!IsValid()) return;
2257
2258 TList *slaves = 0;
2259 if (list == kAll) slaves = fSlaves;
2260 if (list == kActive) slaves = fActiveSlaves;
2261 if (list == kUnique) slaves = fUniqueSlaves;
2262 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2263
2264 if (slaves->GetSize() == 0) return;
2265
2266 TSlave *sl;
2267 TIter next(slaves);
2268
2269 while ((sl = (TSlave *)next())) {
2270 if (sl->IsValid()) {
2271
2272 // Ask slave to progate the interrupt request
2273 sl->Interrupt((Int_t)type);
2274 }
2275 }
2276}
2277
2278////////////////////////////////////////////////////////////////////////////////
2279/// Returns number of slaves active in parallel mode. Returns 0 in case
2280/// there are no active slaves. Returns -1 in case of error.
2281
2283{
2284 if (!IsValid()) return -1;
2285
2286 // iterate over active slaves and return total number of slaves
2287 TIter nextSlave(GetListOfActiveSlaves());
2288 Int_t nparallel = 0;
2289 while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2290 if (sl->GetParallel() >= 0)
2291 nparallel += sl->GetParallel();
2292
2293 return nparallel;
2294}
2295
2296////////////////////////////////////////////////////////////////////////////////
2297/// Returns list of TSlaveInfo's. In case of error return 0.
2298
2300{
2301 if (!IsValid()) return 0;
2302
2303 if (fSlaveInfo == 0) {
2306 } else {
2307 fSlaveInfo->Delete();
2308 }
2309
2310 TList masters;
2311 TIter next(GetListOfSlaves());
2312 TSlave *slave;
2313
2314 while ((slave = (TSlave *) next()) != 0) {
2315 if (slave->GetSlaveType() == TSlave::kSlave) {
2316 const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2317 TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2318 name,
2319 slave->GetPerfIdx());
2320 fSlaveInfo->Add(slaveinfo);
2321
2322 TIter nextactive(GetListOfActiveSlaves());
2323 TSlave *activeslave;
2324 while ((activeslave = (TSlave *) nextactive())) {
2325 if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2326 slaveinfo->SetStatus(TSlaveInfo::kActive);
2327 break;
2328 }
2329 }
2330
2331 TIter nextbad(GetListOfBadSlaves());
2332 TSlave *badslave;
2333 while ((badslave = (TSlave *) nextbad())) {
2334 if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2335 slaveinfo->SetStatus(TSlaveInfo::kBad);
2336 break;
2337 }
2338 }
2339 // Get system info if supported
2340 if (slave->IsValid()) {
2341 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2342 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2343 else
2344 masters.Add(slave);
2345 }
2346
2347 } else if (slave->GetSlaveType() == TSlave::kMaster) {
2348 if (slave->IsValid()) {
2349 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2350 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2351 else
2352 masters.Add(slave);
2353 }
2354 } else {
2355 Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2356 R__ASSERT(0);
2357 }
2358 }
2359 if (masters.GetSize() > 0) Collect(&masters);
2360
2361 return fSlaveInfo;
2362}
2363
2364////////////////////////////////////////////////////////////////////////////////
2365/// Activate slave server list.
2366
2368{
2369 TMonitor *mon = fAllMonitor;
2370 mon->DeActivateAll();
2371
2372 slaves = !slaves ? fActiveSlaves : slaves;
2373
2374 TIter next(slaves);
2375 TSlave *sl;
2376 while ((sl = (TSlave*) next())) {
2377 if (sl->IsValid())
2378 mon->Activate(sl->GetSocket());
2379 }
2380}
2381
2382////////////////////////////////////////////////////////////////////////////////
2383/// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2384/// monitored by 'mon'.
2385
2387{
2388 TMonitor *m = (mon) ? mon : fCurrentMonitor;
2389 if (m) {
2390 if (on)
2391 m->ActivateAll();
2392 else
2393 m->DeActivateAll();
2394 }
2395}
2396
2397////////////////////////////////////////////////////////////////////////////////
2398/// Broadcast the group priority to all workers in the specified list. Returns
2399/// the number of workers the message was successfully sent to.
2400/// Returns -1 in case of error.
2401
2402Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2403{
2404 if (!IsValid()) return -1;
2405
2406 if (workers->GetSize() == 0) return 0;
2407
2408 int nsent = 0;
2409 TIter next(workers);
2410
2411 TSlave *wrk;
2412 while ((wrk = (TSlave *)next())) {
2413 if (wrk->IsValid()) {
2414 if (wrk->SendGroupPriority(grp, priority) == -1)
2415 MarkBad(wrk, "could not send group priority");
2416 else
2417 nsent++;
2418 }
2419 }
2420
2421 return nsent;
2422}
2423
2424////////////////////////////////////////////////////////////////////////////////
2425/// Broadcast the group priority to all workers in the specified list. Returns
2426/// the number of workers the message was successfully sent to.
2427/// Returns -1 in case of error.
2428
2429Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2430{
2431 TList *workers = 0;
2432 if (list == kAll) workers = fSlaves;
2433 if (list == kActive) workers = fActiveSlaves;
2434 if (list == kUnique) workers = fUniqueSlaves;
2435 if (list == kAllUnique) workers = fAllUniqueSlaves;
2436
2437 return BroadcastGroupPriority(grp, priority, workers);
2438}
2439
2440////////////////////////////////////////////////////////////////////////////////
2441/// Reset the merge progress notificator
2442
2444{
2446}
2447
2448////////////////////////////////////////////////////////////////////////////////
2449/// Broadcast a message to all slaves in the specified list. Returns
2450/// the number of slaves the message was successfully sent to.
2451/// Returns -1 in case of error.
2452
2454{
2455 if (!IsValid()) return -1;
2456
2457 if (!slaves || slaves->GetSize() == 0) return 0;
2458
2459 int nsent = 0;
2460 TIter next(slaves);
2461
2462 TSlave *sl;
2463 while ((sl = (TSlave *)next())) {
2464 if (sl->IsValid()) {
2465 if (sl->GetSocket()->Send(mess) == -1)
2466 MarkBad(sl, "could not broadcast request");
2467 else
2468 nsent++;
2469 }
2470 }
2471
2472 return nsent;
2473}
2474
2475////////////////////////////////////////////////////////////////////////////////
2476/// Broadcast a message to all slaves in the specified list (either
2477/// all slaves or only the active slaves). Returns the number of slaves
2478/// the message was successfully sent to. Returns -1 in case of error.
2479
2481{
2482 TList *slaves = 0;
2483 if (list == kAll) slaves = fSlaves;
2484 if (list == kActive) slaves = fActiveSlaves;
2485 if (list == kUnique) slaves = fUniqueSlaves;
2486 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2487
2488 return Broadcast(mess, slaves);
2489}
2490
2491////////////////////////////////////////////////////////////////////////////////
2492/// Broadcast a character string buffer to all slaves in the specified
2493/// list. Use kind to set the TMessage what field. Returns the number of
2494/// slaves the message was sent to. Returns -1 in case of error.
2495
2496Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2497{
2498 TMessage mess(kind);
2499 if (str) mess.WriteString(str);
2500 return Broadcast(mess, slaves);
2501}
2502
2503////////////////////////////////////////////////////////////////////////////////
2504/// Broadcast a character string buffer to all slaves in the specified
2505/// list (either all slaves or only the active slaves). Use kind to
2506/// set the TMessage what field. Returns the number of slaves the message
2507/// was sent to. Returns -1 in case of error.
2508
2509Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2510{
2511 TMessage mess(kind);
2512 if (str) mess.WriteString(str);
2513 return Broadcast(mess, list);
2514}
2515
2516////////////////////////////////////////////////////////////////////////////////
2517/// Broadcast an object to all slaves in the specified list. Use kind to
2518/// set the TMEssage what field. Returns the number of slaves the message
2519/// was sent to. Returns -1 in case of error.
2520
2522{
2523 TMessage mess(kind);
2524 mess.WriteObject(obj);
2525 return Broadcast(mess, slaves);
2526}
2527
2528////////////////////////////////////////////////////////////////////////////////
2529/// Broadcast an object to all slaves in the specified list. Use kind to
2530/// set the TMEssage what field. Returns the number of slaves the message
2531/// was sent to. Returns -1 in case of error.
2532
2534{
2535 TMessage mess(kind);
2536 mess.WriteObject(obj);
2537 return Broadcast(mess, list);
2538}
2539
2540////////////////////////////////////////////////////////////////////////////////
2541/// Broadcast a raw buffer of specified length to all slaves in the
2542/// specified list. Returns the number of slaves the buffer was sent to.
2543/// Returns -1 in case of error.
2544
2545Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2546{
2547 if (!IsValid()) return -1;
2548
2549 if (slaves->GetSize() == 0) return 0;
2550
2551 int nsent = 0;
2552 TIter next(slaves);
2553
2554 TSlave *sl;
2555 while ((sl = (TSlave *)next())) {
2556 if (sl->IsValid()) {
2557 if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2558 MarkBad(sl, "could not send broadcast-raw request");
2559 else
2560 nsent++;
2561 }
2562 }
2563
2564 return nsent;
2565}
2566
2567////////////////////////////////////////////////////////////////////////////////
2568/// Broadcast a raw buffer of specified length to all slaves in the
2569/// specified list. Returns the number of slaves the buffer was sent to.
2570/// Returns -1 in case of error.
2571
2572Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2573{
2574 TList *slaves = 0;
2575 if (list == kAll) slaves = fSlaves;
2576 if (list == kActive) slaves = fActiveSlaves;
2577 if (list == kUnique) slaves = fUniqueSlaves;
2578 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2579
2580 return BroadcastRaw(buffer, length, slaves);
2581}
2582
2583////////////////////////////////////////////////////////////////////////////////
2584/// Broadcast file to all workers in the specified list. Returns the number of workers
2585/// the buffer was sent to.
2586/// Returns -1 in case of error.
2587
2588Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2589{
2590 if (!IsValid()) return -1;
2591
2592 if (wrks->GetSize() == 0) return 0;
2593
2594 int nsent = 0;
2595 TIter next(wrks);
2596
2597 TSlave *wrk;
2598 while ((wrk = (TSlave *)next())) {
2599 if (wrk->IsValid()) {
2600 if (SendFile(file, opt, rfile, wrk) < 0)
2601 Error("BroadcastFile",
2602 "problems sending file to worker %s (%s)",
2603 wrk->GetOrdinal(), wrk->GetName());
2604 else
2605 nsent++;
2606 }
2607 }
2608
2609 return nsent;
2610}
2611
2612////////////////////////////////////////////////////////////////////////////////
2613/// Broadcast file to all workers in the specified list. Returns the number of workers
2614/// the buffer was sent to.
2615/// Returns -1 in case of error.
2616
2617Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2618{
2619 TList *wrks = 0;
2620 if (list == kAll) wrks = fSlaves;
2621 if (list == kActive) wrks = fActiveSlaves;
2622 if (list == kUnique) wrks = fUniqueSlaves;
2623 if (list == kAllUnique) wrks = fAllUniqueSlaves;
2624
2625 return BroadcastFile(file, opt, rfile, wrks);
2626}
2627
2628////////////////////////////////////////////////////////////////////////////////
2629/// Release the used monitor to be used, making sure to delete newly created
2630/// monitors.
2631
2633{
2634 if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2635 && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2636 delete mon;
2637 }
2638}
2639
2640////////////////////////////////////////////////////////////////////////////////
2641/// Collect responses from slave sl. Returns the number of slaves that
2642/// responded (=1).
2643/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2644/// which means wait forever).
2645/// If defined (>= 0) endtype is the message that stops this collection.
2646
2647Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2648{
2649 Int_t rc = 0;
2650
2651 TMonitor *mon = 0;
2652 if (!sl->IsValid()) return 0;
2653
2655 mon = new TMonitor;
2656 } else {
2657 mon = fAllMonitor;
2658 mon->DeActivateAll();
2659 }
2660 mon->Activate(sl->GetSocket());
2661
2662 rc = Collect(mon, timeout, endtype, deactonfail);
2663 ReleaseMonitor(mon);
2664 return rc;
2665}
2666
2667////////////////////////////////////////////////////////////////////////////////
2668/// Collect responses from the slave servers. Returns the number of slaves
2669/// that responded.
2670/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2671/// which means wait forever).
2672/// If defined (>= 0) endtype is the message that stops this collection.
2673
2674Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2675{
2676 Int_t rc = 0;
2677
2678 TMonitor *mon = 0;
2679
2681 mon = new TMonitor;
2682 } else {
2683 mon = fAllMonitor;
2684 mon->DeActivateAll();
2685 }
2686 TIter next(slaves);
2687 TSlave *sl;
2688 while ((sl = (TSlave*) next())) {
2689 if (sl->IsValid())
2690 mon->Activate(sl->GetSocket());
2691 }
2692
2693 rc = Collect(mon, timeout, endtype, deactonfail);
2694 ReleaseMonitor(mon);
2695 return rc;
2696}
2697
2698////////////////////////////////////////////////////////////////////////////////
2699/// Collect responses from the slave servers. Returns the number of slaves
2700/// that responded.
2701/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2702/// which means wait forever).
2703/// If defined (>= 0) endtype is the message that stops this collection.
2704
2705Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2706{
2707 Int_t rc = 0;
2708 TMonitor *mon = 0;
2709
2710 if (list == kAll) mon = fAllMonitor;
2711 if (list == kActive) mon = fActiveMonitor;
2712 if (list == kUnique) mon = fUniqueMonitor;
2713 if (list == kAllUnique) mon = fAllUniqueMonitor;
2714 if (fCurrentMonitor == mon) {
2715 // Get a copy
2716 mon = new TMonitor(*mon);
2717 }
2718 mon->ActivateAll();
2719
2720 rc = Collect(mon, timeout, endtype, deactonfail);
2721 ReleaseMonitor(mon);
2722 return rc;
2723}
2724
2725////////////////////////////////////////////////////////////////////////////////
2726/// Collect responses from the slave servers. Returns the number of messages
2727/// received. Can be 0 if there are no active slaves.
2728/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2729/// which means wait forever).
2730/// If defined (>= 0) endtype is the message that stops this collection.
2731/// Collect also stops its execution from time to time to check for new
2732/// workers in Dynamic Startup mode.
2733
2734Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2735{
2736 Int_t collectId = gRandom->Integer(9999);
2737
2738 PDB(kCollect, 3)
2739 Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2740
2741 // Reset the status flag and clear the messages in the list, if any
2742 fStatus = 0;
2744
2745 Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2746
2747 if (!mon->GetActive(actto)) return 0;
2748
2750
2751 // Used by external code to know what we are monitoring
2752 TMonitor *savedMonitor = 0;
2753 if (fCurrentMonitor) {
2754 savedMonitor = fCurrentMonitor;
2755 fCurrentMonitor = mon;
2756 } else {
2757 fCurrentMonitor = mon;
2758 fBytesRead = 0;
2759 fRealTime = 0.0;
2760 fCpuTime = 0.0;
2761 }
2762
2763 // We want messages on the main window during synchronous collection,
2764 // but we save the present status to restore it at the end
2765 Bool_t saveRedirLog = fRedirLog;
2766 if (!IsIdle() && !IsSync())
2767 fRedirLog = kFALSE;
2768
2769 int cnt = 0, rc = 0;
2770
2771 // Timeout counter
2772 Long_t nto = timeout;
2773 PDB(kCollect, 2)
2774 Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2775
2776 // On clients, handle Ctrl-C during collection
2777 if (fIntHandler)
2778 fIntHandler->Add();
2779
2780 // Sockets w/o activity during the last 'sto' millisecs are deactivated
2781 Int_t nact = 0;
2782 Long_t sto = -1;
2783 Int_t nsto = 60;
2784 Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2785 mon->ResetInterrupt();
2786 while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2787
2788 // Dump last waiting sockets, if in debug mode
2789 PDB(kCollect, 2) {
2790 if (nact < 4) {
2791 TList *al = mon->GetListOfActives();
2792 if (al && al->GetSize() > 0) {
2793 Info("Collect"," %d node(s) still active:", al->GetSize());
2794 TIter nxs(al);
2795 TSocket *xs = 0;
2796 while ((xs = (TSocket *)nxs())) {
2797 TSlave *wrk = FindSlave(xs);
2798 if (wrk)
2799 Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2800 else
2801 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2802 xs->GetInetAddress().GetPort());
2803 }
2804 }
2805 }
2806 }
2807
2808 // Preemptive poll for new workers on the master only in Dynamic Mode and only
2809 // during processing (TODO: should work on Top Master only)
2811 ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2814 fLastPollWorkers_s = time(0);
2816 PDB(kCollect, 1)
2817 Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2818 }
2819
2820 // Wait for a ready socket
2821 PDB(kCollect, 3)
2822 Info("Collect", "Will invoke Select() #%04d", collectId);
2823 TSocket *s = mon->Select(1000);
2824
2825 if (s && s != (TSocket *)(-1)) {
2826 // Get and analyse the info it did receive
2827 rc = CollectInputFrom(s, endtype, deactonfail);
2828 if (rc == 1 || (rc == 2 && !savedMonitor)) {
2829 // Deactivate it if we are done with it
2830 mon->DeActivate(s);
2831 PDB(kCollect, 2)
2832 Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2833 s, mon->GetActive(),
2834 mon->GetListOfActives()->First());
2835 } else if (rc == 2) {
2836 // This end message was for the saved monitor
2837 // Deactivate it if we are done with it
2838 if (savedMonitor) {
2839 savedMonitor->DeActivate(s);
2840 PDB(kCollect, 2)
2841 Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2842 s, savedMonitor->GetActive(),
2843 savedMonitor->GetListOfActives()->First());
2844 }
2845 }
2846
2847 // Update counter (if no error occured)
2848 if (rc >= 0)
2849 cnt++;
2850 } else {
2851 // If not timed-out, exit if not stopped or not aborted
2852 // (player exits status is finished in such a case); otherwise,
2853 // we still need to collect the partial output info
2854 if (!s)
2856 mon->DeActivateAll();
2857 // Decrease the timeout counter if requested
2858 if (s == (TSocket *)(-1) && nto > 0)
2859 nto--;
2860 }
2861
2862 // Check if there are workers with ready output to be sent and ask the first to send it
2864 // Maximum number of concurrent sendings
2865 Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2866 if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2867 mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2868 TIter nxwr(fWrksOutputReady);
2869 TSlave *wrk = 0;
2870 while (mxws && (wrk = (TSlave *) nxwr())) {
2871 if (!wrk->TestBit(TSlave::kOutputRequested)) {
2872 // Ask worker for output
2873 TMessage sendoutput(kPROOF_SENDOUTPUT);
2874 PDB(kCollect, 2)
2875 Info("Collect", "worker %s was asked to send its output to master",
2876 wrk->GetOrdinal());
2877 if (wrk->GetSocket()->Send(sendoutput) != 1) {
2879 mxws--;
2880 }
2881 } else {
2882 // Count
2883 mxws--;
2884 }
2885 }
2886 }
2887
2888 // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2889 sto = -1;
2890 if (--nsto <= 0) {
2891 sto = (Long_t) actto;
2892 nsto = 60;
2893 }
2894
2895 } // end loop over active monitors
2896
2897 // If timed-out, deactivate the remaining sockets
2898 if (nto == 0) {
2899 TList *al = mon->GetListOfActives();
2900 if (al && al->GetSize() > 0) {
2901 // Notify the name of those which did timeout
2902 Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2903 TIter nxs(al);
2904 TSocket *xs = 0;
2905 while ((xs = (TSocket *)nxs())) {
2906 TSlave *wrk = FindSlave(xs);
2907 if (wrk)
2908 Info("Collect"," %s", wrk->GetName());
2909 else
2910 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2911 xs->GetInetAddress().GetPort());
2912 }
2913 }
2914 mon->DeActivateAll();
2915 }
2916
2917 // Deactivate Ctrl-C special handler
2918 if (fIntHandler)
2920
2921 // make sure group view is up to date
2922 SendGroupView();
2923
2924 // Restore redirection setting
2925 fRedirLog = saveRedirLog;
2926
2927 // Restore the monitor
2928 fCurrentMonitor = savedMonitor;
2929
2931
2932 PDB(kCollect, 3)
2933 Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2934
2935 return cnt;
2936}
2937
2938////////////////////////////////////////////////////////////////////////////////
2939/// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2940/// them. Returns the number of new workers found, or <0 on errors.
2941
2943{
2944 // Requests for worker updates
2945 Int_t dummy = 0;
2946 TList *reqWorkers = new TList();
2947 reqWorkers->SetOwner(kFALSE);
2948
2949 if (!TestBit(TProof::kIsMaster)) {
2950 Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2951 return -1;
2952 }
2953 if (!gProofServ) {
2954 Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2955 return -1;
2956 }
2957
2958 gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2959
2960 // List of new workers only (TProofNodeInfo)
2961 TList *newWorkers = new TList();
2962 newWorkers->SetOwner(kTRUE);
2963
2964 TIter next(reqWorkers);
2965 TProofNodeInfo *ni;
2966 TString fullOrd;
2967 while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2968
2969 // Form the full ordinal
2970 fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2971
2972 TIter nextInner(fSlaves);
2973 TSlave *sl;
2974 Bool_t found = kFALSE;
2975 while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
2976 if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
2977 found = kTRUE;
2978 break;
2979 }
2980 }
2981
2982 if (found) delete ni;
2983 else {
2984 newWorkers->Add(ni);
2985 PDB(kGlobal, 1)
2986 Info("PollForNewWorkers", "New worker found: %s:%s",
2987 ni->GetNodeName().Data(), fullOrd.Data());
2988 }
2989 }
2990
2991 delete reqWorkers; // not owner
2992
2993 Int_t nNewWorkers = newWorkers->GetEntries();
2994
2995 // Add the new workers
2996 if (nNewWorkers > 0) {
2997 PDB(kGlobal, 1)
2998 Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
2999 Int_t rv = AddWorkers(newWorkers);
3000 if (rv < 0) {
3001 Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3002 return -1;
3003 }
3004 // Don't delete newWorkers: AddWorkers() will do that
3005 }
3006 else {
3007 PDB(kGlobal, 2)
3008 Info("PollForNewWorkers", "No new worker found");
3009 delete newWorkers;
3010 }
3011
3012 return nNewWorkers;
3013}
3014
3015////////////////////////////////////////////////////////////////////////////////
3016/// Remove links to objects in list 'ol' from gDirectory
3017
3019{
3020 if (ol) {
3021 TIter nxo(ol);
3022 TObject *o = 0;
3023 while ((o = nxo()))
3024 gDirectory->RecursiveRemove(o);
3025 }
3026}
3027
3028////////////////////////////////////////////////////////////////////////////////
3029/// Collect and analyze available input from socket s.
3030/// Returns 0 on success, -1 if any failure occurs.
3031
3033{
3034 TMessage *mess;
3035
3036 Int_t recvrc = 0;
3037 if ((recvrc = s->Recv(mess)) < 0) {
3038 PDB(kCollect,2)
3039 Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3040 Bool_t bad = kTRUE;
3041 if (recvrc == -5) {
3042 // Broken connection: try reconnection
3044 if (s->Reconnect() == 0) {
3046 bad = kFALSE;
3047 }
3048 }
3049 if (bad)
3050 MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3051 // Ignore this wake up
3052 return -1;
3053 }
3054 if (!mess) {
3055 // we get here in case the remote server died
3056 MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3057 return -1;
3058 }
3059 Int_t rc = 0;
3060
3061 Int_t what = mess->What();
3062 TSlave *sl = FindSlave(s);
3063 rc = HandleInputMessage(sl, mess, deactonfail);
3064 if (rc == 1 && (endtype >= 0) && (what != endtype))
3065 // This message was for the base monitor in recursive case
3066 rc = 2;
3067
3068 // We are done successfully
3069 return rc;
3070}
3071
3072////////////////////////////////////////////////////////////////////////////////
3073/// Analyze the received message.
3074/// Returns 0 on success (1 if this the last message from this socket), -1 if
3075/// any failure occurs.
3076
3078{
3079 char str[512];
3080 TObject *obj;
3081 Int_t rc = 0;
3082
3083 if (!mess || !sl) {
3084 Warning("HandleInputMessage", "given an empty message or undefined worker");
3085 return -1;
3086 }
3087 Bool_t delete_mess = kTRUE;
3088 TSocket *s = sl->GetSocket();
3089 if (!s) {
3090 Warning("HandleInputMessage", "worker socket is undefined");
3091 return -1;
3092 }
3093
3094 // The message type
3095 Int_t what = mess->What();
3096
3097 PDB(kCollect,3)
3098 Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3099
3100 switch (what) {
3101
3102 case kMESS_OK:
3103 // Add the message to the list
3104 fRecvMessages->Add(mess);
3105 delete_mess = kFALSE;
3106 break;
3107
3108 case kMESS_OBJECT:
3109 if (fPlayer) fPlayer->HandleRecvHisto(mess);
3110 break;
3111
3112 case kPROOF_FATAL:
3113 { TString msg;
3114 if ((mess->BufferSize() > mess->Length()))
3115 (*mess) >> msg;
3116 if (msg.IsNull()) {
3117 MarkBad(s, "received kPROOF_FATAL");
3118 } else {
3119 MarkBad(s, msg);
3120 }
3121 }
3123 // Finalize the progress dialog
3124 Emit("StopProcess(Bool_t)", kTRUE);
3125 }
3126 break;
3127
3128 case kPROOF_STOP:
3129 // Stop collection from this worker
3130 Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3131 sl->GetOrdinal());
3132 rc = 1;
3133 break;
3134
3136 // Add the message to the list
3137 fRecvMessages->Add(mess);
3138 delete_mess = kFALSE;
3139 rc = 1;
3140 break;
3141
3142 case kPROOF_TOUCH:
3143 // send a request for touching the remote admin file
3144 {
3145 sl->Touch();
3146 }
3147 break;
3148
3149 case kPROOF_GETOBJECT:
3150 // send slave object it asks for
3151 mess->ReadString(str, sizeof(str));
3152 obj = gDirectory->Get(str);
3153 if (obj)
3154 s->SendObject(obj);
3155 else
3156 s->Send(kMESS_NOTOK);
3157 break;
3158
3159 case kPROOF_GETPACKET:
3160 {
3161 PDB(kGlobal,2)
3162 Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3163 TDSetElement *elem = 0;
3164 elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3165
3166 if (elem != (TDSetElement*) -1) {
3168 answ << elem;
3169 s->Send(answ);
3170
3171 while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3172 TPair *p = (TPair*) fWaitingSlaves->First();
3173 s = (TSocket*) p->Key();
3174 TMessage *m = (TMessage*) p->Value();
3175
3176 elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3177 if (elem != (TDSetElement*) -1) {
3179 a << elem;
3180 s->Send(a);
3181 // remove has to happen via Links because TPair does not have
3182 // a Compare() function and therefore RemoveFirst() and
3183 // Remove(TObject*) do not work
3185 delete p;
3186 delete m;
3187 } else {
3188 break;
3189 }
3190 }
3191 } else {
3192 if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3193 fWaitingSlaves->Add(new TPair(s, mess));
3194 delete_mess = kFALSE;
3195 }
3196 }
3197 break;
3198
3199 case kPROOF_LOGFILE:
3200 {
3201 Int_t size;
3202 (*mess) >> size;
3203 PDB(kGlobal,2)
3204 Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3205 RecvLogFile(s, size);
3206 }
3207 break;
3208
3209 case kPROOF_LOGDONE:
3210 (*mess) >> sl->fStatus >> sl->fParallel;
3211 PDB(kCollect,2)
3212 Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3213 sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3214 if (sl->fStatus != 0) {
3215 // Return last nonzero status
3216 fStatus = sl->fStatus;
3217 // Deactivate the worker, if required
3218 if (deactonfail) DeactivateWorker(sl->fOrdinal);
3219 }
3220 // Remove from the workers-ready list
3224 }
3225 rc = 1;
3226 break;
3227
3228 case kPROOF_GETSTATS:
3229 {
3230 (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3231 >> sl->fWorkDir >> sl->fProofWorkDir;
3232 PDB(kCollect,2)
3233 Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3234 TString img;
3235 if ((mess->BufferSize() > mess->Length()))
3236 (*mess) >> img;
3237 // Set image
3238 if (img.IsNull()) {
3239 if (sl->fImage.IsNull())
3240 sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3241 sl->fProofWorkDir.Data());
3242 } else {
3243 sl->fImage = img;
3244 }
3245 PDB(kGlobal,2)
3246 Info("HandleInputMessage",
3247 "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3248
3249 fBytesRead += sl->fBytesRead;
3250 fRealTime += sl->fRealTime;
3251 fCpuTime += sl->fCpuTime;
3252 rc = 1;
3253 }
3254 break;
3255
3256 case kPROOF_GETPARALLEL:
3257 {
3258 Bool_t async = kFALSE;
3259 (*mess) >> sl->fParallel;
3260 if ((mess->BufferSize() > mess->Length()))
3261 (*mess) >> async;
3262 rc = (async) ? 0 : 1;
3263 }
3264 break;
3265
3266 case kPROOF_CHECKFILE:
3267 { // New servers (>= 5.22) send the status
3268 if ((mess->BufferSize() > mess->Length())) {
3269 (*mess) >> fCheckFileStatus;
3270 } else {
3271 // Form old servers this meant success (failure was signaled with the
3272 // dangerous kPROOF_FATAL)
3273 fCheckFileStatus = 1;
3274 }
3275 rc = 1;
3276 }
3277 break;
3278
3279 case kPROOF_SENDFILE:
3280 { // New server: signals ending of sendfile operation
3281 rc = 1;
3282 }
3283 break;
3284
3286 {
3287 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3288 Int_t type = 0;
3289 (*mess) >> type;
3290 switch (type) {
3294 if (fEnabledPackages) {
3296 } else {
3297 Error("HandleInputMessage",
3298 "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3299 }
3300 break;
3304 if (fAvailablePackages) {
3306 } else {
3307 Error("HandleInputMessage",
3308 "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3309 }
3310 break;
3311 default:
3312 Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3313 }
3314 }
3315 break;
3316
3317 case kPROOF_SENDOUTPUT:
3318 {
3319 // We start measuring the merging time
3321
3322 // Worker is ready to send output: make sure the relevant bit is reset
3324 PDB(kGlobal,2)
3325 Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3326 // Create the list if not yet done
3327 if (!fWrksOutputReady) {
3328 fWrksOutputReady = new TList;
3330 }
3331 fWrksOutputReady->Add(sl);
3332 }
3333 break;
3334
3336 {
3337 // We start measuring the merging time
3339
3340 PDB(kGlobal,2)
3341 Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3342 Int_t type = 0;
3343 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3345 Info("HandleInputMessage", "finalization on %s started ...", prefix);
3347 }
3348
3349 while ((mess->BufferSize() > mess->Length())) {
3350 (*mess) >> type;
3351 // If a query result header, add it to the player list
3352 if (fPlayer) {
3353 if (type == 0) {
3354 // Retrieve query result instance (output list not filled)
3355 TQueryResult *pq =
3357 if (pq) {
3358 // Add query to the result list in TProofPlayer
3361 // And clear the output list, as we start merging a new set of results
3362 if (fPlayer->GetOutputList())
3364 // Add the unique query tag as TNamed object to the input list
3365 // so that it is available in TSelectors for monitoring
3366 TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3367 if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3368 fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3369 fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3370 } else {
3371 Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3372 }
3373 } else if (type > 0) {
3374 // Read object
3375 TObject *o = mess->ReadObject(TObject::Class());
3376 // Increment counter on the client side
3378 TString msg;
3379 Bool_t changed = kFALSE;
3380 msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3381 if (gProofServ) {
3383 } else if (IsTty() || changed) {
3384 fprintf(stderr, "%s\r", msg.Data());
3385 }
3386 // Add or merge it
3387 if ((fPlayer->AddOutputObject(o) == 1)) {
3388 // Remove the object if it has been merged
3389 SafeDelete(o);
3390 }
3391 if (type > 1) {
3392 // Update the merger progress info
3394 if (TestBit(TProof::kIsClient) && !IsLite()) {
3395 // In PROOFLite this has to be done once only in TProofLite::Process
3397 if (pq) {
3399 // Add input objects (do not override remote settings, if any)
3400 TObject *xo = 0;
3401 TIter nxin(fPlayer->GetInputList());
3402 // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3403 if (!pq->GetInputList()) pq->SetInputList(new TList());
3404 while ((xo = nxin()))
3405 if (!pq->GetInputList()->FindObject(xo->GetName()))
3406 pq->AddInput(xo->Clone());
3407 // If the last object, notify the GUI that the result arrived
3408 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3409 }
3410 // Processing is over
3411 UpdateDialog();
3412 }
3413 }
3414 }
3415 } else {
3416 Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3417 }
3418 }
3419 }
3420 break;
3421
3422 case kPROOF_OUTPUTLIST:
3423 {
3424 // We start measuring the merging time
3426
3427 PDB(kGlobal,2)
3428 Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3429 TList *out = 0;
3430 if (fPlayer) {
3431 if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3432 out = (TList *) mess->ReadObject(TList::Class());
3433 } else {
3434 TQueryResult *pq =
3436 if (pq) {
3437 // Add query to the result list in TProofPlayer
3440 // To avoid accidental cleanups from anywhere else
3441 // remove objects from gDirectory and clone the list
3442 out = pq->GetOutputList();
3443 CleanGDirectory(out);
3444 out = (TList *) out->Clone();
3445 // Notify the GUI that the result arrived
3446 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3447 } else {
3448 PDB(kGlobal,2)
3449 Info("HandleInputMessage",
3450 "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3451 }
3452 }
3453 if (out) {
3454 out->SetOwner();
3455 fPlayer->AddOutput(out); // Incorporate the list
3456 SafeDelete(out);
3457 } else {
3458 PDB(kGlobal,2)
3459 Info("HandleInputMessage",
3460 "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3461 }
3462 } else {
3463 Warning("HandleInputMessage",
3464 "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3465 }
3466 // On clients at this point processing is over
3467 if (TestBit(TProof::kIsClient) && !IsLite())
3468 UpdateDialog();
3469 }
3470 break;
3471
3472 case kPROOF_QUERYLIST:
3473 {
3474 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3475 (*mess) >> fOtherQueries >> fDrawQueries;
3476 if (fQueries) {
3477 fQueries->Delete();
3478 delete fQueries;
3479 fQueries = 0;
3480 }
3481 fQueries = (TList *) mess->ReadObject(TList::Class());
3482 }
3483 break;
3484
3485 case kPROOF_RETRIEVE:
3486 {
3487 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3488 TQueryResult *pq =
3490 if (pq && fPlayer) {
3492 // Notify the GUI that the result arrived
3493 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3494 } else {
3495 PDB(kGlobal,2)
3496 Info("HandleInputMessage",
3497 "kPROOF_RETRIEVE: query result missing or player undefined");
3498 }
3499 }
3500 break;
3501
3502 case kPROOF_MAXQUERIES:
3503 {
3504 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3505 Int_t max = 0;
3506
3507 (*mess) >> max;
3508 Printf("Number of queries fully kept remotely: %d", max);
3509 }
3510 break;
3511
3513 {
3514 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3515
3516 UInt_t tot = 0, done = 0;
3517 TString action;
3518 Bool_t st = kTRUE;
3519
3520 (*mess) >> action >> tot >> done >> st;
3521
3523 if (tot) {
3524 TString type = (action.Contains("submas")) ? "submasters"
3525 : "workers";
3526 Int_t frac = (Int_t) (done*100.)/tot;
3527 char msg[512] = {0};
3528 if (frac >= 100) {
3529 snprintf(msg, 512, "%s: OK (%d %s) \n",
3530 action.Data(),tot, type.Data());
3531 } else {
3532 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3533 action.Data(), done, tot, frac);
3534 }
3535 if (fSync)
3536 fprintf(stderr,"%s", msg);
3537 else
3538 NotifyLogMsg(msg, 0);
3539 }
3540 // Notify GUIs
3541 StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3542 } else {
3543
3544 // Just send the message one level up
3546 m << action << tot << done << st;
3548 }
3549 }
3550 break;
3551
3553 {
3554 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3555
3556 UInt_t tot = 0, done = 0;
3557 TString action;
3558 Bool_t st = kTRUE;
3559
3560 (*mess) >> action >> tot >> done >> st;
3561
3563 if (tot) {
3564 TString type = "files";
3565 Int_t frac = (Int_t) (done*100.)/tot;
3566 char msg[512] = {0};
3567 if (frac >= 100) {
3568 snprintf(msg, 512, "%s: OK (%d %s) \n",
3569 action.Data(),tot, type.Data());
3570 } else {
3571 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3572 action.Data(), done, tot, frac);
3573 }
3574 if (fSync)
3575 fprintf(stderr,"%s", msg);
3576 else
3577 NotifyLogMsg(msg, 0);
3578 }
3579 // Notify GUIs
3580 DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3581 } else {
3582
3583 // Just send the message one level up
3585 m << action << tot << done << st;
3587 }
3588 }
3589 break;
3590
3592 {
3593 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3594
3595 // For Proof-Lite this variable is the number of workers and is set
3596 // by the player
3597 if (!IsLite()) {
3598 fNotIdle = 1;
3600 }
3601
3602 // Redirect the output, if needed
3604
3605 // The signal is used on masters by XrdProofdProtocol to catch
3606 // the start of processing; on clients it allows to update the
3607 // progress dialog
3608 if (!TestBit(TProof::kIsMaster)) {
3609
3610 // This is the end of preparation
3611 fQuerySTW.Stop();
3613 PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3614
3615 TString selec;
3616 Int_t dsz = -1;
3617 Long64_t first = -1, nent = -1;
3618 (*mess) >> selec >> dsz >> first >> nent;
3619 // Start or reset the progress dialog
3620 if (!gROOT->IsBatch()) {
3621 if (fProgressDialog &&
3624 fProgressDialog->ExecPlugin(5, this,
3625 selec.Data(), dsz, first, nent);
3627 } else {
3628 ResetProgressDialog(selec, dsz, first, nent);
3629 }
3630 }
3632 }
3633 }
3634 }
3635 break;
3636
3637 case kPROOF_ENDINIT:
3638 {
3639 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3640
3642 if (fPlayer)
3644 }
3645 }
3646 break;
3647
3648 case kPROOF_SETIDLE:
3649 {
3650 PDB(kGlobal,2)
3651 Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3652
3653 // The session is idle
3654 if (IsLite()) {
3655 if (fNotIdle > 0) {
3656 fNotIdle--;
3657 PDB(kGlobal,2)
3658 Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3659 } else {
3660 Warning("HandleInputMessage",
3661 "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3662 sl->GetOrdinal());
3663 }
3664 } else {
3665 fNotIdle = 0;
3666 // Check if the query has been enqueued
3667 if ((mess->BufferSize() > mess->Length()))
3668 (*mess) >> fIsWaiting;
3669 }
3670 }
3671 break;
3672
3674 {
3675 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3676
3677 // We have received the sequential number
3678 (*mess) >> fSeqNum;
3679 Bool_t sync = fSync;
3680 if ((mess->BufferSize() > mess->Length()))
3681 (*mess) >> sync;
3682 if (sync != fSync && fSync) {
3683 // The server required to switch to asynchronous mode
3684 Activate();
3685 fSync = kFALSE;
3686 }
3687 DisableGoAsyn();
3688 // Check if the query has been enqueued
3689 fIsWaiting = kTRUE;
3690 // For Proof-Lite this variable is the number of workers and is set by the player
3691 if (!IsLite())
3692 fNotIdle = 1;
3693
3694 rc = 1;
3695 }
3696 break;
3697
3698 case kPROOF_SESSIONTAG:
3699 {
3700 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3701
3702 // We have received the unique tag and save it as name of this object
3703 TString stag;
3704 (*mess) >> stag;
3705 SetName(stag);
3706 // In the TSlave object
3707 sl->SetSessionTag(stag);
3708 // Server may have also sent the group
3709 if ((mess->BufferSize() > mess->Length()))
3710 (*mess) >> fGroup;
3711 // Server may have also sent the user
3712 if ((mess->BufferSize() > mess->Length())) {
3713 TString usr;
3714 (*mess) >> usr;
3715 if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3716 }
3717 }
3718 break;
3719
3720 case kPROOF_FEEDBACK:
3721 {
3722 PDB(kGlobal,2)
3723 Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3724 TList *out = (TList *) mess->ReadObject(TList::Class());
3725 out->SetOwner();
3726 if (fPlayer)
3727 fPlayer->StoreFeedback(sl, out); // Adopts the list
3728 else
3729 // Not yet ready: stop collect asap
3730 rc = 1;
3731 }
3732 break;
3733
3734 case kPROOF_AUTOBIN:
3735 {
3736 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3737
3738 TString name;
3739 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3740
3741 (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3742
3744
3746
3747 answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3748
3749 s->Send(answ);
3750 }
3751 break;
3752
3753 case kPROOF_PROGRESS:
3754 {
3755 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3756
3757 if (GetRemoteProtocol() > 25) {
3758 // New format
3760 (*mess) >> pi;
3761 fPlayer->Progress(sl,pi);
3762 } else if (GetRemoteProtocol() > 11) {
3763 Long64_t total, processed, bytesread;
3764 Float_t initTime, procTime, evtrti, mbrti;
3765 (*mess) >> total >> processed >> bytesread
3766 >> initTime >> procTime
3767 >> evtrti >> mbrti;
3768 if (fPlayer)
3769 fPlayer->Progress(sl, total, processed, bytesread,
3770 initTime, procTime, evtrti, mbrti);
3771
3772 } else {
3773 // Old format
3774 Long64_t total, processed;
3775 (*mess) >> total >> processed;
3776 if (fPlayer)
3777 fPlayer->Progress(sl, total, processed);
3778 }
3779 }
3780 break;
3781
3782 case kPROOF_STOPPROCESS:
3783 {
3784 // This message is sent from a worker that finished processing.
3785 // We determine whether it was asked to finish by the
3786 // packetizer or stopped during processing a packet
3787 // (by TProof::RemoveWorkers() or by an external signal).
3788 // In the later case call packetizer->MarkBad.
3789 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3790
3791 Long64_t events = 0;
3792 Bool_t abort = kFALSE;
3793 TProofProgressStatus *status = 0;
3794
3795 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3796 (*mess) >> status >> abort;
3797 } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3798 (*mess) >> events >> abort;
3799 } else {
3800 (*mess) >> events;
3801 }
3802 if (fPlayer) {
3803 if (fProtocol > 18) {
3804 TList *listOfMissingFiles = 0;
3805 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3806 listOfMissingFiles = new TList();
3807 listOfMissingFiles->SetName("MissingFiles");
3808 if (fPlayer)
3809 fPlayer->AddOutputObject(listOfMissingFiles);
3810 }
3811 if (fPlayer->GetPacketizer()) {
3812 Int_t ret =
3813 fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3814 if (ret > 0)
3815 fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3816 // This object is now owned by the packetizer
3817 status = 0;
3818 }
3819 if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3820 } else {
3821 fPlayer->AddEventsProcessed(events);
3822 }
3823 }
3824 SafeDelete(status);
3826 Emit("StopProcess(Bool_t)", abort);
3827 break;
3828 }
3829
3830 case kPROOF_SUBMERGER:
3831 {
3832 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3833 HandleSubmerger(mess, sl);
3834 }
3835 break;
3836
3838 {
3839 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3840
3841 Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3842 Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3843 TList* tmpinfo = 0;
3844 (*mess) >> tmpinfo;
3845 if (tmpinfo == 0) {
3846 Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3847 } else {
3848 tmpinfo->SetOwner(kFALSE);
3849 Int_t nentries = tmpinfo->GetSize();
3850 for (Int_t i=0; i<nentries; i++) {
3851 TSlaveInfo* slinfo =
3852 dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3853 if (slinfo) {
3854 // If PROOF-Lite
3855 if (IsLite()) slinfo->fHostName = gSystem->HostName();
3856 // Check if we have already a instance for this worker
3857 TIter nxw(fSlaveInfo);
3858 TSlaveInfo *ourwi = 0;
3859 while ((ourwi = (TSlaveInfo *)nxw())) {
3860 if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3861 ourwi->SetSysInfo(slinfo->GetSysInfo());
3862 ourwi->fHostName = slinfo->GetName();
3863 if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3864 ourwi->fDataDir = slinfo->GetDataDir();
3865 break;
3866 }
3867 }
3868 if (!ourwi) {
3869 fSlaveInfo->Add(slinfo);
3870 } else {
3871 slinfo = ourwi;
3872 }
3873 if (slinfo->fStatus != TSlaveInfo::kBad) {
3874 if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3875 if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3876 }
3877 if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3878 slinfo->fMsd = sl->GetMsd();
3879 }
3880 }
3881 delete tmpinfo;
3882 rc = 1;
3883 }
3884 }
3885 break;
3886
3888 {
3889 PDB(kGlobal,2)
3890 Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3891 TDSet* dset = 0;
3892 (*mess) >> dset;
3893 if (!fDSet)
3894 Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3895 else
3896 fDSet->Validate(dset);
3897 delete dset;
3898 }
3899 break;
3900
3901 case kPROOF_DATA_READY:
3902 {
3903 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3904 Bool_t dataready = kFALSE;
3905 Long64_t totalbytes, bytesready;
3906 (*mess) >> dataready >> totalbytes >> bytesready;
3907 fTotalBytes += totalbytes;
3908 fBytesReady += bytesready;
3909 if (dataready == kFALSE) fDataReady = dataready;
3910 }
3911 break;
3912
3913 case kPROOF_PING:
3914 // do nothing (ping is already acknowledged)
3915 break;
3916
3917 case kPROOF_MESSAGE:
3918 {
3919 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3920
3921 // We have received the unique tag and save it as name of this object
3922 TString msg;
3923 (*mess) >> msg;
3924 Bool_t lfeed = kTRUE;
3925 if ((mess->BufferSize() > mess->Length()))
3926 (*mess) >> lfeed;
3927
3929
3930 if (fSync) {
3931 // Notify locally
3932 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3933 } else {
3934 // Notify locally taking care of redirection, windows logs, ...
3935 NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3936 }
3937 } else {
3938
3939 // The message is logged for debugging purposes.
3940 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3941 if (gProofServ) {
3942 // We hide it during normal operations
3944
3945 // And send the message one level up
3946 gProofServ->SendAsynMessage(msg, lfeed);
3947 }
3948 }
3949 }
3950 break;
3951
3953 {
3954 TString vac;
3955 (*mess) >> vac;
3956 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3957 Int_t from = 0;
3958 TString vers, archcomp;
3959 if (vac.Tokenize(vers, from, "|"))
3960 vac.Tokenize(archcomp, from, "|");
3961 sl->SetArchCompiler(archcomp);
3962 vers.ReplaceAll(":","|");
3963 sl->SetROOTVersion(vers);
3964 }
3965 break;
3966
3967 default:
3968 {
3969 Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3970 sl->GetOrdinal(), what);
3971 }
3972 break;
3973 }
3974
3975 // Cleanup
3976 if (delete_mess)
3977 delete mess;
3978
3979 // We are done successfully
3980 return rc;
3981}
3982
3983////////////////////////////////////////////////////////////////////////////////
3984/// Process a message of type kPROOF_SUBMERGER
3985
3987{
3988 // Message sub-type
3989 Int_t type = 0;
3990 (*mess) >> type;
3991 TSocket *s = sl->GetSocket();
3992
3993 switch (type) {
3994 case kOutputSent:
3995 {
3996 if (IsEndMaster()) {
3997 Int_t merger_id = -1;
3998 (*mess) >> merger_id;
3999
4000 PDB(kSubmerger, 2)
4001 Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4002 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4003
4004 if (!fMergers || fMergers->GetSize() <= merger_id) {
4005 Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4006 break;
4007 }
4008 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4009 mi->SetMergedWorker();
4010 if (mi->AreAllWorkersMerged()) {
4011 mi->Deactivate();
4012 if (GetActiveMergersCount() == 0) {
4013 fMergers->Clear();
4014 delete fMergers;
4016 fMergersCount = -1;
4018 PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4019 }
4020 }
4021 } else {
4022 PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4023 }
4024 }
4025 break;
4026
4027 case kMergerDown:
4028 {
4029 Int_t merger_id = -1;
4030 (*mess) >> merger_id;
4031
4032 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4033
4034 if (!fMergers || fMergers->GetSize() <= merger_id) {
4035 Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4036 break;
4037 }
4038
4039 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4040 if (!mi->IsActive()) {
4041 break;
4042 } else {
4043 mi->Deactivate();
4044 }
4045
4046 // Stop the invalid merger in the case it is still listening
4048 stop << Int_t(kStopMerging);
4049 stop << 0;
4050 s->Send(stop);
4051
4052 // Ask for results from merger (only original results from this node as worker are returned)
4053 AskForOutput(mi->GetMerger());
4054
4055 // Ask for results from all workers assigned to this merger
4056 TIter nxo(mi->GetWorkers());
4057 TObject * o = 0;
4058 while ((o = nxo())) {
4059 AskForOutput((TSlave *)o);
4060 }
4061 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4062 }
4063 break;
4064
4065 case kOutputSize:
4066 {
4067 if (IsEndMaster()) {
4068 PDB(kSubmerger, 2)
4069 Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4070
4071 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4072 if (!fFinalizationRunning) {
4073 Info("HandleSubmerger", "finalization on %s started ...", prefix);
4075 }
4076
4077 Int_t output_size = 0;
4078 Int_t merging_port = 0;
4079 (*mess) >> output_size >> merging_port;
4080
4081 PDB(kSubmerger, 2) Info("HandleSubmerger",
4082 "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4083 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4084 TString msg;
4085 if (!fMergersSet) {
4086
4088
4089 // First pass - setting number of mergers according to user or dynamically
4090 fMergersCount = -1; // No mergers used if not set by user
4091 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4092 if (mc) fMergersCount = mc->GetVal(); // Value set by user
4093 TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4094 if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4095
4096 // Mergers count specified by user but not valid
4097 if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4098 msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4099 prefix, fMergersCount, activeWorkers);
4100 if (gProofServ)
4102 else
4103 Printf("%s",msg.Data());
4104 fMergersCount = 0;
4105 }
4106 // Mergers count will be set dynamically
4107 if ((fMergersCount == 0) && (!fMergersByHost)) {
4108 if (activeWorkers > 1) {
4109 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4110 if (activeWorkers / fMergersCount < 2)
4111 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4112 }
4113 if (fMergersCount > 1)
4114 msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4115 prefix, fMergersCount, activeWorkers);
4116 else {
4117 msg.Form("%s: No mergers will be used for %d workers",
4118 prefix, activeWorkers);
4119 fMergersCount = -1;
4120 }
4121 if (gProofServ)
4123 else
4124 Printf("%s",msg.Data());
4125 } else if (fMergersByHost) {
4126 // We force mergers at host level to minimize network traffic
4127 if (activeWorkers > 1) {
4128 fMergersCount = 0;
4129 THashList hosts;
4130 TIter nxwk(fSlaves);
4131 TObject *wrk = 0;
4132 while ((wrk = nxwk())) {
4133 if (!hosts.FindObject(wrk->GetName())) {
4134 hosts.Add(new TObjString(wrk->GetName()));
4135 fMergersCount++;
4136 }
4137 }
4138 }
4139 if (fMergersCount > 1)
4140 msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4141 prefix, fMergersCount, activeWorkers);
4142 else {
4143 msg.Form("%s: No mergers will be used for %d workers",
4144 prefix, activeWorkers);
4145 fMergersCount = -1;
4146 }
4147 if (gProofServ)
4149 else
4150 Printf("%s",msg.Data());
4151 } else {
4152 msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4153 prefix, fMergersCount, activeWorkers);
4154 if (gProofServ)
4156 else
4157 Printf("%s",msg.Data());
4158 }
4159
4160 // We started merging; we call it here because fMergersCount is still the original number
4161 // and can be saved internally
4163
4164 // Update merger counters (new workers are not yet active)
4166
4167 if (fMergersCount > 0) {
4168
4169 fMergers = new TList();
4171 // Total number of workers, which will not act as mergers ('pure workers')
4172 fWorkersToMerge = (activeWorkers - fMergersCount);
4173 // Establish the first merger
4174 if (!CreateMerger(sl, merging_port)) {
4175 // Cannot establish first merger
4176 AskForOutput(sl);
4178 fMergersCount--;
4179 }
4181 } else {
4182 AskForOutput(sl);
4183 }
4185 } else {
4186 // Multiple pass
4187 if (fMergersCount == -1) {
4188 // No mergers. Workers send their outputs directly to master
4189 AskForOutput(sl);
4190 } else {
4191 if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4192 RedirectWorker(s, sl, output_size);
4193 fRedirectNext--;
4194 } else {
4195 Bool_t newMerger = kTRUE;
4196 if (fMergersByHost) {
4197 TIter nxmg(fMergers);
4198 TMergerInfo *mgi = 0;
4199 while ((mgi = (TMergerInfo *) nxmg())) {
4200 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4201 newMerger = kFALSE;
4202 break;
4203 }
4204 }
4205 }
4206 if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4207 // Still not enough mergers established
4208 if (!CreateMerger(sl, merging_port)) {
4209 // Cannot establish a merger
4210 AskForOutput(sl);
4212 fMergersCount--;
4213 }
4214 } else
4215 RedirectWorker(s, sl, output_size);
4216 }
4217 }
4218 }
4219 } else {
4220 Error("HandleSubMerger","kOutputSize received not on endmaster!");
4221 }
4222 }
4223 break;
4224 }
4225}
4226
4227////////////////////////////////////////////////////////////////////////////////
4228/// Redirect output of worker sl to some merger
4229
4231{
4232 Int_t merger_id = -1;
4233
4234 if (fMergersByHost) {
4235 for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4236 TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4237 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4238 merger_id = i;
4239 break;
4240 }
4241 }
4242 } else {
4243 merger_id = FindNextFreeMerger();
4244 }
4245
4246 if (merger_id == -1) {
4247 // No free merger (probably it had crashed before)
4248 AskForOutput(sl);
4249 } else {
4250 TMessage sendoutput(kPROOF_SUBMERGER);
4251 sendoutput << Int_t(kSendOutput);
4252 PDB(kSubmerger, 2)
4253 Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4254
4255 PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4256 if (!fMergers || fMergers->GetSize() <= merger_id) {
4257 Error("RedirectWorker", "#%d not in list ", merger_id);
4258 return;
4259 }
4260 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4261
4262 TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4263 sendoutput << merger_id;
4264 sendoutput << hname;
4265 sendoutput << mi->GetPort();
4266 s->Send(sendoutput);
4267 mi->AddMergedObjects(output_size);
4268 mi->AddWorker(sl);
4269 }
4270}
4271
4272////////////////////////////////////////////////////////////////////////////////
4273/// Return a merger, which is both active and still accepts some workers to be
4274/// assigned to it. It works on the 'round-robin' basis.
4275
4277{
4278 while (fLastAssignedMerger < fMergers->GetSize() &&
4279 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4280 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4282 }
4283
4286 } else {
4287 return fLastAssignedMerger++;
4288 }
4289
4290 while (fLastAssignedMerger < fMergers->GetSize() &&
4291 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4292 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4294 }
4295
4297 return -1;
4298 } else {
4299 return fLastAssignedMerger++;
4300 }
4301}
4302
4303////////////////////////////////////////////////////////////////////////////////
4304/// Master asks for output from worker sl
4305
4307{
4308 TMessage sendoutput(kPROOF_SUBMERGER);
4309 sendoutput << Int_t(kSendOutput);
4310
4311 PDB(kSubmerger, 2) Info("AskForOutput",
4312 "worker %s was asked to send its output to master",
4313 sl->GetOrdinal());
4314
4315 sendoutput << -1;
4316 sendoutput << TString("master");
4317 sendoutput << -1;
4318 sl->GetSocket()->Send(sendoutput);
4320}
4321
4322////////////////////////////////////////////////////////////////////////////////
4323/// Final update of the progress dialog
4324
4326{
4327 if (!fPlayer) return;
4328
4329 // Handle abort ...
4331 if (fSync)
4332 Info("UpdateDialog",
4333 "processing was aborted - %lld events processed",
4335
4336 if (GetRemoteProtocol() > 11) {
4337 // New format
4338 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4339 } else {
4341 }
4342 Emit("StopProcess(Bool_t)", kTRUE);
4343 }
4344
4345 // Handle stop ...
4347 if (fSync)
4348 Info("UpdateDialog",
4349 "processing was stopped - %lld events processed",
4351
4352 if (GetRemoteProtocol() > 25) {
4353 // New format
4354 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4355 } else if (GetRemoteProtocol() > 11) {
4356 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4357 } else {
4359 }
4360 Emit("StopProcess(Bool_t)", kFALSE);
4361 }
4362
4363 // Final update of the dialog box
4364 if (GetRemoteProtocol() > 25) {
4365 // New format
4366 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4367 10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4368 (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4369 } else if (GetRemoteProtocol() > 11) {
4370 // New format
4371 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4372 7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4373 (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4374 } else {
4375 EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4376 }
4377}
4378
4379////////////////////////////////////////////////////////////////////////////////
4380/// Activate the a-sync input handler.
4381
4383{
4384 TIter next(fSlaves);
4385 TSlave *sl;
4386
4387 while ((sl = (TSlave*) next()))
4388 if (sl->GetInputHandler())
4389 sl->GetInputHandler()->Add();
4390}
4391
4392////////////////////////////////////////////////////////////////////////////////
4393/// De-activate a-sync input handler.
4394
4396{
4397 TIter next(fSlaves);
4398 TSlave *sl;
4399
4400 while ((sl = (TSlave*) next()))
4401 if (sl->GetInputHandler())
4402 sl->GetInputHandler()->Remove();
4403}
4404
4405////////////////////////////////////////////////////////////////////////////////
4406/// Get the active mergers count
4407
4409{
4410 if (!fMergers) return 0;
4411
4412 Int_t active_mergers = 0;
4413
4414 TIter mergers(fMergers);
4415 TMergerInfo *mi = 0;
4416 while ((mi = (TMergerInfo *)mergers())) {
4417 if (mi->IsActive()) active_mergers++;
4418 }
4419
4420 return active_mergers;
4421}
4422
4423////////////////////////////////////////////////////////////////////////////////
4424/// Create a new merger
4425
4427{
4428 PDB(kSubmerger, 2)
4429 Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4430
4431 PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4432
4433 if (port <= 0) {
4434 PDB(kSubmerger,2)
4435 Info("CreateMerger", "cannot create merger on port %d - exit", port);
4436 return kFALSE;
4437 }
4438
4439 Int_t workers = -1;
4440 if (!fMergersByHost) {
4441 Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4442 // Number of pure workers, which are not simply divisible by mergers
4443 Int_t rest = fWorkersToMerge % mergersToCreate;
4444 // We add one more worker for each of the first 'rest' mergers being established
4445 if (rest > 0 && fMergers->GetSize() < rest) {
4446 rest = 1;
4447 } else {
4448 rest = 0;
4449 }
4450 workers = (fWorkersToMerge / mergersToCreate) + rest;
4451 } else {
4452 Int_t workersOnHost = 0;
4453 for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4454 if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4455 }
4456 workers = workersOnHost - 1;
4457 }
4458
4459 TString msg;
4460 msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4461
4462 if (gProofServ) {
4464 } else {
4465 Printf("%s",msg.Data());
4466 }
4467 TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4468
4469 TMessage bemerger(kPROOF_SUBMERGER);
4470 bemerger << Int_t(kBeMerger);
4471 bemerger << fMergers->GetSize();
4472 bemerger << workers;
4473 sl->GetSocket()->Send(bemerger);
4474
4475 PDB(kSubmerger,2) Info("CreateMerger",
4476 "merger #%d (port: %d) for %d workers started",
4477 fMergers->GetSize(), port, workers);
4478
4479 fMergers->Add(merger);
4480 fWorkersToMerge = fWorkersToMerge - workers;
4481
4482 fRedirectNext = workers / 2;
4483
4484 PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4485 return kTRUE;
4486}
4487
4488////////////////////////////////////////////////////////////////////////////////
4489/// Add a bad slave server to the bad slave list and remove it from
4490/// the active list and from the two monitor objects. Assume that the work
4491/// done by this worker was lost and ask packerizer to reassign it.
4492
4493void TProof::MarkBad(TSlave *wrk, const char *reason)
4494{
4495 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4496
4497 // We may have been invalidated in the meanwhile: nothing to do in such a case
4498 if (!IsValid()) return;
4499
4500 if (!wrk) {
4501 Error("MarkBad", "worker instance undefined: protocol error? ");
4502 return;
4503 }
4504
4505 // Local URL
4506 static TString thisurl;
4507 if (thisurl.IsNull()) {
4508 if (IsMaster()) {
4509 Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4510 thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4511 if (port > 0) thisurl += TString::Format(":%d", port);
4512 } else {
4513 thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4514 }
4515 }
4516
4517 if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4518 // Message for notification
4519 const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4520 TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4521 TString msg;
4522 msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4523 src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4524 (reason && strlen(reason)) ? reason : "unknown");
4525 Info("MarkBad", "%s", msg.Data());
4526 // Notify one level up, if the case
4527 // Add some hint for diagnostics
4528 if (gProofServ) {
4529 msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4530 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4531 } else {
4532 msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4533 }
4534 msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4535 msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4536 msg += TString::Format(" +++\n");
4537 if (gProofServ) {
4538 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4539 "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4541 } else {
4542 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4543 "Display(\"*\")\n\n", thisurl.Data());
4544 Printf("%s", msg.Data());
4545 }
4546 } else if (reason) {
4547 if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4548 Info("MarkBad", "worker %s at %s:%d asked to terminate",
4549 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4550 }
4551 }
4552
4553 if (IsMaster() && reason) {
4554 if (strcmp(reason, kPROOF_TerminateWorker)) {
4555 // if the reason was not a planned termination
4556 TList *listOfMissingFiles = 0;
4557 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4558 listOfMissingFiles = new TList();
4559 listOfMissingFiles->SetName("MissingFiles");
4560 if (fPlayer)
4561 fPlayer->AddOutputObject(listOfMissingFiles);
4562 }
4563 // If a query is being processed, assume that the work done by
4564 // the worker was lost and needs to be reassigned.
4565 TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4566 if (packetizer) {
4567 // the worker was lost so do resubmit the packets
4568 packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4569 }
4570 } else {
4571 // Tell the coordinator that we are gone
4572 if (gProofServ) {
4573 TString ord(wrk->GetOrdinal());
4574 Int_t id = ord.Last('.');
4575 if (id != kNPOS) ord.Remove(0, id+1);
4577 }
4578 }
4579 } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4580 // We are invalid after this
4581 fValid = kFALSE;
4582 }
4583
4584 fActiveSlaves->Remove(wrk);
4586
4587 fAllMonitor->Remove(wrk->GetSocket());
4589
4591
4592 if (IsMaster()) {
4593 if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4594 // if the reason was a planned termination then delete the worker and
4595 // remove it from all the lists
4596 fSlaves->Remove(wrk);
4597 fBadSlaves->Remove(wrk);
4598 fActiveSlaves->Remove(wrk);
4599 fInactiveSlaves->Remove(wrk);
4600 fUniqueSlaves->Remove(wrk);
4603
4604 // we add it to the list of terminated slave infos instead, so that it
4605 // stays available in the .workers persistent file
4606 TSlaveInfo *si = new TSlaveInfo(
4607 wrk->GetOrdinal(),
4608 Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4609 0, "", wrk->GetWorkDir());
4611 else delete si;
4612
4613 delete wrk;
4614 } else {
4615 fBadSlaves->Add(wrk);
4616 fActiveSlaves->Remove(wrk);
4617 fUniqueSlaves->Remove(wrk);
4621 wrk->Close();
4622 // Update the mergers count, if needed
4623 if (fMergersSet) {
4624 Int_t mergersCount = -1;
4625 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4626 if (mc) mergersCount = mc->GetVal(); // Value set by user
4627 // Mergers count is set dynamically: recalculate it
4628 if (mergersCount == 0) {
4630 if (activeWorkers > 1) {
4631 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4632 if (activeWorkers / fMergersCount < 2)
4633 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4634 }
4635 }
4636 }
4637 }
4638
4639 // Update session workers files
4641 } else {
4642 // On clients the proof session should be removed from the lists
4643 // and deleted, since it is not valid anymore
4644 fSlaves->Remove(wrk);
4645 if (fManager)
4646 fManager->DiscardSession(this);
4647 }
4648}
4649
4650////////////////////////////////////////////////////////////////////////////////
4651/// Add slave with socket s to the bad slave list and remove if from
4652/// the active list and from the two monitor objects.
4653
4654void TProof::MarkBad(TSocket *s, const char *reason)
4655{
4656 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4657
4658 // We may have been invalidated in the meanwhile: nothing to do in such a case
4659 if (!IsValid()) return;
4660
4661 TSlave *wrk = FindSlave(s);
4662 MarkBad(wrk, reason);
4663}
4664
4665////////////////////////////////////////////////////////////////////////////////
4666/// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4667
4669{
4670 if (!wrk) {
4671 Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4672 return;
4673 }
4674
4675 // Send stop message
4676 if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4677 TMessage mess(kPROOF_STOP);
4678 wrk->GetSocket()->Send(mess);
4679 } else {
4680 if (gDebug > 0)
4681 Info("TerminateWorker", "connection to worker is already down: cannot"
4682 " send termination message");
4683 }
4684
4685 // This is a bad worker from now on
4687}
4688
4689////////////////////////////////////////////////////////////////////////////////
4690/// Ask an active worker 'ord' to terminate, i.e. to shutdown
4691
4692void TProof::TerminateWorker(const char *ord)
4693{
4694 if (ord && strlen(ord) > 0) {
4695 Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4696 if (IsMaster()) {
4697 TIter nxw(fSlaves);
4698 TSlave *wrk = 0;
4699 while ((wrk = (TSlave *)nxw())) {
4700 if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4701 TerminateWorker(wrk);
4702 if (!all) break;
4703 }
4704 }
4705 } else {
4706 TMessage mess(kPROOF_STOP);
4707 mess << TString(ord);
4708 Broadcast(mess);
4709 }
4710 }
4711}
4712
4713////////////////////////////////////////////////////////////////////////////////
4714/// Ping PROOF. Returns 1 if master server responded.
4715
4717{
4718 return Ping(kActive);
4719}
4720
4721////////////////////////////////////////////////////////////////////////////////
4722/// Ping PROOF slaves. Returns the number of slaves that responded.
4723
4725{
4726 TList *slaves = 0;
4727 if (list == kAll) slaves = fSlaves;
4728 if (list == kActive) slaves = fActiveSlaves;
4729 if (list == kUnique) slaves = fUniqueSlaves;
4730 if (list == kAllUnique) slaves = fAllUniqueSlaves;
4731
4732 if (slaves->GetSize() == 0) return 0;
4733
4734 int nsent = 0;
4735 TIter next(slaves);
4736
4737 TSlave *sl;
4738 while ((sl = (TSlave *)next())) {
4739 if (sl->IsValid()) {
4740 if (sl->Ping() == -1) {
4741 MarkBad(sl, "ping unsuccessful");
4742 } else {
4743 nsent++;
4744 }
4745 }
4746 }
4747
4748 return nsent;
4749}
4750
4751////////////////////////////////////////////////////////////////////////////////
4752/// Ping PROOF slaves. Returns the number of slaves that responded.
4753
4755{
4756 TList *slaves = fSlaves;
4757
4758 if (slaves->GetSize() == 0) return;
4759
4760 TIter next(slaves);
4761
4762 TSlave *sl;
4763 while ((sl = (TSlave *)next())) {
4764 if (sl->IsValid()) {
4765 sl->Touch();
4766 }
4767 }
4768
4769 return;
4770}
4771
4772////////////////////////////////////////////////////////////////////////////////
4773/// Print status of PROOF cluster.
4774
4775void TProof::Print(Option_t *option) const
4776{
4777 TString secCont;
4778
4780 Printf("Connected to: %s (%s)", GetMaster(),
4781 IsValid() ? "valid" : "invalid");
4782 Printf("Port number: %d", GetPort());
4783 Printf("User: %s", GetUser());
4784 Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4785 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4787 TSlave *sl = (TSlave *)fActiveSlaves->First();
4788 if (sl) {
4789 TString sc;
4790 if (sl->GetSocket()->GetSecContext())
4791 Printf("Security context: %s",
4792 sl->GetSocket()->GetSecContext()->AsString(sc));
4793 Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4794 } else {
4795 Printf("Security context: Error - No connection");
4796 Printf("Proofd protocol version: Error - No connection");
4797 }
4798 Printf("Client protocol version: %d", GetClientProtocol());
4799 Printf("Remote protocol version: %d", GetRemoteProtocol());
4800 Printf("Log level: %d", GetLogLevel());
4801 Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4802 Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4803 if (IsValid())
4804 const_cast<TProof*>(this)->SendPrint(option);
4805 } else {
4806 const_cast<TProof*>(this)->AskStatistics();
4807 if (IsParallel())
4808 Printf("*** Master server %s (parallel mode, %d workers):",
4810 else
4811 Printf("*** Master server %s (sequential mode):",
4813
4814 Printf("Master host name: %s", gSystem->HostName());
4815 Printf("Port number: %d", GetPort());
4816 if (strlen(gProofServ->GetGroup()) > 0) {
4817 Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4818 } else {
4819 Printf("User: %s", GetUser());
4820 }
4821 TString ver;
4822 ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4823 if (gSystem->Getenv("ROOTVERSIONTAG"))
4824 ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4825 Printf("ROOT version|rev|tag: %s", ver.Data());
4826 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4828 Printf("Protocol version: %d", GetClientProtocol());
4829 Printf("Image name: %s", GetImage());
4830 Printf("Working directory: %s", gSystem->WorkingDirectory());
4831 Printf("Config directory: %s", GetConfDir());
4832 Printf("Config file: %s", GetConfFile());
4833 Printf("Log level: %d", GetLogLevel());
4834 Printf("Number of workers: %d", GetNumberOfSlaves());
4835 Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4836 Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4837 Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4838 Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4839 Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4840 Printf("Total real time used (s): %.3f", GetRealTime());
4841 Printf("Total CPU time used (s): %.3f", GetCpuTime());
4842 if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4843 Printf("List of workers:");
4844 TList masters;
4845 TIter nextslave(fSlaves);
4846 while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4847 if (!sl->IsValid()) continue;
4848
4849 if (sl->GetSlaveType() == TSlave::kSlave) {
4850 sl->Print(option);
4851 } else if (sl->GetSlaveType() == TSlave::kMaster) {
4852 TMessage mess(kPROOF_PRINT);
4853 mess.WriteString(option);
4854 if (sl->GetSocket()->Send(mess) == -1)
4855 const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4856 else
4857 masters.Add(sl);
4858 } else {
4859 Error("Print", "TSlave is neither Master nor Worker");
4860 R__ASSERT(0);
4861 }
4862 }
4863 const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4864 }
4865 }
4866}
4867
4868////////////////////////////////////////////////////////////////////////////////
4869/// Extract from opt information about output handling settings.
4870/// The understood keywords are:
4871/// of=<file>, outfile=<file> output file location
4872/// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4873/// mutually exclusive,execution stops
4874/// if both are found)
4875/// sft[=<opt>], savetofile[=<opt>] control saving to file
4876///
4877/// For 'mvf', the <opt> integer has the following meaning:
4878/// <opt> = <how>*10 + <force>
4879/// <force> = 0 save to file if memory threshold is reached
4880/// (the memory threshold is set by the cluster
4881/// admin); in case an output file is defined, the
4882/// files are merged at the end;
4883/// 1 save results to file.
4884/// <how> = 0 save at the end of the query
4885/// 1 save results after each packet (to reduce the
4886/// loss in case of crash).
4887///
4888/// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4889/// to save results after each packet.
4890///
4891/// The separator from the next option is either a ' ' or a ';'
4892///
4893/// All recognized settings are removed from the input string opt.
4894/// If action == 0, set up the output file accordingly, if action == 1 clean related
4895/// output file settings.
4896/// If the final target file is local then 'target' is set to the final local path
4897/// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4898///
4899/// Output file settings are in the form
4900///
4901/// <previous_option>of=name <next_option>
4902/// <previous_option>outfile=name,...;<next_option>
4903///
4904/// The separator from the next option is either a ' ' or a ';'
4905/// Called interanally by TProof::Process.
4906///
4907/// Returns 0 on success, -1 on error.
4908
4910{
4911 TString outfile, dsname, stfopt;
4912 if (action == 0) {
4913 TString tagf, tagd, tags, oo;
4914 Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4915 while (opt.Tokenize(oo, from, "[; ]")) {
4916 if (oo.BeginsWith("of=")) {
4917 tagf = "of=";
4918 iof = opt.Index(tagf);
4919 } else if (oo.BeginsWith("outfile=")) {
4920 tagf = "outfile=";
4921 iof = opt.Index(tagf);
4922 } else if (oo.BeginsWith("ds")) {
4923 tagd = "ds";
4924 iod = opt.Index(tagd);
4925 } else if (oo.BeginsWith("dataset")) {
4926 tagd = "dataset";
4927 iod = opt.Index(tagd);
4928 } else if (oo.BeginsWith("stf")) {
4929 tags = "stf";
4930 ios = opt.Index(tags);
4931 } else if (oo.BeginsWith("savetofile")) {
4932 tags = "savetofile";
4933 ios = opt.Index(tags);
4934 }
4935 }
4936 // Check consistency
4937 if (iof != kNPOS && iod != kNPOS) {
4938 Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4939 return -1;
4940 }
4941
4942 // Check output file first
4943 if (iof != kNPOS) {
4944 from = iof + tagf.Length();
4945 if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4946 Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4947 return -1;
4948 }
4949 // For removal from original options string
4950 tagf += outfile;
4951 }
4952 // Check dataset
4953 if (iod != kNPOS) {
4954 from = iod + tagd.Length();
4955 if (!opt.Tokenize(dsname, from, "[; ]"))
4956 if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4957 // For removal from original options string
4958 tagd += dsname;
4959 // The name may be empty or beginning with a '='
4960 if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4961 if (dsname.Contains("|V")) {
4962 target = "ds|V";
4963 dsname.ReplaceAll("|V", "");
4964 }
4965 if (dsname.IsNull()) dsname = "dataset_<qtag>";
4966 }
4967 // Check stf
4968 if (ios != kNPOS) {
4969 from = ios + tags.Length();
4970 if (!opt.Tokenize(stfopt, from, "[; ]"))
4971 if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
4972 // For removal from original options string
4973 tags += stfopt;
4974 // It must be digit
4975 if (!stfopt.IsNull()) {
4976 if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
4977 if (!stfopt.IsNull()) {
4978 if (!stfopt.IsDigit()) {
4979 Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
4980 return -1;
4981 }
4982 } else {
4983 // Default
4984 stfopt = "1";
4985 }
4986 } else {
4987 // Default
4988 stfopt = "1";
4989 }
4990 }
4991 // Remove from original options string
4992 opt.ReplaceAll(tagf, "");
4993 opt.ReplaceAll(tagd, "");
4994 opt.ReplaceAll(tags, "");
4995 }
4996
4997 // Parse now
4998 if (action == 0) {
4999 // Output file
5000 if (!outfile.IsNull()) {
5001 if (!outfile.BeginsWith("master:")) {
5003 Warning("HandleOutputOptions",
5004 "directory '%s' for the output file does not exists or is not writable:"
5005 " saving to master", gSystem->DirName(outfile.Data()));
5006 outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5007 } else {
5008 if (!IsLite()) {
5009 // The target file is local, so we need to retrieve it
5010 target = outfile;
5011 if (!stfopt.IsNull()) {
5012 outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5013 } else {
5014 outfile = "";
5015 }
5016 }
5017 }
5018 }
5019 if (outfile.BeginsWith("master:")) {
5020 outfile.ReplaceAll("master:", "");
5021 if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5022 // Get the master data dir
5023 TString ddir, emsg;
5024 if (!IsLite()) {
5025 if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5026 TObjString *os = fMacroLog.GetLineWith("const char");
5027 if (os) {
5028 Ssiz_t fst = os->GetString().First('\"');
5029 Ssiz_t lst = os->GetString().Last('\"');
5030 ddir = os->GetString()(fst+1, lst-fst-1);
5031 } else {
5032 emsg = "could not find 'const char *' string in macro log! cannot continue";
5033 }
5034 } else {
5035 emsg = "could not retrieve master data directory info! cannot continue";
5036 }
5037 if (!emsg.IsNull()) {
5038 Error("HandleOutputOptions", "%s", emsg.Data());
5039 return -1;
5040 }
5041 }
5042 if (!ddir.IsNull()) ddir += "/";
5043 if (outfile.IsNull()) {
5044 outfile.Form("%s<file>", ddir.Data());
5045 } else {
5046 outfile.Insert(0, TString::Format("%s", ddir.Data()));
5047 }
5048 }
5049 }
5050 // Set the parameter
5051 if (!outfile.IsNull()) {
5052 if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5053 SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5054 }
5055 }
5056 // Dataset creation
5057 if (!dsname.IsNull()) {
5058 dsname.Insert(0, "ds:");
5059 // Set the parameter
5060 SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5061 // Check the Save-To-File option
5062 if (!stfopt.IsNull()) {
5063 Int_t ostf = (Int_t) stfopt.Atoi();
5064 if (ostf%10 <= 0) {
5065 Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5066 stfopt.Form("%d", ostf+1);
5067 }
5068 } else {
5069 // Minimal setting
5070 stfopt = "1";
5071 }
5072 }
5073 // Save-To-File options
5074 if (!stfopt.IsNull()) {
5075 // Set the parameter
5076 SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5077 }
5078 } else {
5079 // Retrieve the file, if required
5080 if (GetOutputList()) {
5081 if (target == "ds|V") {
5082 // Find the dataset
5083 dsname = "";
5084 TIter nxo(GetOutputList());
5085 TObject *o = 0;
5086 while ((o = nxo())) {
5088 VerifyDataSet(o->GetName());
5089 dsname = o->GetName();
5090 break;
5091 }
5092 }
5093 if (!dsname.IsNull()) {
5094 TFileCollection *fc = GetDataSet(dsname);
5095 if (fc) {
5096 fc->Print();
5097 } else {
5098 Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5099 }
5100 } else {
5101 Warning("HandleOutputOptions", "dataset not found!");
5102 }
5103 } else {
5104 Bool_t targetcopied = kFALSE;
5105 TProofOutputFile *pf = 0;
5106 if (!target.IsNull())
5108 if (pf) {
5109 // Copy the file
5110 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5111 TUrl(target, kTRUE).GetUrl())) {
5112 if (TFile::Cp(pf->GetOutputFileName(), target)) {
5113 Printf(" Output successfully copied to %s", target.Data());
5114 targetcopied = kTRUE;
5115 } else {
5116 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5117 }
5118 }
5119 }
5120 TFile *fout = 0;
5121 TObject *o = 0;
5122 TIter nxo(GetOutputList());
5123 Bool_t swapcopied = kFALSE;
5124 while ((o = nxo())) {
5125 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5126 if (pof) {
5127 if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5128 if (pof == pf && targetcopied) continue;
5129 // Copy the file
5130 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5131 TUrl(target, kTRUE).GetUrl())) {
5132 if (TFile::Cp(pof->GetOutputFileName(), target)) {
5133 Printf(" Output successfully copied to %s", target.Data());
5134 swapcopied = kTRUE;
5135 } else {
5136 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5137 }
5138 }
5139 } else if (pof->IsRetrieve()) {
5140 // Retrieve this file to the local path indicated in the title
5141 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5142 TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5143 if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5144 Printf(" Output successfully copied to %s", pof->GetTitle());
5145 } else {
5146 Warning("HandleOutputOptions",
5147 "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5148 }
5149 }
5150 }
5151 }
5152 }
5153 if (!target.IsNull() && !swapcopied) {
5154 if (!fout && !pf) {
5155 fout = TFile::Open(target, "RECREATE");
5156 if (!fout || (fout && fout->IsZombie())) {
5157 SafeDelete(fout);
5158 Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5159 }
5160 }
5161 if (fout) {
5162 nxo.Reset();
5163 while ((o = nxo())) {
5164 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5165 if (!pof) {
5166 // Write the object to the open output file
5167 o->Write();
5168 }
5169 }
5170 }
5171 }
5172 // Clean-up
5173 if (fout) {
5174 fout->Close();
5175 SafeDelete(fout);
5176 Printf(" Output saved to %s", target.Data());
5177 }
5178 }
5179 }
5180 // Remove the parameter
5181 DeleteParameters("PROOF_DefaultOutputOption");
5182 // Remove the parameter
5183 DeleteParameters("PROOF_SavePartialResults");
5184 }
5185 // Done
5186 return 0;
5187}
5188
5189////////////////////////////////////////////////////////////////////////////////
5190/// Extract from opt in optfb information about wanted feedback settings.
5191/// Feedback are removed from the input string opt.
5192/// If action == 0, set up feedback accordingly, if action == 1 clean related
5193/// feedback settings (using info in optfb, if available, or reparsing opt).
5194///
5195/// Feedback requirements are in the form
5196///
5197/// <previous_option>fb=name1,name2,name3,... <next_option>
5198/// <previous_option>feedback=name1,name2,name3,...;<next_option>
5199///
5200/// The special name 'stats' triggers feedback about events and packets.
5201/// The separator from the next option is either a ' ' or a ';'.
5202/// Called interanally by TProof::Process.
5203
5204void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5205{
5206 Ssiz_t from = 0;
5207 if (action == 0 || (action == 1 && optfb.IsNull())) {
5208 TString tag("fb=");
5209 Ssiz_t ifb = opt.Index(tag);
5210 if (ifb == kNPOS) {
5211 tag = "feedback=";
5212 ifb = opt.Index(tag);
5213 }
5214 if (ifb == kNPOS) return;
5215 from = ifb + tag.Length();
5216
5217 if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5218 Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5219 return;
5220 }
5221 // Remove from original options string
5222 tag += optfb;
5223 opt.ReplaceAll(tag, "");
5224 }
5225
5226 // Parse now
5227 TString nm, startdraw, stopdraw;
5228 from = 0;
5229 while (optfb.Tokenize(nm, from, ",")) {
5230 // Special name first
5231 if (nm == "stats") {
5232 if (action == 0) {
5233 startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5234 gROOT->ProcessLine(startdraw.Data());
5235 SetParameter("PROOF_StatsHist", "");
5236 AddFeedback("PROOF_EventsHist");
5237 AddFeedback("PROOF_PacketsHist");
5238 AddFeedback("PROOF_ProcPcktHist");
5239 } else {
5240 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5241 " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5242 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5243 gROOT->ProcessLine(stopdraw.Data());
5244 DeleteParameters("PROOF_StatsHist");
5245 RemoveFeedback("PROOF_EventsHist");
5246 RemoveFeedback("PROOF_PacketsHist");
5247 RemoveFeedback("PROOF_ProcPcktHist");
5248 }
5249 } else {
5250 if (action == 0) {
5251 // Enable or
5252 AddFeedback(nm);
5253 startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5254 gROOT->ProcessLine(startdraw.Data());
5255 } else {
5256 // ... or disable
5258 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5259 " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5260 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5261 gROOT->ProcessLine(stopdraw.Data());
5262 }
5263 }
5264 }
5265}
5266
5267////////////////////////////////////////////////////////////////////////////////
5268/// Process a data set (TDSet) using the specified selector (.C) file or
5269/// Tselector object
5270/// Entry- or event-lists should be set in the data set object using
5271/// TDSet::SetEntryList.
5272/// The return value is -1 in case of error and TSelector::GetStatus() in
5273/// in case of success.
5274
5275Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5277{
5278 if (!IsValid() || !fPlayer) return -1;
5279
5280 // Set PROOF to running state
5282
5283 TString opt(option), optfb, outfile;
5284 // Enable feedback, if required
5285 if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5286 // Define output file, either from 'opt' or the default one
5287 if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5288
5289 // Resolve query mode
5290 fSync = (GetQueryMode(opt) == kSync);
5291
5292 if (fSync && (!IsIdle() || IsWaiting())) {
5293 // Already queued or processing queries: switch to asynchronous mode
5294 Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5295 fSync = kFALSE;
5296 opt.ReplaceAll("SYNC","");
5297 opt += "ASYN";
5298 }
5299
5300 // Cleanup old temporary datasets
5301 if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5304 }
5305
5306 // deactivate the default application interrupt handler
5307 // ctrl-c's will be forwarded to PROOF to stop the processing
5308 TSignalHandler *sh = 0;
5309 if (fSync) {
5310 if (gApplication)
5312 }
5313
5314 // Make sure we get a fresh result
5316
5317 // Make sure that the workers ready list is empty
5318 if (fWrksOutputReady) {
5321 }
5322
5323 // Make sure the selector path is in the macro path
5324 TProof::AssertMacroPath(selector);
5325
5326 // Reset time measurements
5327 fQuerySTW.Reset();
5328
5329 Long64_t rv = -1;
5330 if (selector && strlen(selector)) {
5331 rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5332 } else if (fSelector) {
5333 rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5334 } else {
5335 Error("Process", "neither a selecrot file nor a selector object have"
5336 " been specified: cannot process!");
5337 }
5338
5339 // This is the end of merging
5340 fQuerySTW.Stop();
5341 Float_t rt = fQuerySTW.RealTime();
5342 // Update the query content
5344 if (qr) {
5345 qr->SetTermTime(rt);
5347 }
5348
5349 // Disable feedback, if required
5350 if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5351 // Finalise output file settings (opt is ignored in here)
5352 if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5353
5354 // Retrieve status from the output list
5355 if (rv >= 0) {
5357 (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5358 if (sst) rv = sst->GetVal();
5359 }
5360
5361 if (fSync) {
5362 // reactivate the default application interrupt handler
5363 if (sh)
5365 // Save the performance info, if required
5366 if (!fPerfTree.IsNull()) {
5367 if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5368 // Must be re-enabled each time
5369 SetPerfTree(0);
5370 }
5371 }
5372
5373 return rv;
5374}
5375
5376////////////////////////////////////////////////////////////////////////////////
5377/// Process a data set (TFileCollection) using the specified selector (.C) file
5378/// or TSelector object.
5379/// The default tree is analyzed (i.e. the first one found). To specify another
5380/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5381/// The return value is -1 in case of error and TSelector::GetStatus() in
5382/// in case of success.
5383
5386{
5387 if (!IsValid() || !fPlayer) return -1;
5388
5389 if (fProtocol < 17) {
5390 Info("Process", "server version < 5.18/00:"
5391 " processing of TFileCollection not supported");
5392 return -1;
5393 }
5394
5395 // We include the TFileCollection to the input list and we create a
5396 // fake TDSet with infor about it
5397 TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5399
5400
5401 Long64_t retval = -1;
5402 if (selector && strlen(selector)) {
5403 retval = Process(dset, selector, option, nentries, first);
5404 } else if (fSelector) {
5405 retval = Process(dset, fSelector, option, nentries, first);
5406 } else {
5407 Error("Process", "neither a selecrot file nor a selector object have"
5408 " been specified: cannot process!");
5409 }
5410 fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5411
5412 // Cleanup
5413 if (IsLite() && !fSync) {
5414 if (!fRunningDSets) fRunningDSets = new TList;
5415 fRunningDSets->Add(dset);
5416 } else {
5417 delete dset;
5418 }
5419
5420 return retval;
5421}
5422
5423////////////////////////////////////////////////////////////////////////////////
5424/// Process a dataset which is stored on the master with name 'dsetname'.
5425/// The syntax for dsetname is name[#[dir/]objname], e.g.
5426/// "mydset" analysis of the first tree in the top dir of the dataset
5427/// named "mydset"
5428/// "mydset#T" analysis tree "T" in the top dir of the dataset
5429/// named "mydset"
5430/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5431/// named "mydset"
5432/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5433/// dataset named "mydset"
5434/// The component 'name' in its more general form contains also the group and
5435/// user name following "/<group>/<user>/<dsname>". Each of these components
5436/// can contain one or more wildcards '*', in which case all the datasets matching
5437/// the expression are added together as a global dataset (wildcard support has
5438/// been added in version 5.27/02).
5439/// The last argument 'elist' specifies an entry- or event-list to be used as
5440/// event selection.
5441/// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5442/// at once in a more flexible way that the one provided by wildcarding. There
5443/// are three possibilities:
5444/// 1) specifying the dataset names separated by the OR operator '|', e.g.
5445/// dsetname = "<dset1>|<dset2>|<dset3>|..."
5446/// in this case the datasets are a seen as a global unique dataset
5447/// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5448/// dsetname = "<dset1>,<dset2> <dset3>,..."
5449/// in this case the datasets are processed one after the other and the
5450/// selector is notified when switching dataset via a bit in the current
5451/// processed element.
5452/// 3) giving the path of a textfile where the dataset names are specified
5453/// on one or multiple lines; the lines found are joined as in 1), unless
5454/// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5455/// with the dataset names listed in 'datasets.txt') in which case they are
5456/// treated as in 2); the file is open in raw mode with TFile::Open and
5457/// therefore it cane be remote, e.g. on a Web server.
5458/// Each <dsetj> has the format specified above for the single dataset processing,
5459/// included wildcarding (the name of the tree and subdirectory must be same for
5460/// all the datasets).
5461/// In the case of multiple datasets, 'elist' is treated a global entry list.
5462/// It is possible to specify per-dataset entry lists using the syntax
5463/// "mydset[#adir/[T]]?enl=entrylist"
5464/// or
5465/// "mydset[#adir/[T]]<<entrylist"
5466/// Here 'entrylist' is a tag identifying, in the order :
5467/// i. a named entry-list in the input list or in the input data list
5468/// ii. a named entry-list in memory (in gDirectory)
5469/// iii. the path of a file containing the entry-list to be used
5470/// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5471/// data list.
5472/// The return value is -1 in case of error and TSelector::GetStatus() in
5473/// in case of success.
5474
5475Long64_t TProof::Process(const char *dsetname, const char *selector,
5476 Option_t *option, Long64_t nentries,
5477 Long64_t first, TObject *elist)
5478{
5479 if (fProtocol < 13) {
5480 Info("Process", "processing 'by name' not supported by the server");
5481 return -1;
5482 }
5483
5484 TString dsname, fname(dsetname);
5485 // If the 'dsetname' corresponds to an existing and readable file we will try to
5486 // interpretate its content as names of datasets to be processed. One line can contain
5487 // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5488 // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5489 // joined with ','.
5490 const char *separator = (fname.EndsWith(",")) ? "," : "|";
5491 if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5492 if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5493 TUrl uf(fname, kTRUE);
5494 uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5495 TFile *f = TFile::Open(uf.GetUrl());
5496 if (f && !(f->IsZombie())) {
5497 const Int_t blen = 8192;
5498 char buf[blen];
5499 Long64_t rest = f->GetSize();
5500 while (rest > 0) {
5501 Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5502 if (f->ReadBuffer(buf, len)) {
5503 Error("Process", "problems reading from file '%s'", fname.Data());
5504 dsname = "";
5505 break;
5506 }
5507 buf[len] = '\0';
5508 dsname += buf;
5509 rest -= len;
5510 }
5511 f->Close();
5512 SafeDelete(f);
5513 // We fail if a failure occured
5514 if (rest > 0) return -1;
5515 } else {
5516 Error("Process", "could not open file '%s'", fname.Data());
5517 return -1;
5518 }
5519 }
5520 if (dsname.IsNull()) {
5521 dsname = dsetname;
5522 } else {
5523 // Remove trailing '\n'
5524 if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5525 // Replace all '\n' with the proper separator
5526 dsname.ReplaceAll("\n", separator);
5527 if (gDebug > 0) {
5528 Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5529 Info("Process", " '%s'", dsname.Data());
5530 }
5531 }
5532
5533 TString names(dsname), name, enl, newname;
5534 // If multi-dataset check if server supports it
5535 if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5536 Info("Process", "multi-dataset processing not supported by the server");
5537 return -1;
5538 }
5539
5540 TEntryList *el = 0;
5541 TString dsobj, dsdir;
5542 Int_t from = 0;
5543 while (names.Tokenize(name, from, "[, |]")) {
5544
5545 newname = name;
5546 // Extract the specific entry-list, if any
5547 enl = "";
5548 Int_t ienl = name.Index("?enl=");
5549 if (ienl == kNPOS) {
5550 ienl = name.Index("<<");
5551 if (ienl != kNPOS) {
5552 newname.Remove(ienl);
5553 ienl += strlen("<<");
5554 }
5555 } else {
5556 newname.Remove(ienl);
5557 ienl += strlen("?enl=");
5558 }
5559
5560 // Check the name syntax first
5561 TString obj, dir("/");
5562 Int_t idxc = newname.Index("#");
5563 if (idxc != kNPOS) {
5564 Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5565 if (idxs != kNPOS) {
5566 obj = newname(idxs+1, newname.Length());
5567 dir = newname(idxc+1, newname.Length());
5568 dir.Remove(dir.Index("/") + 1);
5569 newname.Remove(idxc);
5570 } else {
5571 obj = newname(idxc+1, newname.Length());
5572 newname.Remove(idxc);
5573 }
5574 } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5575 // protection against using ':' instead of '#'
5576 Error("Process", "bad name syntax (%s): please use"
5577 " a '#' after the dataset name", name.Data());
5578 dsname.ReplaceAll(name, "");
5579 continue;
5580 }
5581 if (dsobj.IsNull() && dsdir.IsNull()) {
5582 // The first one specifies obj and dir
5583 dsobj = obj;
5584 dsdir = dir;
5585 } else if (obj != dsobj || dir != dsdir) {
5586 // Inconsistent specification: not supported
5587 Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5588 }
5589 // Process the entry-list name, if any
5590 if (ienl != kNPOS) {
5591 // Get entrylist name or path
5592 enl = name(ienl, name.Length());
5593 el = 0;
5594 TObject *oel = 0;
5595 // If not in the input list ...
5596 TList *inpl = GetInputList();
5597 if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5598 // ... check the heap
5599 if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5600 if ((el = dynamic_cast<TEntryList *>(oel))) {
5601 // Add to the input list (input data not available on master where
5602 // this info will be processed)
5603 if (fProtocol >= 28)
5604 if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5605 }
5606 }
5607 // If not in the heap, check a file, if any
5608 if (!el) {
5609 if (!gSystem->AccessPathName(enl)) {
5610 TFile *f = TFile::Open(enl);
5611 if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5612 TIter nxk(f->GetListOfKeys());
5613 TKey *k = 0;
5614 while ((k = (TKey *) nxk())) {
5615 if (!strcmp(k->GetClassName(), "TEntryList")) {
5616 if (!el) {
5617 if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5618 // Add to the input list (input data not available on master where
5619 // this info will be processed)
5620 if (fProtocol >= 28) {
5621 if (!(inpl->FindObject(el->GetName()))) {
5622 el = (TEntryList *) el->Clone();
5623 AddInput(el);
5624 }
5625 } else {
5626 el = (TEntryList *) el->Clone();
5627 }
5628 }
5629 } else if (strcmp(el->GetName(), k->GetName())) {
5630 Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5631 "if this is not what you want, load first the content in memory"
5632 "and select it by name ", enl.Data());
5633 }
5634 }
5635 }
5636 } else {
5637 Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5638 }
5639 }
5640 }
5641 // Transmit the information
5642 if (fProtocol >= 28) {
5643 newname += "?enl=";
5644 if (el) {
5645 // An entry list object is avalaible in the input list: add its name
5646 newname += el->GetName();
5647 } else {
5648 // The entry list object was not found: send the name, the future entry list manager will
5649 // find it on the server side
5650 newname += enl;
5651 }
5652 }
5653 }
5654 // Adjust the name for this dataset
5655 dsname.ReplaceAll(name, newname);
5656 }
5657
5658 // Create the dataset object
5659 TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5660 // Set entry list
5661 if (el && fProtocol < 28) {
5662 dset->SetEntryList(el);
5663 } else {
5664 dset->SetEntryList(elist);
5665 }
5666 // Run
5667 Long64_t retval = -1;
5668 if (selector && strlen(selector)) {
5669 retval = Process(dset, selector, option, nentries, first);
5670 } else if (fSelector) {
5671 retval = Process(dset, fSelector, option, nentries, first);
5672 } else {
5673 Error("Process", "neither a selector file nor a selector object have"
5674 " been specified: cannot process!");
5675 }
5676 // Cleanup
5677 if (IsLite() && !fSync) {
5678 if (!fRunningDSets) fRunningDSets = new TList;
5679 fRunningDSets->Add(dset);
5680 } else {
5681 delete dset;
5682 }
5683
5684 return retval;
5685}
5686
5687////////////////////////////////////////////////////////////////////////////////
5688/// Generic (non-data based) selector processing: the Process() method of the
5689/// specified selector (.C) or TSelector object is called 'n' times.
5690/// The return value is -1 in case of error and TSelector::GetStatus() in
5691/// in case of success.
5692
5693Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5694{
5695 if (!IsValid()) return -1;
5696
5697 if (fProtocol < 16) {
5698 Info("Process", "server version < 5.17/04: generic processing not supported");
5699 return -1;
5700 }
5701
5702 // Fake data set
5703 TDSet *dset = new TDSet;
5704 dset->SetBit(TDSet::kEmpty);
5705
5706 Long64_t retval = -1;
5707 if (selector && strlen(selector)) {
5708 retval = Process(dset, selector, option, n);
5709 } else if (fSelector) {
5710 retval = Process(dset, fSelector, option, n);
5711 } else {
5712 Error("Process", "neither a selector file nor a selector object have"
5713 " been specified: cannot process!");
5714 }
5715
5716 // Cleanup
5717 if (IsLite() && !fSync) {
5718 if (!fRunningDSets) fRunningDSets = new TList;
5719 fRunningDSets->Add(dset);
5720 } else {
5721 delete dset;
5722 }
5723 return retval;
5724}
5725
5726////////////////////////////////////////////////////////////////////////////////
5727/// Process a data set (TDSet) using the specified selector object.
5728/// Entry- or event-lists should be set in the data set object using
5729/// TDSet::SetEntryList.
5730/// The return value is -1 in case of error and TSelector::GetStatus() in
5731/// in case of success.
5732
5735{
5736 if (fProtocol < 34) {
5737 Error("Process", "server version < 5.33/02:"
5738 "processing by object not supported");
5739 return -1;
5740 }
5741 if (!selector) {
5742 Error("Process", "selector object undefined!");
5743 return -1;
5744 }
5745 fSelector = selector;
5746 Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5747 fSelector = 0;
5748 // Done
5749 return rc;
5750}
5751
5752////////////////////////////////////////////////////////////////////////////////
5753/// Process a data set (TFileCollection) using the specified selector object
5754/// The default tree is analyzed (i.e. the first one found). To specify another
5755/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5756/// The return value is -1 in case of error and TSelector::GetStatus() in
5757/// in case of success.
5758
5761{
5762 if (fProtocol < 34) {
5763 Error("Process", "server version < 5.33/02:"
5764 "processing by object not supported");
5765 return -1;
5766 }
5767 if (!selector) {
5768 Error("Process", "selector object undefined!");
5769 return -1;
5770 }
5771 fSelector = selector;
5772 Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5773 fSelector = 0;
5774 // Done
5775 return rc;
5776}
5777
5778////////////////////////////////////////////////////////////////////////////////
5779/// Process with name of dataset and TSelector object
5780
5781Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5782 Option_t *option, Long64_t nentries,
5783 Long64_t first, TObject *elist)
5784{
5785 if (fProtocol < 34) {
5786 Error("Process", "server version < 5.33/02:"
5787 "processing by object not supported");
5788 return -1;
5789 }
5790 if (!selector) {
5791 Error("Process", "selector object undefined!");
5792 return -1;
5793 }
5794 fSelector = selector;
5795 Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5796 fSelector = 0;
5797 // Done
5798 return rc;
5799}
5800
5801////////////////////////////////////////////////////////////////////////////////
5802/// Generic (non-data based) selector processing: the Process() method of the
5803/// specified selector is called 'n' times.
5804/// The return value is -1 in case of error and TSelector::GetStatus() in
5805/// in case of success.
5806
5808{
5809 if (fProtocol < 34) {
5810 Error("Process", "server version < 5.33/02:"
5811 "processing by object not supported");
5812 return -1;
5813 }
5814 if (!selector) {
5815 Error("Process", "selector object undefined!");
5816 return -1;
5817 }
5818 fSelector = selector;
5819 Long64_t rc = Process((const char*)0, n, option);
5820 fSelector = 0;
5821 // Done
5822 return rc;
5823}
5824
5825////////////////////////////////////////////////////////////////////////////////
5826/// Get reference for the qry-th query in fQueries (as
5827/// displayed by ShowQueries).
5828
5830{
5831 ref = "";
5832 if (qry > 0) {
5833 if (!fQueries)
5835 if (fQueries) {
5836 TIter nxq(fQueries);
5837 TQueryResult *qr = 0;
5838 while ((qr = (TQueryResult *) nxq()))
5839 if (qr->GetSeqNum() == qry) {
5840 ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5841 return 0;
5842 }
5843 }
5844 }
5845 return -1;
5846}
5847
5848////////////////////////////////////////////////////////////////////////////////
5849/// Finalize the qry-th query in fQueries.
5850/// If force, force retrieval if the query is found in the local list
5851/// but has already been finalized (default kFALSE).
5852/// If query < 0, finalize current query.
5853/// Return 0 on success, -1 on error
5854
5856{
5857 if (fPlayer) {
5858 if (qry > 0) {
5859 TString ref;
5860 if (GetQueryReference(qry, ref) == 0) {
5861 return Finalize(ref, force);
5862 } else {
5863 Info("Finalize", "query #%d not found", qry);
5864 }
5865 } else {
5866 // The last query
5867 return Finalize("", force);
5868 }
5869 }
5870 return -1;
5871}
5872
5873////////////////////////////////////////////////////////////////////////////////
5874/// Finalize query with reference ref.
5875/// If force, force retrieval if the query is found in the local list
5876/// but has already been finalized (default kFALSE).
5877/// If ref = 0, finalize current query.
5878/// Return 0 on success, -1 on error
5879
5880Long64_t TProof::Finalize(const char *ref, Bool_t force)
5881{
5882 if (fPlayer) {
5883 // Get the pointer to the query
5884 TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5885 : GetQueryResult();
5887 TString xref(ref);
5888 if (!qr) {
5889 if (!xref.IsNull()) {
5890 retrieve = kTRUE;
5891 }
5892 } else {
5893 if (qr->IsFinalized()) {
5894 if (force) {
5895 retrieve = kTRUE;
5896 } else {
5897 Info("Finalize","query already finalized:"
5898 " use Finalize(<qry>,kTRUE) to force new retrieval");
5899 qr = 0;
5900 }
5901 } else {
5902 retrieve = kTRUE;
5903 xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5904 }
5905 }
5906 if (retrieve) {
5907 Retrieve(xref.Data());
5908 qr = fPlayer->GetQueryResult(xref.Data());
5909 }
5910 if (qr)
5911 return fPlayer->Finalize(qr);
5912 }
5913 return -1;
5914}
5915
5916////////////////////////////////////////////////////////////////////////////////
5917/// Send retrieve request for the qry-th query in fQueries.
5918/// If path is defined save it to path.
5919
5920Int_t TProof::Retrieve(Int_t qry, const char *path)
5921{
5922 if (qry > 0) {
5923 TString ref;
5924 if (GetQueryReference(qry, ref) == 0)
5925 return Retrieve(ref, path);
5926 else
5927 Info("Retrieve", "query #%d not found", qry);
5928 } else {
5929 Info("Retrieve","positive argument required - do nothing");
5930 }
5931 return -1;
5932}
5933
5934////////////////////////////////////////////////////////////////////////////////
5935/// Send retrieve request for the query specified by ref.
5936/// If path is defined save it to path.
5937/// Generic method working for all queries known by the server.
5938
5939Int_t TProof::Retrieve(const char *ref, const char *path)
5940{
5941 if (ref) {
5943 m << TString(ref);
5946
5947 // Archive it locally, if required
5948 if (path) {
5949
5950 // Get pointer to query
5951 TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5952
5953 if (qr) {
5954
5955 TFile *farc = TFile::Open(path,"UPDATE");
5956 if (!farc || (farc && !(farc->IsOpen()))) {
5957 Info("Retrieve", "archive file cannot be open (%s)", path);
5958 return 0;
5959 }
5960 farc->cd();
5961
5962 // Update query status
5963 qr->SetArchived(path);
5964
5965 // Write to file
5966 qr->Write();
5967
5968 farc->Close();
5969 SafeDelete(farc);
5970
5971 } else {
5972 Info("Retrieve", "query not found after retrieve");
5973 return -1;
5974 }
5975 }
5976
5977 return 0;
5978 }
5979 return -1;
5980}
5981
5982////////////////////////////////////////////////////////////////////////////////
5983/// Send remove request for the qry-th query in fQueries.
5984
5986{
5987 if (qry > 0) {
5988 TString ref;
5989 if (GetQueryReference(qry, ref) == 0)
5990 return Remove(ref, all);
5991 else
5992 Info("Remove", "query #%d not found", qry);
5993 } else {
5994 Info("Remove","positive argument required - do nothing");
5995 }
5996 return -1;
5997}
5998
5999////////////////////////////////////////////////////////////////////////////////
6000/// Send remove request for the query specified by ref.
6001/// If all = TRUE remove also local copies of the query, if any.
6002/// Generic method working for all queries known by the server.
6003/// This method can be also used to reset the list of queries
6004/// waiting to be processed: for that purpose use ref == "cleanupqueue".
6005
6006Int_t TProof::Remove(const char *ref, Bool_t all)
6007{
6008 if (all) {
6009 // Remove also local copies, if any
6010 if (fPlayer)
6012 }
6013
6014 if (IsLite()) return 0;
6015
6016 if (ref) {
6018 m << TString(ref);
6021 return 0;
6022 }
6023 return -1;
6024}
6025
6026////////////////////////////////////////////////////////////////////////////////
6027/// Send archive request for the qry-th query in fQueries.
6028
6029Int_t TProof::Archive(Int_t qry, const char *path)
6030{
6031 if (qry > 0) {
6032 TString ref;
6033 if (GetQueryReference(qry, ref) == 0)
6034 return Archive(ref, path);
6035 else
6036 Info("Archive", "query #%d not found", qry);
6037 } else {
6038 Info("Archive","positive argument required - do nothing");
6039 }
6040 return -1;
6041}
6042
6043////////////////////////////////////////////////////////////////////////////////
6044/// Send archive request for the query specified by ref.
6045/// Generic method working for all queries known by the server.
6046/// If ref == "Default", path is understood as a default path for
6047/// archiving.
6048
6049Int_t TProof::Archive(const char *ref, const char *path)
6050{
6051 if (ref) {
6053 m << TString(ref) << TString(path);
6056 return 0;
6057 }
6058 return -1;
6059}
6060
6061////////////////////////////////////////////////////////////////////////////////
6062/// Send cleanup request for the session specified by tag.
6063
6064Int_t TProof::CleanupSession(const char *sessiontag)
6065{
6066 if (sessiontag) {
6068 m << TString(sessiontag);
6071 return 0;
6072 }
6073 return -1;
6074}
6075
6076////////////////////////////////////////////////////////////////////////////////
6077/// Change query running mode to the one specified by 'mode'.
6078
6080{
6081 fQueryMode = mode;
6082
6083 if (gDebug > 0)
6084 Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6085 "Sync" : "Async");
6086}
6087
6088////////////////////////////////////////////////////////////////////////////////
6089/// Find out the query mode based on the current setting and 'mode'.
6090
6092{
6093 EQueryMode qmode = fQueryMode;
6094
6095 if (mode && (strlen(mode) > 0)) {
6096 TString m(mode);
6097 m.ToUpper();
6098 if (m.Contains("ASYN")) {
6099 qmode = kAsync;
6100 } else if (m.Contains("SYNC")) {
6101 qmode = kSync;
6102 }
6103 }
6104
6105 if (gDebug > 0)
6106 Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6107 "Sync" : "Async");
6108
6109 return qmode;
6110}
6111
6112////////////////////////////////////////////////////////////////////////////////
6113/// Execute the specified drawing action on a data set (TDSet).
6114/// Event- or Entry-lists should be set in the data set object using
6115/// TDSet::SetEntryList.
6116/// Returns -1 in case of error or number of selected events otherwise.
6117
6118Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6119 const char *selection, Option_t *option,
6121{
6122 if (!IsValid() || !fPlayer) return -1;
6123
6124 // Make sure that asynchronous processing is not active
6125 if (!IsIdle()) {
6126 Info("DrawSelect","not idle, asynchronous Draw not supported");
6127 return -1;
6128 }
6129 TString opt(option);
6130 Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6131 if (idx != kNPOS)
6132 opt.Replace(idx,4,"");
6133
6134 return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6135}
6136
6137////////////////////////////////////////////////////////////////////////////////
6138/// Execute the specified drawing action on a data set which is stored on the
6139/// master with name 'dsetname'.
6140/// The syntax for dsetname is name[#[dir/]objname], e.g.
6141/// "mydset" analysis of the first tree in the top dir of the dataset
6142/// named "mydset"
6143/// "mydset#T" analysis tree "T" in the top dir of the dataset
6144/// named "mydset"
6145/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6146/// named "mydset"
6147/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6148/// dataset named "mydset"
6149/// The last argument 'enl' specifies an entry- or event-list to be used as
6150/// event selection.
6151/// The return value is -1 in case of error and TSelector::GetStatus() in
6152/// in case of success.
6153
6154Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6155 const char *selection, Option_t *option,
6157{
6158 if (fProtocol < 13) {
6159 Info("Process", "processing 'by name' not supported by the server");
6160 return -1;
6161 }
6162
6163 TString name(dsetname);
6164 TString obj;
6165 TString dir = "/";
6166 Int_t idxc = name.Index("#");
6167 if (idxc != kNPOS) {
6168 Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6169 if (idxs != kNPOS) {
6170 obj = name(idxs+1, name.Length());
6171 dir = name(idxc+1, name.Length());
6172 dir.Remove(dir.Index("/") + 1);
6173 name.Remove(idxc);
6174 } else {
6175 obj = name(idxc+1, name.Length());
6176 name.Remove(idxc);
6177 }
6178 } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6179 // protection against using ':' instead of '#'
6180 Error("DrawSelect", "bad name syntax (%s): please use"
6181 " a '#' after the dataset name", dsetname);
6182 return -1;
6183 }
6184
6185 TDSet *dset = new TDSet(name, obj, dir);
6186 // Set entry-list, if required
6187 dset->SetEntryList(enl);
6188 Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6189 delete dset;
6190 return retval;
6191}
6192
6193////////////////////////////////////////////////////////////////////////////////
6194/// Send STOPPROCESS message to master and workers.
6195
6197{
6198 PDB(kGlobal,2)
6199 Info("StopProcess","enter %d", abort);
6200
6201 if (!IsValid())
6202 return;
6203
6204 // Flag that we have been stopped
6206 SetRunStatus(rst);
6207
6208 if (fPlayer)
6209 fPlayer->StopProcess(abort, timeout);
6210
6211 // Stop any blocking 'Collect' request; on masters we do this only if
6212 // aborting; when stopping, we still need to receive the results
6213 if (TestBit(TProof::kIsClient) || abort)
6215
6216 if (fSlaves->GetSize() == 0)
6217 return;
6218
6219 // Notify the remote counterpart
6220 TSlave *sl;
6221 TIter next(fSlaves);
6222 while ((sl = (TSlave *)next()))
6223 if (sl->IsValid())
6224 // Ask slave to progate the stop/abort request
6225 sl->StopProcess(abort, timeout);
6226}
6227
6228////////////////////////////////////////////////////////////////////////////////
6229/// Signal to disable related switches
6230
6232{
6233 Emit("DisableGoAsyn()");
6234}
6235
6236////////////////////////////////////////////////////////////////////////////////
6237/// Send GOASYNC message to the master.
6238
6240{
6241 if (!IsValid()) return;
6242
6243 if (GetRemoteProtocol() < 22) {
6244 Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6245 return;
6246 }
6247
6248 if (fSync && !IsIdle()) {
6250 Broadcast(m);
6251 } else {
6252 Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6253 }
6254}
6255
6256////////////////////////////////////////////////////////////////////////////////
6257/// Receive the log file of the slave with socket s.
6258
6260{
6261 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6262 char buf[kMAXBUF];
6263
6264 // If macro saving is enabled prepare macro
6268 }
6269
6270 // Append messages to active logging unit
6271 Int_t fdout = -1;
6272 if (!fLogToWindowOnly) {
6273 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6274 if (fdout < 0) {
6275 Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6276 " will not log msgs", fdout);
6277 return;
6278 }
6279 lseek(fdout, (off_t) 0, SEEK_END);
6280 }
6281
6282 Int_t left, rec, r;
6283 Long_t filesize = 0;
6284
6285 while (filesize < size) {
6286 left = Int_t(size - filesize);
6287 if (left >= kMAXBUF)
6288 left = kMAXBUF-1;
6289 rec = s->RecvRaw(&buf, left);
6290 filesize = (rec > 0) ? (filesize + rec) : filesize;
6292 if (rec > 0) {
6293
6294 char *p = buf;
6295 r = rec;
6296 while (r) {
6297 Int_t w;
6298
6299 w = write(fdout, p, r);
6300
6301 if (w < 0) {
6302 SysError("RecvLogFile", "error writing to unit: %d", fdout);
6303 break;
6304 }
6305 r -= w;
6306 p += w;
6307 }
6308 } else if (rec < 0) {
6309 Error("RecvLogFile", "error during receiving log file");
6310 break;
6311 }
6312 }
6313 if (rec > 0) {
6314 buf[rec] = 0;
6315 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6316 // If macro saving is enabled add to TMacro
6318 }
6319 }
6320
6321 // If idle restore logs to main session window
6323 fRedirLog = kFALSE;
6324}
6325
6326////////////////////////////////////////////////////////////////////////////////
6327/// Notify locally 'msg' to the appropriate units (file, stdout, window)
6328/// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6329
6330void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6331{
6332 // Must have somenthing to notify
6333 Int_t len = 0;
6334 if (!msg || (len = strlen(msg)) <= 0)
6335 return;
6336
6337 // Get suffix length if any
6338 Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6339
6340 // Append messages to active logging unit
6341 Int_t fdout = -1;
6342 if (!fLogToWindowOnly) {
6343 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6344 if (fdout < 0) {
6345 Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6346 " will not notify msgs", fdout);
6347 return;
6348 }
6349 lseek(fdout, (off_t) 0, SEEK_END);
6350 }
6351
6352 if (!fLogToWindowOnly) {
6353 // Write to output unit (stdout or a log file)
6354 if (len > 0) {
6355 char *p = (char *)msg;
6356 Int_t r = len;
6357 while (r) {
6358 Int_t w = write(fdout, p, r);
6359 if (w < 0) {
6360 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6361 break;
6362 }
6363 r -= w;
6364 p += w;
6365 }
6366 // Add a suffix, if requested
6367 if (lsfx > 0)
6368 if (write(fdout, sfx, lsfx) != lsfx)
6369 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6370 }
6371 }
6372 if (len > 0) {
6373 // Publish the message to the separate window (if the latter is missing
6374 // the message will just get lost)
6375 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6376 }
6377
6378 // If idle restore logs to main session window
6379 if (fRedirLog && IsIdle())
6380 fRedirLog = kFALSE;
6381}
6382
6383////////////////////////////////////////////////////////////////////////////////
6384/// Log a message into the appropriate window by emitting a signal.
6385
6386void TProof::LogMessage(const char *msg, Bool_t all)
6387{
6388 PDB(kGlobal,1)
6389 Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6390 all ? "true" : "false");
6391
6392 if (gROOT->IsBatch()) {
6393 PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6394 return;
6395 }
6396
6397 if (msg)
6398 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6399
6400 // Re-position at the beginning of the file, if requested.
6401 // This is used by the dialog when it re-opens the log window to
6402 // provide all the session messages
6403 if (all)
6404 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6405
6406 const Int_t kMAXBUF = 32768;
6407 char buf[kMAXBUF];
6408 Int_t len;
6409 do {
6410 while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6411 TSystem::GetErrno() == EINTR)
6413
6414 if (len < 0) {
6415 Error("LogMessage", "error reading log file");
6416 break;
6417 }
6418
6419 if (len > 0) {
6420 buf[len] = 0;
6421 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6422 }
6423
6424 } while (len > 0);
6425}
6426
6427////////////////////////////////////////////////////////////////////////////////
6428/// Send to all active slaves servers the current slave group size
6429/// and their unique id. Returns number of active slaves.
6430/// Returns -1 in case of error.
6431
6433{
6434 if (!IsValid()) return -1;
6435 if (TestBit(TProof::kIsClient)) return 0;
6436 if (!fSendGroupView) return 0;
6438
6439 TIter next(fActiveSlaves);
6440 TSlave *sl;
6441
6442 int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6443 char str[32];
6444
6445 while ((sl = (TSlave *)next())) {
6446 snprintf(str, 32, "%d %d", cnt, size);
6447 if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6448 MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6449 bad++;
6450 } else
6451 cnt++;
6452 }
6453
6454 // Send the group view again in case there was a change in the
6455 // group size due to a bad slave
6456
6457 if (bad) SendGroupView();
6458
6459 return GetNumberOfActiveSlaves();
6460}
6461
6462////////////////////////////////////////////////////////////////////////////////
6463/// Static method to extract the filename (if any) form a CINT command.
6464/// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6465/// appliable.
6466
6468{
6469 TString s = cmd;
6470 s = s.Strip(TString::kBoth);
6471
6472 if (s.Length() > 0 &&
6473 (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6474 TString file = s(2, s.Length());
6475 TString acm, arg, io;
6476 fn = gSystem->SplitAclicMode(file, acm, arg, io);
6477 if (!fn.IsNull())
6478 return kTRUE;
6479 }
6480
6481 // Not found
6482 return kFALSE;
6483}
6484
6485////////////////////////////////////////////////////////////////////////////////
6486/// Send command to be executed on the PROOF master and/or slaves.
6487/// If plusMaster is kTRUE then exeucte on slaves and master too.
6488/// Command can be any legal command line command. Commands like
6489/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6490/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6491/// succes.
6492
6493Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6494{
6495 return Exec(cmd, kActive, plusMaster);
6496}
6497
6498////////////////////////////////////////////////////////////////////////////////
6499/// Send command to be executed on the PROOF master and/or slaves.
6500/// Command can be any legal command line command. Commands like
6501/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6502/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6503/// succes.
6504
6505Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6506{
6507 if (!IsValid()) return -1;
6508
6509 TString s = cmd;
6510 s = s.Strip(TString::kBoth);
6511
6512 if (!s.Length()) return 0;
6513
6514 // check for macro file and make sure the file is available on all slaves
6515 TString filename;
6516 if (TProof::GetFileInCmd(s.Data(), filename)) {
6517 char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6518 if (fn) {
6519 if (GetNumberOfUniqueSlaves() > 0) {
6520 if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6521 Error("Exec", "file %s could not be transfered", fn);
6522 delete [] fn;
6523 return -1;
6524 }
6525 } else {
6526 TString scmd = s(0,3) + fn;
6527 Int_t n = SendCommand(scmd, list);
6528 delete [] fn;
6529 return n;
6530 }
6531 } else {
6532 Error("Exec", "macro %s not found", filename.Data());
6533 return -1;
6534 }
6535 delete [] fn;
6536 }
6537
6538 if (plusMaster) {
6539 if (IsLite()) {
6540 gROOT->ProcessLine(cmd);
6541 } else {
6542 DeactivateWorker("*");
6543 Int_t res = SendCommand(cmd, list);
6544 ActivateWorker("restore");
6545 if (res < 0)
6546 return res;
6547 }
6548 }
6549 return SendCommand(cmd, list);
6550}
6551
6552////////////////////////////////////////////////////////////////////////////////
6553/// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6554/// Command can be any legal command line command. Commands like
6555/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6556/// to the PROOF cluster.
6557/// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6558/// TMacro, accessible via TMacro::GetMacroLog();
6559/// Returns -1 in case of error, >=0 in case of succes.
6560
6561Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6562{
6563 if (!IsValid()) return -1;
6564
6565 TString s = cmd;
6566 s = s.Strip(TString::kBoth);
6567
6568 if (!s.Length()) return 0;
6569
6570 Int_t res = 0;
6571 if (IsLite()) {
6572 gROOT->ProcessLine(cmd);
6573 } else {
6574 Bool_t oldRedirLog = fRedirLog;
6575 fRedirLog = kTRUE;
6576 // Deactivate all workers
6577 DeactivateWorker("*");
6578 fRedirLog = kFALSE;
6579 // Reactivate the target ones, if needed
6580 if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6581 // Honour log-to-macro-saving settings
6582 Bool_t oldSaveLog = fSaveLogToMacro;
6583 fSaveLogToMacro = logtomacro;
6584 res = SendCommand(cmd, kActive);
6585 fSaveLogToMacro = oldSaveLog;
6586 fRedirLog = kTRUE;
6587 ActivateWorker("restore");
6588 fRedirLog = oldRedirLog;
6589 }
6590 // Done
6591 return res;
6592}
6593
6594////////////////////////////////////////////////////////////////////////////////
6595/// Send command to be executed on the PROOF master and/or slaves.
6596/// Command can be any legal command line command, however commands
6597/// like ".x file.C" or ".L file.C" will not cause the file.C to be
6598/// transfered to the PROOF cluster. In that case use TProof::Exec().
6599/// Returns the status send by the remote server as part of the
6600/// kPROOF_LOGDONE message. Typically this is the return code of the
6601/// command on the remote side. Returns -1 in case of error.
6602
6603Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6604{
6605 if (!IsValid()) return -1;
6606
6607 Broadcast(cmd, kMESS_CINT, list);
6608 Collect(list);
6609
6610 return fStatus;
6611}
6612
6613////////////////////////////////////////////////////////////////////////////////
6614/// Get value of environment variable 'env' on node 'ord'
6615
6616TString TProof::Getenv(const char *env, const char *ord)
6617{
6618 // The command to be executed
6619 TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6620 if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6621 // Get the line
6622 TObjString *os = fMacroLog.GetLineWith("const char");
6623 if (os) {
6624 TString info;
6625 Ssiz_t from = 0;
6626 os->GetString().Tokenize(info, from, "\"");
6627 os->GetString().Tokenize(info, from, "\"");
6628 if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6629 return info;
6630 }
6631 return TString("");
6632}
6633
6634////////////////////////////////////////////////////////////////////////////////
6635/// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6636
6637Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6638{
6639 // The command to be executed
6640 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6641 // Exectute the command saving the logs to macro
6642 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6643 // Get the line
6644 TObjString *os = fMacroLog.GetLineWith("const char");
6645 Int_t rc = -1;
6646 if (os) {
6647 Ssiz_t fst = os->GetString().First('\"');
6648 Ssiz_t lst = os->GetString().Last('\"');
6649 TString info = os->GetString()(fst+1, lst-fst-1);
6650 if (info.IsDigit()) {
6651 env = info.Atoi();
6652 rc = 0;
6653 if (gDebug > 0)
6654 Printf("%s: %d", rcenv, env);
6655 }
6656 }
6657 return rc;
6658}
6659
6660////////////////////////////////////////////////////////////////////////////////
6661/// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6662
6663Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6664{
6665 // The command to be executed
6666 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6667 // Exectute the command saving the logs to macro
6668 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6669 // Get the line
6670 TObjString *os = fMacroLog.GetLineWith("const char");
6671 Int_t rc = -1;
6672 if (os) {
6673 Ssiz_t fst = os->GetString().First('\"');
6674 Ssiz_t lst = os->GetString().Last('\"');
6675 TString info = os->GetString()(fst+1, lst-fst-1);
6676 if (info.IsFloat()) {
6677 env = info.Atof();
6678 rc = 0;
6679 if (gDebug > 0)
6680 Printf("%s: %f", rcenv, env);
6681 }
6682 }
6683 return rc;
6684}
6685
6686////////////////////////////////////////////////////////////////////////////////
6687/// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6688
6689Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6690{
6691 // The command to be executed
6692 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6693 // Exectute the command saving the logs to macro
6694 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6695 // Get the line
6696 TObjString *os = fMacroLog.GetLineWith("const char");
6697 Int_t rc = -1;
6698 if (os) {
6699 Ssiz_t fst = os->GetString().First('\"');
6700 Ssiz_t lst = os->GetString().Last('\"');
6701 env = os->GetString()(fst+1, lst-fst-1);
6702 rc = 0;
6703 if (gDebug > 0)
6704 Printf("%s: %s", rcenv, env.Data());
6705 }
6706 return rc;
6707}
6708
6709////////////////////////////////////////////////////////////////////////////////
6710/// Transfer the current state of the master to the active slave servers.
6711/// The current state includes: the current working directory, etc.
6712/// Returns the number of active slaves. Returns -1 in case of error.
6713
6715{
6716 if (!IsValid()) return -1;
6717
6718 // Go to the new directory, reset the interpreter environment and
6719 // tell slave to delete all objects from its new current directory.
6720 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6721
6722 return GetParallel();
6723}
6724
6725////////////////////////////////////////////////////////////////////////////////
6726/// Transfer the current state of the master to the active slave servers.
6727/// The current state includes: the current working directory, etc.
6728/// Returns the number of active slaves. Returns -1 in case of error.
6729
6731{
6732 if (!IsValid()) return -1;
6733
6734 // Go to the new directory, reset the interpreter environment and
6735 // tell slave to delete all objects from its new current directory.
6736 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6737
6738 return GetParallel();
6739}
6740
6741////////////////////////////////////////////////////////////////////////////////
6742/// Transfer the initial (i.e. current) state of the master to all
6743/// slave servers. Currently the initial state includes: log level.
6744/// Returns the number of active slaves. Returns -1 in case of error.
6745
6747{
6748 if (!IsValid()) return -1;
6749
6751
6752 return GetNumberOfActiveSlaves();
6753}
6754
6755////////////////////////////////////////////////////////////////////////////////
6756/// Check if a file needs to be send to the slave. Use the following
6757/// algorithm:
6758/// - check if file appears in file map
6759/// - if yes, get file's modtime and check against time in map,
6760/// if modtime not same get md5 and compare against md5 in map,
6761/// if not same return kTRUE.
6762/// - if no, get file's md5 and modtime and store in file map, ask
6763/// slave if file exists with specific md5, if yes return kFALSE,
6764/// if no return kTRUE.
6765/// The options 'cpopt' define if to copy things from cache to sandbox and what.
6766/// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6767/// must be set in cpopt; the default is copy everything.
6768/// Returns kTRUE in case file needs to be send, returns kFALSE in case
6769/// file is already on remote node.
6770
6771Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6772{
6773 Bool_t sendto = kFALSE;
6774
6775 // create worker based filename
6776 TString sn = slave->GetName();
6777 sn += ":";
6778 sn += slave->GetOrdinal();
6779 sn += ":";
6780 sn += gSystem->BaseName(file);
6781
6782 // check if file is in map
6783 FileMap_t::const_iterator it;
6784 if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6785 // file in map
6786 MD5Mod_t md = (*it).second;
6787 if (md.fModtime != modtime) {
6789 if (md5) {
6790 if ((*md5) != md.fMD5) {
6791 sendto = kTRUE;
6792 md.fMD5 = *md5;
6793 md.fModtime = modtime;
6794 fFileMap[sn] = md;
6795 // When on the master, the master and/or slaves may share
6796 // their file systems and cache. Therefore always make a
6797 // check for the file. If the file already exists with the
6798 // expected md5 the kPROOF_CHECKFILE command will cause the
6799 // file to be copied from cache to slave sandbox.
6801 sendto = kFALSE;
6803 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6804 slave->GetSocket()->Send(mess);
6805
6806 fCheckFileStatus = 0;
6808 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6809 }
6810 }
6811 delete md5;
6812 } else {
6813 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6814 return kFALSE;
6815 }
6816 }
6817 } else {
6818 // file not in map
6820 MD5Mod_t md;
6821 if (md5) {
6822 md.fMD5 = *md5;
6823 md.fModtime = modtime;
6824 fFileMap[sn] = md;
6825 delete md5;
6826 } else {
6827 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6828 return kFALSE;
6829 }
6831 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6832 slave->GetSocket()->Send(mess);
6833
6834 fCheckFileStatus = 0;
6836 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6837 }
6838
6839 return sendto;
6840}
6841
6842////////////////////////////////////////////////////////////////////////////////
6843/// Send a file to master or slave servers. Returns number of slaves
6844/// the file was sent to, maybe 0 in case master and slaves have the same
6845/// file system image, -1 in case of error.
6846/// If defined, send to worker 'wrk' only.
6847/// If defined, the full path of the remote path will be rfile.
6848/// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6849/// (to copy to the cache on a different name use rfile = "cache:newname").
6850/// The mask 'opt' is an or of ESendFileOpt:
6851///
6852/// kAscii (0x0) if set true ascii file transfer is used
6853/// kBinary (0x1) if set true binary file transfer is used
6854/// kForce (0x2) if not set an attempt is done to find out
6855/// whether the file really needs to be downloaded
6856/// (a valid copy may already exist in the cache
6857/// from a previous run); the bit is set by
6858/// UploadPackage, since the check is done elsewhere.
6859/// kForward (0x4) if set, ask server to forward the file to slave
6860/// or submaster (meaningless for slave servers).
6861/// kCpBin (0x8) Retrieve from the cache the binaries associated
6862/// with the file
6863/// kCp (0x10) Retrieve the files from the cache
6864///
6865
6866Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6867{
6868 if (!IsValid()) return -1;
6869
6870 // Use the active slaves list ...
6871 TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6872 // ... or the specified slave, if any
6873 if (wrk) {
6874 slaves = new TList();
6875 slaves->Add(wrk);
6876 }
6877
6878 if (slaves->GetSize() == 0) return 0;
6879
6880#ifndef R__WIN32
6881 Int_t fd = open(file, O_RDONLY);
6882#else
6883 Int_t fd = open(file, O_RDONLY | O_BINARY);
6884#endif
6885 if (fd < 0) {
6886 SysError("SendFile", "cannot open file %s", file);
6887 return -1;
6888 }
6889
6890 // Get info about the file
6891 Long64_t size = -1;
6892 Long_t id, flags, modtime = 0;
6893 if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6894 Error("SendFile", "cannot stat file %s", file);
6895 close(fd);
6896 return -1;
6897 }
6898 if (size == 0) {
6899 Error("SendFile", "empty file %s", file);
6900 close(fd);
6901 return -1;
6902 }
6903
6904 // Decode options
6905 Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6906 Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6907 Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6908
6909 // Copy options
6910 Int_t cpopt = 0;
6911 if ((opt & kCp)) cpopt |= kCp;
6912 if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6913
6914 const Int_t kMAXBUF = 32768; //16384 //65536;
6915 char buf[kMAXBUF];
6916 Int_t nsl = 0;
6917
6918 TIter next(slaves);
6919 TSlave *sl;
6920 TString fnam(rfile);
6921 if (fnam == "cache") {
6922 fnam += TString::Format(":%s", gSystem->BaseName(file));
6923 } else if (fnam.IsNull()) {
6924 fnam = gSystem->BaseName(file);
6925 }
6926 // List on which we will collect the results
6927 fStatus = 0;
6928 while ((sl = (TSlave *)next())) {
6929 if (!sl->IsValid())
6930 continue;
6931
6932 Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6933 // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6934 // is false. Masters might still need to send the file to newly added
6935 // slaves.
6936 PDB(kPackage,2) {
6937 const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6938 Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6939 file, sl->GetName(), sl->GetOrdinal(), sendto);
6940 }
6941 if (sl->fSlaveType == TSlave::kSlave && !sendto)
6942 continue;
6943 // The value of 'size' is used as flag remotely, so we need to
6944 // reset it to 0 if we are not going to send the file
6945 Long64_t siz = sendto ? size : 0;
6946 snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6947 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6948 MarkBad(sl, "could not send kPROOF_SENDFILE request");
6949 continue;
6950 }
6951
6952 if (sendto) {
6953
6954 lseek(fd, 0, SEEK_SET);
6955
6956 Int_t len;
6957 do {
6958 while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6960
6961 if (len < 0) {
6962 SysError("SendFile", "error reading from file %s", file);
6964 close(fd);
6965 return -1;
6966 }
6967
6968 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6969 SysError("SendFile", "error writing to slave %s:%s (now offline)",
6970 sl->GetName(), sl->GetOrdinal());
6971 MarkBad(sl, "sendraw failure");
6972 sl = 0;
6973 break;
6974 }
6975
6976 } while (len > 0);
6977
6978 nsl++;
6979 }
6980 // Wait for the operation to be done
6981 if (sl)
6983 }
6984
6985 close(fd);
6986
6987 // Cleanup temporary list, if any
6988 if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
6989 SafeDelete(slaves);
6990
6991 // We return failure is at least one unique worker failed
6992 return (fStatus != 0) ? -1 : nsl;
6993}
6994
6995////////////////////////////////////////////////////////////////////////////////
6996/// Sends an object to master and workers and expect them to send back a
6997/// message with the output of its TObject::Print(). Returns -1 on error, the
6998/// number of workers that received the objects on success.
6999
7001{
7002 if (!IsValid() || !obj) return -1;
7003 TMessage mess(kPROOF_ECHO);
7004 mess.WriteObject(obj);
7005 return Broadcast(mess);
7006}
7007
7008////////////////////////////////////////////////////////////////////////////////
7009/// Sends a string to master and workers and expect them to echo it back to
7010/// the client via a message. It is a special case of the generic Echo()
7011/// that works with TObjects. Returns -1 on error, the number of workers that
7012/// received the message on success.
7013
7014Int_t TProof::Echo(const char *str)
7015{
7016 TObjString *os = new TObjString(str);
7017 Int_t rv = Echo(os);
7018 delete os;
7019 return rv;
7020}
7021
7022////////////////////////////////////////////////////////////////////////////////
7023/// Send object to master or slave servers. Returns number of slaves object
7024/// was sent to, -1 in case of error.
7025
7027{
7028 if (!IsValid() || !obj) return -1;
7029
7030 TMessage mess(kMESS_OBJECT);
7031
7032 mess.WriteObject(obj);
7033 return Broadcast(mess, list);
7034}
7035
7036////////////////////////////////////////////////////////////////////////////////
7037/// Send print command to master server. Returns number of slaves message
7038/// was sent to. Returns -1 in case of error.
7039
7041{
7042 if (!IsValid()) return -1;
7043
7044 Broadcast(option, kPROOF_PRINT, kActive);
7046}
7047
7048////////////////////////////////////////////////////////////////////////////////
7049/// Set server logging level.
7050
7052{
7053 char str[32];
7054 fLogLevel = level;
7055 gProofDebugLevel = level;
7057 snprintf(str, 32, "%d %u", level, mask);
7059}
7060
7061////////////////////////////////////////////////////////////////////////////////
7062/// Switch ON/OFF the real-time logging facility. When this option is
7063/// ON, log messages from processing are sent back as they come, instead of
7064/// being sent back at the end in one go. This may help debugging or monitoring
7065/// in some cases, but, depending on the amount of log, it may have significant
7066/// consequencies on the load over the network, so it must be used with care.
7067
7069{
7070 if (IsValid()) {
7072 mess << on;
7073 Broadcast(mess);
7074 } else {
7075 Warning("SetRealTimeLog","session is invalid - do nothing");
7076 }
7077}
7078
7079////////////////////////////////////////////////////////////////////////////////
7080/// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7081/// selection is done (if nodes is less than the available nodes).
7082/// Returns the number of parallel slaves. Returns -1 in case of error.
7083
7085{
7086 if (!IsValid()) return -1;
7087
7089 if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7090 return SendCurrentState();
7091 } else {
7092 if (nodes < 0) {
7093 PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7094 } else {
7095 PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7096 nodes == 1 ? "" : "s");
7097 }
7099 mess << nodes << random;
7100 Broadcast(mess);
7102 Int_t n = GetParallel();
7103 PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7104 return n;
7105 }
7106}
7107
7108////////////////////////////////////////////////////////////////////////////////
7109/// Tell PROOF how many slaves to use in parallel. Returns the number of
7110/// parallel slaves. Returns -1 in case of error.
7111
7113{
7114 // If delayed startup reset settings, if required
7115 if (fDynamicStartup && nodes < 0) {
7116 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7117 }
7118
7119 Int_t n = SetParallelSilent(nodes, random);
7121 if (n < 1) {
7122 Printf("PROOF set to sequential mode");
7123 } else {
7124 TString subfix = (n == 1) ? "" : "s";
7125 if (random)
7126 subfix += ", randomly selected";
7127 Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7128 }
7129 } else if (fDynamicStartup && nodes >= 0) {
7130 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7131 gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7132 }
7133 return n;
7134}
7135
7136////////////////////////////////////////////////////////////////////////////////
7137/// Add nWorkersToAdd workers to current list of workers. This function is
7138/// works on the master only, and only when an analysis is ongoing. A message
7139/// is sent back to the client when we go "more" parallel.
7140/// Returns -1 on error, number of total (not added!) workers on success.
7141
7143{
7144 if (!IsValid() || !IsMaster() || IsIdle()) {
7145 Error("GoMoreParallel", "can't invoke here -- should not happen!");
7146 return -1;
7147 }
7148 if (!gProofServ && !IsLite()) {
7149 Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7150 return -1;
7151 }
7152
7153 TSlave *sl = 0x0;
7154 TIter next( fSlaves );
7155 Int_t nAddedWorkers = 0;
7156
7157 while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7158 (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7159
7160 // If worker is of an invalid type, break everything: it should not happen!
7161 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7162 (sl->GetSlaveType() != TSlave::kMaster)) {
7163 Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7164 sl->GetName(), sl->GetOrdinal());
7165 R__ASSERT(0);
7166 }
7167
7168 // Skip current worker if it is not a good candidate
7169 if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7170 (strcmp("IGNORE", sl->GetImage()) == 0)) {
7171 PDB(kGlobal, 2)
7172 Info("GoMoreParallel", "Worker %s:%s won't be considered",
7173 sl->GetName(), sl->GetOrdinal());
7174 continue;
7175 }
7176
7177 // Worker is good but it is already active: skip it
7178 if (fActiveSlaves->FindObject(sl)) {
7179 Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7180 sl->GetName(), sl->GetOrdinal());
7181 continue;
7182 }
7183
7184 //
7185 // From here on: worker is a good candidate
7186 //
7187
7188 if (sl->GetSlaveType() == TSlave::kSlave) {
7190 fActiveSlaves->Add(sl);
7193 nAddedWorkers++;
7194 PDB(kGlobal, 2)
7195 Info("GoMoreParallel", "Worker %s:%s marked as active!",
7196 sl->GetName(), sl->GetOrdinal());
7197 }
7198 else {
7199 // Can't add masters dynamically: this should not happen!
7200 Error("GoMoreParallel", "Dynamic addition of master is not supported");
7201 R__ASSERT(0);
7202 }
7203
7204 } // end loop over all slaves
7205
7206 // Get slave status (will set the slaves fWorkDir correctly)
7207 PDB(kGlobal, 3)
7208 Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7209 AskStatistics();
7210
7211 // Find active slaves with unique image
7212 PDB(kGlobal, 3)
7213 Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7215
7216 // Send new group-view to slaves
7217 PDB(kGlobal, 3)
7218 Info("GoMoreParallel", "Will invoke SendGroupView()");
7219 SendGroupView();
7220
7221 PDB(kGlobal, 3)
7222 Info("GoMoreParallel", "Will invoke GetParallel()");
7223 Int_t nTotalWorkers = GetParallel();
7224
7225 // Notify the client that we've got more workers, and print info on
7226 // Master's log as well
7227 TString s;
7228 s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7229 nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7230 nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7232 Info("GoMoreParallel", "%s", s.Data());
7233
7234 return nTotalWorkers;
7235}
7236
7237////////////////////////////////////////////////////////////////////////////////
7238/// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7239/// list is sorted by slave performace the active list will contain first
7240/// the most performant nodes. Returns the number of active slaves.
7241/// If random is TRUE, and nodes is less than the number of available workers,
7242/// a random selection is done.
7243/// Returns -1 in case of error.
7244
7246{
7247 if (!IsValid()) return -1;
7248
7251
7252 // Prepare the list of candidates first.
7253 // Algorithm depends on random option.
7254 TSlave *sl = 0;
7255 TList *wlst = new TList;
7256 TIter nxt(fSlaves);
7258 while ((sl = (TSlave *)nxt())) {
7259 if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7260 if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7261 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7262 (sl->GetSlaveType() != TSlave::kMaster)) {
7263 Error("GoParallel", "TSlave is neither Master nor Slave");
7264 R__ASSERT(0);
7265 }
7266 // Good candidate
7267 wlst->Add(sl);
7268 // Set it inactive
7269 fInactiveSlaves->Add(sl);
7271 }
7272 }
7273 Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7274 int cnt = 0;
7276 while (cnt < nwrks) {
7277 // Random choice, if requested
7278 if (random) {
7279 Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7280 sl = (TSlave *) wlst->At(iwrk);
7281 } else {
7282 // The first available
7283 sl = (TSlave *) wlst->First();
7284 }
7285 if (!sl) {
7286 Error("GoParallel", "attaching to candidate!");
7287 break;
7288 }
7289 // Remove from the list
7290 wlst->Remove(sl);
7291
7292 Int_t slavenodes = 0;
7293 if (sl->GetSlaveType() == TSlave::kSlave) {
7295 fActiveSlaves->Add(sl);
7298 slavenodes = 1;
7299 } else if (sl->GetSlaveType() == TSlave::kMaster) {
7302 if (!attach) {
7303 Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7304 mess << nn;
7305 } else {
7306 // To get the number of slaves
7307 mess.SetWhat(kPROOF_LOGFILE);
7308 mess << -1 << -1;
7309 }
7310 if (sl->GetSocket()->Send(mess) == -1) {
7311 MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7312 slavenodes = 0;
7313 } else {
7315 if (sl->IsValid()) {
7317 fActiveSlaves->Add(sl);
7320 if (sl->GetParallel() > 0) {
7321 slavenodes = sl->GetParallel();
7322 } else {
7323 // Sequential mode: the master acts as a worker
7324 slavenodes = 1;
7325 }
7326 } else {
7327 MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7328 slavenodes = 0;
7329 }
7330 }
7331 }
7332 // 'slavenodes' may be different than 1 in multimaster setups
7333 cnt += slavenodes;
7334 }
7335
7336 // Cleanup list
7337 wlst->SetOwner(0);
7338 SafeDelete(wlst);
7339
7340 // Get slave status (will set the slaves fWorkDir correctly)
7341 AskStatistics();
7342
7343 // Find active slaves with unique image
7345
7346 // Send new group-view to slaves
7347 if (!attach)
7348 SendGroupView();
7349
7350 Int_t n = GetParallel();
7351
7353 if (n < 1)
7354 printf("PROOF set to sequential mode\n");
7355 else
7356 printf("PROOF set to parallel mode (%d worker%s)\n",
7357 n, n == 1 ? "" : "s");
7358 }
7359
7360 PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7361 return n;
7362}
7363
7364////////////////////////////////////////////////////////////////////////////////
7365/// List contents of the data directory in the sandbox.
7366/// This is the place where files produced by the client queries are kept
7367
7369{
7370 if (!IsValid() || !fManager) return;
7371
7372 // This is run via the manager
7373 fManager->Find("~/data", "-type f", "all");
7374}
7375
7376////////////////////////////////////////////////////////////////////////////////
7377/// Remove files for the data directory.
7378/// The option 'what' can take the values:
7379/// kPurge remove all files and directories under '~/data'
7380/// kUnregistered remove only files not in registered datasets (default)
7381/// kDataset remove files belonging to dataset 'dsname'
7382/// User is prompt for confirmation, unless kForceClear is ORed with the option
7383
7384void TProof::ClearData(UInt_t what, const char *dsname)
7385{
7386 if (!IsValid() || !fManager) return;
7387
7388 // Check whether we need to prompt
7389 TString prompt, a("Y");
7390 Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7391 Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7392
7393 // If all just send the request
7394 if ((what & TProof::kPurge)) {
7395 // Prompt, if requested
7396 if (doask && !Prompt("Do you really want to remove all data files")) return;
7397 if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7398 Warning("ClearData", "problems purging data directory");
7399 return;
7400 } else if ((what & TProof::kDataset)) {
7401 // We must have got a name
7402 if (!dsname || strlen(dsname) <= 0) {
7403 Error("ClearData", "dataset name mandatory when removing a full dataset");
7404 return;
7405 }
7406 // Check if the dataset is registered
7407 if (!ExistsDataSet(dsname)) {
7408 Error("ClearData", "dataset '%s' does not exists", dsname);
7409 return;
7410 }
7411 // Get the file content
7412 TFileCollection *fc = GetDataSet(dsname);
7413 if (!fc) {
7414 Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7415 return;
7416 }
7417 // Prompt, if requested
7418 TString pmpt = TString::Format("Do you really want to remove all data files"
7419 " of dataset '%s'", dsname);
7420 if (doask && !Prompt(pmpt.Data())) return;
7421
7422 // Loop through the files
7423 Bool_t rmds = kTRUE;
7424 TIter nxf(fc->GetList());
7425 TFileInfo *fi = 0;
7426 Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7427 while ((fi = (TFileInfo *) nxf())) {
7428 // Fill the host info
7429 TString host, file;
7430 // Take info from the current url
7431 if (!(fi->GetFirstUrl())) {
7432 Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7433 fi->GetName());
7434 continue;
7435 }
7436 TUrl uf(*(fi->GetFirstUrl()));
7437 file = uf.GetFile();
7438 host = uf.GetHost();
7439 // Now search for any "file:" url
7440 Int_t nurl = fi->GetNUrls();
7441 fi->ResetUrl();
7442 TUrl *up = 0;
7443 while (nurl-- && fi->NextUrl()) {
7444 up = fi->GetCurrentUrl();
7445 if (!strcmp(up->GetProtocol(), "file")) {
7446 TString opt(up->GetOptions());
7447 if (opt.BeginsWith("node=")) {
7448 host=opt;
7449 host.ReplaceAll("node=","");
7450 file = up->GetFile();
7451 break;
7452 }
7453 }
7454 }
7455 // Issue a remove request now
7456 if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7457 Error("ClearData", "problems removing '%s'", file.Data());
7458 // Some files not removed: keep the meta info about this dataset
7459 rmds = kFALSE;
7460 }
7461 rfiles++;
7462 ClearDataProgress(rfiles, nfiles);
7463 }
7464 fprintf(stderr, "\n");
7465 if (rmds) {
7466 // All files were removed successfully: remove also the dataset meta info
7467 RemoveDataSet(dsname);
7468 }
7469 } else if (what & TProof::kUnregistered) {
7470
7471 // Get the existing files
7472 TString outtmp("ProofClearData_");
7473 FILE *ftmp = gSystem->TempFileName(outtmp);
7474 if (!ftmp) {
7475 Error("ClearData", "cannot create temp file for logs");
7476 return;
7477 }
7478 fclose(ftmp);
7480 gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7481 ShowData();
7482 gSystem->RedirectOutput(0, 0, &h);
7483 // Parse the output file now
7484 std::ifstream in;
7485 in.open(outtmp.Data());
7486 if (!in.is_open()) {
7487 Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7488 gSystem->Unlink(outtmp);
7489 return;
7490 }
7491 // Go through
7492 Int_t nfiles = 0;
7493 TMap *afmap = new TMap;
7494 TString line, host, file;
7495 Int_t from = 0;
7496 while (in.good()) {
7497 line.ReadLine(in);
7498 if (line.IsNull()) continue;
7499 while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7500 from = 0;
7501 host = "";
7502 if (!line.Tokenize(host, from, "| ")) continue;
7503 file = "";
7504 if (!line.Tokenize(file, from, "| ")) continue;
7505 if (!host.IsNull() && !file.IsNull()) {
7506 TList *fl = (TList *) afmap->GetValue(host.Data());
7507 if (!fl) {
7508 fl = new TList();
7509 fl->SetName(host);
7510 afmap->Add(new TObjString(host), fl);
7511 }
7512 fl->Add(new TObjString(file));
7513 nfiles++;
7514 PDB(kDataset,2)
7515 Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7516 } else {
7517 Warning("ClearData", "found incomplete line: '%s'", line.Data());
7518 }
7519 }
7520 // Close and remove the file
7521 in.close();
7522 gSystem->Unlink(outtmp);
7523
7524 // Get registered data files
7525 TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7526 TMap *fcmap = GetDataSets(sel);
7527 if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7528 PDB(kDataset,1)
7529 Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7530 SafeDelete(fcmap);
7531 }
7532
7533 // Go thorugh and prepare the lists per node
7534 TString opt;
7535 TObjString *os = 0;
7536 if (fcmap) {
7537 TIter nxfc(fcmap);
7538 while ((os = (TObjString *) nxfc())) {
7539 TFileCollection *fc = 0;
7540 if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7541 TFileInfo *fi = 0;
7542 TIter nxfi(fc->GetList());
7543 while ((fi = (TFileInfo *) nxfi())) {
7544 // Get special "file:" url
7545 fi->ResetUrl();
7546 Int_t nurl = fi->GetNUrls();
7547 TUrl *up = 0;
7548 while (nurl-- && fi->NextUrl()) {
7549 up = fi->GetCurrentUrl();
7550 if (!strcmp(up->GetProtocol(), "file")) {
7551 opt = up->GetOptions();
7552 if (opt.BeginsWith("node=")) {
7553 host=opt;
7554 host.ReplaceAll("node=","");
7555 file = up->GetFile();
7556 PDB(kDataset,2)
7557 Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7558 // Remove this from the full list, if there
7559 TList *fl = (TList *) afmap->GetValue(host.Data());
7560 if (fl) {
7561 TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7562 if (fn) {
7563 fl->Remove(fn);
7564 SafeDelete(fn);
7565 nfiles--;
7566 } else {
7567 Warning("ClearData",
7568 "registered file '%s' not found in the full list!",
7569 file.Data());
7570 }
7571 }
7572 break;
7573 }
7574 }
7575 }
7576 }
7577 }
7578 }
7579 // Clean up the the received map
7580 if (fcmap) fcmap->SetOwner(kTRUE);
7581 SafeDelete(fcmap);
7582 }
7583 // List of the files to be removed
7584 Info("ClearData", "%d unregistered files to be removed:", nfiles);
7585 afmap->Print();
7586 // Prompt, if requested
7587 TString pmpt = TString::Format("Do you really want to remove all %d"
7588 " unregistered data files", nfiles);
7589 if (doask && !Prompt(pmpt.Data())) return;
7590
7591 // Remove one by one; we may implement a bloc remove in the future
7592 Int_t rfiles = 0;
7593 TIter nxls(afmap);
7594 while ((os = (TObjString *) nxls())) {
7595 TList *fl = 0;
7596 if ((fl = (TList *) afmap->GetValue(os))) {
7597 TIter nxf(fl);
7598 TObjString *fn = 0;
7599 while ((fn = (TObjString *) nxf())) {
7600 // Issue a remove request now
7601 if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7602 Error("ClearData", "problems removing '%s' on host '%s'",
7603 fn->GetName(), os->GetName());
7604 }
7605 rfiles++;
7606 ClearDataProgress(rfiles, nfiles);
7607 }
7608 }
7609 }
7610 fprintf(stderr, "\n");
7611 // Final cleanup
7612 afmap->SetOwner(kTRUE);
7613 SafeDelete(afmap);
7614 }
7615}
7616
7617////////////////////////////////////////////////////////////////////////////////
7618/// Prompt the question 'p' requiring an answer y,Y,n,N
7619/// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7620
7622{
7623 TString pp(p);
7624 if (!pp.Contains("?")) pp += "?";
7625 if (!pp.Contains("[y/N]")) pp += " [y/N]";
7626 TString a = Getline(pp.Data());
7627 if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7628 Printf("Please answer y, Y, n or N");
7629 // Unclear answer: assume negative
7630 return kFALSE;
7631 } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7632 // Explicitly Negative answer
7633 return kFALSE;
7634 }
7635 // Explicitly Positive answer
7636 return kTRUE;
7637}
7638
7639////////////////////////////////////////////////////////////////////////////////
7640/// Progress bar for clear data
7641
7643{
7644 fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7645 for (Int_t l = 0; l < 20; l++) {
7646 if (r > 0 && t > 0) {
7647 if (l < 20*r/t)
7648 fprintf(stderr, "=");
7649 else if (l == 20*r/t)
7650 fprintf(stderr, ">");
7651 else if (l > 20*r/t)
7652 fprintf(stderr, ".");
7653 } else
7654 fprintf(stderr, "=");
7655 }
7656 fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7657}
7658
7659////////////////////////////////////////////////////////////////////////////////
7660/// List contents of file cache. If all is true show all caches also on
7661/// slaves. If everything is ok all caches are to be the same.
7662
7664{
7665 if (!IsValid()) return;
7666
7667 TMessage mess(kPROOF_CACHE);
7668 mess << Int_t(kShowCache) << all;
7669 Broadcast(mess, kUnique);
7670
7671 if (all) {
7672 TMessage mess2(kPROOF_CACHE);
7673 mess2 << Int_t(kShowSubCache) << all;
7675
7677 } else {
7679 }
7680}
7681
7682////////////////////////////////////////////////////////////////////////////////
7683/// Remove file from all file caches. If file is 0 or "" or "*", remove all
7684/// the files
7685
7686void TProof::ClearCache(const char *file)
7687{
7688 if (!IsValid()) return;
7689
7690 TMessage mess(kPROOF_CACHE);
7691 mess << Int_t(kClearCache) << TString(file);
7692 Broadcast(mess, kUnique);
7693
7694 TMessage mess2(kPROOF_CACHE);
7695 mess2 << Int_t(kClearSubCache) << TString(file);
7697
7699
7700 // clear file map so files get send again to remote nodes
7701 fFileMap.clear();
7702}
7703
7704////////////////////////////////////////////////////////////////////////////////
7705/// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7706
7707void TProof::SystemCmd(const char *cmd, Int_t fdout)
7708{
7709 if (fdout < 0) {
7710 // Exec directly the command
7711 gSystem->Exec(cmd);
7712 } else {
7713 // Exec via a pipe
7714 FILE *fin = gSystem->OpenPipe(cmd, "r");
7715 if (fin) {
7716 // Now we go
7717 char line[2048];
7718 while (fgets(line, 2048, fin)) {
7719 Int_t r = strlen(line);
7720 if (r > 0) {
7721 if (write(fdout, line, r) < 0) {
7722 ::Warning("TProof::SystemCmd",
7723 "errno %d writing to file descriptor %d",
7724 TSystem::GetErrno(), fdout);
7725 }
7726 } else {
7727 // Done
7728 break;
7729 }
7730 }
7731 gSystem->ClosePipe(fin);
7732 }
7733 }
7734}
7735
7736////////////////////////////////////////////////////////////////////////////////
7737/// List contents of package directory. If all is true show all package
7738/// directories also on slaves. If everything is ok all package directories
7739/// should be the same. If redir is kTRUE the result is redirected to the log
7740/// file (option available for internal actions).
7741
7743{
7744 if (!IsValid()) return;
7745
7746 Bool_t oldredir = fRedirLog;
7747 if (redirlog) fRedirLog = kTRUE;
7748
7749 // Active logging unit
7750 FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7751 if (!fout) {
7752 Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7753 " will not log msgs", fout);
7754 return;
7755 }
7756 lseek(fileno(fout), (off_t) 0, SEEK_END);
7757
7759 fPackMgr->Show();
7760 }
7761
7762 // Nothing more to do if we are a Lite-session
7763 if (IsLite()) {
7764 fRedirLog = oldredir;
7765 return;
7766 }
7767
7768 TMessage mess(kPROOF_CACHE);
7769 mess << Int_t(kShowPackages) << all;
7770 Broadcast(mess, kUnique);
7771
7772 if (all) {
7773 TMessage mess2(kPROOF_CACHE);
7774 mess2 << Int_t(kShowSubPackages) << all;
7776
7778 } else {
7780 }
7781 // Restore logging option
7782 fRedirLog = oldredir;
7783}
7784
7785////////////////////////////////////////////////////////////////////////////////
7786/// List which packages are enabled. If all is true show enabled packages
7787/// for all active slaves. If everything is ok all active slaves should
7788/// have the same packages enabled.
7789
7791{
7792 if (!IsValid()) return;
7793
7795 fPackMgr->ShowEnabled(TString::Format("*** Enabled packages on client on %s\n",
7796 gSystem->HostName()));
7797 }
7798
7799 // Nothing more to do if we are a Lite-session
7800 if (IsLite()) return;
7801
7802 TMessage mess(kPROOF_CACHE);
7803 mess << Int_t(kShowEnabledPackages) << all;
7804 Broadcast(mess);
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809/// Remove all packages.
7810/// Returns 0 in case of success and -1 in case of error.
7811
7813{
7814 if (!IsValid()) return -1;
7815
7816 if (UnloadPackages() == -1)
7817 return -1;
7818
7819 if (DisablePackages() == -1)
7820 return -1;
7821
7822 return fStatus;
7823}
7824
7825////////////////////////////////////////////////////////////////////////////////
7826/// Remove a specific package.
7827/// Returns 0 in case of success and -1 in case of error.
7828
7829Int_t TProof::ClearPackage(const char *package)
7830{
7831 if (!IsValid()) return -1;
7832
7833 if (!package || !package[0]) {
7834 Error("ClearPackage", "need to specify a package name");
7835 return -1;
7836 }
7837
7838 // if name, erroneously, is a par pathname strip off .par and path
7839 TString pac = package;
7840 if (pac.EndsWith(".par"))
7841 pac.Remove(pac.Length()-4);
7842 pac = gSystem->BaseName(pac);
7843
7844 if (UnloadPackage(pac) == -1)
7845 return -1;
7846
7847 if (DisablePackage(pac) == -1)
7848 return -1;
7849
7850 return fStatus;
7851}
7852
7853////////////////////////////////////////////////////////////////////////////////
7854/// Remove a specific package.
7855/// Returns 0 in case of success and -1 in case of error.
7856
7858{
7859 if (!IsValid()) return -1;
7860
7861 if (!pack || strlen(pack) <= 0) {
7862 Error("DisablePackage", "need to specify a package name");
7863 return -1;
7864 }
7865
7866 // if name, erroneously, is a par pathname strip off .par and path
7867 TString pac = pack;
7868 if (pac.EndsWith(".par"))
7869 pac.Remove(pac.Length()-4);
7870 pac = gSystem->BaseName(pac);
7871
7872 if (fPackMgr->Remove(pack) < 0)
7873 Warning("DisablePackage", "problem removing locally package '%s'", pack);
7874
7875 // Nothing more to do if we are a Lite-session
7876 if (IsLite()) return 0;
7877
7878 Int_t st = -1;
7879 Bool_t done = kFALSE;
7880 if (fManager) {
7881 // Try to do it via XROOTD (new way)
7882 TString path;
7883 path.Form("~/packages/%s", pack);
7884 if (fManager->Rm(path, "-rf", "all") != -1) {
7885 path.Append(".par");
7886 if (fManager->Rm(path, "-f", "all") != -1) {
7887 done = kTRUE;
7888 st = 0;
7889 }
7890 }
7891 }
7892 if (!done) {
7893 // Try via TProofServ (old way)
7894 TMessage mess(kPROOF_CACHE);
7895 mess << Int_t(kDisablePackage) << pac;
7896 Broadcast(mess, kUnique);
7897
7898 TMessage mess2(kPROOF_CACHE);
7899 mess2 << Int_t(kDisableSubPackage) << pac;
7901
7903 st = fStatus;
7904 }
7905
7906 // Done
7907 return st;
7908}
7909
7910////////////////////////////////////////////////////////////////////////////////
7911/// Remove all packages.
7912/// Returns 0 in case of success and -1 in case of error.
7913
7915{
7916 if (!IsValid()) return -1;
7917
7918 // remove all packages on client
7919 if (fPackMgr->Remove(nullptr) < 0)
7920 Warning("DisablePackages", "problem removing packages locally");
7921
7922 // Nothing more to do if we are a Lite-session
7923 if (IsLite()) return 0;
7924
7925 Int_t st = -1;
7926 Bool_t done = kFALSE;
7927 if (fManager) {
7928 // Try to do it via XROOTD (new way)
7929 if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
7930 done = kTRUE;
7931 st = 0;
7932 }
7933 }
7934 if (!done) {
7935
7936 TMessage mess(kPROOF_CACHE);
7937 mess << Int_t(kDisablePackages);
7938 Broadcast(mess, kUnique);
7939
7940 TMessage mess2(kPROOF_CACHE);
7941 mess2 << Int_t(kDisableSubPackages);
7943
7945 st = fStatus;
7946 }
7947
7948 // Done
7949 return st;
7950}
7951
7952////////////////////////////////////////////////////////////////////////////////
7953/// Build specified package. Executes the PROOF-INF/BUILD.sh
7954/// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
7955/// then submit build command to slaves, but don't wait
7956/// for results. If opt is kCollectBuildResults then collect result
7957/// from slaves. To be used on the master.
7958/// If opt = kBuildAll (default) then submit and wait for results
7959/// (to be used on the client).
7960/// Returns 0 in case of success and -1 in case of error.
7961
7962Int_t TProof::BuildPackage(const char *package,
7963 EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
7964{
7965 if (!IsValid()) return -1;
7966
7967 if (!package || !package[0]) {
7968 Error("BuildPackage", "need to specify a package name");
7969 return -1;
7970 }
7971
7972 // if name, erroneously, is a par pathname strip off .par and path
7973 TString pac = package;
7974 if (pac.EndsWith(".par"))
7975 pac.Remove(pac.Length()-4);
7976 pac = gSystem->BaseName(pac);
7977
7978 Bool_t buildOnClient = kTRUE;
7979 if (opt == kDontBuildOnClient) {
7980 buildOnClient = kFALSE;
7981 opt = kBuildAll;
7982 }
7983 // Prepare the local package
7984 TString pdir;
7985 Int_t st = 0;
7986
7987 if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
7988 if (workers) {
7989 TMessage mess(kPROOF_CACHE);
7990 mess << Int_t(kBuildPackage) << pac << chkveropt;
7991 Broadcast(mess, workers);
7992
7993 } else {
7994 TMessage mess(kPROOF_CACHE);
7995 mess << Int_t(kBuildPackage) << pac << chkveropt;
7996 Broadcast(mess, kUnique);
7997
7998 TMessage mess2(kPROOF_CACHE);
7999 mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8001 }
8002 }
8003
8004 if (opt >= kBuildAll) {
8005 // by first forwarding the build commands to the master and slaves
8006 // and only then building locally we build in parallel
8007 if (buildOnClient) {
8008 st = fPackMgr->Build(pac, chkveropt);
8009 }
8010
8011
8012 fStatus = 0;
8013 if (!IsLite() || !buildOnClient) {
8014
8015 // On the master, workers that fail are deactivated
8016 // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8017 if (workers) {
8018// Collect(workers, -1, -1, deactivateOnFailure);
8019 Collect(workers);
8020 } else {
8022 }
8023 }
8024
8025 if (fStatus < 0 || st < 0)
8026 return -1;
8027 }
8028
8029 return 0;
8030}
8031
8032////////////////////////////////////////////////////////////////////////////////
8033/// Load specified package. Executes the PROOF-INF/SETUP.C script
8034/// on all active nodes. If notOnClient = true, don't load package
8035/// on the client. The default is to load the package also on the client.
8036/// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8037/// The objects in the list must be streamable; the SETUP macro will be executed
8038/// like this: SETUP.C(loadopts).
8039/// Returns 0 in case of success and -1 in case of error.
8040
8041Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8042 TList *loadopts, TList *workers)
8043{
8044 if (!IsValid()) return -1;
8045
8046 if (!package || !package[0]) {
8047 Error("LoadPackage", "need to specify a package name");
8048 return -1;
8049 }
8050
8051 // if name, erroneously, is a par pathname strip off .par and path
8052 TString pac = package;
8053 if (pac.EndsWith(".par"))
8054 pac.Remove(pac.Length()-4);
8055 pac = gSystem->BaseName(pac);
8056
8057 if (!notOnClient && TestBit(TProof::kIsClient))
8058 if (fPackMgr->Load(package, loadopts) == -1) return -1;
8059
8060 TMessage mess(kPROOF_CACHE);
8061 mess << Int_t(kLoadPackage) << pac;
8062 if (loadopts) mess << loadopts;
8063
8064 // On the master, workers that fail are deactivated
8065 Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8066
8067 Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8068
8069 if (workers) {
8070 PDB(kPackage, 3)
8071 Info("LoadPackage", "Sending load message to selected workers only");
8072 Broadcast(mess, workers);
8073 if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8074 } else {
8075 Broadcast(mess);
8076 Collect(kActive, -1, -1, deactivateOnFailure);
8077 }
8078
8079 return fStatus;
8080}
8081
8082////////////////////////////////////////////////////////////////////////////////
8083/// Unload specified package.
8084/// Returns 0 in case of success and -1 in case of error.
8085
8086Int_t TProof::UnloadPackage(const char *package)
8087{
8088 if (!IsValid()) return -1;
8089
8090 if (!package || !package[0]) {
8091 Error("UnloadPackage", "need to specify a package name");
8092 return -1;
8093 }
8094
8095 // if name, erroneously, is a par pathname strip off .par and path
8096 TString pac = package;
8097 if (pac.EndsWith(".par"))
8098 pac.Remove(pac.Length()-4);
8099 pac = gSystem->BaseName(pac);
8100
8101 if (fPackMgr->Unload(package) < 0)
8102 Warning("UnloadPackage", "unable to remove symlink to %s", package);
8103
8104 // Nothing more to do if we are a Lite-session
8105 if (IsLite()) return 0;
8106
8107 TMessage mess(kPROOF_CACHE);
8108 mess << Int_t(kUnloadPackage) << pac;
8109 Broadcast(mess);
8110 Collect();
8111
8112 return fStatus;
8113}
8114
8115////////////////////////////////////////////////////////////////////////////////
8116/// Unload all packages.
8117/// Returns 0 in case of success and -1 in case of error.
8118
8120{
8121 if (!IsValid()) return -1;
8122
8124 if (fPackMgr->Unload(0) < 0) return -1;
8125 }
8126
8127 // Nothing more to do if we are a Lite-session
8128 if (IsLite()) return 0;
8129
8130 TMessage mess(kPROOF_CACHE);
8131 mess << Int_t(kUnloadPackages);
8132 Broadcast(mess);
8133 Collect();
8134
8135 return fStatus;
8136}
8137
8138////////////////////////////////////////////////////////////////////////////////
8139/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8140/// script if it exists followed by the PROOF-INF/SETUP.C script.
8141/// In case notOnClient = true, don't enable the package on the client.
8142/// The default is to enable packages also on the client.
8143/// If specified, enables packages only on the specified workers.
8144/// Returns 0 in case of success and -1 in case of error.
8145/// Provided for backward compatibility.
8146
8147Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8148 TList *workers)
8149{
8150 return EnablePackage(package, (TList *)0, notOnClient, workers);
8151}
8152
8153////////////////////////////////////////////////////////////////////////////////
8154/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8155/// script if it exists followed by the PROOF-INF/SETUP.C script.
8156/// In case notOnClient = true, don't enable the package on the client.
8157/// The default is to enable packages also on the client.
8158/// It is is possible to specify options for the loading step via 'loadopts';
8159/// the string will be passed passed as argument to SETUP.
8160/// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8161/// plugin version checking during building: possible choices are:
8162/// off no check; failure may occur at loading
8163/// on check ROOT version [default]
8164/// svn check ROOT version and Git commit SHA1.
8165/// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8166/// If specified, enables packages only on the specified workers.
8167/// Returns 0 in case of success and -1 in case of error.
8168
8169Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8170 Bool_t notOnClient, TList *workers)
8171{
8172 TList *optls = 0;
8173 if (loadopts && strlen(loadopts)) {
8174 if (fProtocol > 28) {
8175 TObjString *os = new TObjString(loadopts);
8176 // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8177 os->String().ReplaceAll("checkversion=", "chkv=");
8178 Ssiz_t fcv = kNPOS, lcv = kNPOS;
8179 if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8180 TRegexp re("[; |]");
8181 if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8182 lcv = os->String().Length();
8183 }
8184 TString ocv = os->String()(fcv, lcv - fcv);
8185 Int_t cvopt = -1;
8186 if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8187 cvopt = (Int_t) TPackMgr::kDontCheck;
8188 else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8189 cvopt = (Int_t) TPackMgr::kCheckROOT;
8190 else
8191 Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8192 if (cvopt > -1) {
8193 if (gDebug > 0)
8194 Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8195 optls = new TList;
8196 optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8197 // Remove the special option from; we leave a separator if there were two (one before and one after)
8198 if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8199 if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8200 os->String().ReplaceAll(ocv.Data(), "");
8201 }
8202 }
8203 if (!os->String().IsNull()) {
8204 if (!optls) optls = new TList;
8205 optls->Add(new TObjString(os->String().Data()));
8206 }
8207 if (optls) optls->SetOwner(kTRUE);
8208 } else {
8209 // Notify
8210 Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8211 }
8212 }
8213 // Run
8214 Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8215 // Clean up
8216 SafeDelete(optls);
8217 // Done
8218 return rc;
8219}
8220
8221////////////////////////////////////////////////////////////////////////////////
8222/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8223/// script if it exists followed by the PROOF-INF/SETUP.C script.
8224/// In case notOnClient = true, don't enable the package on the client.
8225/// The default is to enable packages also on the client.
8226/// It is is possible to specify a list of objects to be passed to the SETUP
8227/// functions via 'loadopts'; the objects must be streamable.
8228/// Returns 0 in case of success and -1 in case of error.
8229
8230Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8231 Bool_t notOnClient, TList *workers)
8232{
8233 if (!IsValid()) return -1;
8234
8235 if (!package || !package[0]) {
8236 Error("EnablePackage", "need to specify a package name");
8237 return -1;
8238 }
8239
8240 // if name, erroneously, is a par pathname strip off .par and path
8241 TString pac = package;
8242 if (pac.EndsWith(".par"))
8243 pac.Remove(pac.Length()-4);
8244 pac = gSystem->BaseName(pac);
8245
8247 if (notOnClient)
8248 opt = kDontBuildOnClient;
8249
8250 // Get check version option; user settings have priority
8251 Int_t chkveropt = TPackMgr::kCheckROOT;
8252 TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8253 if (!ocv.IsNull()) {
8254 if (ocv == "off" || ocv == "0")
8255 chkveropt = (Int_t) TPackMgr::kDontCheck;
8256 else if (ocv == "on" || ocv == "1")
8257 chkveropt = (Int_t) TPackMgr::kCheckROOT;
8258 else
8259 Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8260 }
8261 if (loadopts) {
8262 TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8263 if (pcv) {
8264 chkveropt = pcv->GetVal();
8265 loadopts->Remove(pcv);
8266 delete pcv;
8267 }
8268 }
8269 if (gDebug > 0)
8270 Info("EnablePackage", "using check version option: %d", chkveropt);
8271
8272 if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8273 return -1;
8274
8275 TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8276 if (optls && fProtocol <= 28) {
8277 Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8278 optls = 0;
8279 }
8280
8281 if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8282 return -1;
8283
8284 // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8288 }
8290 TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8291 : new TPair(new TObjString(pac), 0);
8293 }
8294
8295 return 0;
8296}
8297
8298////////////////////////////////////////////////////////////////////////////////
8299/// Download a PROOF archive (PAR file) from the master package repository.
8300/// The PAR file is downloaded in the current directory or in the directory
8301/// specified by 'dstdir'. If a package with the same name already exists
8302/// at destination, a check on the MD5 sum is done and the user warned or
8303/// prompted for action, depending is the file is equal or different.
8304/// Returns 0 in case of success and -1 in case of error.
8305
8306Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8307{
8308 if (!fManager || !(fManager->IsValid())) {
8309 Error("DownloadPackage", "the manager is undefined!");
8310 return -1;
8311 }
8312
8313 // Create the default source and destination paths
8314 TString parname(gSystem->BaseName(pack)), src, dst;
8315 if (!parname.EndsWith(".par")) parname += ".par";
8316 src.Form("packages/%s", parname.Data());
8317 if (!dstdir || strlen(dstdir) <= 0) {
8318 dst.Form("./%s", parname.Data());
8319 } else {
8320 // Check the destination directory
8321 FileStat_t st;
8322 if (gSystem->GetPathInfo(dstdir, st) != 0) {
8323 // Directory does not exit: create it
8324 if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8325 Error("DownloadPackage",
8326 "could not create the destination directory '%s' (errno: %d)",
8327 dstdir, TSystem::GetErrno());
8328 return -1;
8329 }
8330 } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8331 Error("DownloadPackage",
8332 "destination path '%s' exist but is not a directory!", dstdir);
8333 return -1;
8334 }
8335 dst.Form("%s/%s", dstdir, parname.Data());
8336 }
8337
8338 // Make sure the source file exists
8339 FileStat_t stsrc;
8341 if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8342 Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8343 Int_t rc = fManager->Stat(src, stsrc);
8344 if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8345 Warning("DownloadPackage", "problems restoring output");
8346 if (rc != 0) {
8347 // Check if there is another possible source
8349 TMacro *mp = GetLastLog();
8350 if (mp) {
8351 // Look for global directories
8352 Bool_t isGlobal = kFALSE;
8353 TIter nxl(mp->GetListOfLines());
8354 TObjString *os = 0;
8355 TString globaldir;
8356 while ((os = (TObjString *) nxl())) {
8357 TString s(os->GetName());
8358 if (s.Contains("*** Global Package cache")) {
8359 // Get the directory
8360 s.Remove(0, s.Last(':') + 1);
8361 s.Remove(s.Last(' '));
8362 globaldir = s;
8363 isGlobal = kTRUE;
8364 } else if (s.Contains("*** Package cache")) {
8365 isGlobal = kFALSE;
8366 globaldir = "";
8367 }
8368 // Check for the package
8369 if (isGlobal && s.Contains(parname)) {
8370 src.Form("%s/%s", globaldir.Data(), parname.Data());
8371 break;
8372 }
8373 }
8374 // Cleanup
8375 delete mp;
8376 }
8377 }
8378
8379 // Do it via the manager
8380 if (fManager->GetFile(src, dst, "silent") != 0) {
8381 Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8382 pack, src.Data(), dst.Data());
8383 return -1;
8384 } else {
8385 Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8386 pack, dst.Data());
8387 }
8388 // Done
8389 return 0;
8390}
8391
8392////////////////////////////////////////////////////////////////////////////////
8393/// Upload a PROOF archive (PAR file). A PAR file is a compressed
8394/// tar file with one special additional directory, PROOF-INF
8395/// (blatantly copied from Java's jar format). It must have the extension
8396/// .par. A PAR file can be directly a binary or a source with a build
8397/// procedure. In the PROOF-INF directory there can be a build script:
8398/// BUILD.sh to be called to build the package, in case of a binary PAR
8399/// file don't specify a build script or make it a no-op. Then there is
8400/// SETUP.C which sets the right environment variables to use the package,
8401/// like LD_LIBRARY_PATH, etc.
8402/// The 'opt' allows to specify whether the .PAR should be just unpacked
8403/// in the existing dir (opt = kUntar, default) or a remove of the existing
8404/// directory should be executed (opt = kRemoveOld), so triggering a full
8405/// re-build. The option if effective only for PROOF protocol > 8 .
8406/// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8407/// an alternative global directory for global usage. This may require special
8408/// privileges.
8409/// If download is kTRUE and the package is not found locally, then it is downloaded
8410/// from the master repository.
8411/// Returns 0 in case of success and -1 in case of error.
8412
8414 TList *workers)
8415{
8416 if (!IsValid()) return -1;
8417
8418 // Remote PAR ?
8420 Bool_t remotepar = (ft == TFile::kWeb || ft == TFile::kNet) ? kTRUE : kFALSE;
8421
8422 TString par(pack), base, name;
8423 if (par.EndsWith(".par")) {
8424 base = gSystem->BaseName(par);
8425 name = base(0, base.Length() - strlen(".par"));
8426 } else {
8427 name = gSystem->BaseName(par);
8428 base.Form("%s.par", name.Data());
8429 par += ".par";
8430 }
8431
8432 // Default location is the local working dir; then the package dir
8433 gSystem->ExpandPathName(par);
8435 Int_t xrc = -1;
8436 if (!remotepar) xrc = TPackMgr::FindParPath(fPackMgr, name, par);
8437 if (xrc == 0) {
8438 // Package is in the global dirs
8439 if (gDebug > 0)
8440 Info("UploadPackage", "global package found (%s): no upload needed",
8441 par.Data());
8442 return 0;
8443 } else if (xrc < 0) {
8444 Error("UploadPackage", "PAR file '%s' not found", par.Data());
8445 return -1;
8446 }
8447 }
8448
8449 // Strategy:
8450 // On the client:
8451 // get md5 of package and check if it is different
8452 // from the one stored in the local package directory. If it is lock
8453 // the package directory and copy the package, unlock the directory.
8454 // On the masters:
8455 // get md5 of package and check if it is different from the
8456 // one stored on the remote node. If it is different lock the remote
8457 // package directory and use TFTP or SendFile to ftp the package to the
8458 // remote node, unlock the directory.
8459
8460
8462 Bool_t rmold = (opt == TProof::kRemoveOld) ? kTRUE : kFALSE;
8463 if (fPackMgr->Install(par, rmold) < 0) {
8464 Error("UploadPackage", "installing '%s' failed", gSystem->BaseName(par));
8465 return -1;
8466 }
8467 }
8468
8469 // Nothing more to do if we are a Lite-session
8470 if (IsLite()) return 0;
8471
8472 TMD5 *md5 = fPackMgr->ReadMD5(name);
8473
8474 TString smsg;
8475 if (remotepar && GetRemoteProtocol() > 36) {
8476 smsg.Form("+%s", par.Data());
8477 } else {
8478 smsg.Form("+%s", base.Data());
8479 }
8480
8482 mess << smsg << (*md5);
8484 smsg.Replace(0, 1, "-");
8485 mess2 << smsg << (*md5);
8487 smsg.Replace(0, 1, "=");
8488 mess3 << smsg << (*md5);
8489
8490 delete md5;
8491
8492 if (fProtocol > 8) {
8493 // Send also the option
8494 mess << (UInt_t) opt;
8495 mess2 << (UInt_t) opt;
8496 mess3 << (UInt_t) opt;
8497 }
8498
8499 // Loop over all slaves with unique fs image, or to a selected
8500 // list of workers, if specified
8501 if (!workers)
8502 workers = fUniqueSlaves;
8503 TIter next(workers);
8504 TSlave *sl = 0;
8505 while ((sl = (TSlave *) next())) {
8506 if (!sl->IsValid())
8507 continue;
8508
8509 sl->GetSocket()->Send(mess);
8510
8511 fCheckFileStatus = 0;
8513 if (fCheckFileStatus == 0) {
8514
8515 if (fProtocol > 5) {
8516 // remote directory is locked, upload file over the open channel
8517 smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
8518 if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
8519 Error("UploadPackage", "%s: problems uploading file %s",
8520 sl->GetOrdinal(), par.Data());
8521 return -1;
8522 }
8523 } else {
8524 // old servers receive it via TFTP
8525 TFTP ftp(TString("root://")+sl->GetName(), 1);
8526 if (!ftp.IsZombie()) {
8527 smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
8528 ftp.cd(smsg.Data());
8529 ftp.put(par, base.Data());
8530 }
8531 }
8532
8533 // install package and unlock dir
8534 sl->GetSocket()->Send(mess2);
8535 fCheckFileStatus = 0;
8537 if (fCheckFileStatus == 0) {
8538 Error("UploadPackage", "%s: unpacking of package %s failed",
8539 sl->GetOrdinal(), base.Data());
8540 return -1;
8541 }
8542 }
8543 }
8544
8545 // loop over all other master nodes
8546 TIter nextmaster(fNonUniqueMasters);
8547 TSlave *ma;
8548 while ((ma = (TSlave *) nextmaster())) {
8549 if (!ma->IsValid())
8550 continue;
8551
8552 ma->GetSocket()->Send(mess3);
8553
8554 fCheckFileStatus = 0;
8556 if (fCheckFileStatus == 0) {
8557 // error -> package should have been found
8558 Error("UploadPackage", "package %s did not exist on submaster %s",
8559 base.Data(), ma->GetOrdinal());
8560 return -1;
8561 }
8562 }
8563
8564 return 0;
8565}
8566
8567
8568////////////////////////////////////////////////////////////////////////////////
8569/// Make sure that the directory path contained by macro is in the macro path
8570
8571void TProof::AssertMacroPath(const char *macro)
8572{
8573 static TString macrop(gROOT->GetMacroPath());
8574 if (macro && strlen(macro) > 0) {
8575 TString dirn(gSystem->DirName(macro));
8576 if (!macrop.Contains(dirn)) {
8577 macrop += TString::Format("%s:", dirn.Data());
8578 gROOT->SetMacroPath(macrop);
8579 }
8580 }
8581}
8582
8583
8584////////////////////////////////////////////////////////////////////////////////
8585/// Load the specified macro on master, workers and, if notOnClient is
8586/// kFALSE, on the client. The macro file is uploaded if new or updated.
8587/// Additional files to be uploaded (or updated, if needed) can be specified
8588/// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
8589/// If existing in the same directory, a header basename(macro).h or .hh, is also
8590/// uploaded.
8591/// The default is to load the macro also on the client; notOnClient can be used
8592/// to avoid loading on the client.
8593/// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
8594/// only, and collection is not done; if uniqueWorkers is kFALSE, collection
8595/// from the previous request is done, and broadcasting + collection from the
8596/// other workers is done.
8597/// The wrks arg can be used on the master to limit the set of workers.
8598/// Returns 0 in case of success and -1 in case of error.
8599
8600Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
8601 TList *wrks)
8602{
8603 if (!IsValid()) return -1;
8604
8605 if (!macro || !macro[0]) {
8606 Error("Load", "need to specify a macro name");
8607 return -1;
8608 }
8609
8610 // Make sure the path is in the macro path
8612
8613 if (TestBit(TProof::kIsClient) && !wrks) {
8614
8615 // Extract the file implementation name first
8616 TString addsname, implname = macro;
8617 Ssiz_t icom = implname.Index(",");
8618 if (icom != kNPOS) {
8619 addsname = implname(icom + 1, implname.Length());
8620 implname.Remove(icom);
8621 }
8622 TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
8623 TString bmsg(basemacro), acmode, args, io;
8624 implname = gSystem->SplitAclicMode(implname, acmode, args, io);
8625
8626 // Macro names must have a standard format
8627 Int_t dot = implname.Last('.');
8628 if (dot == kNPOS) {
8629 Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
8630 return -1;
8631 }
8632
8633 // Is there any associated header file
8634 Bool_t hasHeader = kTRUE;
8635 TString headname = implname;
8636 headname.Remove(dot);
8637 headname += ".h";
8638 if (gSystem->AccessPathName(headname, kReadPermission)) {
8639 TString h = headname;
8640 headname.Remove(dot);
8641 headname += ".hh";
8642 if (gSystem->AccessPathName(headname, kReadPermission)) {
8643 hasHeader = kFALSE;
8644 if (gDebug > 0)
8645 Info("Load", "no associated header file found: tried: %s %s",
8646 h.Data(), headname.Data());
8647 }
8648 }
8649
8650 // Is there any additional file ?
8651 TString addincs;
8652 TList addfiles;
8653 if (!addsname.IsNull()) {
8654 TString fn;
8655 Int_t from = 0;
8656 while (addsname.Tokenize(fn, from, ",")) {
8658 Error("Load", "additional file '%s' not found", fn.Data());
8659 return -1;
8660 }
8661 // Create the additional include statement
8662 if (!notOnClient) {
8663 TString dirn(gSystem->DirName(fn));
8664 if (addincs.IsNull()) {
8665 addincs.Form("-I%s", dirn.Data());
8666 } else if (!addincs.Contains(dirn)) {
8667 addincs += TString::Format(" -I%s", dirn.Data());
8668 }
8669 }
8670 // Remember these files ...
8671 addfiles.Add(new TObjString(fn));
8672 }
8673 }
8674
8675 // Send files now; the md5 check is run here; see SendFile for more
8676 // details.
8677 if (SendFile(implname, kAscii | kForward , "cache") == -1) {
8678 Error("Load", "problems sending implementation file %s", implname.Data());
8679 return -1;
8680 }
8681 if (hasHeader)
8682 if (SendFile(headname, kAscii | kForward , "cache") == -1) {
8683 Error("Load", "problems sending header file %s", headname.Data());
8684 return -1;
8685 }
8686 // Additional files
8687 if (addfiles.GetSize() > 0) {
8688 TIter nxfn(&addfiles);
8689 TObjString *os = 0;
8690 while ((os = (TObjString *) nxfn())) {
8691 // These files need to be available everywhere, cache and sandbox
8692 if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
8693 Error("Load", "problems sending additional file %s", os->GetName());
8694 return -1;
8695 }
8696 // Add the base names to the message broadcasted
8697 bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
8698 }
8699 addfiles.SetOwner(kTRUE);
8700 }
8701
8702 // The files are now on the workers: now we send the loading request
8703 TMessage mess(kPROOF_CACHE);
8704 if (GetRemoteProtocol() < 34) {
8705 mess << Int_t(kLoadMacro) << basemacro;
8706 // This may be needed
8707 AddIncludePath("../../cache");
8708 } else {
8709 mess << Int_t(kLoadMacro) << bmsg;
8710 }
8711 Broadcast(mess, kActive);
8712
8713 // Load locally, if required
8714 if (!notOnClient) {
8715 // Mofify the include path
8716 TString oldincs = gSystem->GetIncludePath();
8717 if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
8718
8719 // By first forwarding the load command to the master and workers
8720 // and only then loading locally we load/build in parallel
8721 gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
8722
8723 // Restore include path
8724 if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
8725
8726 // Update the macro path
8728 TString np(gSystem->DirName(macro));
8729 if (!np.IsNull()) {
8730 np += ":";
8731 if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
8732 Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
8733 mp.Insert(ip, np);
8735 if (gDebug > 0)
8736 Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
8737 }
8738 }
8739 }
8740
8741 // Wait for master and workers to be done
8743
8744 if (IsLite()) {
8745 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8746 if (!fLoadedMacros) {
8747 fLoadedMacros = new TList();
8749 }
8750 // if wrks is specified the macro should already be loaded on the master.
8751 fLoadedMacros->Add(new TObjString(macro));
8752 }
8753
8754 } else {
8755 // On master
8756
8757 // The files are now on the workers: now we send the loading request first
8758 // to the unique workers, so that the eventual compilation occurs only once.
8759 TString basemacro = gSystem->BaseName(macro);
8760 TMessage mess(kPROOF_CACHE);
8761
8762 if (uniqueWorkers) {
8763 mess << Int_t(kLoadMacro) << basemacro;
8764 if (wrks) {
8765 Broadcast(mess, wrks);
8766 Collect(wrks);
8767 } else {
8768 Broadcast(mess, kUnique);
8769 }
8770 } else {
8771 // Wait for the result of the previous sending
8773
8774 // We then send a tuned loading request to the other workers
8775 TList others;
8776 TSlave *wrk = 0;
8777 TIter nxw(fActiveSlaves);
8778 while ((wrk = (TSlave *)nxw())) {
8779 if (!fUniqueSlaves->FindObject(wrk)) {
8780 others.Add(wrk);
8781 }
8782 }
8783
8784 // Do not force compilation, if it was requested
8785 Int_t ld = basemacro.Last('.');
8786 if (ld != kNPOS) {
8787 Int_t lpp = basemacro.Index("++", ld);
8788 if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
8789 }
8790 mess << Int_t(kLoadMacro) << basemacro;
8791 Broadcast(mess, &others);
8792 Collect(&others);
8793 }
8794
8795 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8796 if (!fLoadedMacros) {
8797 fLoadedMacros = new TList();
8799 }
8800 // if wrks is specified the macro should already be loaded on the master.
8801 if (!wrks)
8802 fLoadedMacros->Add(new TObjString(macro));
8803 }
8804
8805 // Done
8806 return 0;
8807}
8808
8809////////////////////////////////////////////////////////////////////////////////
8810/// Add 'libpath' to the lib path search.
8811/// Multiple paths can be specified at once separating them with a comma or
8812/// a blank.
8813/// Return 0 on success, -1 otherwise
8814
8815Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
8816 Bool_t doCollect)
8817{
8818 if ((!libpath || !libpath[0])) {
8819 if (gDebug > 0)
8820 Info("AddDynamicPath", "list is empty - nothing to do");
8821 return 0;
8822 }
8823
8824 // Do it also on clients, if required
8825 if (onClient)
8826 HandleLibIncPath("lib", kTRUE, libpath);
8827
8829 m << TString("lib") << (Bool_t)kTRUE;
8830
8831 // Add paths
8832 if (libpath && strlen(libpath)) {
8833 m << TString(libpath);
8834 } else {
8835 m << TString("-");
8836 }
8837
8838 // Tell the server to send back or not
8839 m << (Int_t)doCollect;
8840
8841 // Forward the request
8842 if (wrks) {
8843 Broadcast(m, wrks);
8844 if (doCollect)
8845 Collect(wrks, fCollectTimeout);
8846 } else {
8847 Broadcast(m);
8849 }
8850
8851 return 0;
8852}
8853
8854////////////////////////////////////////////////////////////////////////////////
8855/// Add 'incpath' to the inc path search.
8856/// Multiple paths can be specified at once separating them with a comma or
8857/// a blank.
8858/// Return 0 on success, -1 otherwise
8859
8860Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
8861 Bool_t doCollect)
8862{
8863 if ((!incpath || !incpath[0])) {
8864 if (gDebug > 0)
8865 Info("AddIncludePath", "list is empty - nothing to do");
8866 return 0;
8867 }
8868
8869 // Do it also on clients, if required
8870 if (onClient)
8871 HandleLibIncPath("inc", kTRUE, incpath);
8872
8874 m << TString("inc") << (Bool_t)kTRUE;
8875
8876 // Add paths
8877 if (incpath && strlen(incpath)) {
8878 m << TString(incpath);
8879 } else {
8880 m << TString("-");
8881 }
8882
8883 // Tell the server to send back or not
8884 m << (Int_t)doCollect;
8885
8886 // Forward the request
8887 if (wrks) {
8888 Broadcast(m, wrks);
8889 if (doCollect)
8890 Collect(wrks, fCollectTimeout);
8891 } else {
8892 Broadcast(m);
8894 }
8895
8896 return 0;
8897}
8898
8899////////////////////////////////////////////////////////////////////////////////
8900/// Remove 'libpath' from the lib path search.
8901/// Multiple paths can be specified at once separating them with a comma or
8902/// a blank.
8903/// Return 0 on success, -1 otherwise
8904
8905Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
8906{
8907 if ((!libpath || !libpath[0])) {
8908 if (gDebug > 0)
8909 Info("RemoveDynamicPath", "list is empty - nothing to do");
8910 return 0;
8911 }
8912
8913 // Do it also on clients, if required
8914 if (onClient)
8915 HandleLibIncPath("lib", kFALSE, libpath);
8916
8918 m << TString("lib") <<(Bool_t)kFALSE;
8919
8920 // Add paths
8921 if (libpath && strlen(libpath))
8922 m << TString(libpath);
8923 else
8924 m << TString("-");
8925
8926 // Forward the request
8927 Broadcast(m);
8929
8930 return 0;
8931}
8932
8933////////////////////////////////////////////////////////////////////////////////
8934/// Remove 'incpath' from the inc path search.
8935/// Multiple paths can be specified at once separating them with a comma or
8936/// a blank.
8937/// Return 0 on success, -1 otherwise
8938
8939Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
8940{
8941 if ((!incpath || !incpath[0])) {
8942 if (gDebug > 0)
8943 Info("RemoveIncludePath", "list is empty - nothing to do");
8944 return 0;
8945 }
8946
8947 // Do it also on clients, if required
8948 if (onClient)
8949 HandleLibIncPath("in", kFALSE, incpath);
8950
8952 m << TString("inc") << (Bool_t)kFALSE;
8953
8954 // Add paths
8955 if (incpath && strlen(incpath))
8956 m << TString(incpath);
8957 else
8958 m << TString("-");
8959
8960 // Forward the request
8961 Broadcast(m);
8963
8964 return 0;
8965}
8966
8967////////////////////////////////////////////////////////////////////////////////
8968/// Handle lib, inc search paths modification request
8969
8970void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
8971{
8972 TString type(what);
8973 TString path(dirs);
8974
8975 // Check type of action
8976 if ((type != "lib") && (type != "inc")) {
8977 Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
8978 return;
8979 }
8980
8981 // Separators can be either commas or blanks
8982 path.ReplaceAll(","," ");
8983
8984 // Decompose lists
8985 TObjArray *op = 0;
8986 if (path.Length() > 0 && path != "-") {
8987 if (!(op = path.Tokenize(" "))) {
8988 Warning("HandleLibIncPath","decomposing path %s", path.Data());
8989 return;
8990 }
8991 }
8992
8993 if (add) {
8994
8995 if (type == "lib") {
8996
8997 // Add libs
8998 TIter nxl(op, kIterBackward);
8999 TObjString *lib = 0;
9000 while ((lib = (TObjString *) nxl())) {
9001 // Expand path
9002 TString xlib = lib->GetName();
9003 gSystem->ExpandPathName(xlib);
9004 // Add to the dynamic lib search path if it exists and can be read
9005 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9006 TString newlibpath = gSystem->GetDynamicPath();
9007 // In the first position after the working dir
9008 Int_t pos = 0;
9009 if (newlibpath.BeginsWith(".:"))
9010 pos = 2;
9011 if (newlibpath.Index(xlib) == kNPOS) {
9012 newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9013 gSystem->SetDynamicPath(newlibpath);
9014 }
9015 } else {
9016 if (gDebug > 0)
9017 Info("HandleLibIncPath",
9018 "libpath %s does not exist or cannot be read - not added", xlib.Data());
9019 }
9020 }
9021
9022 } else {
9023
9024 // Add incs
9025 TIter nxi(op);
9026 TObjString *inc = 0;
9027 while ((inc = (TObjString *) nxi())) {
9028 // Expand path
9029 TString xinc = inc->GetName();
9030 gSystem->ExpandPathName(xinc);
9031 // Add to the dynamic lib search path if it exists and can be read
9032 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9033 TString curincpath = gSystem->GetIncludePath();
9034 if (curincpath.Index(xinc) == kNPOS)
9035 gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9036 } else
9037 if (gDebug > 0)
9038 Info("HandleLibIncPath",
9039 "incpath %s does not exist or cannot be read - not added", xinc.Data());
9040 }
9041 }
9042
9043
9044 } else {
9045
9046 if (type == "lib") {
9047
9048 // Remove libs
9049 TIter nxl(op);
9050 TObjString *lib = 0;
9051 while ((lib = (TObjString *) nxl())) {
9052 // Expand path
9053 TString xlib = lib->GetName();
9054 gSystem->ExpandPathName(xlib);
9055 // Remove from the dynamic lib search path
9056 TString newlibpath = gSystem->GetDynamicPath();
9057 newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9058 gSystem->SetDynamicPath(newlibpath);
9059 }
9060
9061 } else {
9062
9063 // Remove incs
9064 TIter nxi(op);
9065 TObjString *inc = 0;
9066 while ((inc = (TObjString *) nxi())) {
9067 TString newincpath = gSystem->GetIncludePath();
9068 newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9069 // Remove the interpreter path (added anyhow internally)
9070 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9071 gSystem->SetIncludePath(newincpath);
9072 }
9073 }
9074 }
9075}
9076
9077////////////////////////////////////////////////////////////////////////////////
9078/// Get from the master the list of names of the packages available.
9079
9081{
9082 if (!IsValid())
9083 return (TList *)0;
9084
9085 TMessage mess(kPROOF_CACHE);
9086 mess << Int_t(kListPackages);
9087 Broadcast(mess);
9089
9090 return fAvailablePackages;
9091}
9092
9093////////////////////////////////////////////////////////////////////////////////
9094/// Get from the master the list of names of the packages enabled.
9095
9097{
9098 if (!IsValid())
9099 return (TList *)0;
9100
9101 TMessage mess(kPROOF_CACHE);
9102 mess << Int_t(kListEnabledPackages);
9103 Broadcast(mess);
9105
9106 return fEnabledPackages;
9107}
9108
9109////////////////////////////////////////////////////////////////////////////////
9110/// Print a progress bar on stderr. Used in batch mode.
9111
9113 Float_t procTime, Long64_t bytesread)
9114{
9115 if (fPrintProgress) {
9116 Bool_t redirlog = fRedirLog;
9117 fRedirLog = kFALSE;
9118 // Call the external function
9119 (*fPrintProgress)(total, processed, procTime, bytesread);
9120 fRedirLog = redirlog;
9121 return;
9122 }
9123
9124 fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9125
9126 for (int l = 0; l < 20; l++) {
9127 if (total > 0) {
9128 if (l < 20*processed/total)
9129 fprintf(stderr, "=");
9130 else if (l == 20*processed/total)
9131 fprintf(stderr, ">");
9132 else if (l > 20*processed/total)
9133 fprintf(stderr, ".");
9134 } else
9135 fprintf(stderr, "=");
9136 }
9137 Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9138 Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9139 TString sunit("B/s");
9140 if (evtrti > 0.) {
9141 Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9142 if (mbsrti > 0.) {
9143 const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9144 if (mbsrti >= toG) {
9145 mbsrti /= toG;
9146 sunit = "GB/s";
9147 } else if (mbsrti >= toM) {
9148 mbsrti /= toM;
9149 sunit = "MB/s";
9150 } else if (mbsrti >= toK) {
9151 mbsrti /= toK;
9152 sunit = "kB/s";
9153 }
9154 fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9155 (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9156 } else {
9157 fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9158 (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9159 }
9160 } else {
9161 fprintf(stderr, "| %.02f %%\r",
9162 (total ? ((100.0*processed)/total) : 100.0));
9163 }
9164 if (processed >= total) {
9165 fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9166 }
9167}
9168
9169////////////////////////////////////////////////////////////////////////////////
9170/// Get query progress information. Connect a slot to this signal
9171/// to track progress.
9172
9174{
9175 if (fPrintProgress) {
9176 // Call the external function
9177 return (*fPrintProgress)(total, processed, -1., -1);
9178 }
9179
9180 PDB(kGlobal,1)
9181 Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9182
9183 if (gROOT->IsBatch()) {
9184 // Simple progress bar
9185 if (total > 0)
9186 PrintProgress(total, processed);
9187 } else {
9188 EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9189 }
9190}
9191
9192////////////////////////////////////////////////////////////////////////////////
9193/// Get query progress information. Connect a slot to this signal
9194/// to track progress.
9195
9197 Float_t initTime, Float_t procTime,
9198 Float_t evtrti, Float_t mbrti)
9199{
9200 PDB(kGlobal,1)
9201 Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9202 initTime, procTime, evtrti, mbrti);
9203
9204 if (gROOT->IsBatch()) {
9205 // Simple progress bar
9206 if (total > 0)
9207 PrintProgress(total, processed, procTime, bytesread);
9208 } else {
9209 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9210 7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9211 }
9212}
9213
9214////////////////////////////////////////////////////////////////////////////////
9215/// Get query progress information. Connect a slot to this signal
9216/// to track progress.
9217
9219 Float_t initTime, Float_t procTime,
9220 Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9221{
9222 PDB(kGlobal,1)
9223 Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9224 initTime, procTime, evtrti, mbrti, actw, eses);
9225
9226 if (gROOT->IsBatch()) {
9227 // Simple progress bar
9228 if (total > 0)
9229 PrintProgress(total, processed, procTime, bytesread);
9230 } else {
9231 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9232 10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9233 }
9234}
9235
9236////////////////////////////////////////////////////////////////////////////////
9237/// Get list of feedback objects. Connect a slot to this signal
9238/// to monitor the feedback object.
9239
9241{
9242 PDB(kGlobal,1)
9243 Info("Feedback","%d objects", objs->GetSize());
9244 PDB(kFeedback,1) {
9245 Info("Feedback","%d objects", objs->GetSize());
9246 objs->ls();
9247 }
9248
9249 Emit("Feedback(TList *objs)", (Long_t) objs);
9250}
9251
9252////////////////////////////////////////////////////////////////////////////////
9253/// Close progress dialog.
9254
9256{
9257 PDB(kGlobal,1)
9258 Info("CloseProgressDialog",
9259 "called: have progress dialog: %d", fProgressDialogStarted);
9260
9261 // Nothing to do if not there
9263 return;
9264
9265 Emit("CloseProgressDialog()");
9266}
9267
9268////////////////////////////////////////////////////////////////////////////////
9269/// Reset progress dialog.
9270
9271void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9272 Long64_t ent)
9273{
9274 PDB(kGlobal,1)
9275 Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9276
9277 EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9278 4, sel, sz, fst, ent);
9279}
9280
9281////////////////////////////////////////////////////////////////////////////////
9282/// Send startup message.
9283
9284void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9285{
9286 PDB(kGlobal,1)
9287 Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9288
9289 EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9290 4, msg, st, done, total);
9291}
9292
9293////////////////////////////////////////////////////////////////////////////////
9294/// Send dataset preparation status.
9295
9296void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9297{
9298 PDB(kGlobal,1)
9299 Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9300
9301 EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9302 4, msg, st, done, total);
9303}
9304
9305////////////////////////////////////////////////////////////////////////////////
9306/// Send or notify data set status
9307
9308void TProof::SendDataSetStatus(const char *action, UInt_t done,
9309 UInt_t tot, Bool_t st)
9310{
9311 if (IsLite()) {
9312 if (tot) {
9313 TString type = "files";
9314 Int_t frac = (Int_t) (done*100.)/tot;
9315 char msg[512] = {0};
9316 if (frac >= 100) {
9317 snprintf(msg, 512, "%s: OK (%d %s) \n",
9318 action,tot, type.Data());
9319 } else {
9320 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9321 action, done, tot, frac);
9322 }
9323 if (fSync)
9324 fprintf(stderr,"%s", msg);
9325 else
9326 NotifyLogMsg(msg, 0);
9327 }
9328 return;
9329 }
9330
9333 mess << TString(action) << tot << done << st;
9334 gProofServ->GetSocket()->Send(mess);
9335 }
9336}
9337
9338////////////////////////////////////////////////////////////////////////////////
9339/// Notify availability of a query result.
9340
9341void TProof::QueryResultReady(const char *ref)
9342{
9343 PDB(kGlobal,1)
9344 Info("QueryResultReady","ref: %s", ref);
9345
9346 Emit("QueryResultReady(const char*)",ref);
9347}
9348
9349////////////////////////////////////////////////////////////////////////////////
9350/// Validate a TDSet.
9351
9353{
9354 if (dset->ElementsValid()) return;
9355
9356 TList nodes;
9357 nodes.SetOwner();
9358
9359 TList slholder;
9360 slholder.SetOwner();
9361 TList elemholder;
9362 elemholder.SetOwner();
9363
9364 // build nodelist with slaves and elements
9365 TIter nextSlave(GetListOfActiveSlaves());
9366 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9367 TList *sllist = 0;
9368 TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9369 if (!p) {
9370 sllist = new TList;
9371 sllist->SetName(sl->GetName());
9372 slholder.Add(sllist);
9373 TList *elemlist = new TList;
9374 elemlist->SetName(TString(sl->GetName())+"_elem");
9375 elemholder.Add(elemlist);
9376 nodes.Add(new TPair(sllist, elemlist));
9377 } else {
9378 sllist = dynamic_cast<TList*>(p->Key());
9379 }
9380 if (sllist) sllist->Add(sl);
9381 }
9382
9383 // add local elements to nodes
9384 TList nonLocal; // list of nonlocal elements
9385 // make two iterations - first add local elements - then distribute nonlocals
9386 for (Int_t i = 0; i < 2; i++) {
9387 Bool_t local = i>0?kFALSE:kTRUE;
9388 TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9389 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9390 if (elem->GetValid()) continue;
9391 TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9392 if (p) {
9393 TList *eli = dynamic_cast<TList*>(p->Value());
9394 TList *sli = dynamic_cast<TList*>(p->Key());
9395 if (eli && sli) {
9396 eli->Add(elem);
9397
9398 // order list by elements/slave
9399 TPair *p2 = p;
9400 Bool_t stop = kFALSE;
9401 while (!stop) {
9402 TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9403 if (p3) {
9404 TList *p3v = dynamic_cast<TList*>(p3->Value());
9405 TList *p3k = dynamic_cast<TList*>(p3->Key());
9406 if (p3v && p3k) {
9407 Int_t nelem = p3v->GetSize();
9408 Int_t nsl = p3k->GetSize();
9409 if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
9410 else stop = kTRUE;
9411 }
9412 } else {
9413 stop = kTRUE;
9414 }
9415 }
9416
9417 if (p2!=p) {
9418 nodes.Remove(p->Key());
9419 nodes.AddAfter(p2->Key(), p);
9420 }
9421 } else {
9422 Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
9423 continue;
9424 }
9425
9426 } else {
9427 if (local) {
9428 nonLocal.Add(elem);
9429 } else {
9430 Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
9431 }
9432 }
9433 }
9434 }
9435
9436 // send to slaves
9437 TList usedslaves;
9438 TIter nextNode(&nodes);
9439 SetDSet(dset); // set dset to be validated in Collect()
9440 while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
9441 TList *slaves = dynamic_cast<TList*>(node->Key());
9442 TList *setelements = dynamic_cast<TList*>(node->Value());
9443 if (!slaves || !setelements) continue;
9444 // distribute elements over the slaves
9445 Int_t nslaves = slaves->GetSize();
9446 Int_t nelements = setelements->GetSize();
9447 for (Int_t i=0; i<nslaves; i++) {
9448
9449 TDSet copyset(dset->GetType(), dset->GetObjName(),
9450 dset->GetDirectory());
9451 for (Int_t j = (i*nelements)/nslaves;
9452 j < ((i+1)*nelements)/nslaves;
9453 j++) {
9454 TDSetElement *elem =
9455 dynamic_cast<TDSetElement*>(setelements->At(j));
9456 if (elem) {
9457 copyset.Add(elem->GetFileName(), elem->GetObjName(),
9458 elem->GetDirectory(), elem->GetFirst(),
9459 elem->GetNum(), elem->GetMsd());
9460 }
9461 }
9462
9463 if (copyset.GetListOfElements()->GetSize()>0) {
9465 mesg << &copyset;
9466
9467 TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
9468 if (sl) {
9469 PDB(kGlobal,1) Info("ValidateDSet",
9470 "Sending TDSet with %d elements to slave %s"
9471 " to be validated",
9472 copyset.GetListOfElements()->GetSize(),
9473 sl->GetOrdinal());
9474 sl->GetSocket()->Send(mesg);
9475 usedslaves.Add(sl);
9476 }
9477 }
9478 }
9479 }
9480
9481 PDB(kGlobal,1)
9482 Info("ValidateDSet","Calling Collect");
9483 Collect(&usedslaves);
9484 SetDSet(0);
9485}
9486
9487////////////////////////////////////////////////////////////////////////////////
9488/// Add data objects that might be needed during the processing of
9489/// the selector (see Process()). This object can be very large, so they
9490/// are distributed in an optimized way using a dedicated file.
9491/// If push is TRUE the input data are sent over even if no apparent change
9492/// occured to the list.
9493
9495{
9496 if (obj) {
9497 if (!fInputData) fInputData = new TList;
9498 if (!fInputData->FindObject(obj)) {
9499 fInputData->Add(obj);
9501 }
9502 }
9503 if (push) SetBit(TProof::kNewInputData);
9504}
9505
9506////////////////////////////////////////////////////////////////////////////////
9507/// Remove obj form the input data list; if obj is null (default), clear the
9508/// input data info.
9509
9511{
9512 if (!obj) {
9513 if (fInputData) {
9516 }
9518
9519 // Also remove any info about input data in the input list
9520 TObject *o = 0;
9521 TList *in = GetInputList();
9522 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9523 in->Remove(o);
9524 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9525 in->Remove(o);
9526
9527 // ... and reset the file
9528 fInputDataFile = "";
9530
9531 } else if (fInputData) {
9532 Int_t sz = fInputData->GetSize();
9533 while (fInputData->FindObject(obj))
9534 fInputData->Remove(obj);
9535 // Flag for update, if anything changed
9536 if (sz != fInputData->GetSize())
9538 }
9539}
9540
9541////////////////////////////////////////////////////////////////////////////////
9542/// Remove obj 'name' form the input data list;
9543
9545{
9546 TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
9547 if (obj) ClearInputData(obj);
9548}
9549
9550////////////////////////////////////////////////////////////////////////////////
9551/// Set the file to be used to optimally distribute the input data objects.
9552/// If the file exists the object in the file are added to those in the
9553/// fInputData list. If the file path is null, a default file will be created
9554/// at the moment of sending the processing request with the content of
9555/// the fInputData list. See also SendInputDataFile.
9556
9557void TProof::SetInputDataFile(const char *datafile)
9558{
9559 if (datafile && strlen(datafile) > 0) {
9560 if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
9562 fInputDataFile = datafile;
9563 } else {
9564 if (!fInputDataFile.IsNull())
9566 fInputDataFile = "";
9567 }
9568 // Make sure that the chosen file is readable
9571 fInputDataFile = "";
9572 }
9573}
9574
9575////////////////////////////////////////////////////////////////////////////////
9576/// Send the input data objects to the master; the objects are taken from the
9577/// dedicated list and / or the specified file.
9578/// If the fInputData is empty the specified file is sent over.
9579/// If there is no specified file, a file named "inputdata.root" is created locally
9580/// with the content of fInputData and sent over to the master.
9581/// If both fInputData and the specified file are not empty, a copy of the file
9582/// is made locally and augmented with the content of fInputData.
9583
9585{
9586 // Prepare the file
9587 TString dataFile;
9588 PrepareInputDataFile(dataFile);
9589
9590 // Send it, if not empty
9591 if (dataFile.Length() > 0) {
9592
9593 Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
9594 BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
9595
9596 // Set the name in the input list
9597 TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
9598 AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
9599 }
9600}
9601
9602////////////////////////////////////////////////////////////////////////////////
9603/// Prepare the file with the input data objects to be sent the master; the
9604/// objects are taken from the dedicated list and / or the specified file.
9605/// If the fInputData is empty the specified file is sent over.
9606/// If there is no specified file, a file named "inputdata.root" is created locally
9607/// with the content of fInputData and sent over to the master.
9608/// If both fInputData and the specified file are not empty, a copy of the file
9609/// is made locally and augmented with the content of fInputData.
9610
9612{
9613 // Save info about new data for usage in this call;
9615 // Next time we need some change
9617
9618 // Check the list
9619 Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
9620 // Check the file
9621 Bool_t file_ok = kFALSE;
9624 // It must contain something
9626 if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
9627 file_ok = kTRUE;
9628 }
9629
9630 // Remove any info about input data in the input list
9631 TObject *o = 0;
9632 TList *in = GetInputList();
9633 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9634 in->Remove(o);
9635 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9636 in->Remove(o);
9637
9638 // We must have something to send
9639 dataFile = "";
9640 if (!list_ok && !file_ok) return;
9641
9642 // Three cases:
9643 if (file_ok && !list_ok) {
9644 // Just send the file
9645 dataFile = fInputDataFile;
9646 } else if (!file_ok && list_ok) {
9648 // Nothing to do, if no new data
9649 if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
9650 // Create the file first
9651 TFile *f = TFile::Open(fInputDataFile, "RECREATE");
9652 if (f) {
9653 f->cd();
9654 TIter next(fInputData);
9655 TObject *obj;
9656 while ((obj = next())) {
9657 obj->Write(0, TObject::kSingleKey, 0);
9658 }
9659 f->Close();
9660 SafeDelete(f);
9661 } else {
9662 Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
9663 return;
9664 }
9665 dataFile = fInputDataFile;
9666 } else if (file_ok && list_ok) {
9667 dataFile = kPROOF_InputDataFile;
9668 // Create the file if not existing or there are new data
9669 if (newdata || gSystem->AccessPathName(dataFile)) {
9670 // Cleanup previous file if obsolete
9671 if (!gSystem->AccessPathName(dataFile))
9672 gSystem->Unlink(dataFile);
9673 if (dataFile != fInputDataFile) {
9674 // Make a local copy first
9675 if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
9676 Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
9677 return;
9678 }
9679 }
9680 // Add the input data list
9681 TFile *f = TFile::Open(dataFile, "UPDATE");
9682 if (f) {
9683 f->cd();
9684 TIter next(fInputData);
9685 TObject *obj = 0;
9686 while ((obj = next())) {
9687 obj->Write(0, TObject::kSingleKey, 0);
9688 }
9689 f->Close();
9690 SafeDelete(f);
9691 } else {
9692 Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
9693 return;
9694 }
9695 }
9696 }
9697
9698 // Done
9699 return;
9700}
9701
9702////////////////////////////////////////////////////////////////////////////////
9703/// Add objects that might be needed during the processing of
9704/// the selector (see Process()).
9705
9707{
9708 if (fPlayer) fPlayer->AddInput(obj);
9709}
9710
9711////////////////////////////////////////////////////////////////////////////////
9712/// Clear input object list.
9713
9715{
9716 if (fPlayer) fPlayer->ClearInput();
9717
9718 // the system feedback list is always in the input list
9720}
9721
9722////////////////////////////////////////////////////////////////////////////////
9723/// Get input list.
9724
9726{
9727 return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
9728}
9729
9730////////////////////////////////////////////////////////////////////////////////
9731/// Get specified object that has been produced during the processing
9732/// (see Process()).
9733
9735{
9736
9738 // Can be called by MarkBad on the master before the player is initialized
9739 return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
9740
9741 // This checks also associated output files
9742 return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
9743}
9744
9745////////////////////////////////////////////////////////////////////////////////
9746/// Find object 'name' in list 'out' or in the files specified in there
9747
9749{
9750 TObject *o = 0;
9751 if (!name || (name && strlen(name) <= 0) ||
9752 !out || (out && out->GetSize() <= 0)) return o;
9753 if ((o = out->FindObject(name))) return o;
9754
9755 // For the time being we always check for all the files; this may require
9756 // some caching
9757 TProofOutputFile *pf = 0;
9758 TIter nxo(out);
9759 while ((o = nxo())) {
9760 if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
9761 TFile *f = 0;
9762 if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
9763 TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
9764 f = TFile::Open(fn.Data());
9765 if (!f || (f && f->IsZombie())) {
9766 ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
9767 }
9768 }
9769 if (f && (o = f->Get(name))) return o;
9770 }
9771 }
9772
9773 // Done, unsuccessfully
9774 return o;
9775}
9776
9777////////////////////////////////////////////////////////////////////////////////
9778/// Get list with all object created during processing (see Process()).
9779
9781{
9782 if (fOutputList.GetSize() > 0) return &fOutputList;
9783 if (fPlayer) {
9785 return &fOutputList;
9786 }
9787 return (TList *)0;
9788}
9789
9790////////////////////////////////////////////////////////////////////////////////
9791/// Set input list parameter. If the parameter is already
9792/// set it will be set to the new value.
9793
9794void TProof::SetParameter(const char *par, const char *value)
9795{
9796 if (!fPlayer) {
9797 Warning("SetParameter", "player undefined! Ignoring");
9798 return;
9799 }
9800
9801 TList *il = fPlayer->GetInputList();
9802 TObject *item = il->FindObject(par);
9803 if (item) {
9804 il->Remove(item);
9805 delete item;
9806 }
9807 il->Add(new TNamed(par, value));
9808}
9809
9810////////////////////////////////////////////////////////////////////////////////
9811/// Set an input list parameter.
9812
9813void TProof::SetParameter(const char *par, Int_t value)
9814{
9815 if (!fPlayer) {
9816 Warning("SetParameter", "player undefined! Ignoring");
9817 return;
9818 }
9819
9820 TList *il = fPlayer->GetInputList();
9821 TObject *item = il->FindObject(par);
9822 if (item) {
9823 il->Remove(item);
9824 delete item;
9825 }
9826 il->Add(new TParameter<Int_t>(par, value));
9827}
9828
9829////////////////////////////////////////////////////////////////////////////////
9830/// Set an input list parameter.
9831
9832void TProof::SetParameter(const char *par, Long_t value)
9833{
9834 if (!fPlayer) {
9835 Warning("SetParameter", "player undefined! Ignoring");
9836 return;
9837 }
9838
9839 TList *il = fPlayer->GetInputList();
9840 TObject *item = il->FindObject(par);
9841 if (item) {
9842 il->Remove(item);
9843 delete item;
9844 }
9845 il->Add(new TParameter<Long_t>(par, value));
9846}
9847
9848////////////////////////////////////////////////////////////////////////////////
9849/// Set an input list parameter.
9850
9851void TProof::SetParameter(const char *par, Long64_t value)
9852{
9853 if (!fPlayer) {
9854 Warning("SetParameter", "player undefined! Ignoring");
9855 return;
9856 }
9857
9858 TList *il = fPlayer->GetInputList();
9859 TObject *item = il->FindObject(par);
9860 if (item) {
9861 il->Remove(item);
9862 delete item;
9863 }
9864 il->Add(new TParameter<Long64_t>(par, value));
9865}
9866
9867////////////////////////////////////////////////////////////////////////////////
9868/// Set an input list parameter.
9869
9870void TProof::SetParameter(const char *par, Double_t value)
9871{
9872 if (!fPlayer) {
9873 Warning("SetParameter", "player undefined! Ignoring");
9874 return;
9875 }
9876
9877 TList *il = fPlayer->GetInputList();
9878 TObject *item = il->FindObject(par);
9879 if (item) {
9880 il->Remove(item);
9881 delete item;
9882 }
9883 il->Add(new TParameter<Double_t>(par, value));
9884}
9885
9886////////////////////////////////////////////////////////////////////////////////
9887/// Get specified parameter. A parameter set via SetParameter() is either
9888/// a TParameter or a TNamed or 0 in case par is not defined.
9889
9890TObject *TProof::GetParameter(const char *par) const
9891{
9892 if (!fPlayer) {
9893 Warning("GetParameter", "player undefined! Ignoring");
9894 return (TObject *)0;
9895 }
9896
9897 TList *il = fPlayer->GetInputList();
9898 return il->FindObject(par);
9899}
9900
9901////////////////////////////////////////////////////////////////////////////////
9902/// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
9903/// or exact name (e.g. PROOF_MaxSlavesPerNode).
9904
9905void TProof::DeleteParameters(const char *wildcard)
9906{
9907 if (!fPlayer) return;
9908
9909 if (!wildcard) wildcard = "";
9910 TRegexp re(wildcard, kTRUE);
9911 Int_t nch = strlen(wildcard);
9912
9913 TList *il = fPlayer->GetInputList();
9914 if (il) {
9915 TObject *p = 0;
9916 TIter next(il);
9917 while ((p = next())) {
9918 TString s = p->GetName();
9919 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9920 il->Remove(p);
9921 delete p;
9922 }
9923 }
9924}
9925
9926////////////////////////////////////////////////////////////////////////////////
9927/// Show the input list parameters specified by the wildcard.
9928/// Default is the special PROOF control parameters (PROOF_*).
9929
9930void TProof::ShowParameters(const char *wildcard) const
9931{
9932 if (!fPlayer) return;
9933
9934 if (!wildcard) wildcard = "";
9935 TRegexp re(wildcard, kTRUE);
9936 Int_t nch = strlen(wildcard);
9937
9938 TList *il = fPlayer->GetInputList();
9939 TObject *p;
9940 TIter next(il);
9941 while ((p = next())) {
9942 TString s = p->GetName();
9943 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9944 if (p->IsA() == TNamed::Class()) {
9945 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9946 } else if (p->IsA() == TParameter<Long_t>::Class()) {
9947 Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
9948 } else if (p->IsA() == TParameter<Long64_t>::Class()) {
9949 Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
9950 } else if (p->IsA() == TParameter<Double_t>::Class()) {
9951 Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
9952 } else {
9953 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9954 }
9955 }
9956}
9957
9958////////////////////////////////////////////////////////////////////////////////
9959/// Add object to feedback list.
9960
9961void TProof::AddFeedback(const char *name)
9962{
9963 PDB(kFeedback, 3)
9964 Info("AddFeedback", "Adding object \"%s\" to feedback", name);
9965 if (fFeedback->FindObject(name) == 0)
9967}
9968
9969////////////////////////////////////////////////////////////////////////////////
9970/// Remove object from feedback list.
9971
9973{
9975 if (obj != 0) {
9976 fFeedback->Remove(obj);
9977 delete obj;
9978 }
9979}
9980
9981////////////////////////////////////////////////////////////////////////////////
9982/// Clear feedback list.
9983
9985{
9986 fFeedback->Delete();
9987}
9988
9989////////////////////////////////////////////////////////////////////////////////
9990/// Show items in feedback list.
9991
9993{
9994 if (fFeedback->GetSize() == 0) {
9995 Info("","no feedback requested");
9996 return;
9997 }
9998
9999 fFeedback->Print();
10000}
10001
10002////////////////////////////////////////////////////////////////////////////////
10003/// Return feedback list.
10004
10006{
10007 return fFeedback;
10008}
10009
10010////////////////////////////////////////////////////////////////////////////////
10011/// Creates a tree header (a tree with nonexisting files) object for
10012/// the DataSet.
10013
10015{
10017 TSlave *sl = (TSlave*) l->First();
10018 if (sl == 0) {
10019 Error("GetTreeHeader", "No connection");
10020 return 0;
10021 }
10022
10023 TSocket *soc = sl->GetSocket();
10025
10026 msg << dset;
10027
10028 soc->Send(msg);
10029
10030 TMessage *reply;
10031 Int_t d = -1;
10032 if (fProtocol >= 20) {
10034 reply = (TMessage *) fRecvMessages->First();
10035 } else {
10036 d = soc->Recv(reply);
10037 }
10038 if (!reply) {
10039 Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10040 return 0;
10041 }
10042
10043 TString s1;
10044 TTree *t = 0;
10045 (*reply) >> s1;
10046 if (s1 == "Success")
10047 (*reply) >> t;
10048
10049 PDB(kGlobal, 1) {
10050 if (t) {
10051 Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10052 s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10053 } else {
10054 Info("GetTreeHeader", "tree header retrieval failed");
10055 }
10056 }
10057 delete reply;
10058
10059 return t;
10060}
10061
10062////////////////////////////////////////////////////////////////////////////////
10063/// Draw feedback creation proxy. When accessed via TProof avoids
10064/// link dependency on libProofPlayer.
10065
10067{
10068 return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10069}
10070
10071////////////////////////////////////////////////////////////////////////////////
10072/// Set draw feedback option.
10073
10075{
10077}
10078
10079////////////////////////////////////////////////////////////////////////////////
10080/// Delete draw feedback object.
10081
10083{
10085}
10086
10087////////////////////////////////////////////////////////////////////////////////
10088/// FIXME: to be written
10089
10091{
10092 return 0;
10093/*
10094 TMessage msg(kPROOF_GETOUTPUTLIST);
10095 TList* slaves = fActiveSlaves;
10096 Broadcast(msg, slaves);
10097 TMonitor mon;
10098 TList* outputList = new TList();
10099
10100 TIter si(slaves);
10101 TSlave *slave;
10102 while ((slave = (TSlave*)si.Next()) != 0) {
10103 PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10104 slave->GetSocket(), slave->GetName());
10105 mon.Add(slave->GetSocket());
10106 }
10107 mon.ActivateAll();
10108 ((TProof*)gProof)->DeActivateAsyncInput();
10109 ((TProof*)gProof)->fCurrentMonitor = &mon;
10110
10111 while (mon.GetActive() != 0) {
10112 TSocket *sock = mon.Select();
10113 if (!sock) {
10114 Error("GetOutputList","TMonitor::.Select failed!");
10115 break;
10116 }
10117 mon.DeActivate(sock);
10118 TMessage *reply;
10119 if (sock->Recv(reply) <= 0) {
10120 MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10121// Error("GetOutputList","Recv failed! for slave-%d (%s)",
10122// slave->GetOrdinal(), slave->GetName());
10123 continue;
10124 }
10125 if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10126// Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10127// slave->GetOrdinal(), slave->GetName());
10128 MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10129 continue;
10130 }
10131 TList* l;
10132
10133 (*reply) >> l;
10134 TIter next(l);
10135 TNamed *n;
10136 while ( (n = dynamic_cast<TNamed*> (next())) ) {
10137 if (!outputList->FindObject(n->GetName()))
10138 outputList->Add(n);
10139 }
10140 delete reply;
10141 }
10142 ((TProof*)gProof)->fCurrentMonitor = 0;
10143
10144 return outputList;
10145*/
10146}
10147
10148////////////////////////////////////////////////////////////////////////////////
10149/// Build the PROOF's structure in the browser.
10150
10152{
10153 b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10154 b->Add(&fMaster, fMaster.Class(), "fMaster");
10155 b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10156 b->Add(fChains, fChains->Class(), "fChains");
10157
10158 if (fPlayer) {
10159 b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10160 if (fPlayer->GetOutputList())
10161 b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10163 b->Add(fPlayer->GetListOfResults(),
10164 fPlayer->GetListOfResults()->Class(), "ListOfResults");
10165 }
10166}
10167
10168////////////////////////////////////////////////////////////////////////////////
10169/// Set a new PROOF player.
10170
10172{
10173 if (fPlayer)
10174 delete fPlayer;
10175 fPlayer = player;
10176};
10177
10178////////////////////////////////////////////////////////////////////////////////
10179/// Construct a TProofPlayer object. The player string specifies which
10180/// player should be created: remote, slave, sm (supermaster) or base.
10181/// Default is remote. Socket is needed in case a slave player is created.
10182
10184{
10185 if (!player)
10186 player = "remote";
10187
10188 SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10189 return GetPlayer();
10190}
10191
10192////////////////////////////////////////////////////////////////////////////////
10193/// Add chain to data set
10194
10196{
10197 fChains->Add(chain);
10198}
10199
10200////////////////////////////////////////////////////////////////////////////////
10201/// Remove chain from data set
10202
10204{
10205 fChains->Remove(chain);
10206}
10207
10208////////////////////////////////////////////////////////////////////////////////
10209/// Ask for remote logs in the range [start, end]. If start == -1 all the
10210/// messages not yet received are sent back.
10211
10213{
10214 if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10215
10217
10218 msg << start << end;
10219
10220 Broadcast(msg, kActive);
10222}
10223
10224////////////////////////////////////////////////////////////////////////////////
10225/// Fill a TMacro with the log lines since the last reading (fLogFileR)
10226/// Return (TMacro *)0 if no line was logged.
10227/// The returned TMacro must be deleted by the caller.
10228
10230{
10231 TMacro *maclog = 0;
10232
10233 // Save present offset
10234 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10235 if (nowlog < 0) {
10236 SysError("GetLastLog",
10237 "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10238 return maclog;
10239 }
10240
10241 // Get extremes
10242 off_t startlog = nowlog;
10243 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10244 if (endlog < 0) {
10245 SysError("GetLastLog",
10246 "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10247 return maclog;
10248 }
10249
10250 // Perhaps nothing to log
10251 UInt_t tolog = (UInt_t)(endlog - startlog);
10252 if (tolog <= 0) return maclog;
10253
10254 // Set starting point
10255 if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10256 SysError("GetLastLog",
10257 "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10258 return maclog;
10259 }
10260
10261 // Create the output object
10262 maclog = new TMacro;
10263
10264 // Now we go
10265 char line[2048];
10266 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10267 while (fgets(line, wanted, fLogFileR)) {
10268 Int_t r = strlen(line);
10269 if (r > 0) {
10270 if (line[r-1] == '\n') line[r-1] = '\0';
10271 maclog->AddLine(line);
10272 } else {
10273 // Done
10274 break;
10275 }
10276 tolog -= r;
10277 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10278 }
10279
10280 // Restore original pointer
10281 if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10282 Warning("GetLastLog",
10283 "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10284 }
10285
10286 // Done
10287 return maclog;
10288}
10289
10290////////////////////////////////////////////////////////////////////////////////
10291/// Display log of query pq into the log window frame
10292
10294{
10295 if (!pq) return;
10296
10297 TList *lines = pq->GetLogFile()->GetListOfLines();
10298 if (lines) {
10299 TIter nxl(lines);
10300 TObjString *l = 0;
10301 while ((l = (TObjString *)nxl()))
10302 EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10303 }
10304}
10305
10306////////////////////////////////////////////////////////////////////////////////
10307/// Display on screen the content of the temporary log file for query
10308/// in reference
10309
10310void TProof::ShowLog(const char *queryref)
10311{
10312 // Make sure we have all info (GetListOfQueries retrieves the
10313 // head info only)
10314 Retrieve(queryref);
10315
10316 if (fPlayer) {
10317 if (queryref) {
10318 if (fPlayer->GetListOfResults()) {
10320 TQueryResult *qr = 0;
10321 while ((qr = (TQueryResult *) nxq()))
10322 if (strstr(queryref, qr->GetTitle()) &&
10323 strstr(queryref, qr->GetName()))
10324 break;
10325 if (qr) {
10326 PutLog(qr);
10327 return;
10328 }
10329
10330 }
10331 }
10332 }
10333}
10334
10335////////////////////////////////////////////////////////////////////////////////
10336/// Display on screen the content of the temporary log file.
10337/// If qry == -2 show messages from the last (current) query.
10338/// If qry == -1 all the messages not yet displayed are shown (default).
10339/// If qry == 0, all the messages in the file are shown.
10340/// If qry > 0, only the messages related to query 'qry' are shown.
10341/// For qry != -1 the original file offset is restored at the end
10342
10344{
10345 // Save present offset
10346 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10347 if (nowlog < 0) {
10348 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10349 return;
10350 }
10351
10352 // Get extremes
10353 off_t startlog = nowlog;
10354 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10355 if (endlog < 0) {
10356 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10357 return;
10358 }
10359
10360 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10361 if (qry == 0) {
10362 startlog = 0;
10363 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10364 } else if (qry != -1) {
10365
10366 TQueryResult *pq = 0;
10367 if (qry == -2) {
10368 // Pickup the last one
10369 pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10370 if (!pq) {
10372 if (fQueries)
10373 pq = (TQueryResult *)(fQueries->Last());
10374 }
10375 } else if (qry > 0) {
10376 TList *queries = GetQueryResults();
10377 if (queries) {
10378 TIter nxq(queries);
10379 while ((pq = (TQueryResult *)nxq()))
10380 if (qry == pq->GetSeqNum())
10381 break;
10382 }
10383 if (!pq) {
10384 queries = GetListOfQueries();
10385 TIter nxq(queries);
10386 while ((pq = (TQueryResult *)nxq()))
10387 if (qry == pq->GetSeqNum())
10388 break;
10389 }
10390 }
10391 if (pq) {
10392 PutLog(pq);
10393 return;
10394 } else {
10395 if (gDebug > 0)
10396 Info("ShowLog","query %d not found in list", qry);
10397 qry = -1;
10398 }
10399 }
10400
10401 // Number of bytes to log
10402 UInt_t tolog = (UInt_t)(endlog - startlog);
10403
10404 // Perhaps nothing
10405 if (tolog <= 0) {
10406 // Set starting point
10407 lseek(fileno(fLogFileR), startlog, SEEK_SET);
10408 }
10409
10410 // Now we go
10411 Int_t np = 0;
10412 char line[2048];
10413 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10414 while (fgets(line, wanted, fLogFileR)) {
10415
10416 Int_t r = strlen(line);
10417 if (!SendingLogToWindow()) {
10418 if (line[r-1] != '\n') line[r-1] = '\n';
10419 if (r > 0) {
10420 char *p = line;
10421 while (r) {
10422 Int_t w = write(fileno(stdout), p, r);
10423 if (w < 0) {
10424 SysError("ShowLog", "error writing to stdout");
10425 break;
10426 }
10427 r -= w;
10428 p += w;
10429 }
10430 }
10431 tolog -= strlen(line);
10432 np++;
10433
10434 // Ask if more is wanted
10435 if (!(np%10)) {
10436 const char *opt = Getline("More (y/n)? [y]");
10437 if (opt[0] == 'n')
10438 break;
10439 }
10440
10441 // We may be over
10442 if (tolog <= 0)
10443 break;
10444
10445 // Update wanted bytes
10446 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10447 } else {
10448 // Log to window
10449 if (line[r-1] == '\n') line[r-1] = 0;
10451 }
10452 }
10453 if (!SendingLogToWindow()) {
10454 // Avoid screwing up the prompt
10455 if (write(fileno(stdout), "\n", 1) != 1)
10456 SysError("ShowLog", "error writing to stdout");
10457 }
10458
10459 // Restore original pointer
10460 if (qry > -1)
10461 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10462}
10463
10464////////////////////////////////////////////////////////////////////////////////
10465/// Set session with 'id' the default one. If 'id' is not found in the list,
10466/// the current session is set as default
10467
10469{
10470 if (GetManager()) {
10472 if (d) {
10473 if (d->GetProof()) {
10474 gProof = d->GetProof();
10475 return;
10476 }
10477 }
10478
10479 // Id not found or undefined: set as default this session
10480 gProof = this;
10481 }
10482
10483 return;
10484}
10485
10486////////////////////////////////////////////////////////////////////////////////
10487/// Detach this instance to its proofserv.
10488/// If opt is 'S' or 's' the remote server is shutdown
10489
10491{
10492 // Nothing to do if not in contact with proofserv
10493 if (!IsValid()) return;
10494
10495 // Get worker and socket instances
10496 TSlave *sl = (TSlave *) fActiveSlaves->First();
10497 TSocket *s = 0;
10498 if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
10499 Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
10500 return;
10501 }
10502
10503 Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
10504
10505 // If processing, try to stop processing first
10506 if (shutdown && !IsIdle()) {
10507 // Remove pending requests
10508 Remove("cleanupqueue");
10509 // Do not wait for ever, but al least 20 seconds
10510 Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
10511 timeout = (timeout > 20) ? timeout : 20;
10512 // Send stop signal
10513 StopProcess(kFALSE, (Long_t) (timeout / 2));
10514 // Receive results
10515 Collect(kActive, timeout);
10516 }
10517
10518 // Avoid spurious messages: deactivate new inputs ...
10520
10521 // ... and discard existing ones
10522 sl->FlushSocket();
10523
10524 // Close session (we always close the connection)
10525 Close(opt);
10526
10527 // Close the progress dialog, if any
10530
10531 // Update info in the table of our manager, if any
10532 if (GetManager() && GetManager()->QuerySessions("L")) {
10533 TIter nxd(GetManager()->QuerySessions("L"));
10534 TProofDesc *d = 0;
10535 while ((d = (TProofDesc *)nxd())) {
10536 if (d->GetProof() == this) {
10537 d->SetProof(0);
10538 GetManager()->QuerySessions("L")->Remove(d);
10539 break;
10540 }
10541 }
10542 }
10543
10544 // Invalidate this instance
10545 fValid = kFALSE;
10546
10547 return;
10548}
10549
10550////////////////////////////////////////////////////////////////////////////////
10551/// Set an alias for this session. If reconnection is supported, the alias
10552/// will be communicated to the remote coordinator so that it can be recovered
10553/// when reconnecting
10554
10555void TProof::SetAlias(const char *alias)
10556{
10557 // Set it locally
10558 TNamed::SetTitle(alias);
10560 // Set the name at the same value
10561 TNamed::SetName(alias);
10562
10563 // Nothing to do if not in contact with coordinator
10564 if (!IsValid()) return;
10565
10566 if (!IsProofd() && TestBit(TProof::kIsClient)) {
10567 TSlave *sl = (TSlave *) fActiveSlaves->First();
10568 if (sl)
10569 sl->SetAlias(alias);
10570 }
10571
10572 return;
10573}
10574
10575////////////////////////////////////////////////////////////////////////////////
10576/// *** This function is deprecated and will disappear in future versions ***
10577/// *** It is just a wrapper around TFile::Cp.
10578/// *** Please use TProofMgr::UploadFiles.
10579///
10580/// Upload a set of files and save the list of files by name dataSetName.
10581/// The 'files' argument is a list of TFileInfo objects describing the files
10582/// as first url.
10583/// The mask 'opt' is a combination of EUploadOpt:
10584/// kAppend (0x1) if set true files will be appended to
10585/// the dataset existing by given name
10586/// kOverwriteDataSet (0x2) if dataset with given name exited it
10587/// would be overwritten
10588/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10589/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10590/// kOverwriteNoFiles (0x10) overwrite none
10591/// kAskUser (0x0) ask user before overwriteng dataset/files
10592/// The default value is kAskUser.
10593/// The user will be asked to confirm overwriting dataset or files unless
10594/// specified opt provides the answer!
10595/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10596/// skippedFiles argument. The function will add to this list TFileInfo
10597/// objects describing all files that existed on the cluster and were
10598/// not uploaded.
10599///
10600/// Communication Summary
10601/// Client Master
10602/// |------------>DataSetName----------->|
10603/// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
10604/// (*)|-------> call RegisterDataSet ------->|
10605/// (*) - optional
10606
10607Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
10608{
10609 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10610
10611 return -1;
10612}
10613
10614////////////////////////////////////////////////////////////////////////////////
10615/// *** This function is deprecated and will disappear in future versions ***
10616/// *** It is just a wrapper around TFile::Cp.
10617/// *** Please use TProofMgr::UploadFiles.
10618///
10619/// Upload a set of files and save the list of files by name dataSetName.
10620/// The mask 'opt' is a combination of EUploadOpt:
10621/// kAppend (0x1) if set true files will be appended to
10622/// the dataset existing by given name
10623/// kOverwriteDataSet (0x2) if dataset with given name exited it
10624/// would be overwritten
10625/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10626/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10627/// kOverwriteNoFiles (0x10) overwrite none
10628/// kAskUser (0x0) ask user before overwriteng dataset/files
10629/// The default value is kAskUser.
10630/// The user will be asked to confirm overwriting dataset or files unless
10631/// specified opt provides the answer!
10632/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10633/// skippedFiles argument. The function will add to this list TFileInfo
10634/// objects describing all files that existed on the cluster and were
10635/// not uploaded.
10636///
10637
10638Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
10639{
10640 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10641
10642 return -1;
10643}
10644
10645////////////////////////////////////////////////////////////////////////////////
10646/// *** This function is deprecated and will disappear in future versions ***
10647/// *** It is just a wrapper around TFile::Cp.
10648/// *** Please use TProofMgr::UploadFiles.
10649///
10650/// Upload files listed in "file" to PROOF cluster.
10651/// Where file = name of file containing list of files and
10652/// dataset = dataset name and opt is a combination of EUploadOpt bits.
10653/// Each file description (line) can include wildcards.
10654/// Check TFileInfo compatibility
10655
10656Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
10657{
10658 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10659
10660 // Done
10661 return -1;
10662}
10663
10664////////////////////////////////////////////////////////////////////////////////
10665/// Register the 'dataSet' on the cluster under the current
10666/// user, group and the given 'dataSetName'.
10667/// If a dataset with the same name already exists the action fails unless 'opts'
10668/// contains 'O', in which case the old dataset is overwritten, or contains 'U',
10669/// in which case 'newDataSet' is added to the existing dataset (duplications are
10670/// ignored, if any).
10671/// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
10672/// is configured to allow so). By default the dataset is not verified.
10673/// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
10674/// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
10675/// If 'opts' contains 'S' validation would be run serially (meaningful only if
10676/// validation is required).
10677/// Returns kTRUE on success.
10678
10679Bool_t TProof::RegisterDataSet(const char *dataSetName,
10680 TFileCollection *dataSet, const char *optStr)
10681{
10682 // Check TFileInfo compatibility
10683 if (fProtocol < 17) {
10684 Info("RegisterDataSet",
10685 "functionality not available: the server does not have dataset support");
10686 return kFALSE;
10687 }
10688
10689 if (!dataSetName || strlen(dataSetName) <= 0) {
10690 Info("RegisterDataSet", "specifying a dataset name is mandatory");
10691 return kFALSE;
10692 }
10693
10694 Bool_t parallelverify = kFALSE;
10695 TString sopt(optStr);
10696 if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
10697 // We do verification in parallel later on; just register for now
10698 parallelverify = kTRUE;
10699 sopt.ReplaceAll("V", "");
10700 }
10701 // This would screw up things remotely, make sure is not there
10702 sopt.ReplaceAll("S", "");
10703
10705 mess << Int_t(kRegisterDataSet);
10706 mess << TString(dataSetName);
10707 mess << sopt;
10708 mess.WriteObject(dataSet);
10709 Broadcast(mess);
10710
10711 Bool_t result = kTRUE;
10712 Collect();
10713 if (fStatus != 0) {
10714 Error("RegisterDataSet", "dataset was not saved");
10715 result = kFALSE;
10716 return result;
10717 }
10718
10719 // If old server or not verifying in parallel we are done
10720 if (!parallelverify) return result;
10721
10722 // If we are here it means that we will verify in parallel
10723 sopt += "V";
10724 if (VerifyDataSet(dataSetName, sopt) < 0){
10725 Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
10726 return kFALSE;
10727 }
10728
10729 // We are done
10730 return kTRUE;
10731}
10732
10733////////////////////////////////////////////////////////////////////////////////
10734/// Set/Change the name of the default tree. The tree name may contain
10735/// subdir specification in the form "subdir/name".
10736/// Returns 0 on success, -1 otherwise.
10737
10738Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
10739{
10740 // Check TFileInfo compatibility
10741 if (fProtocol < 23) {
10742 Info("SetDataSetTreeName", "functionality not supported by the server");
10743 return -1;
10744 }
10745
10746 if (!dataset || strlen(dataset) <= 0) {
10747 Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
10748 return -1;
10749 }
10750
10751 if (!treename || strlen(treename) <= 0) {
10752 Info("SetDataSetTreeName", "specifying a tree name is mandatory");
10753 return -1;
10754 }
10755
10756 TUri uri(dataset);
10757 TString fragment(treename);
10758 if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
10759 uri.SetFragment(fragment);
10760
10762 mess << Int_t(kSetDefaultTreeName);
10763 mess << uri.GetUri();
10764 Broadcast(mess);
10765
10766 Collect();
10767 if (fStatus != 0) {
10768 Error("SetDataSetTreeName", "some error occured: default tree name not changed");
10769 return -1;
10770 }
10771 return 0;
10772}
10773
10774////////////////////////////////////////////////////////////////////////////////
10775/// Lists all datasets that match given uri.
10776/// The 'optStr' can contain a comma-separated list of servers for which the
10777/// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
10778/// only the global information in the TFileCollection is retrieved; useful to only
10779/// get the list of available datasets.
10780
10781TMap *TProof::GetDataSets(const char *uri, const char *optStr)
10782{
10783 if (fProtocol < 15) {
10784 Info("GetDataSets",
10785 "functionality not available: the server does not have dataset support");
10786 return 0;
10787 }
10788 if (fProtocol < 31 && strstr(optStr, ":lite:"))
10789 Warning("GetDataSets", "'lite' option not supported by the server");
10790
10792 mess << Int_t(kGetDataSets);
10793 mess << TString(uri ? uri : "");
10794 mess << TString(optStr ? optStr : "");
10795 Broadcast(mess);
10797
10798 TMap *dataSetMap = 0;
10799 if (fStatus != 0) {
10800 Error("GetDataSets", "error receiving datasets information");
10801 } else {
10802 // Look in the list
10803 TMessage *retMess = (TMessage *) fRecvMessages->First();
10804 if (retMess && retMess->What() == kMESS_OK) {
10805 if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
10806 Error("GetDataSets", "error receiving datasets");
10807 } else
10808 Error("GetDataSets", "message not found or wrong type (%p)", retMess);
10809 }
10810
10811 return dataSetMap;
10812}
10813
10814////////////////////////////////////////////////////////////////////////////////
10815/// Shows datasets in locations that match the uri.
10816/// By default shows the user's datasets and global ones
10817
10818void TProof::ShowDataSets(const char *uri, const char* optStr)
10819{
10820 if (fProtocol < 15) {
10821 Info("ShowDataSets",
10822 "functionality not available: the server does not have dataset support");
10823 return;
10824 }
10825
10827 mess << Int_t(kShowDataSets);
10828 mess << TString(uri ? uri : "");
10829 mess << TString(optStr ? optStr : "");
10830 Broadcast(mess);
10831
10833 if (fStatus != 0)
10834 Error("ShowDataSets", "error receiving datasets information");
10835}
10836
10837////////////////////////////////////////////////////////////////////////////////
10838/// Returns kTRUE if 'dataset' exists, kFALSE otherwise
10839
10840Bool_t TProof::ExistsDataSet(const char *dataset)
10841{
10842 if (fProtocol < 15) {
10843 Info("ExistsDataSet", "functionality not available: the server has an"
10844 " incompatible version of TFileInfo");
10845 return kFALSE;
10846 }
10847
10848 if (!dataset || strlen(dataset) <= 0) {
10849 Error("ExistsDataSet", "dataset name missing");
10850 return kFALSE;
10851 }
10852
10854 msg << Int_t(kCheckDataSetName) << TString(dataset);
10855 Broadcast(msg);
10857 if (fStatus == -1) {
10858 // The dataset exists
10859 return kTRUE;
10860 }
10861 // The dataset does not exists
10862 return kFALSE;
10863}
10864
10865////////////////////////////////////////////////////////////////////////////////
10866/// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
10867
10868void TProof::ClearDataSetCache(const char *dataset)
10869{
10870 if (fProtocol < 28) {
10871 Info("ClearDataSetCache", "functionality not available on server");
10872 return;
10873 }
10874
10876 msg << Int_t(kCache) << TString(dataset) << TString("clear");
10877 Broadcast(msg);
10879 // Done
10880 return;
10881}
10882
10883////////////////////////////////////////////////////////////////////////////////
10884/// Display the content of the dataset cache, if any (matching 'dataset', if defined).
10885
10886void TProof::ShowDataSetCache(const char *dataset)
10887{
10888 if (fProtocol < 28) {
10889 Info("ShowDataSetCache", "functionality not available on server");
10890 return;
10891 }
10892
10894 msg << Int_t(kCache) << TString(dataset) << TString("show");
10895 Broadcast(msg);
10897 // Done
10898 return;
10899}
10900
10901////////////////////////////////////////////////////////////////////////////////
10902/// Get a list of TFileInfo objects describing the files of the specified
10903/// dataset.
10904/// To get the short version (containing only the global meta information)
10905/// specify optStr = "S:" or optStr = "short:".
10906/// To get the sub-dataset of files located on a given server(s) specify
10907/// the list of servers (comma-separated) in the 'optStr' field.
10908
10909TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10910{
10911 if (fProtocol < 15) {
10912 Info("GetDataSet", "functionality not available: the server has an"
10913 " incompatible version of TFileInfo");
10914 return 0;
10915 }
10916
10917 if (!uri || strlen(uri) <= 0) {
10918 Info("GetDataSet", "specifying a dataset name is mandatory");
10919 return 0;
10920 }
10921
10922 TMessage nameMess(kPROOF_DATASETS);
10923 nameMess << Int_t(kGetDataSet);
10924 nameMess << TString(uri);
10925 nameMess << TString(optStr ? optStr: "");
10926 if (Broadcast(nameMess) < 0)
10927 Error("GetDataSet", "sending request failed");
10928
10930 TFileCollection *fileList = 0;
10931 if (fStatus != 0) {
10932 Error("GetDataSet", "error receiving datasets information");
10933 } else {
10934 // Look in the list
10935 TMessage *retMess = (TMessage *) fRecvMessages->First();
10936 if (retMess && retMess->What() == kMESS_OK) {
10937 if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10938 Error("GetDataSet", "error reading list of files");
10939 } else
10940 Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10941 }
10942
10943 return fileList;
10944}
10945
10946////////////////////////////////////////////////////////////////////////////////
10947/// display meta-info for given dataset usi
10948
10949void TProof::ShowDataSet(const char *uri, const char* opt)
10950{
10951 TFileCollection *fileList = 0;
10952 if ((fileList = GetDataSet(uri))) {
10953 fileList->Print(opt);
10954 delete fileList;
10955 } else
10956 Warning("ShowDataSet","no such dataset: %s", uri);
10957}
10958
10959////////////////////////////////////////////////////////////////////////////////
10960/// Remove the specified dataset from the PROOF cluster.
10961/// Files are not deleted.
10962
10963Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10964{
10965 TMessage nameMess(kPROOF_DATASETS);
10966 nameMess << Int_t(kRemoveDataSet);
10967 nameMess << TString(uri?uri:"");
10968 nameMess << TString(optStr?optStr:"");
10969 if (Broadcast(nameMess) < 0)
10970 Error("RemoveDataSet", "sending request failed");
10972
10973 if (fStatus != 0)
10974 return -1;
10975 else
10976 return 0;
10977}
10978
10979////////////////////////////////////////////////////////////////////////////////
10980/// Find datasets, returns in a TList all found datasets.
10981
10982TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
10983{
10984 Error ("FindDataSets", "not yet implemented");
10985 return (TList *) 0;
10986}
10987
10988////////////////////////////////////////////////////////////////////////////////
10989/// Allows users to request staging of a particular dataset. Requests are
10990/// saved in a special dataset repository and must be honored by the endpoint.
10991
10993{
10994 if (fProtocol < 35) {
10995 Error("RequestStagingDataSet",
10996 "functionality not supported by the server");
10997 return kFALSE;
10998 }
10999
11001 mess << Int_t(kRequestStaging);
11002 mess << TString(dataset);
11003 Broadcast(mess);
11004
11005 Collect();
11006 if (fStatus != 0) {
11007 Error("RequestStagingDataSet", "staging request was unsuccessful");
11008 return kFALSE;
11009 }
11010
11011 return kTRUE;
11012}
11013
11014////////////////////////////////////////////////////////////////////////////////
11015/// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11016/// failure. Dataset not found equals to a failure.
11017
11019{
11020 if (fProtocol < 36) {
11021 Error("CancelStagingDataSet",
11022 "functionality not supported by the server");
11023 return kFALSE;
11024 }
11025
11027 mess << Int_t(kCancelStaging);
11028 mess << TString(dataset);
11029 Broadcast(mess);
11030
11031 Collect();
11032 if (fStatus != 0) {
11033 Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11034 return kFALSE;
11035 }
11036
11037 return kTRUE;
11038}
11039
11040////////////////////////////////////////////////////////////////////////////////
11041/// Obtains a TFileCollection showing the staging status of the specified
11042/// dataset. A valid dataset manager and dataset staging requests repository
11043/// must be present on the endpoint.
11044
11046{
11047 if (fProtocol < 35) {
11048 Error("GetStagingStatusDataSet",
11049 "functionality not supported by the server");
11050 return NULL;
11051 }
11052
11053 TMessage nameMess(kPROOF_DATASETS);
11054 nameMess << Int_t(kStagingStatus);
11055 nameMess << TString(dataset);
11056 if (Broadcast(nameMess) < 0) {
11057 Error("GetStagingStatusDataSet", "sending request failed");
11058 return NULL;
11059 }
11060
11062 TFileCollection *fc = NULL;
11063
11064 if (fStatus < 0) {
11065 Error("GetStagingStatusDataSet", "problem processing the request");
11066 }
11067 else if (fStatus == 0) {
11068 TMessage *retMess = (TMessage *)fRecvMessages->First();
11069 if (retMess && (retMess->What() == kMESS_OK)) {
11070 fc = (TFileCollection *)(
11071 retMess->ReadObject(TFileCollection::Class()) );
11072 if (!fc)
11073 Error("GetStagingStatusDataSet", "error reading list of files");
11074 }
11075 else {
11076 Error("GetStagingStatusDataSet",
11077 "response message not found or wrong type (%p)", retMess);
11078 }
11079 }
11080 //else {}
11081
11082 return fc;
11083}
11084
11085////////////////////////////////////////////////////////////////////////////////
11086/// Like GetStagingStatusDataSet, but displays results immediately.
11087
11088void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11089{
11091 if (fc) {
11092 fc->Print(opt);
11093 delete fc;
11094 }
11095}
11096
11097////////////////////////////////////////////////////////////////////////////////
11098/// Verify if all files in the specified dataset are available.
11099/// Print a list and return the number of missing files.
11100/// Returns -1 in case of error.
11101
11102Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11103{
11104 if (fProtocol < 15) {
11105 Info("VerifyDataSet", "functionality not available: the server has an"
11106 " incompatible version of TFileInfo");
11107 return -1;
11108 }
11109
11110 // Sanity check
11111 if (!uri || (uri && strlen(uri) <= 0)) {
11112 Error("VerifyDataSet", "dataset name is is mandatory");
11113 return -1;
11114 }
11115
11116 Int_t nmissingfiles = 0;
11117
11118 TString sopt(optStr);
11119 if (fProtocol < 34 || sopt.Contains("S")) {
11120 sopt.ReplaceAll("S", "");
11121 Info("VerifyDataSet", "Master-only verification");
11122 TMessage nameMess(kPROOF_DATASETS);
11123 nameMess << Int_t(kVerifyDataSet);
11124 nameMess << TString(uri);
11125 nameMess << sopt;
11126 Broadcast(nameMess);
11127
11129
11130 if (fStatus < 0) {
11131 Info("VerifyDataSet", "no such dataset %s", uri);
11132 return -1;
11133 } else
11134 nmissingfiles = fStatus;
11135 return nmissingfiles;
11136 }
11137
11138 // Request for parallel verification: can only be done if we have workers
11139 if (!IsParallel() && !fDynamicStartup) {
11140 Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11141 Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11142 return -1;
11143 }
11144
11145 // Do parallel verification
11146 return VerifyDataSetParallel(uri, optStr);
11147}
11148
11149////////////////////////////////////////////////////////////////////////////////
11150/// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11151/// TProofLite::VerifyDataSet
11152
11153Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11154{
11155 Int_t nmissingfiles = 0;
11156
11157 // Let PROOF master prepare node-files map
11158 SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11159
11160 // Use TPacketizerFile
11161 TString oldpack;
11162 if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11163 SetParameter("PROOF_Packetizer", "TPacketizerFile");
11164
11165 // Add dataset name
11166 SetParameter("PROOF_VerifyDataSet", uri);
11167 // Add options
11168 SetParameter("PROOF_VerifyDataSetOption", optStr);
11169 SetParameter("PROOF_SavePartialResults", (Int_t)0);
11170 Int_t oldifiip = -1;
11171 if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11172 SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11173
11174 // TO DO : figure out mss and stageoption
11175 const char* mss="";
11176 SetParameter("PROOF_MSS", mss);
11177 const char* stageoption="";
11178 SetParameter("PROOF_StageOption", stageoption);
11179
11180 // Process verification in parallel
11181 Process("TSelVerifyDataSet", (Long64_t) 1);
11182
11183 // Restore packetizer
11184 if (!oldpack.IsNull())
11185 SetParameter("PROOF_Packetizer", oldpack);
11186 else
11187 DeleteParameters("PROOF_Packetizer");
11188
11189 // Delete or restore parameters
11190 DeleteParameters("PROOF_FilesToProcess");
11191 DeleteParameters("PROOF_VerifyDataSet");
11192 DeleteParameters("PROOF_VerifyDataSetOption");
11193 DeleteParameters("PROOF_MSS");
11194 DeleteParameters("PROOF_StageOption");
11195 if (oldifiip > -1) {
11196 SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11197 } else {
11198 DeleteParameters("PROOF_IncludeFileInfoInPacket");
11199 }
11200 DeleteParameters("PROOF_SavePartialResults");
11201
11202 // Merge outputs
11203 Int_t nopened = 0;
11204 Int_t ntouched = 0;
11205 Bool_t changed_ds = kFALSE;
11206
11207 TIter nxtout(GetOutputList());
11208 TObject* obj;
11209 TList *lfiindout = new TList;
11210 while ((obj = nxtout())) {
11211 TList *l = dynamic_cast<TList *>(obj);
11212 if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11213 TIter nxt(l);
11214 TFileInfo *fiindout = 0;
11215 while ((fiindout = (TFileInfo*) nxt())) {
11216 lfiindout->Add(fiindout);
11217 }
11218 }
11219 // Add up number of disppeared files
11220 TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11221 if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11222 nmissingfiles += pdisappeared->GetVal();
11223 }
11224 TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11225 if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11226 nopened += pnopened->GetVal();
11227 }
11228 TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11229 if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11230 ntouched += pntouched->GetVal();
11231 }
11232 TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11233 if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11234 if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11235 }
11236 }
11237
11238 Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11239 " # missing files = %d)",
11240 uri, changed_ds, nopened, ntouched, nmissingfiles);
11241 // Done
11242 return nmissingfiles;
11243}
11244
11245////////////////////////////////////////////////////////////////////////////////
11246/// returns a map of the quotas of all groups
11247
11248TMap *TProof::GetDataSetQuota(const char* optStr)
11249{
11250 if (IsLite()) {
11251 Info("UploadDataSet", "Lite-session: functionality not implemented");
11252 return (TMap *)0;
11253 }
11254
11256 mess << Int_t(kGetQuota);
11257 mess << TString(optStr?optStr:"");
11258 Broadcast(mess);
11259
11261 TMap *groupQuotaMap = 0;
11262 if (fStatus < 0) {
11263 Info("GetDataSetQuota", "could not receive quota");
11264 } else {
11265 // Look in the list
11266 TMessage *retMess = (TMessage *) fRecvMessages->First();
11267 if (retMess && retMess->What() == kMESS_OK) {
11268 if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11269 Error("GetDataSetQuota", "error getting quotas");
11270 } else
11271 Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11272 }
11273
11274 return groupQuotaMap;
11275}
11276
11277////////////////////////////////////////////////////////////////////////////////
11278/// shows the quota and usage of all groups
11279/// if opt contains "U" shows also distribution of usage on user-level
11280
11282{
11283 if (fProtocol < 15) {
11284 Info("ShowDataSetQuota",
11285 "functionality not available: the server does not have dataset support");
11286 return;
11287 }
11288
11289 if (IsLite()) {
11290 Info("UploadDataSet", "Lite-session: functionality not implemented");
11291 return;
11292 }
11293
11295 mess << Int_t(kShowQuota);
11296 mess << TString(opt?opt:"");
11297 Broadcast(mess);
11298
11299 Collect();
11300 if (fStatus != 0)
11301 Error("ShowDataSetQuota", "error receiving quota information");
11302}
11303
11304////////////////////////////////////////////////////////////////////////////////
11305/// If in active in a monitor set ready state
11306
11308{
11309 if (fCurrentMonitor)
11311}
11312
11313////////////////////////////////////////////////////////////////////////////////
11314/// Make sure that the worker identified by the ordinal number 'ord' is
11315/// in the active list. The request will be forwarded to the master
11316/// in direct contact with the worker. If needed, this master will move
11317/// the worker from the inactive to the active list and rebuild the list
11318/// of unique workers.
11319/// Use ord = "*" to activate all inactive workers.
11320/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11321/// status of which will be modified at once.
11322/// Return <0 if something went wrong (-2 if at least one worker was not found)
11323/// or the number of workers with status change (on master; 0 on client).
11324
11326{
11327 return ModifyWorkerLists(ord, kTRUE, save);
11328}
11329
11330////////////////////////////////////////////////////////////////////////////////
11331/// Remove the worker identified by the ordinal number 'ord' from the
11332/// the active list. The request will be forwarded to the master
11333/// in direct contact with the worker. If needed, this master will move
11334/// the worker from the active to the inactive list and rebuild the list
11335/// of unique workers.
11336/// Use ord = "*" to deactivate all active workers.
11337/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11338/// status of which will be modified at once.
11339/// Return <0 if something went wrong (-2 if at least one worker was not found)
11340/// or the number of workers with status change (on master; 0 on client).
11341
11343{
11344 return ModifyWorkerLists(ord, kFALSE, save);
11345}
11346
11347////////////////////////////////////////////////////////////////////////////////
11348/// Modify the worker active/inactive list by making the worker identified by
11349/// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11350/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11351/// status of which will be modified at once.
11352/// If needed, the request will be forwarded to the master in direct contact
11353/// with the worker. The end-master will move the worker from one list to the
11354/// other active and rebuild the list of unique active workers.
11355/// Use ord = "*" to deactivate all active workers.
11356/// If save is TRUE the current active list is saved before any modification is
11357/// done; re-running with ord = "restore" restores the saved list
11358/// Return <0 if something went wrong (-2 if at least one worker was not found)
11359/// or the number of workers with status change (on master; 0 on client).
11360
11362{
11363 // Make sure the input make sense
11364 if (!ord || strlen(ord) <= 0) {
11365 Info("ModifyWorkerLists",
11366 "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11367 return -1;
11368 }
11369 if (gDebug > 0)
11370 Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11371
11372 Int_t nwc = 0;
11373 Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11374 if (IsEndMaster()) {
11375 if (restoring) {
11376 // We are asked to restore the previous settings
11377 nwc = RestoreActiveList();
11378 } else {
11379 if (save) SaveActiveList();
11380 }
11381 }
11382
11383 Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11384
11385 // Check if this is for us
11387 if (!allord &&
11388 strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11389 return 0;
11390 }
11391
11392 Bool_t fw = kTRUE; // Whether to forward one step down
11393 Bool_t rs = kFALSE; // Whether to rescan for unique workers
11394
11395 // Appropriate list pointing
11396 TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11397 TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11398
11399 if (IsEndMaster() && !restoring) {
11400 // Create the hash list of ordinal numbers
11401 THashList *ords = 0;
11402 if (!allord) {
11403 ords = new THashList();
11404 const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
11405 TString oo(ord), o;
11406 Int_t from = 0;
11407 while(oo.Tokenize(o, from, ","))
11408 if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
11409 }
11410 // We do not need to send forward
11411 fw = kFALSE;
11412 // Look for the worker in the initial list
11413 TObject *os = 0;
11414 TSlave *wrk = 0;
11415 if (in->GetSize() > 0) {
11416 TIter nxw(in);
11417 while ((wrk = (TSlave *) nxw())) {
11418 os = 0;
11419 if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
11420 // Add it to the final list
11421 if (!out->FindObject(wrk)) {
11422 out->Add(wrk);
11423 if (add)
11424 fActiveMonitor->Add(wrk->GetSocket());
11425 }
11426 // Remove it from the initial list
11427 in->Remove(wrk);
11428 if (!add) {
11431 } else
11433 // Count
11434 nwc++;
11435 // Nothing to forward (ord is unique)
11436 fw = kFALSE;
11437 // Rescan for unique workers (active list modified)
11438 rs = kTRUE;
11439 // We may be done, if not option 'all'
11440 if (!allord && ords) {
11441 if (os) ords->Remove(os);
11442 if (ords->GetSize() == 0) break;
11443 SafeDelete(os);
11444 }
11445 }
11446 }
11447 }
11448 // If some worker not found, notify it if at the end
11449 if (!fw && ords && ords->GetSize() > 0) {
11450 TString oo;
11451 TIter nxo(ords);
11452 while ((os = nxo())) {
11453 TIter nxw(out);
11454 while ((wrk = (TSlave *) nxw()))
11455 if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
11456 if (!wrk) {
11457 if (!oo.IsNull()) oo += ",";
11458 oo += os->GetName();
11459 }
11460 }
11461 if (!oo.IsNull()) {
11462 Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
11463 nwc = -2;
11464 }
11465 }
11466 // Cleanup hash list
11467 if (ords) {
11468 ords->Delete();
11469 SafeDelete(ords);
11470 }
11471 }
11472
11473 // Rescan for unique workers
11474 if (rs)
11476
11477 // Forward the request one step down, if needed
11478 Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
11479 if (fw) {
11480 if (fProtocol > 32) {
11482 mess << action << TString(ord);
11483 Broadcast(mess);
11485 if (fStatus != 0) {
11486 nwc = (fStatus < nwc) ? fStatus : nwc;
11487 if (fStatus == -2) {
11488 if (gDebug > 0)
11489 Warning("ModifyWorkerLists", "request not completely full filled");
11490 } else {
11491 Error("ModifyWorkerLists", "request failed");
11492 }
11493 }
11494 } else {
11495 TString oo(ord), o;
11496 if (oo.Contains(","))
11497 Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
11498 Int_t from = 0;
11499 while(oo.Tokenize(o, from, ",")) {
11501 mess << action << o;
11502 Broadcast(mess);
11504 }
11505 }
11506 }
11507 // Done
11508 return nwc;
11509}
11510
11511////////////////////////////////////////////////////////////////////////////////
11512/// Save current list of active workers
11513
11515{
11517 if (fInactiveSlaves->GetSize() == 0) {
11518 fActiveSlavesSaved = "*";
11519 } else {
11520 TIter nxw(fActiveSlaves);
11521 TSlave *wk = 0;
11522 while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
11523 }
11524}
11525
11526////////////////////////////////////////////////////////////////////////////////
11527/// Restore saved list of active workers
11528
11530{
11531 // Clear the current active list
11533 // Restore the previous active list
11536
11537 return 0;
11538}
11539
11540////////////////////////////////////////////////////////////////////////////////
11541/// Start a PROOF session on a specific cluster. If cluster is 0 (the
11542/// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
11543/// If cluster is "lite://" we start a PROOF-lite session.
11544/// If cluster is "" (empty string) then we connect to the cluster specified
11545/// by 'Proof.LocalDefault', defaulting to "lite://".
11546/// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
11547/// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
11548/// Via conffile a specific PROOF config file in the confir directory can be specified.
11549/// Use loglevel to set the default loging level for debugging.
11550/// The appropriate instance of TProofMgr is created, if not
11551/// yet existing. The instantiated TProof object is returned.
11552/// Use TProof::cd() to switch between PROOF sessions.
11553/// For more info on PROOF see the TProof ctor.
11554
11555TProof *TProof::Open(const char *cluster, const char *conffile,
11556 const char *confdir, Int_t loglevel)
11557{
11558 const char *pn = "TProof::Open";
11559
11560 // Make sure libProof and dependents are loaded and TProof can be created,
11561 // dependents are loaded via the information in the [system].rootmap file
11562 if (!cluster) {
11563
11564 TPluginManager *pm = gROOT->GetPluginManager();
11565 if (!pm) {
11566 ::Error(pn, "plugin manager not found");
11567 return 0;
11568 }
11569
11570 if (gROOT->IsBatch()) {
11571 ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
11572 return 0;
11573 }
11574 // start PROOF Session Viewer
11575 TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
11576 if (!sv) {
11577 ::Error(pn, "no plugin found for TSessionViewer");
11578 return 0;
11579 }
11580 if (sv->LoadPlugin() == -1) {
11581 ::Error(pn, "plugin for TSessionViewer could not be loaded");
11582 return 0;
11583 }
11584 sv->ExecPlugin(0);
11585 return 0;
11586
11587 } else {
11588
11589 TString clst(cluster);
11590
11591 // Check for PoD cluster
11592 if (PoDCheckUrl( &clst ) < 0) return 0;
11593
11594 if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
11595 if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
11596
11597 // Parse input URL
11598 TUrl u(clst);
11599
11600 // *** GG, 060711: this does not seem to work any more (at XrdClient level)
11601 // *** to be investigated (it is not really needed; static tunnels work).
11602 // Dynamic tunnel:
11603 // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
11604 TString opts(u.GetOptions());
11605 if (!opts.IsNull()) {
11606 Int_t it = opts.Index("tunnel=");
11607 if (it != kNPOS) {
11608 TString sport = opts(it + strlen("tunnel="), opts.Length());
11609 TString host("127.0.0.1");
11610 Int_t port = -1;
11611 Int_t ic = sport.Index(":");
11612 if (ic != kNPOS) {
11613 // Isolate the host
11614 host = sport(0, ic);
11615 sport.Remove(0, ic + 1);
11616 }
11617 if (!sport.IsDigit()) {
11618 // Remove the non digit part
11619 TRegexp re("[^0-9]");
11620 Int_t ind = sport.Index(re);
11621 if (ind != kNPOS)
11622 sport.Remove(ind);
11623 }
11624 // Set the port
11625 if (sport.IsDigit())
11626 port = sport.Atoi();
11627 if (port > 0) {
11628 // Set the relevant variables
11629 ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
11630 gEnv->SetValue("XNet.SOCKS4Host", host);
11631 gEnv->SetValue("XNet.SOCKS4Port", port);
11632 } else {
11633 // Warn parsing problems
11634 ::Warning("TProof::Open",
11635 "problems parsing tunnelling info from options: %s", opts.Data());
11636 }
11637 }
11638 }
11639
11640 // Find out if we are required to attach to a specific session
11641 Int_t locid = -1;
11642 Bool_t create = kFALSE;
11643 if (opts.Length() > 0) {
11644 if (opts.BeginsWith("N",TString::kIgnoreCase)) {
11645 create = kTRUE;
11646 opts.Remove(0,1);
11647 u.SetOptions(opts);
11648 } else if (opts.IsDigit()) {
11649 locid = opts.Atoi();
11650 }
11651 }
11652
11653 // Attach-to or create the appropriate manager
11655
11656 TProof *proof = 0;
11657 if (mgr && mgr->IsValid()) {
11658
11659 // If XProofd we always attempt an attach first (unless
11660 // explicitly not requested).
11661 Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
11662 if (attach) {
11663 TProofDesc *d = 0;
11664 if (locid < 0)
11665 // Get the list of sessions
11666 d = (TProofDesc *) mgr->QuerySessions("")->First();
11667 else
11668 d = (TProofDesc *) mgr->GetProofDesc(locid);
11669 if (d) {
11670 proof = (TProof*) mgr->AttachSession(d);
11671 if (!proof || !proof->IsValid()) {
11672 if (locid)
11673 ::Error(pn, "new session could not be attached");
11674 SafeDelete(proof);
11675 }
11676 }
11677 }
11678
11679 // start the PROOF session
11680 if (!proof) {
11681 proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
11682 if (!proof || !proof->IsValid()) {
11683 ::Error(pn, "new session could not be created");
11684 SafeDelete(proof);
11685 }
11686 }
11687 }
11688 return proof;
11689 }
11690}
11691
11692////////////////////////////////////////////////////////////////////////////////
11693/// Get instance of the effective manager for 'url'
11694/// Return 0 on failure.
11695
11696TProofMgr *TProof::Mgr(const char *url)
11697{
11698 if (!url)
11699 return (TProofMgr *)0;
11700
11701 // Attach or create the relevant instance
11702 return TProofMgr::Create(url);
11703}
11704
11705////////////////////////////////////////////////////////////////////////////////
11706/// Wrapper around TProofMgr::Reset(...).
11707
11708void TProof::Reset(const char *url, Bool_t hard)
11709{
11710 if (url) {
11711 TProofMgr *mgr = TProof::Mgr(url);
11712 if (mgr && mgr->IsValid())
11713 mgr->Reset(hard);
11714 else
11715 ::Error("TProof::Reset",
11716 "unable to initialize a valid manager instance");
11717 }
11718}
11719
11720////////////////////////////////////////////////////////////////////////////////
11721/// Get environemnt variables.
11722
11724{
11725 return fgProofEnvList;
11726}
11727
11728////////////////////////////////////////////////////////////////////////////////
11729/// Add an variable to the list of environment variables passed to proofserv
11730/// on the master and slaves
11731
11732void TProof::AddEnvVar(const char *name, const char *value)
11733{
11734 if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
11735
11736 if (fgProofEnvList == 0) {
11737 // initialize the list if needed
11738 fgProofEnvList = new TList;
11740 } else {
11741 // replace old entries with the same name
11743 if (o != 0) {
11745 }
11746 }
11747 fgProofEnvList->Add(new TNamed(name, value));
11748}
11749
11750////////////////////////////////////////////////////////////////////////////////
11751/// Remove an variable from the list of environment variables passed to proofserv
11752/// on the master and slaves
11753
11754void TProof::DelEnvVar(const char *name)
11755{
11756 if (fgProofEnvList == 0) return;
11757
11759 if (o != 0) {
11761 }
11762}
11763
11764////////////////////////////////////////////////////////////////////////////////
11765/// Clear the list of environment variables passed to proofserv
11766/// on the master and slaves
11767
11769{
11770 if (fgProofEnvList == 0) return;
11771
11773}
11774
11775////////////////////////////////////////////////////////////////////////////////
11776/// Save information about the worker set in the file .workers in the working
11777/// dir. Called each time there is a change in the worker setup, e.g. by
11778/// TProof::MarkBad().
11779
11781{
11782 // We must be masters
11784 return;
11785
11786 // We must have a server defined
11787 if (!gProofServ) {
11788 Error("SaveWorkerInfo","gProofServ undefined");
11789 return;
11790 }
11791
11792 // The relevant lists must be defined
11793 if (!fSlaves && !fBadSlaves) {
11794 Warning("SaveWorkerInfo","all relevant worker lists is undefined");
11795 return;
11796 }
11797
11798 // Create or truncate the file first
11799 TString fnwrk = TString::Format("%s/.workers",
11801 FILE *fwrk = fopen(fnwrk.Data(),"w");
11802 if (!fwrk) {
11803 Error("SaveWorkerInfo",
11804 "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
11805 return;
11806 }
11807
11808 // Do we need to register an additional line for another log?
11809 TString addlogext;
11810 TString addLogTag;
11811 if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
11812 addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
11813 TPMERegexp reLogTag("^__(.*)__\\.log"); // $
11814 if (reLogTag.Match(addlogext) == 2) {
11815 addLogTag = reLogTag[1];
11816 }
11817 else {
11818 addLogTag = "+++";
11819 }
11820 if (gDebug > 0)
11821 Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
11822 }
11823
11824 // Used to eliminate datetime and PID from workdir to obtain log file name
11825 TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
11826
11827 // Loop over the list of workers (active is any worker not flagged as bad)
11828 TIter nxa(fSlaves);
11829 TSlave *wrk = 0;
11830 TString logfile;
11831 while ((wrk = (TSlave *) nxa())) {
11832 Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
11833 logfile = wrk->GetWorkDir();
11834 if (re.Match(logfile) == 2) logfile = re[1];
11835 else continue; // invalid (should not happen)
11836 // Write out record for this worker
11837 fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
11838 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11839 wrk->GetOrdinal(), logfile.Data());
11840 // Additional line, if required
11841 if (addlogext.Length() > 0) {
11842 fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
11843 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11844 wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
11845 }
11846
11847 }
11848
11849 // Loop also over the list of bad workers (if they failed to startup they are not in
11850 // the overall list
11851 TIter nxb(fBadSlaves);
11852 while ((wrk = (TSlave *) nxb())) {
11853 logfile = wrk->GetWorkDir();
11854 if (re.Match(logfile) == 2) logfile = re[1];
11855 else continue; // invalid (should not happen)
11856 if (!fSlaves->FindObject(wrk)) {
11857 // Write out record for this worker
11858 fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
11859 wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
11860 wrk->GetOrdinal(), logfile.Data());
11861 }
11862 }
11863
11864 // Eventually loop over the list of gracefully terminated workers: we'll get
11865 // logfiles from those workers as well. They'll be shown with a special
11866 // status of "2"
11868 TSlaveInfo *sli;
11869 while (( sli = (TSlaveInfo *)nxt() )) {
11870 logfile = sli->GetDataDir();
11871 if (re.Match(logfile) == 2) logfile = re[1];
11872 else continue; // invalid (should not happen)
11873 fprintf(fwrk, "%s 2 %s %s.log\n",
11874 sli->GetName(), sli->GetOrdinal(), logfile.Data());
11875 // Additional line, if required
11876 if (addlogext.Length() > 0) {
11877 fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
11878 sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
11879 logfile.Data(), addlogext.Data());
11880 }
11881 }
11882
11883 // Close file
11884 fclose(fwrk);
11885
11886 // We are done
11887 return;
11888}
11889
11890////////////////////////////////////////////////////////////////////////////////
11891/// Get the value from the specified parameter from the specified collection.
11892/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11893/// or value type does not match), 0 otherwise.
11894
11896{
11897 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11898 if (obj) {
11899 TNamed *p = dynamic_cast<TNamed*>(obj);
11900 if (p) {
11901 value = p->GetTitle();
11902 return 0;
11903 }
11904 }
11905 return -1;
11906
11907}
11908
11909////////////////////////////////////////////////////////////////////////////////
11910/// Get the value from the specified parameter from the specified collection.
11911/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11912/// or value type does not match), 0 otherwise.
11913
11915{
11916 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11917 if (obj) {
11918 TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
11919 if (p) {
11920 value = p->GetVal();
11921 return 0;
11922 }
11923 }
11924 return -1;
11925}
11926
11927////////////////////////////////////////////////////////////////////////////////
11928/// Get the value from the specified parameter from the specified collection.
11929/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11930/// or value type does not match), 0 otherwise.
11931
11933{
11934 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11935 if (obj) {
11936 TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
11937 if (p) {
11938 value = p->GetVal();
11939 return 0;
11940 }
11941 }
11942 return -1;
11943}
11944
11945////////////////////////////////////////////////////////////////////////////////
11946/// Get the value from the specified parameter from the specified collection.
11947/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11948/// or value type does not match), 0 otherwise.
11949
11951{
11952 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11953 if (obj) {
11954 TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
11955 if (p) {
11956 value = p->GetVal();
11957 return 0;
11958 }
11959 }
11960 return -1;
11961}
11962
11963////////////////////////////////////////////////////////////////////////////////
11964/// Get the value from the specified parameter from the specified collection.
11965/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11966/// or value type does not match), 0 otherwise.
11967
11969{
11970 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11971 if (obj) {
11972 TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
11973 if (p) {
11974 value = p->GetVal();
11975 return 0;
11976 }
11977 }
11978 return -1;
11979}
11980
11981////////////////////////////////////////////////////////////////////////////////
11982/// Make sure that dataset is in the form to be processed. This may mean
11983/// retrieving the relevant info from the dataset manager or from the
11984/// attached input list.
11985/// Returns 0 on success, -1 on error
11986
11988 TDataSetManager *mgr, TString &emsg)
11989{
11990 emsg = "";
11991
11992 // We must have something to process
11993 if (!dset || !input || !mgr) {
11994 emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
11995 return -1;
11996 }
11997
11998 TList *datasets = new TList;
11999 TFileCollection *dataset = 0;
12000 TString lookupopt;
12001 TString dsname(dset->GetName());
12002
12003 // First extract the "entry list" part on the global name, if any
12004 TString dsns(dsname), enlname;
12005 Ssiz_t eli = dsns.Index("?enl=");
12006 if (eli != kNPOS) {
12007 enlname = dsns(eli + strlen("?enl="), dsns.Length());
12008 dsns.Remove(eli, dsns.Length()-eli);
12009 }
12010
12011 // The dataset maybe in the form of a TFileCollection in the input list
12012 if (dsname.BeginsWith("TFileCollection:")) {
12013 // Isolate the real name
12014 dsname.ReplaceAll("TFileCollection:", "");
12015 // Get the object
12016 dataset = (TFileCollection *) input->FindObject(dsname);
12017 if (!dataset) {
12018 emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12019 return -1;
12020 }
12021 // Remove from everywhere
12022 input->RecursiveRemove(dataset);
12023 // Add it to the local list
12024 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12025 // Make sure we lookup everything (unless the client or the administrator
12026 // required something else)
12027 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12028 lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12029 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12030 }
12031 }
12032
12033 // This is the name we parse for additional specifications, such directory
12034 // and object name; for multiple datasets we assume that the directory and
12035 // and object name are the same for all datasets
12036 TString dsnparse;
12037 // The received message included an empty dataset, with only the name
12038 // defined: assume that a dataset, stored on the PROOF master by that
12039 // name, should be processed.
12040 if (!dataset) {
12041
12042 TFileCollection *fc = nullptr;
12043
12044 // Check if the entry list and dataset name are valid. If they have spaces,
12045 // commas, or pipes, they are not considered as valid and we revert to the
12046 // "multiple datasets" case
12047 TRegexp rg("[, |]");
12048 Bool_t validEnl = (enlname.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12049 Bool_t validSdsn = (dsns.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12050
12051 if (validEnl && validSdsn && (( fc = mgr->GetDataSet(dsns) ))) {
12052
12053 //
12054 // String corresponds to ONE dataset only
12055 //
12056
12057 TIter nxfi(fc->GetList());
12058 TFileInfo *fi;
12059 while (( fi = (TFileInfo *)nxfi() ))
12060 fi->SetTitle(dsns.Data());
12061 dataset = fc;
12062 dsnparse = dsns; // without entry list
12063
12064 // Adds the entry list (or empty string if not specified)
12065 datasets->Add( new TPair(dataset, new TObjString( enlname.Data() )) );
12066
12067 } else {
12068
12069 //
12070 // String does NOT correspond to one dataset: check if many datasets
12071 // were specified instead
12072 //
12073
12074 dsns = dsname.Data();
12075 TString dsn1;
12076 Int_t from1 = 0;
12077 while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12078 TString dsn2;
12079 Int_t from2 = 0;
12080 while (dsn1.Tokenize(dsn2, from2, "|")) {
12081 enlname = "";
12082 Int_t ienl = dsn2.Index("?enl=");
12083 if (ienl != kNPOS) {
12084 enlname = dsn2(ienl + 5, dsn2.Length());
12085 dsn2.Remove(ienl);
12086 }
12087 if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12088 // Save dataset name in TFileInfo's title to use it in TDset
12089 TIter nxfi(fc->GetList());
12090 TFileInfo *fi;
12091 while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12092 dsnparse = dsn2;
12093 if (!dataset) {
12094 // This is our dataset
12095 dataset = fc;
12096 } else {
12097 // Add it to the dataset
12098 dataset->Add(fc);
12099 SafeDelete(fc);
12100 }
12101 }
12102 }
12103 // The dataset name(s) in the first element
12104 if (dataset) {
12105 if (dataset->GetList()->First())
12106 ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12107 // Add it to the local list
12108 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12109 }
12110 // Reset the pointer
12111 dataset = 0;
12112 }
12113
12114 }
12115
12116 //
12117 // At this point the dataset(s) to be processed, if any, are found in the
12118 // "datasets" variable
12119 //
12120
12121 if (!datasets || datasets->GetSize() <= 0) {
12122 emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12123 return -1;
12124 } else {
12125 // Make 'dataset' to point to the first one in the list
12126 if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12127 emsg.Form("dataset pointer is null: corruption? - aborting");
12128 return -1;
12129 }
12130 }
12131 // Apply the lookup option requested by the client or the administartor
12132 // (by default we trust the information in the dataset)
12133 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12134 lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12135 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12136 }
12137 } else {
12138 // We were given a named, single, TFileCollection
12139 dsnparse = dsname;
12140 }
12141
12142 // Logic for the subdir/obj names: try first to see if the dataset name contains
12143 // some info; if not check the settings in the TDSet object itself; if still empty
12144 // check the default tree name / path in the TFileCollection object; if still empty
12145 // use the default as the flow will determine
12146 TString dsTree;
12147 // Get the [subdir/]tree, if any
12148 mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12149 if (dsTree.IsNull()) {
12150 // Use what we have in the original dataset; we need this to locate the
12151 // meta data information
12152 dsTree += dset->GetDirectory();
12153 dsTree += dset->GetObjName();
12154 }
12155 if (!dsTree.IsNull() && dsTree != "/") {
12156 TString tree(dsTree);
12157 Int_t idx = tree.Index("/");
12158 if (idx != kNPOS) {
12159 TString dir = tree(0, idx+1);
12160 tree.Remove(0, idx);
12161 dset->SetDirectory(dir);
12162 }
12163 dset->SetObjName(tree);
12164 } else {
12165 // Use the default obj name from the TFileCollection
12166 dsTree = dataset->GetDefaultTreeName();
12167 }
12168
12169 // Pass dataset server mapping instructions, if any
12171 TList *srvmapslist = srvmapsref;
12172 TString srvmaps;
12173 if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12174 srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12175 if (gProofServ) {
12176 TString msg;
12177 if (srvmapsref && !srvmapslist) {
12178 msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12179 } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12180 msg.Form("+++ Info: dataset server mapping(s) modified by user");
12181 } else if (!srvmapsref && srvmapslist) {
12182 msg.Form("+++ Info: dataset server mapping(s) added by user");
12183 }
12185 }
12186 }
12187
12188 // Flag multi-datasets
12189 if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12190 // Loop over the list of datasets
12191 TList *listOfMissingFiles = new TList;
12192 TEntryList *entrylist = 0;
12193 TPair *pair = 0;
12194 TIter nxds(datasets);
12195 while ((pair = (TPair *) nxds())) {
12196 // File Collection
12197 dataset = (TFileCollection *) pair->Key();
12198 // Entry list, if any
12199 TEntryList *enl = 0;
12200 TObjString *os = (TObjString *) pair->Value();
12201 if (strlen(os->GetName())) {
12202 if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12203 if (gProofServ)
12205 " entry list %s not found", os->GetName()));
12206 }
12207 if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12208 if (gProofServ)
12210 " no sub-lists in entry-list!"));
12211 }
12212 }
12213 TList *missingFiles = new TList;
12214 TSeqCollection* files = dataset->GetList();
12215 if (gDebug > 0) files->Print();
12216 Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12217 if (dset->TestBit(TDSet::kMultiDSet)) {
12218 TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12219 ds->SetSrvMaps(srvmapslist);
12220 if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12221 emsg.Form("error integrating dataset %s", dataset->GetName());
12222 continue;
12223 }
12224 // Add the TDSet object to the multi-dataset
12225 dset->Add(ds);
12226 // Add entry list if any
12227 if (enl) ds->SetEntryList(enl);
12228 } else {
12229 dset->SetSrvMaps(srvmapslist);
12230 if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12231 emsg.Form("error integrating dataset %s", dataset->GetName());
12232 continue;
12233 }
12234 if (enl) entrylist = enl;
12235 }
12236 if (missingFiles) {
12237 // The missing files objects have to be removed from the dataset
12238 // before delete.
12239 TIter next(missingFiles);
12240 TObject *file;
12241 while ((file = next())) {
12242 dataset->GetList()->Remove(file);
12243 listOfMissingFiles->Add(file);
12244 }
12245 missingFiles->SetOwner(kFALSE);
12246 missingFiles->Clear();
12247 }
12248 SafeDelete(missingFiles);
12249 }
12250 // Cleanup; we need to do this because pairs do no delete their content
12251 nxds.Reset();
12252 while ((pair = (TPair *) nxds())) {
12253 if (pair->Key()) delete pair->Key();
12254 if (pair->Value()) delete pair->Value();
12255 }
12256 datasets->SetOwner(kTRUE);
12257 SafeDelete(datasets);
12258
12259 // Cleanup the server mapping list, if created by the user
12260 if (srvmapslist && srvmapslist != srvmapsref) {
12261 srvmapslist->SetOwner(kTRUE);
12262 SafeDelete(srvmapslist);
12263 }
12264
12265 // Set the global entrylist, if required
12266 if (entrylist) dset->SetEntryList(entrylist);
12267
12268 // Make sure it will be sent back merged with other similar lists created
12269 // during processing; this list will be transferred by the player to the
12270 // output list, once the latter has been created (see TProofPlayerRemote::Process)
12271 if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12272 listOfMissingFiles->SetName("MissingFiles");
12273 input->Add(listOfMissingFiles);
12274 }
12275
12276 // Done
12277 return 0;
12278}
12279
12280////////////////////////////////////////////////////////////////////////////////
12281/// Save input data file from 'cachedir' into the sandbox or create a the file
12282/// with input data objects
12283
12284Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12285{
12286 TList *input = 0;
12287
12288 // We must have got something to process
12289 if (!qr || !(input = qr->GetInputList()) ||
12290 !cachedir || strlen(cachedir) <= 0) return 0;
12291
12292 // There must be some input data or input data file
12293 TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12294 TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12295 if (!data && !inputdata) return 0;
12296 // Default dstination filename
12297 if (!data)
12298 input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12299
12300 TString dstname(data->GetTitle()), srcname;
12301 Bool_t fromcache = kFALSE;
12302 if (dstname.BeginsWith("cache:")) {
12303 fromcache = kTRUE;
12304 dstname.ReplaceAll("cache:", "");
12305 srcname.Form("%s/%s", cachedir, dstname.Data());
12306 if (gSystem->AccessPathName(srcname)) {
12307 emsg.Form("input data file not found in cache (%s)", srcname.Data());
12308 return -1;
12309 }
12310 }
12311
12312 // If from cache, just move the cache file
12313 if (fromcache) {
12314 if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12315 emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12316 return -1;
12317 }
12318 } else {
12319 // Create the file
12320 if (inputdata && inputdata->GetSize() > 0) {
12321 TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12322 if (f) {
12323 f->cd();
12324 inputdata->Write();
12325 f->Close();
12326 delete f;
12327 } else {
12328 emsg.Form("could not create %s", dstname.Data());
12329 return -1;
12330 }
12331 } else {
12332 emsg.Form("no input data!");
12333 return -1;
12334 }
12335 }
12336 ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12337
12338 // Save the file name and clean up the data list
12339 data->SetTitle(dstname);
12340 if (inputdata) {
12341 input->Remove(inputdata);
12342 inputdata->SetOwner();
12343 delete inputdata;
12344 }
12345
12346 // Done
12347 return 0;
12348}
12349
12350////////////////////////////////////////////////////////////////////////////////
12351/// Send the input data file to the workers
12352
12354{
12355 TList *input = 0;
12356
12357 // We must have got something to process
12358 if (!qr || !(input = qr->GetInputList())) return 0;
12359
12360 // There must be some input data or input data file
12361 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12362 if (!inputdata) return 0;
12363
12364 TString fname(inputdata->GetTitle());
12365 if (gSystem->AccessPathName(fname)) {
12366 emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12367 return -1;
12368 }
12369
12370 // PROOF session must available
12371 if (!p || !p->IsValid()) {
12372 emsg.Form("TProof object undefined or invalid: protocol error!");
12373 return -1;
12374 }
12375
12376 // Send to unique workers and submasters
12377 p->BroadcastFile(fname, TProof::kBinary, "cache");
12378
12379 // Done
12380 return 0;
12381}
12382
12383////////////////////////////////////////////////////////////////////////////////
12384/// Get the input data from the file defined in the input list
12385
12386Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12387{
12388 // We must have got something to process
12389 if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12390
12391 // There must be some input data or input data file
12392 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12393 if (!inputdata) return 0;
12394
12395 TString fname;
12396 fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12397 if (gSystem->AccessPathName(fname)) {
12398 emsg.Form("input data file not found in cache (%s)", fname.Data());
12399 return -1;
12400 }
12401
12402 // List of added objects (for proper cleaning ...)
12403 TList *added = new TList;
12404 added->SetName("PROOF_InputObjsFromFile");
12405 // Read the input data into the input list
12406 TFile *f = TFile::Open(fname.Data());
12407 if (f) {
12408 TList *keys = (TList *) f->GetListOfKeys();
12409 if (!keys) {
12410 emsg.Form("could not get list of object keys from file");
12411 return -1;
12412 }
12413 TIter nxk(keys);
12414 TKey *k = 0;
12415 while ((k = (TKey *)nxk())) {
12416 TObject *o = f->Get(k->GetName());
12417 if (o) {
12418 input->Add(o);
12419 added->Add(o);
12420 }
12421 }
12422 // Add the file as last one
12423 if (added->GetSize() > 0) {
12424 added->Add(f);
12425 input->Add(added);
12426 } else {
12427 // Cleanup the file now
12428 f->Close();
12429 delete f;
12430 }
12431 } else {
12432 emsg.Form("could not open %s", fname.Data());
12433 return -1;
12434 }
12435
12436 // Done
12437 return 0;
12438}
12439
12440////////////////////////////////////////////////////////////////////////////////
12441/// Start the log viewer window usign the plugin manager
12442
12443void TProof::LogViewer(const char *url, Int_t idx)
12444{
12445 if (!gROOT->IsBatch()) {
12446 // Get the handler, if not yet done
12447 if (!fgLogViewer) {
12448 if ((fgLogViewer =
12449 gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
12450 if (fgLogViewer->LoadPlugin() == -1) {
12451 fgLogViewer = 0;
12452 ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
12453 return;
12454 }
12455 }
12456 }
12457 if (fgLogViewer) {
12458 // Execute the plug-in
12459 TString u = (url && strlen(url) <= 0) ? "lite" : url;
12460 fgLogViewer->ExecPlugin(2, u.Data(), idx);
12461 }
12462 } else {
12463 if (url && strlen(url) > 0) {
12464 ::Info("TProof::LogViewer",
12465 "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
12466 } else if (url && strlen(url) <= 0) {
12467 ::Info("TProof::LogViewer",
12468 "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
12469 } else {
12470 ::Info("TProof::LogViewer",
12471 "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
12472 }
12473 }
12474 // Done
12475 return;
12476}
12477
12478////////////////////////////////////////////////////////////////////////////////
12479/// Enable/Disable the graphic progress dialog.
12480/// By default the dialog is enabled
12481
12483{
12484 if (on)
12486 else
12488}
12489
12490////////////////////////////////////////////////////////////////////////////////
12491/// Show information about missing files during query described by 'qr' or the
12492/// last query if qr is null (default).
12493/// A short summary is printed in the end.
12494
12496{
12497 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12498 if (!xqr) {
12499 Warning("ShowMissingFiles", "no (last) query found: do nothing");
12500 return;
12501 }
12502
12503 // Get the list, if any
12504 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12505 if (!missing) {
12506 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12507 return;
12508 }
12509
12510 Int_t nmf = 0, ncf = 0;
12511 Long64_t msz = 0, mszzip = 0, mev = 0;
12512 // Scan the list
12513 TFileInfo *fi = 0;
12514 TIter nxf(missing);
12515 while ((fi = (TFileInfo *) nxf())) {
12516 char status = 'M';
12517 if (fi->TestBit(TFileInfo::kCorrupted)) {
12518 ncf++;
12519 status = 'C';
12520 } else {
12521 nmf++;
12522 }
12523 TFileInfoMeta *im = fi->GetMetaData();
12524 if (im) {
12525 if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
12526 if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
12527 mev += im->GetEntries();
12528 Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
12529 } else {
12530 Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
12531 }
12532 }
12533
12534 // Final notification
12535 if (msz <= 0) msz = -1;
12536 if (mszzip <= 0) mszzip = -1;
12537 Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
12538 if (msz > 0. || mszzip > 0.) {
12539 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12540 " about %.2f%% of the total (%lld bytes, %lld zipped)",
12541 nmf, ncf, mev, xf * 100., msz, mszzip);
12542 } else {
12543 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12544 " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
12545 }
12546}
12547
12548////////////////////////////////////////////////////////////////////////////////
12549/// Get a TFileCollection with the files missing in the query described by 'qr'
12550/// or the last query if qr is null (default).
12551/// Return a null pointer if none were found, for whatever reason.
12552/// The caller is responsible for the returned object.
12553
12555{
12556 TFileCollection *fc = 0;
12557
12558 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12559 if (!xqr) {
12560 Warning("GetMissingFiles", "no (last) query found: do nothing");
12561 return fc;
12562 }
12563
12564 // Get the list, if any
12565 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12566 if (!missing) {
12567 if (gDebug > 0)
12568 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12569 return fc;
12570 }
12571
12572 // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
12573 TString fcname("unknown");
12574 TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
12575 if (ds) {
12576 fcname.Form("%s.m0", ds->GetName());
12577 Int_t j = 1;
12578 while (gDirectory->FindObject(fcname) && j < 1000)
12579 fcname.Form("%s.m%d", ds->GetName(), j++);
12580 }
12581 fc = new TFileCollection(fcname, "Missing Files");
12582 if (ds) fc->SetDefaultTreeName(ds->GetObjName());
12583 // Scan the list
12584 TFileInfo *fi = 0;
12585 TIter nxf(missing);
12586 while ((fi = (TFileInfo *) nxf())) {
12587 fc->Add((TFileInfo *) fi->Clone());
12588 }
12589 fc->Update();
12590 // Done
12591 return fc;
12592}
12593
12594////////////////////////////////////////////////////////////////////////////////
12595/// Enable/Disable saving of the performance tree
12596
12597void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
12598{
12599 if (pf && strlen(pf) > 0) {
12600 fPerfTree = pf;
12601 SetParameter("PROOF_StatsHist", "");
12602 SetParameter("PROOF_StatsTrace", "");
12603 if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
12604 Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
12605 } else {
12606 fPerfTree = "";
12607 DeleteParameters("PROOF_StatsHist");
12608 DeleteParameters("PROOF_StatsTrace");
12609 DeleteParameters("PROOF_SlaveStatsTrace");
12610 Info("SetPerfTree", "saving of the performance tree disabled");
12611 }
12612}
12613
12614////////////////////////////////////////////////////////////////////////////////
12615/// Save performance information from TPerfStats to file 'pf'.
12616/// If 'ref' is defined, do it for query 'ref'.
12617/// Return 0 on sucecss, -1 in case of any error
12618
12619Int_t TProof::SavePerfTree(const char *pf, const char *ref)
12620{
12621 if (!IsValid()) {
12622 Error("SafePerfTree", "this TProof instance is invalid!");
12623 return -1;
12624 }
12625
12626 TList *outls = GetOutputList();
12627 TString sref;
12628 if (ref && strlen(ref) > 0) {
12629 if (!fPlayer) {
12630 Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
12631 return -1;
12632 }
12634 if (!qr) {
12635 Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
12636 return -1;
12637 }
12638 outls = qr->GetOutputList();
12639 sref.Form(" for requested query '%s'", ref);
12640 }
12641 if (!outls || (outls && outls->GetSize() <= 0)) {
12642 Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
12643 return -1;
12644 }
12645
12646 TString fn = fPerfTree;
12647 if (pf && strlen(pf)) fn = pf;
12648 if (fn.IsNull()) fn = "perftree.root";
12649
12650 TFile f(fn, "RECREATE");
12651 if (f.IsZombie()) {
12652 Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
12653 } else {
12654 f.cd();
12655 TIter nxo(outls);
12656 TObject* obj = 0;
12657 while ((obj = nxo())) {
12658 TString objname(obj->GetName());
12659 if (objname.BeginsWith("PROOF_")) {
12660 // Must list the objects since other PROOF_ objects exist
12661 // besides timing objects
12662 if (objname == "PROOF_PerfStats" ||
12663 objname == "PROOF_PacketsHist" ||
12664 objname == "PROOF_EventsHist" ||
12665 objname == "PROOF_NodeHist" ||
12666 objname == "PROOF_LatencyHist" ||
12667 objname == "PROOF_ProcTimeHist" ||
12668 objname == "PROOF_CpuTimeHist")
12669 obj->Write();
12670 }
12671 }
12672 f.Close();
12673 }
12674 Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
12675
12676 // Done
12677 return 0;
12678}
void Class()
Definition: Class.C:29
@ kPROOF_VALIDATE_DSET
Definition: MessageTypes.h:70
@ kPROOF_PING
Definition: MessageTypes.h:48
@ kMESS_OK
Definition: MessageTypes.h:32
@ kPROOF_DATA_READY
Definition: MessageTypes.h:71
@ kPROOF_GETSTATS
Definition: MessageTypes.h:68
@ kPROOF_GETTREEHEADER
Definition: MessageTypes.h:66
@ kPROOF_PROGRESS
Definition: MessageTypes.h:61
@ kPROOF_QUERYLIST
Definition: MessageTypes.h:72
@ kPROOF_CHECKFILE
Definition: MessageTypes.h:53
@ kPROOF_GOASYNC
Definition: MessageTypes.h:96
@ kPROOF_PARALLEL
Definition: MessageTypes.h:55
@ kPROOF_LOGLEVEL
Definition: MessageTypes.h:44
@ kMESS_NOTOK
Definition: MessageTypes.h:33
@ kPROOF_SENDOUTPUT
Definition: MessageTypes.h:99
@ kPROOF_SESSIONTAG
Definition: MessageTypes.h:79
@ kPROOF_RETRIEVE
Definition: MessageTypes.h:73
@ kPROOF_AUTOBIN
Definition: MessageTypes.h:58
@ kPROOF_TOUCH
Definition: MessageTypes.h:94
@ kPROOF_GETOBJECT
Definition: MessageTypes.h:51
@ kMESS_OBJECT
Definition: MessageTypes.h:35
@ kPROOF_STOPPROCESS
Definition: MessageTypes.h:63
@ kPROOF_VERSARCHCOMP
Definition: MessageTypes.h:92
@ kPROOF_LOGFILE
Definition: MessageTypes.h:45
@ kPROOF_REMOVE
Definition: MessageTypes.h:75
@ kPROOF_FATAL
Definition: MessageTypes.h:43
@ kPROOF_OUTPUTOBJECT
Definition: MessageTypes.h:89
@ kPROOF_REALTIMELOG
Definition: MessageTypes.h:91
@ kPROOF_SUBMERGER
Definition: MessageTypes.h:97
@ kPROOF_QUERYSUBMITTED
Definition: MessageTypes.h:78
@ kPROOF_ARCHIVE
Definition: MessageTypes.h:74
@ kPROOF_SENDFILE
Definition: MessageTypes.h:54
@ kPROOF_ECHO
Definition: MessageTypes.h:98
@ kPROOF_GETPACKET
Definition: MessageTypes.h:52
@ kPROOF_WORKERLISTS
Definition: MessageTypes.h:87
@ kPROOF_OUTPUTLIST
Definition: MessageTypes.h:57
@ kPROOF_RESET
Definition: MessageTypes.h:50
@ kPROOF_GETPARALLEL
Definition: MessageTypes.h:69
@ kPROOF_PRINT
Definition: MessageTypes.h:49
@ kPROOF_FEEDBACK
Definition: MessageTypes.h:62
@ kPROOF_SERVERSTARTED
Definition: MessageTypes.h:82
@ kPROOF_DATASET_STATUS
Definition: MessageTypes.h:88
@ kPROOF_LIB_INC_PATH
Definition: MessageTypes.h:86
@ kPROOF_CACHE
Definition: MessageTypes.h:59
@ kPROOF_MESSAGE
Definition: MessageTypes.h:85
@ kPROOF_LOGDONE
Definition: MessageTypes.h:46
@ kPROOF_DATASETS
Definition: MessageTypes.h:83
@ kMESS_CINT
Definition: MessageTypes.h:36
@ kPROOF_ENDINIT
Definition: MessageTypes.h:93
@ kPROOF_PACKAGE_LIST
Definition: MessageTypes.h:84
@ kPROOF_SETIDLE
Definition: MessageTypes.h:77
@ kPROOF_STARTPROCESS
Definition: MessageTypes.h:76
@ kPROOF_GETSLAVEINFO
Definition: MessageTypes.h:65
@ kPROOF_MAXQUERIES
Definition: MessageTypes.h:80
@ kPROOF_CLEANUPSESSION
Definition: MessageTypes.h:81
@ kPROOF_STOP
Definition: MessageTypes.h:42
@ kPROOF_GROUPVIEW
Definition: MessageTypes.h:41
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:529
#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 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)
static double p3(double t, double a, double b, double c, double d)
static double p2(double t, double a, double b, double c)
static RooMathCoreReg dummy
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:363
R__EXTERN Int_t gDebug
Definition: Rtypes.h:90
R__EXTERN TApplication * gApplication
Definition: TApplication.h:165
const Bool_t kIterBackward
Definition: TCollection.h:41
#define gDirectory
Definition: TDirectory.h:213
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
#define R__ASSERT(e)
Definition: TError.h:96
void Error(const char *location, const char *msgfmt,...)
static unsigned int total
int type
Definition: TGX11.cxx:120
#define Printf
Definition: TGeoToOCC.h:18
float xmin
Definition: THbookFile.cxx:93
int nentries
Definition: THbookFile.cxx:89
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
#define gInterpreter
Definition: TInterpreter.h:538
const Bool_t kSortDescending
Definition: TList.h:38
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:344
TProof * gProof
Definition: TProof.cxx:105
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
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
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
#define gROOT
Definition: TROOT.h:410
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
char * Form(const char *fmt,...)
@ kFileExists
Definition: TSystem.h:45
@ kReadPermission
Definition: TSystem.h:48
@ kWritePermission
Definition: TSystem.h:47
Bool_t R_ISLNK(Int_t mode)
Definition: TSystem.h:120
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:116
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
#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
Definition: TApplication.h:106
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
virtual void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE)
Write object to I/O buffer.
Definition: TBufferIO.cxx:530
Int_t BufferSize() const
Definition: TBuffer.h:94
Int_t Length() const
Definition: TBuffer.h:96
A chain is a collection of files containing TTree objects.
Definition: TChain.h:33
Collection abstract base class.
Definition: TCollection.h:63
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)
Definition: TCollection.h:204
virtual Int_t GetEntries() const
Definition: TCollection.h:177
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
Definition: TCollection.h:169
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
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.
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Utility class to draw objects in the feedback list during queries.
Definition: TDrawFeedback.h:35
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:26
virtual TList * GetLists() const
Definition: TEntryList.h:73
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=0)
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:144
Long64_t GetTotBytes() const
Definition: TFileInfo.h:143
Long64_t GetEntries() const
Definition: TFileInfo.h:139
Class describing a generic file including meta information.
Definition: TFileInfo.h:38
@ kCorrupted
Definition: TFileInfo.h:58
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
Definition: TFileInfo.cxx:260
TUrl * GetFirstUrl() const
Definition: TFileInfo.h:71
Int_t GetNUrls() const
Definition: TFileInfo.h:74
void ResetUrl()
Definition: TFileInfo.h:68
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:248
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
Definition: TFileInfo.cxx:424
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:912
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=0)
Resolve the file type as a function of the protocol field in 'name'.
Definition: TFile.cxx:4690
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1418
EFileType
File type.
Definition: TFile.h:187
@ kWeb
Definition: TFile.h:187
@ kNet
Definition: TFile.h:187
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:4873
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3975
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.
Definition: THashList.cxx:262
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:378
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:207
Int_t GetPort() const
Definition: TInetAddress.h:73
const char * GetHostName() const
Definition: TInetAddress.h:71
void Reset()
Definition: TCollection.h:252
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual const char * GetClassName() const
Definition: TKey.h:71
Iterator of linked list.
Definition: TList.h:200
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:327
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:689
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:247
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:760
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
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:139
TList * GetListOfLines() const
Definition: TMacro.h:51
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:301
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:53
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition: TProof.cxx:328
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job.
Definition: TProof.cxx:320
TSlave * GetMerger()
Definition: TProof.h:274
virtual ~TMergerInfo()
Destructor.
Definition: TProof.cxx:284
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:295
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition: TProof.cxx:306
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-posteriory.
Definition: TMessage.cxx:221
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:37
Collectable string class.
Definition: TObjString.h:28
const char * GetName() const
Returns name of object.
Definition: TObjString.h:39
const TString & GetString() const
Definition: TObjString.h:47
TString & String()
Definition: TObjString.h:49
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:144
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:894
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:321
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
@ kSingleKey
write collection with single key
Definition: TObject.h:87
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
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:708
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:933
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition: TPackMgr.cxx:871
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:37
const AParamType & GetVal() const
Definition: TParameter.h:69
const char * GetName() const
Returns name of object.
Definition: TParameter.h:68
Long_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.
TProofInputHandler(const TProofInputHandler &)
TProof * fProof
Definition: TProof.h:201
Bool_t Notify()
Handle input.
Definition: TProof.cxx:166
TSocket * fSocket
Definition: TProof.h:200
Bool_t Notify()
TProof interrupt handler.
Definition: TProof.cxx:119
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.
Definition: TProofMgr.cxx:306
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
Definition: TProofMgr.cxx:228
static TProofMgr * Create(const char *url, Int_t loglevel=-1, const char *alias=0, Bool_t xpd=kTRUE)
Static method returning the appropriate TProofMgr object using the plugin manager.
Definition: TProofMgr.cxx:498
virtual Int_t Rm(const char *, const char *=0, const char *=0)
Run 'rm' on 'what'. Locally it is just a call to TSystem::Unlink .
Definition: TProofMgr.cxx:1065
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).
Definition: TProofMgr.cxx:386
virtual Bool_t IsValid() const
Definition: TProofMgr.h:77
@ kProofLite
Definition: TProofMgr.h:46
@ kXProofd
Definition: TProofMgr.h:46
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.
Definition: TProofMgr.cxx:123
virtual Bool_t IsProofd() const
Definition: TProofMgr.h:76
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to 'id'.
Definition: TProofMgr.cxx:324
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.
Definition: TProofMgr.cxx:366
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>, , <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:8970
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:6505
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition: TProof.cxx:1974
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7742
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition: TProof.cxx:7368
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:7040
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition: TProof.cxx:11696
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition: TProof.cxx:4426
Int_t BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list=kAllUnique)
Broadcast the group priority to all workers in the specified list.
Definition: TProof.cxx:2429
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:2083
TProofMgr * fManager
Definition: TProof.h:587
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition: TProof.cxx:4382
TList * GetOutputNames()
FIXME: to be written.
Definition: TProof.cxx:10090
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:6231
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition: TProof.cxx:10293
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:6330
void Activate(TList *slaves=0)
Activate slave server list.
Definition: TProof.cxx:2367
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8413
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:5204
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6730
void Close(Option_t *option="")
Close all open slave servers.
Definition: TProof.cxx:1776
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:7084
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:7914
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:8306
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:11248
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:12284
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:2143
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:7962
Bool_t IsTty() const
Definition: TProof.h:938
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4775
Int_t GetClientProtocol() const
Definition: TProof.h:914
Int_t fCollectTimeout
Definition: TProof.h:583
virtual ~TProof()
Clean up PROOF environment.
Definition: TProof.cxx:649
EQueryMode fQueryMode
Definition: TProof.h:588
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition: TProof.cxx:10203
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition: TProof.cxx:1512
static Int_t GetInputData(TList *input, const char *cachedir, TString &emsg)
Get the input data from the file defined in the input list.
Definition: TProof.cxx:12386
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:7026
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition: TProof.cxx:4909
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:9961
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:12443
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:716
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition: TProof.cxx:3018
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition: TProof.cxx:4395
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:2545
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:11768
void AddInputData(TObject *obj, Bool_t push=kFALSE)
Add data objects that might be needed during the processing of the selector (see Process()).
Definition: TProof.cxx:9494
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2055
FileMap_t fFileMap
Definition: TProof.h:502
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7686
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:10868
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:11325
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition: TProof.cxx:6064
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition: TProof.cxx:11018
TList * fChains
Definition: TProof.h:496
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:9890
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:6029
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition: TProof.cxx:4306
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition: TProof.cxx:9080
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'.
Definition: TProof.cxx:2126
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition: TProof.cxx:1956
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition: TProof.cxx:9284
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:8571
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:8860
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition: TProof.cxx:10781
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:7663
void ClearFeedback()
Clear feedback list.
Definition: TProof.cxx:9984
static TProof * Open(const char *url=0, const char *conffile=0, const char *confdir=0, Int_t loglevel=0)
Start a PROOF session on a specific cluster.
Definition: TProof.cxx:11555
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition: TProof.cxx:10151
Int_t GetPort() const
Definition: TProof.h:912
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition: TProof.cxx:11307
void ResetMergePrg()
Reset the merge progress notificator.
Definition: TProof.cxx:2443
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition: TProof.cxx:12597
void ClearData(UInt_t what=kUnregistered, const char *dsname=0)
Remove files for the data directory.
Definition: TProof.cxx:7384
Bool_t IsValid() const
Definition: TProof.h:937
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4754
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:1253
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition: TProof.cxx:11088
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition: TProof.cxx:11153
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:11361
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7112
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition: TProof.cxx:7142
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:10886
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:4276
@ 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:6637
static void AddEnvVar(const char *name, const char *value)
Add an variable to the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:11732
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:6467
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition: TProof.cxx:10818
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:2647
Float_t GetCpuTime() const
Definition: TProof.h:931
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition: TProof.cxx:7642
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition: TProof.cxx:12353
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10171
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7829
Int_t SendInitialState()
Transfer the initial (i.e.
Definition: TProof.cxx:6746
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1304
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition: TProof.cxx:2013
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:10679
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition: TProof.cxx:2453
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:9905
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:9611
void InitMembers()
Default initializations.
Definition: TProof.cxx:524
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition: TProof.cxx:4230
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition: TProof.cxx:3986
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:9557
Int_t fStatus
Definition: TProof.h:470
TList * fRunningDSets
Definition: TProof.h:581
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7812
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:9794
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition: TProof.cxx:1638
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition: TProof.cxx:4716
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:1853
void SaveActiveList()
Save current list of active workers.
Definition: TProof.cxx:11514
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:10738
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:12495
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:8939
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'.
Definition: TProof.cxx:2386
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2282
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:8086
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition: TProof.cxx:9972
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition: TProof.cxx:5985
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:4325
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2000
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition: TProof.cxx:10555
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:10490
void PrintProgress(Long64_t total, Long64_t processed, Float_t procTime=-1., Long64_t bytesread=-1)
Print a progress bar on stderr. Used in batch mode.
Definition: TProof.cxx:9112
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:745
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:6118
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:11342
@ 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:7068
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition: TProof.cxx:10468
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:12554
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning,...
Definition: TProof.cxx:1031
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition: TProof.cxx:1992
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition: TProof.cxx:5920
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:2588
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:9930
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:9308
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:10963
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition: TProof.cxx:6386
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition: TProof.cxx:11708
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition: TProof.cxx:2942
Int_t fLastAssignedMerger
Definition: TProof.h:552
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition: TProof.cxx:2117
void ShowFeedback() const
Show items in feedback list.
Definition: TProof.cxx:9992
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:7245
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition: TProof.cxx:6079
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8119
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10183
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:10982
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition: TProof.cxx:12619
virtual Int_t Load(const char *macro, Bool_t notOnClient=kFALSE, Bool_t uniqueOnly=kTRUE, TList *wrks=0)
Load the specified macro on master, workers and, if notOnClient is kFALSE, on the client.
Definition: TProof.cxx:8600
@ 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:8815
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition: TProof.cxx:510
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:1575
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition: TProof.cxx:9173
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition: TProof.cxx:5855
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:8905
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:11281
Bool_t fIsPollingWorkers
Definition: TProof.h:475
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition: TProof.cxx:10082
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:11045
Bool_t CheckFile(const char *file, TSlave *sl, Long_t modtime, Int_t cpopt=(kCp|kCpBin))
Check if a file needs to be send to the slave.
Definition: TProof.cxx:6771
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:7621
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition: TProof.cxx:12482
TString fLogFileName
Definition: TProof.h:511
void GoAsynchronous()
Send GOASYNC message to the master.
Definition: TProof.cxx:6239
Int_t fCheckFileStatus
Definition: TProof.h:471
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:9780
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:1285
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition: TProof.cxx:6616
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:6196
TList * GetEnabledPackages() const
Definition: TProof.h:735
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition: TProof.cxx:1965
TSlave * CreateSlave(const char *url, const char *ord, Int_t perf, const char *image, const char *workdir)
Create a new TSlave of type TSlave::kSlave.
Definition: TProof.cxx:1831
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition: TProof.cxx:2106
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:6866
static Int_t AssertDataSet(TDSet *dset, TList *input, TDataSetManager *mgr, TString &emsg)
Make sure that dataset is in the form to be processed.
Definition: TProof.cxx:11987
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:2254
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:10607
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:4493
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition: TProof.cxx:6432
Bool_t IsProofd() const
Definition: TProof.h:934
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition: TProof.cxx:11529
virtual Int_t Echo(const TObject *obj)
Sends an object to master and workers and expect them to send back a message with the output of its T...
Definition: TProof.cxx:7000
void ShowLog(Int_t qry=-1)
Display on screen the content of the temporary log file.
Definition: TProof.cxx:10343
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:9510
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6603
void Feedback(TList *objs)
Get list of feedback objects.
Definition: TProof.cxx:9240
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition: TProof.cxx:10992
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:9734
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2299
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition: TProof.cxx:10014
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9352
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:10656
@ 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:1890
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:4668
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition: TProof.cxx:7707
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition: TProof.cxx:6091
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:8041
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:9271
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition: TProof.cxx:10074
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:10909
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:10066
void AddChain(TChain *chain)
Add chain to data set.
Definition: TProof.cxx:10195
static const TList * GetEnvVars()
Get environemnt variables.
Definition: TProof.cxx:11723
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition: TProof.cxx:1869
TString fGroup
Definition: TProof.h:468
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition: TProof.cxx:9096
TList * GetFeedbackList() const
Return feedback list.
Definition: TProof.cxx:10005
virtual void SendInputDataFile()
Send the input data objects to the master; the objects are taken from the dedicated list and / or the...
Definition: TProof.cxx:9584
TList * fEnabledPackages
Definition: TProof.h:580
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2066
static void DelEnvVar(const char *name)
Remove an variable from the list of environment variables passed to proofserv on the master and slave...
Definition: TProof.cxx:11754
Int_t BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
Broadcast an object to all slaves in the specified list.
Definition: TProof.cxx:2521
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7051
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:5275
void ClearInput()
Clear input object list.
Definition: TProof.cxx:9714
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:1004
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7857
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition: TProof.cxx:5829
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition: TProof.cxx:1983
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition: TProof.cxx:10840
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition: TProof.cxx:10949
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition: TProof.cxx:3077
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:9706
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:6259
Bool_t IsMaster() const
Definition: TProof.h:936
void CloseProgressDialog()
Close progress dialog.
Definition: TProof.cxx:9255
TProofOutputList fOutputList
Definition: TProof.h:538
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition: TProof.cxx:4408
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition: TProof.cxx:9296
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition: TProof.cxx:10229
TList * GetInputList()
Get input list.
Definition: TProof.cxx:9725
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:2632
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7790
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition: TProof.cxx:2093
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition: TProof.cxx:10212
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition: TProof.cxx:3032
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:9341
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition: TProof.cxx:11780
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition: TProof.cxx:8147
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:2218
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:11102
TString fImage
Definition: TProof.h:570
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:165
void EmitVA(const char *signal_name, Int_t, const T &... params)
Emit a signal with a varying number of arguments.
Definition: TQObject.h:101
A container class for query results.
Definition: TQueryResult.h:36
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
Long64_t GetEntries() const
Definition: TQueryResult.h:122
Int_t GetSeqNum() const
Definition: TQueryResult.h:115
void SetTermTime(Float_t termtime)
Definition: TQueryResult.h:100
void SetArchived(const char *archfile)
Set (or update) query in archived state.
TList * GetOutputList()
Definition: TQueryResult.h:131
void SetPrepTime(Float_t preptime)
Definition: TQueryResult.h:97
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()
Definition: TQueryResult.h:120
TMacro * GetLogFile() const
Definition: TQueryResult.h:126
Bool_t IsFinalized() const
Definition: TQueryResult.h:145
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2764
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition: TROOT.cxx:2790
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:533
virtual UInt_t Integer(UInt_t imax)
Returns a random integer on [ 0, imax-1 ].
Definition: TRandom.cxx:341
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:33
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:180
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
@ kActive
Definition: TProof.h:214
@ 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:265
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:208
const char * GetDataDir() const
Definition: TProof.h:229
void Print(Option_t *option="") const
Print slave info.
Definition: TProof.cxx:222
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:656
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:630
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:442
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:394
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition: TSlave.cxx:511
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:179
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition: TSlave.cxx:494
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:277
Int_t GetPerfIdx() const
Definition: TSlave.h:132
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:817
Int_t GetRemoteProtocol() const
Definition: TSocket.h:146
TInetAddress GetInetAddress() const
Definition: TSocket.h:133
TSecContext * GetSecContext() const
Definition: TSocket.h:147
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 Bool_t IsValid() const
Definition: TSocket.h:152
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...
Definition: TStopwatch.cxx:110
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:77
void Reset()
Definition: TStopwatch.h:52
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:406
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:644
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1896
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2152
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1081
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:1962
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1766
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:487
const char * Data() const
Definition: TString.h:364
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1738
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
@ kTrailing
Definition: TString.h:262
@ kBoth
Definition: TString.h:262
@ kIgnoreCase
Definition: TString.h:263
@ kExact
Definition: TString.h:263
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:876
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2172
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Prepend(const char *cs)
Definition: TString.h:656
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2286
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2264
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3820
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:285
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1264
const char * pwd()
Definition: TSystem.h:405
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:269
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:4061
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:1496
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1013
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:716
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1331
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1652
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3894
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4160
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:913
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:662
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:4096
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:671
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:1388
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:1286
virtual FILE * TempFileName(TString &base, const char *dir=0)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition: TSystem.cxx:1487
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:680
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:941
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:541
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1782
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:689
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:312
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1644
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:958
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1793
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:878
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1536
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2334
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:551
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1636
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3804
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1371
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1588
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1702
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1472
A TTree object has a header with a name and a title.
Definition: TTree.h:71
virtual Long64_t GetMaxEntryLoop() const
Definition: TTree.h:436
This class represents a RFC 3986 compatible URI.
Definition: TUri.h:35
Bool_t SetFragment(const TString &fragment)
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:35
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
const char * GetFile() const
Definition: TUrl.h:72
void SetUser(const char *user)
Definition: TUrl.h:85
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition: TUrl.cxx:518
const char * GetUser() const
Definition: TUrl.h:68
const char * GetHost() const
Definition: TUrl.h:70
void SetOptions(const char *opt)
Definition: TUrl.h:90
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
const char * GetOptions() const
Definition: TUrl.h:74
void SetHost(const char *host)
Definition: TUrl.h:87
const char * GetProtocol() const
Definition: TUrl.h:67
void SetPort(Int_t port)
Definition: TUrl.h:91
Int_t GetPort() const
Definition: TUrl.h:81
void SetPasswd(const char *pw)
Definition: TUrl.h:86
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
static constexpr double nm
static constexpr double s
static constexpr double pc
static constexpr double pi
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:701
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
Definition: file.py:1
Definition: first.py:1
Definition: tree.py:1
const char * cnt
Definition: TXMLSetup.cxx:74
Int_t fMode
Definition: TSystem.h:128
Bool_t fIsLink
Definition: TSystem.h:133
Int_t fCpuSpeed
Definition: TSystem.h:156
Int_t fL2Cache
Definition: TSystem.h:158
Int_t fBusSpeed
Definition: TSystem.h:157
TString fCpuType
Definition: TSystem.h:154
Int_t fCpus
Definition: TSystem.h:155
Int_t fPhysRam
Definition: TSystem.h:159
TString fOS
Definition: TSystem.h:152
TString fModel
Definition: TSystem.h:153
Long_t fModtime
Definition: TProof.h:499
TString fUser
Definition: TSystem.h:142
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12