Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TProof.cxx
Go to the documentation of this file.
1// @(#)root/proof:$Id: a2a50e759072c37ccbc65ecbcce735a76de86e95 $
2// Author: Fons Rademakers 13/02/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11/**
12 \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 "TFTP.h"
65#include "THashList.h"
66#include "TInterpreter.h"
67#include "TKey.h"
68#include "TMap.h"
69#include "TMath.h"
70#include "TMessage.h"
71#include "TMonitor.h"
72#include "TObjArray.h"
73#include "TObjString.h"
74#include "TParameter.h"
75#include "TProof.h"
76#include "TProofNodeInfo.h"
77#include "TProofOutputFile.h"
78#include "TVirtualProofPlayer.h"
79#include "TVirtualPacketizer.h"
80#include "TProofServ.h"
81#include "TPluginManager.h"
82#include "TQueryResult.h"
83#include "TRandom.h"
84#include "TRegexp.h"
85#include "TROOT.h"
86#include "TSlave.h"
87#include "TSocket.h"
88#include "TSortedList.h"
89#include "TSystem.h"
90#include "TTree.h"
91#include "TUrl.h"
92#include "TFileCollection.h"
93#include "TDataSetManager.h"
94#include "TDataSetManagerFile.h"
95#include "TMacro.h"
96#include "TSelector.h"
97#include "TPRegexp.h"
98#include "TPackMgr.h"
99
100#include <mutex>
101
103
104// Rotating indicator
105char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
106
107TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
108TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
109
111
112//----- PROOF Interrupt signal handler -----------------------------------------
113////////////////////////////////////////////////////////////////////////////////
114/// TProof interrupt handler.
115
117{
118 if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
119
120 // Cannot ask the user : abort any remote processing
122
123 } else {
124 // Real stop or request to switch to asynchronous?
125 const char *a = 0;
126 if (fProof->GetRemoteProtocol() < 22) {
127 a = Getline("\nSwitch to asynchronous mode not supported remotely:"
128 "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
129 } else {
130 a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
131 " any other key to continue: ");
132 }
133 if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
134
135 Info("Notify","Processing interrupt signal ... %c", a[0]);
136
137 // Stop or abort any remote processing
138 Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
139 fProof->StopProcess(abort);
140
141 } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
142 // Stop any remote processing
144 }
145 }
146
147 return kTRUE;
148}
149
150//----- Input handler for messages from TProofServ -----------------------------
151////////////////////////////////////////////////////////////////////////////////
152/// Constructor
153
155 : TFileHandler(s->GetDescriptor(),1),
156 fSocket(s), fProof(p)
157{
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Handle input
162
164{
166 return kTRUE;
167}
168
169
170//------------------------------------------------------------------------------
171
173
174////////////////////////////////////////////////////////////////////////////////
175/// Used to sort slaveinfos by ordinal.
176
178{
179 if (!obj) return 1;
180
181 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
182
183 if (!si) return fOrdinal.CompareTo(obj->GetName());
184
185 const char *myord = GetOrdinal();
186 const char *otherord = si->GetOrdinal();
187 while (myord && otherord) {
188 Int_t myval = atoi(myord);
189 Int_t otherval = atoi(otherord);
190 if (myval < otherval) return 1;
191 if (myval > otherval) return -1;
192 myord = strchr(myord, '.');
193 if (myord) myord++;
194 otherord = strchr(otherord, '.');
195 if (otherord) otherord++;
196 }
197 if (myord) return -1;
198 if (otherord) return 1;
199 return 0;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Used to compare slaveinfos by ordinal.
204
206{
207 if (!obj) return kFALSE;
208 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
209 if (!si) return kFALSE;
210 return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
211}
212
213////////////////////////////////////////////////////////////////////////////////
214/// Print slave info. If opt = "active" print only the active
215/// slaves, if opt="notactive" print only the not active slaves,
216/// if opt = "bad" print only the bad slaves, else
217/// print all slaves.
218
220{
221 TString stat = fStatus == kActive ? "active" :
222 fStatus == kBad ? "bad" :
223 "not active";
224
225 Bool_t newfmt = kFALSE;
226 TString oo(opt);
227 if (oo.Contains("N")) {
228 newfmt = kTRUE;
229 oo.ReplaceAll("N","");
230 }
231 if (oo == "active" && fStatus != kActive) return;
232 if (oo == "notactive" && fStatus != kNotActive) return;
233 if (oo == "bad" && fStatus != kBad) return;
234
235 if (newfmt) {
236 TString msd, si, datadir;
237 if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
238 if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
239 if (fSysInfo.fCpus > 0) {
240 si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
242 } else {
243 si.Form("| %s", fHostName.Data());
244 }
245 Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
246
247 } else {
248 TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
249
250 std::cout << "Slave: " << fOrdinal
251 << " hostname: " << fHostName
252 << " msd: " << msd
253 << " perf index: " << fPerfIndex
254 << " " << stat
255 << std::endl;
256 }
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// Setter for fSysInfo
261
263{
264 fSysInfo.fOS = si.fOS; // OS
265 fSysInfo.fModel = si.fModel; // computer model
266 fSysInfo.fCpuType = si.fCpuType; // type of cpu
267 fSysInfo.fCpus = si.fCpus; // number of cpus
268 fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
269 fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
270 fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
271 fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
272}
273
275
276//------------------------------------------------------------------------------
277
278////////////////////////////////////////////////////////////////////////////////
279/// Destructor
280
282{
283 // Just delete the list, the objects are owned by other list
284 if (fWorkers) {
287 }
288}
289////////////////////////////////////////////////////////////////////////////////
290/// Increase number of already merged workers by 1
291
293{
295 Error("SetMergedWorker", "all workers have been already merged before!");
296 else
298}
299
300////////////////////////////////////////////////////////////////////////////////
301/// Add new worker to the list of workers to be merged by this merger
302
304{
305 if (!fWorkers)
306 fWorkers = new TList();
307 if (fWorkersToMerge == fWorkers->GetSize()) {
308 Error("AddWorker", "all workers have been already assigned to this merger");
309 return;
310 }
311 fWorkers->Add(sl);
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Return if merger has already merged all workers, i.e. if it has finished its merging job
316
318{
320}
321
322////////////////////////////////////////////////////////////////////////////////
323/// Return if the determined number of workers has been already assigned to this merger
324
326{
327 if (!fWorkers)
328 return kFALSE;
329
330 return (fWorkers->GetSize() == fWorkersToMerge);
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// This a private API function.
335/// It checks whether the connection string contains a PoD cluster protocol.
336/// If it does, then the connection string will be changed to reflect
337/// a real PROOF connection string for a PROOF cluster managed by PoD.
338/// PoD: http://pod.gsi.de .
339/// Return -1 if the PoD request failed; return 0 otherwise.
340
341static Int_t PoDCheckUrl(TString *_cluster)
342{
343 if ( !_cluster )
344 return 0;
345
346 // trim spaces from both sides of the string
347 *_cluster = _cluster->Strip( TString::kBoth );
348 // PoD protocol string
349 const TString pod_prot("pod");
350
351 // URL test
352 // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
353 TUrl url( _cluster->Data() );
354 if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
355 return 0;
356
357 // PoD cluster is used
358 // call pod-info in a batch mode (-b).
359 // pod-info will find either a local PoD cluster or
360 // a remote one, manged by pod-remote.
361 *_cluster = gSystem->GetFromPipe("pod-info -c -b");
362 if( 0 == _cluster->Length() ) {
363 Error("PoDCheckUrl", "PoD server is not running");
364 return -1;
365 }
366 return 0;
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Create a PROOF environment. Starting PROOF involves either connecting
371/// to a master server, which in turn will start a set of slave servers, or
372/// directly starting as master server (if master = ""). Masterurl is of
373/// the form: [proof[s]://]host[:port]. Conffile is the name of the config
374/// file describing the remote PROOF cluster (this argument alows you to
375/// describe different cluster configurations).
376/// The default is proof.conf. Confdir is the directory where the config
377/// file and other PROOF related files are (like motd and noproof files).
378/// Loglevel is the log level (default = 1). User specified custom config
379/// files will be first looked for in $HOME/.conffile.
380
381TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
382 Int_t loglevel, const char *alias, TProofMgr *mgr)
383 : fUrl(masterurl)
384{
385 // Default initializations
386 InitMembers();
387
388 // This may be needed during init
389 fManager = mgr;
390
391 // Default server type
393
394 // Default query mode
396
397 // Parse the main URL, adjusting the missing fields and setting the relevant
398 // bits
401
402 // Protocol and Host
403 if (!masterurl || strlen(masterurl) <= 0) {
404 fUrl.SetProtocol("proof");
405 fUrl.SetHost("__master__");
406 } else if (!(strstr(masterurl, "://"))) {
407 fUrl.SetProtocol("proof");
408 }
409 // Port
410 if (fUrl.GetPort() == TUrl(" ").GetPort())
411 fUrl.SetPort(TUrl("proof:// ").GetPort());
412
413 // Make sure to store the FQDN, so to get a solid reference for subsequent checks
414 if (!strcmp(fUrl.GetHost(), "__master__"))
415 fMaster = fUrl.GetHost();
416 else if (!strlen(fUrl.GetHost()))
418 else
420
421 // Server type
422 if (strlen(fUrl.GetOptions()) > 0) {
423 TString opts(fUrl.GetOptions());
424 if (!(strncmp(fUrl.GetOptions(),"std",3))) {
426 opts.Remove(0,3);
427 fUrl.SetOptions(opts.Data());
428 } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
430 opts.Remove(0,4);
431 fUrl.SetOptions(opts.Data());
432 }
433 }
434
435 // Instance type
439 if (fMaster == "__master__") {
443 } else if (fMaster == "prooflite") {
444 // Client and master are merged
447 }
448 // Flag that we are a client
450 if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
451
452 Init(masterurl, conffile, confdir, loglevel, alias);
453
454 // If the user was not set, get it from the master
455 if (strlen(fUrl.GetUser()) <= 0) {
456 TString usr, emsg;
457 if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
458 TObjString *os = fMacroLog.GetLineWith("const char");
459 if (os) {
460 Ssiz_t fst = os->GetString().First('\"');
461 Ssiz_t lst = os->GetString().Last('\"');
462 usr = os->GetString()(fst+1, lst-fst-1);
463 } else {
464 emsg = "could not find 'const char *' string in macro log";
465 }
466 } else {
467 emsg = "could not retrieve user info";
468 }
469 if (!emsg.IsNull()) {
470 // Get user logon name
472 if (pw) {
473 usr = pw->fUser;
474 delete pw;
475 }
476 Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
477 }
478 // Set the user name in the main URL
479 fUrl.SetUser(usr.Data());
480 }
481
482 // If called by a manager, make sure it stays in last position
483 // for cleaning
484 if (mgr) {
486 gROOT->GetListOfSockets()->Remove(mgr);
487 gROOT->GetListOfSockets()->Add(mgr);
488 }
489
490 // Old-style server type: we add this to the list and set the global pointer
492 if (!gROOT->GetListOfProofs()->FindObject(this))
493 gROOT->GetListOfProofs()->Add(this);
494
495 // Still needed by the packetizers: needs to be changed
496 gProof = this;
497}
498
499////////////////////////////////////////////////////////////////////////////////
500/// Protected constructor to be used by classes deriving from TProof
501/// (they have to call Init themselves and override StartSlaves
502/// appropriately).
503///
504/// This constructor simply closes any previous gProof and sets gProof
505/// to this instance.
506
507TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
508{
509 // Default initializations
510 InitMembers();
511
512 if (!gROOT->GetListOfProofs()->FindObject(this))
513 gROOT->GetListOfProofs()->Add(this);
514
515 gProof = this;
516}
517
518////////////////////////////////////////////////////////////////////////////////
519/// Default initializations
520
522{
523 fValid = kFALSE;
524 fTty = kFALSE;
525 fRecvMessages = 0;
526 fSlaveInfo = 0;
531 fActiveSlaves = 0;
532 fInactiveSlaves = 0;
533 fUniqueSlaves = 0;
536 fActiveMonitor = 0;
537 fUniqueMonitor = 0;
539 fCurrentMonitor = 0;
540 fBytesRead = 0;
541 fRealTime = 0;
542 fCpuTime = 0;
543 fIntHandler = 0;
544 fProgressDialog = 0;
547 fPlayer = 0;
548 fFeedback = 0;
549 fChains = 0;
550 fDSet = 0;
551 fNotIdle = 0;
552 fSync = kTRUE;
556 fLogFileW = 0;
557 fLogFileR = 0;
560 fMacroLog.SetName("ProofLogMacro");
561
562 fWaitingSlaves = 0;
563 fQueries = 0;
564 fOtherQueries = 0;
565 fDrawQueries = 0;
566 fMaxDrawQueries = 1;
567 fSeqNum = 0;
568
569 fSessionID = -1;
571
572 fPackMgr = 0;
574
575 fInputData = 0;
576
577 fPrintProgress = 0;
578
579 fLoadedMacros = 0;
580
581 fProtocol = -1;
582 fSlaves = 0;
584 fBadSlaves = 0;
585 fAllMonitor = 0;
587 fBytesReady = 0;
588 fTotalBytes = 0;
591 fRunningDSets = 0;
592
593 fCollectTimeout = -1;
594
595 fManager = 0;
598
601 fMergers = 0;
602 fMergersCount = -1;
604 fWorkersToMerge = 0;
606
607 fPerfTree = "";
608
610
611 fSelector = 0;
612
613 fPrepTime = 0.;
614
615 // Check if the user defined a list of environment variables to send over:
616 // include them into the dedicated list
617 if (gSystem->Getenv("PROOF_ENVVARS")) {
618 TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
619 Int_t from = 0;
620 while (envs.Tokenize(env, from, ",")) {
621 if (!env.IsNull()) {
622 if (!gSystem->Getenv(env)) {
623 Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
624 } else {
625 if (!envsfound.IsNull()) envsfound += ",";
626 envsfound += env;
628 TProof::AddEnvVar(env, gSystem->Getenv(env));
629 }
630 }
631 }
632 if (envsfound.IsNull()) {
633 Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
634 } else {
635 Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
636 }
637 }
638
639 // Done
640 return;
641}
642
643////////////////////////////////////////////////////////////////////////////////
644/// Clean up PROOF environment.
645
647{
648 if (fChains) {
649 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
650 // remove "chain" from list
651 chain->SetProof(0);
652 RemoveChain(chain);
653 }
654 }
655
656 // remove links to packages enabled on the client
658 // iterate over all packages
660 if (epl) {
661 TIter nxp(epl);
662 while (TObjString *pck = (TObjString *)(nxp())) {
663 FileStat_t stat;
664 if (gSystem->GetPathInfo(pck->String(), stat) == 0) {
665 // check if symlink, if so unlink
666 // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
667 // existing file or to a directory, but if fIsLink is true the symlink exists
668 if (stat.fIsLink)
669 gSystem->Unlink(pck->String());
670 }
671 }
672 epl->Delete();
673 delete epl;
674 }
675 }
676
677 Close();
704 if (fWrksOutputReady) {
706 delete fWrksOutputReady;
707 }
708 if (fQueries) {
709 fQueries->Delete();
710 delete fQueries;
711 }
712
713 // remove file with redirected logs
715 if (fLogFileR)
716 fclose(fLogFileR);
717 if (fLogFileW)
718 fclose(fLogFileW);
719 if (fLogFileName.Length() > 0)
721 }
722
723 // Remove for the global list
724 gROOT->GetListOfProofs()->Remove(this);
725 // ... and from the manager list
726 if (fManager && fManager->IsValid())
728
729 if (gProof && gProof == this) {
730 // Set previous as default
731 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
732 while ((gProof = (TProof *)pvp())) {
733 if (gProof->InheritsFrom(TProof::Class()))
734 break;
735 }
736 }
737
738 // For those interested in our destruction ...
739 Emit("~TProof()");
740 Emit("CloseWindow()");
741}
742
743////////////////////////////////////////////////////////////////////////////////
744/// Start the PROOF environment. Starting PROOF involves either connecting
745/// to a master server, which in turn will start a set of slave servers, or
746/// directly starting as master server (if master = ""). For a description
747/// of the arguments see the TProof ctor. Returns the number of started
748/// master or slave servers, returns 0 in case of error, in which case
749/// fValid remains false.
750
751Int_t TProof::Init(const char *, const char *conffile,
752 const char *confdir, Int_t loglevel, const char *alias)
753{
755
756 fValid = kFALSE;
757
758 // Connected to terminal?
759 fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
760
761 // If in attach mode, options is filled with additional info
762 Bool_t attach = kFALSE;
763 if (strlen(fUrl.GetOptions()) > 0) {
764 attach = kTRUE;
765 // A flag from the GUI
766 TString opts = fUrl.GetOptions();
767 if (opts.Contains("GUI")) {
769 opts.Remove(opts.Index("GUI"));
770 fUrl.SetOptions(opts);
771 }
772 }
773
775 // Fill default conf file and conf dir
776 if (!conffile || !conffile[0])
778 if (!confdir || !confdir[0])
780 // The group; the client receives it in the kPROOF_SESSIONTAG message
782 } else {
783 fConfDir = confdir;
784 fConfFile = conffile;
785 }
786
787 // Analysise the conffile field
788 if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
790
792 fLogLevel = loglevel;
795 fImage = fMasterServ ? "" : "<local>";
796 fIntHandler = 0;
797 fStatus = 0;
798 fRecvMessages = new TList;
800 fSlaveInfo = 0;
801 fChains = new TList;
804 fRunningDSets = 0;
806 fInputData = 0;
808 fPrintProgress = 0;
809
810 // Timeout for some collect actions
811 fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
812
813 // Should the workers be started dynamically; default: no
814 fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
815
816 // Default entry point for the data pool is the master
818 fDataPoolUrl.Form("root://%s", fMaster.Data());
819 else
820 fDataPoolUrl = "";
821
822 fProgressDialog = 0;
824
825 // Default alias is the master name
826 TString al = (alias) ? alias : fMaster.Data();
827 SetAlias(al);
828
829 // Client logging of messages from the master and slaves
832 fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
833 if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
834 Error("Init", "could not create temporary logfile");
835 if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
836 Error("Init", "could not open temp logfile for reading");
837 }
839
840 // Status of cluster
841 fNotIdle = 0;
842 // Query type
843 fSync = (attach) ? kFALSE : kTRUE;
844 // Not enqueued
846
847 // Counters
848 fBytesRead = 0;
849 fRealTime = 0;
850 fCpuTime = 0;
851
852 // List of queries
853 fQueries = 0;
854 fOtherQueries = 0;
855 fDrawQueries = 0;
856 fMaxDrawQueries = 1;
857 fSeqNum = 0;
858
859 // Remote ID of the session
860 fSessionID = -1;
861
862 // Part of active query
863 fWaitingSlaves = 0;
864
865 // Make remote PROOF player
866 fPlayer = 0;
867 MakePlayer();
868
869 fFeedback = new TList;
871 fFeedback->SetName("FeedbackList");
873
874 // sort slaves by descending performance index
876 fActiveSlaves = new TList;
878 fUniqueSlaves = new TList;
881 fBadSlaves = new TList;
882 fAllMonitor = new TMonitor;
886 fCurrentMonitor = 0;
887
890
891 fLoadedMacros = 0;
892 fPackMgr = 0;
893
894 // Enable optimized sending of streamer infos to use embedded backward/forward
895 // compatibility support between different ROOT versions and different versions of
896 // users classes
897 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
898 if (enableSchemaEvolution) {
900 } else {
901 Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
902 }
903
904 if (IsMaster()) {
905 // to make UploadPackage() method work on the master as well.
907 } else {
908
909 TString sandbox;
910 if (GetSandbox(sandbox, kTRUE) != 0) {
911 Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
912 return 0;
913 }
914
915 // Package Dir
916 TString packdir = gEnv->GetValue("Proof.PackageDir", "");
917 if (packdir.IsNull())
918 packdir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
919 if (AssertPath(packdir, kTRUE) != 0) {
920 Error("Init", "failure asserting directory %s", packdir.Data());
921 return 0;
922 }
923 fPackMgr = new TPackMgr(packdir);
924 if (gDebug > 0)
925 Info("Init", "package directory set to %s", packdir.Data());
926 }
927
928 if (!IsMaster()) {
929 // List of directories where to look for global packages
930 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
932 Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
933 if (gDebug > 0)
934 Info("Init", " %d global package directories registered", nglb);
935 }
936
937 // Master may want dynamic startup
938 if (fDynamicStartup) {
939 if (!IsMaster()) {
940 // If on client - start the master
941 if (!StartSlaves(attach))
942 return 0;
943 }
944 } else {
945
946 // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
947 // result retrieving, ...)
948 Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
949 if (!IsMaster() || !masterOnly) {
950 // Start slaves (the old, static, per-session way)
951 if (!StartSlaves(attach))
952 return 0;
953 // Client: Is Master in dynamic startup mode?
954 if (!IsMaster()) {
955 Int_t dyn = 0;
956 GetRC("Proof.DynamicStartup", dyn);
957 if (dyn != 0) fDynamicStartup = kTRUE;
958 }
959 }
960 }
961 // we are now properly initialized
962 fValid = kTRUE;
963
964 // De-activate monitor (will be activated in Collect)
966
967 // By default go into parallel mode
968 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
969 TNamed *n = 0;
970 if (TProof::GetEnvVars() &&
971 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
972 TString s(n->GetTitle());
973 if (s.IsDigit()) nwrk = s.Atoi();
974 }
975 GoParallel(nwrk, attach);
976
977 // Send relevant initial state to slaves
978 if (!attach)
980 else if (!IsIdle())
981 // redirect log
983
984 // Done at this point, the alias will be communicated to the coordinator, if any
986 SetAlias(al);
987
989
990 if (IsValid()) {
991
992 // Activate input handler
994
996 gROOT->GetListOfSockets()->Add(this);
997 }
998
999 AskParallel();
1000
1001 return fActiveSlaves->GetSize();
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005/// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1006/// Use the existing setting or the default if nothing is found.
1007/// If 'assert' is kTRUE, make also sure that the path exists.
1008/// Return 0 on success, -1 on failure
1009
1010Int_t TProof::GetSandbox(TString &sb, Bool_t assert, const char *rc)
1011{
1012 // Get it from 'rc', if defined
1013 if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1014 // Or use the default 'rc'
1015 if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1016 // If nothing found , use the default
1017 if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1018 // Expand special settings
1019 if (sb == ".") {
1020 sb = gSystem->pwd();
1021 } else if (sb == "..") {
1022 sb = gSystem->GetDirName(gSystem->pwd());
1023 }
1025
1026 // Assert the path, if required
1027 if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1028 // Done
1029 return 0;
1030}
1031
1032////////////////////////////////////////////////////////////////////////////////
1033/// The config file field may contain special instructions which need to be
1034/// parsed at the beginning, e.g. for debug runs with valgrind.
1035/// Several options can be given separated by a ','
1036
1037void TProof::ParseConfigField(const char *config)
1038{
1039 TString sconf(config), opt;
1040 Ssiz_t from = 0;
1041 Bool_t cpuPin = kFALSE;
1042
1043 // Analysise the field
1044 const char *cq = (IsLite()) ? "\"" : "";
1045 while (sconf.Tokenize(opt, from, ",")) {
1046 if (opt.IsNull()) continue;
1047
1048 if (opt.BeginsWith("valgrind")) {
1049 // Any existing valgrind setting? User can give full settings, which we fully respect,
1050 // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1051 // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1052 // will add option "--time-stamp --leak-check=full" to our default options
1053 TString mst, top, sub, wrk, all;
1054 TList *envs = fgProofEnvList;
1055 TNamed *n = 0;
1056 if (envs) {
1057 if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1058 all = n->GetTitle();
1059 if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1060 mst = n->GetTitle();
1061 if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1062 top = n->GetTitle();
1063 if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1064 sub = n->GetTitle();
1065 if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1066 wrk = n->GetTitle();
1067 }
1068 if (all != "" && mst == "") mst = all;
1069 if (all != "" && top == "") top = all;
1070 if (all != "" && sub == "") sub = all;
1071 if (all != "" && wrk == "") wrk = all;
1072 if (all != "" && all.BeginsWith("valgrind_opts:")) {
1073 // The field is used to add an option Reset the setting
1074 Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1075 " must be set again for next run , if any");
1076 TProof::DelEnvVar("PROOF_WRAPPERCMD");
1077 }
1078 TString var, cmd;
1079 cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1080 TString mstlab("NO"), wrklab("NO");
1081 Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1082 !opt.Contains("topmaster") && !opt.Contains("submaster")))
1083 ? kTRUE : kFALSE;
1084 if (doMaster) {
1085 if (!IsLite()) {
1086 // Check if we have to add a var
1087 if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1088 mst.ReplaceAll("valgrind_opts:","");
1089 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1090 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1091 mstlab = "YES";
1092 } else if (mst != "") {
1093 mstlab = "YES";
1094 }
1095 } else {
1096 if (opt.Contains("master")) {
1097 Warning("ParseConfigField",
1098 "master valgrinding does not make sense for PROOF-Lite: ignoring");
1099 opt.ReplaceAll("master", "");
1100 if (!opt.Contains("workers")) return;
1101 }
1102 if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1103 }
1104 }
1105 if (opt.Contains("topmaster")) {
1106 // Check if we have to add a var
1107 if (top == "" || top.BeginsWith("valgrind_opts:")) {
1108 top.ReplaceAll("valgrind_opts:","");
1109 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1110 TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1111 mstlab = "YES";
1112 } else if (top != "") {
1113 mstlab = "YES";
1114 }
1115 }
1116 if (opt.Contains("submaster")) {
1117 // Check if we have to add a var
1118 if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1119 sub.ReplaceAll("valgrind_opts:","");
1120 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1121 TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1122 mstlab = "YES";
1123 } else if (sub != "") {
1124 mstlab = "YES";
1125 }
1126 }
1127 if (opt.Contains("=workers") || opt.Contains("+workers")) {
1128 // Check if we have to add a var
1129 if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1130 wrk.ReplaceAll("valgrind_opts:","");
1131 var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1132 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1133 TString nwrks("2");
1134 Int_t inw = opt.Index('#');
1135 if (inw != kNPOS) {
1136 nwrks = opt(inw+1, opt.Length());
1137 if (!nwrks.IsDigit()) nwrks = "2";
1138 }
1139 // Set the relevant variables
1140 if (!IsLite()) {
1141 TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1142 } else {
1143 gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1144 }
1145 wrklab = nwrks;
1146 // Register the additional worker log in the session file
1147 // (for the master this is done automatically)
1148 TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1149 } else if (wrk != "") {
1150 wrklab = "ALL";
1151 }
1152 }
1153 // Increase the relevant timeouts
1154 if (!IsLite()) {
1155 TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1156 gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1157 } else {
1158 gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1159 }
1160 // Warn for slowness
1161 Printf(" ");
1162 if (!IsLite()) {
1163 Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1164 } else {
1165 Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1166 }
1167 Printf(" ---> Please be patient: startup may be VERY slow ...");
1168 Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1169 Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1170 Printf(" ");
1171
1172 } else if (opt.BeginsWith("igprof-pp")) {
1173
1174 // IgProf profiling on master and worker. PROOF does not set the
1175 // environment for you: proper environment variables (like PATH and
1176 // LD_LIBRARY_PATH) should be set externally
1177
1178 Printf("*** Requested IgProf performance profiling ***");
1179 TString addLogExt = "__igprof.pp__.log";
1180 TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1181 TString tmp;
1182
1183 if (IsLite()) {
1184 addLogFmt.Append("\"");
1185 addLogFmt.Prepend("\"");
1186 }
1187
1188 tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1189 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1190
1191 tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1192 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1193
1194 TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1195
1196 } else if (opt.BeginsWith("cpupin=")) {
1197 // Enable CPU pinning. Takes as argument the list of processor IDs
1198 // that will be used in order. Processor IDs are numbered from 0,
1199 // use likwid to see how they are organized. A possible parameter
1200 // format would be:
1201 //
1202 // cpupin=3+4+0+9+10+22+7
1203 //
1204 // Only the specified processor IDs will be used in a round-robin
1205 // fashion, dealing with the fact that you can request more workers
1206 // than the number of processor IDs you have specified.
1207 //
1208 // To use all available processors in their order:
1209 //
1210 // cpupin=*
1211
1212 opt.Remove(0, 7);
1213
1214 // Remove any char which is neither a number nor a plus '+'
1215 for (Ssiz_t i=0; i<opt.Length(); i++) {
1216 Char_t c = opt[i];
1217 if ((c != '+') && ((c < '0') || (c > '9')))
1218 opt[i] = '_';
1219 }
1220 opt.ReplaceAll("_", "");
1221 TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1222 cpuPin = kTRUE;
1223 } else if (opt.BeginsWith("workers=")) {
1224
1225 // Request for a given number of workers (within the max) or worker
1226 // startup combination:
1227 // workers=5 start max 5 workers (or less, if less are assigned)
1228 // workers=2x start max 2 workers per node (or less, if less are assigned)
1229 opt.ReplaceAll("workers=","");
1230 TProof::AddEnvVar("PROOF_NWORKERS", opt);
1231 }
1232 }
1233
1234 // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1235 #ifdef R__LINUX
1236 if (IsLite() && cpuPin) {
1237 Printf("*** Requested CPU pinning ***");
1238 const TList *ev = GetEnvVars();
1239 const char *pinCmd = "taskset -c <cpupin>";
1240 TString val;
1241 TNamed *p;
1242 if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1243 val = p->GetTitle();
1244 val.Insert(val.Length()-1, " ");
1245 val.Insert(val.Length()-1, pinCmd);
1246 }
1247 else {
1248 val.Form("\"%s\"", pinCmd);
1249 }
1250 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1251 }
1252 #endif
1253}
1254
1255////////////////////////////////////////////////////////////////////////////////
1256/// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1257/// that the path is writable
1258
1259Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1260{
1261 if (!inpath || strlen(inpath) <= 0) {
1262 Error("AssertPath", "undefined input path");
1263 return -1;
1264 }
1265
1266 TString path(inpath);
1267 gSystem->ExpandPathName(path);
1268
1269 if (gSystem->AccessPathName(path, kFileExists)) {
1270 if (gSystem->mkdir(path, kTRUE) != 0) {
1271 Error("AssertPath", "could not create path %s", path.Data());
1272 return -1;
1273 }
1274 }
1275 // It must be writable
1276 if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1277 if (gSystem->Chmod(path, 0666) != 0) {
1278 Error("AssertPath", "could not make path %s writable", path.Data());
1279 return -1;
1280 }
1281 }
1282
1283 // Done
1284 return 0;
1285}
1286
1287////////////////////////////////////////////////////////////////////////////////
1288/// Set manager and schedule its destruction after this for clean
1289/// operations.
1290
1292{
1293 fManager = mgr;
1294
1295 if (mgr) {
1297 gROOT->GetListOfSockets()->Remove(mgr);
1298 gROOT->GetListOfSockets()->Add(mgr);
1299 }
1300}
1301
1302////////////////////////////////////////////////////////////////////////////////
1303/// Works on the master node only.
1304/// It starts workers on the machines in workerList and sets the paths,
1305/// packages and macros as on the master.
1306/// It is a subbstitute for StartSlaves(...)
1307/// The code is mostly the master part of StartSlaves,
1308/// with the parallel startup removed.
1309
1311{
1312 if (!IsMaster()) {
1313 Error("AddWorkers", "AddWorkers can only be called on the master!");
1314 return -1;
1315 }
1316
1317 if (!workerList || !(workerList->GetSize())) {
1318 Error("AddWorkers", "empty list of workers!");
1319 return -2;
1320 }
1321
1322 // Code taken from master part of StartSlaves with the parllel part removed
1323
1325 if (fImage.IsNull())
1327
1328 // Get all workers
1329 UInt_t nSlaves = workerList->GetSize();
1330 UInt_t nSlavesDone = 0;
1331 Int_t ord = 0;
1332
1333 // Loop over all new workers and start them (if we had already workers it means we are
1334 // increasing parallelism or that is not the first time we are called)
1335 Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1336
1337 // A list of TSlave objects for workers that are being added
1338 TList *addedWorkers = new TList();
1339 if (!addedWorkers) {
1340 // This is needed to silence Coverity ...
1341 Error("AddWorkers", "cannot create new list for the workers to be added");
1342 return -2;
1343 }
1344 addedWorkers->SetOwner(kFALSE);
1345 TListIter next(workerList);
1346 TObject *to;
1347 TProofNodeInfo *worker;
1348 TSlaveInfo *dummysi = new TSlaveInfo();
1349 while ((to = next())) {
1350 // Get the next worker from the list
1351 worker = (TProofNodeInfo *)to;
1352
1353 // Read back worker node info
1354 const Char_t *image = worker->GetImage().Data();
1355 const Char_t *workdir = worker->GetWorkDir().Data();
1356 Int_t perfidx = worker->GetPerfIndex();
1357 Int_t sport = worker->GetPort();
1358 if (sport == -1)
1359 sport = fUrl.GetPort();
1360
1361 // Create worker server
1362 TString fullord;
1363 if (worker->GetOrdinal().Length() > 0) {
1364 fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1365 } else {
1366 fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1367 }
1368
1369 // Remove worker from the list of workers terminated gracefully
1370 dummysi->SetOrdinal(fullord);
1372 SafeDelete(rmsi);
1373
1374 // Create worker server
1375 TString wn(worker->GetNodeName());
1376 if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1377 TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1378 // Add group info in the password firdl, if any
1379 if (strlen(gProofServ->GetGroup()) > 0) {
1380 // Set also the user, otherwise the password is not exported
1381 if (strlen(u.GetUser()) <= 0)
1384 }
1385 TSlave *slave = 0;
1386 if (worker->IsWorker()) {
1387 slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1388 } else {
1389 slave = CreateSubmaster(u.GetUrl(), fullord,
1390 image, worker->GetMsd(), worker->GetNWrks());
1391 }
1392
1393 // Add to global list (we will add to the monitor list after
1394 // finalizing the server startup)
1395 Bool_t slaveOk = kTRUE;
1396 fSlaves->Add(slave);
1397 if (slave->IsValid()) {
1398 addedWorkers->Add(slave);
1399 } else {
1400 slaveOk = kFALSE;
1401 fBadSlaves->Add(slave);
1402 Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1403 }
1404
1405 PDB(kGlobal,3)
1406 Info("AddWorkers", "worker on host %s created"
1407 " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1408
1409 // Notify opening of connection
1410 nSlavesDone++;
1412 m << TString("Opening connections to workers") << nSlaves
1413 << nSlavesDone << slaveOk;
1415
1416 ord++;
1417 } //end of the worker loop
1418 SafeDelete(dummysi);
1419
1420 // Cleanup
1421 SafeDelete(workerList);
1422
1423 nSlavesDone = 0;
1424
1425 // Here we finalize the server startup: in this way the bulk
1426 // of remote operations are almost parallelized
1427 TIter nxsl(addedWorkers);
1428 TSlave *sl = 0;
1429 while ((sl = (TSlave *) nxsl())) {
1430
1431 // Finalize setup of the server
1432 if (sl->IsValid())
1433 sl->SetupServ(TSlave::kSlave, 0);
1434
1435 // Monitor good slaves
1436 Bool_t slaveOk = kTRUE;
1437 if (sl->IsValid()) {
1438 fAllMonitor->Add(sl->GetSocket());
1439 PDB(kGlobal,3)
1440 Info("AddWorkers", "worker on host %s finalized"
1441 " and added to list", sl->GetOrdinal());
1442 } else {
1443 slaveOk = kFALSE;
1444 fBadSlaves->Add(sl);
1445 }
1446
1447 // Notify end of startup operations
1448 nSlavesDone++;
1450 m << TString("Setting up worker servers") << nSlaves
1451 << nSlavesDone << slaveOk;
1453 }
1454
1455 // Now set new state on the added workers (on all workers for simplicity)
1456 // use fEnabledPackages, fLoadedMacros,
1457 // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1458 // no need to load packages that are only loaded and not enabled (dyn mode)
1459 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1460 TNamed *n = 0;
1461 if (TProof::GetEnvVars() &&
1462 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1463 TString s(n->GetTitle());
1464 if (s.IsDigit()) nwrk = s.Atoi();
1465 }
1466
1467 if (fDynamicStartup && goMoreParallel) {
1468
1469 PDB(kGlobal, 3)
1470 Info("AddWorkers", "will invoke GoMoreParallel()");
1471 Int_t nw = GoMoreParallel(nwrk);
1472 PDB(kGlobal, 3)
1473 Info("AddWorkers", "GoMoreParallel()=%d", nw);
1474
1475 }
1476 else {
1477 // Not in Dynamic Workers mode
1478 PDB(kGlobal, 3)
1479 Info("AddWorkers", "will invoke GoParallel()");
1480 GoParallel(nwrk, kFALSE, 0);
1481 }
1482
1483 // Set worker processing environment
1484 SetupWorkersEnv(addedWorkers, goMoreParallel);
1485
1486 // Update list of current workers
1487 PDB(kGlobal, 3)
1488 Info("AddWorkers", "will invoke SaveWorkerInfo()");
1490
1491 // Inform the client that the number of workers has changed
1492 if (fDynamicStartup && gProofServ) {
1493 PDB(kGlobal, 3)
1494 Info("AddWorkers", "will invoke SendParallel()");
1496
1497 if (goMoreParallel && fPlayer) {
1498 // In case we are adding workers dynamically to an existing process, we
1499 // should invoke a special player's Process() to set only added workers
1500 // to the proper state
1501 PDB(kGlobal, 3)
1502 Info("AddWorkers", "will send the PROCESS message to selected workers");
1503 fPlayer->JoinProcess(addedWorkers);
1504 // Update merger counters (new workers are not yet active)
1505 fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1506 }
1507 }
1508
1509 // Cleanup
1510 delete addedWorkers;
1511
1512 return 0;
1513}
1514
1515////////////////////////////////////////////////////////////////////////////////
1516/// Set up packages, loaded macros, include and lib paths ...
1517
1518void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1519{
1520 TList *server_packs = gProofServ ? gProofServ->GetEnabledPackages() : nullptr;
1521 // Packages
1522 TList *packs = server_packs ? server_packs : GetEnabledPackages();
1523 if (packs && packs->GetSize() > 0) {
1524 TIter nxp(packs);
1525 TPair *pck = 0;
1526 while ((pck = (TPair *) nxp())) {
1527 // Upload and Enable methods are intelligent and avoid
1528 // re-uploading or re-enabling of a package to a node that has it.
1529 if (fDynamicStartup && increasingWorkers) {
1530 // Upload only on added workers
1531 PDB(kGlobal, 3)
1532 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1533 if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1534 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1535 } else {
1536 PDB(kGlobal, 3)
1537 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1538 if (UploadPackage(pck->GetName()) >= 0)
1539 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1540 }
1541 }
1542 }
1543
1544 if (server_packs) {
1545 server_packs->Delete();
1546 delete server_packs;
1547 }
1548
1549 // Loaded macros
1550 if (fLoadedMacros) {
1551 TIter nxp(fLoadedMacros);
1552 TObjString *os = 0;
1553 while ((os = (TObjString *) nxp())) {
1554 PDB(kGlobal, 3) {
1555 Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1556 Printf("Loading a macro : %s", os->GetName());
1557 }
1558 Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1559 }
1560 }
1561
1562 // Dynamic path
1564 dyn.ReplaceAll(":", " ");
1565 dyn.ReplaceAll("\"", " ");
1566 PDB(kGlobal, 3)
1567 Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1568 AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1569
1570 // Include path
1572 inc.ReplaceAll("-I", " ");
1573 inc.ReplaceAll("\"", " ");
1574 PDB(kGlobal, 3)
1575 Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1576 AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1577
1578 // Done
1579 return;
1580}
1581
1582////////////////////////////////////////////////////////////////////////////////
1583/// Used for shuting down the workres after a query is finished.
1584/// Sends each of the workers from the workerList, a kPROOF_STOP message.
1585/// If the workerList == 0, shutdown all the workers.
1586
1588{
1589 if (!IsMaster()) {
1590 Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1591 return -1;
1592 }
1593
1594 fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1595
1596 if (!workerList) {
1597 // shutdown all the workers
1598 TIter nxsl(fSlaves);
1599 TSlave *sl = 0;
1600 while ((sl = (TSlave *) nxsl())) {
1601 // Shut down the worker assumig that it is not processing
1602 TerminateWorker(sl);
1603 }
1604
1605 } else {
1606 if (!(workerList->GetSize())) {
1607 Error("RemoveWorkers", "The list of workers should not be empty!");
1608 return -2;
1609 }
1610
1611 // Loop over all the workers and stop them
1612 TListIter next(workerList);
1613 TObject *to;
1614 TProofNodeInfo *worker;
1615 while ((to = next())) {
1616 TSlave *sl = 0;
1617 if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1618 // Get the next worker from the list
1619 worker = (TProofNodeInfo *)to;
1620 TIter nxsl(fSlaves);
1621 while ((sl = (TSlave *) nxsl())) {
1622 // Shut down the worker assumig that it is not processing
1623 if (sl->GetName() == worker->GetNodeName())
1624 break;
1625 }
1626 } else if (to->InheritsFrom(TSlave::Class())) {
1627 sl = (TSlave *) to;
1628 } else {
1629 Warning("RemoveWorkers","unknown object type: %s - it should be"
1630 " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1631 }
1632 // Shut down the worker assumig that it is not processing
1633 if (sl) {
1634 if (gDebug > 0)
1635 Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1636 TerminateWorker(sl);
1637 }
1638 }
1639 }
1640
1641 // Update also the master counter
1642 if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1643
1644 return 0;
1645}
1646
1647////////////////////////////////////////////////////////////////////////////////
1648/// Start up PROOF slaves.
1649
1651{
1652 // If this is a master server, find the config file and start slave
1653 // servers as specified in the config file
1655
1656 Int_t pc = 0;
1657 TList *workerList = new TList;
1658 // Get list of workers
1659 if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1660 TString emsg("no resource currently available for this session: please retry later");
1661 if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1663 return kFALSE;
1664 }
1665 // Setup the workers
1666 if (AddWorkers(workerList) < 0)
1667 return kFALSE;
1668
1669 } else {
1670
1671 // create master server
1672 Printf("Starting master: opening connection ...");
1673 TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1674
1675 if (slave->IsValid()) {
1676
1677 // Notify
1678 fprintf(stderr,"Starting master:"
1679 " connection open: setting up server ... \r");
1680 StartupMessage("Connection to master opened", kTRUE, 1, 1);
1681
1682 if (!attach) {
1683
1684 // Set worker interrupt handler
1685 slave->SetInterruptHandler(kTRUE);
1686
1687 // Finalize setup of the server
1689
1690 if (slave->IsValid()) {
1691
1692 // Notify
1693 Printf("Starting master: OK ");
1694 StartupMessage("Master started", kTRUE, 1, 1);
1695
1696 // check protocol compatibility
1697 // protocol 1 is not supported anymore
1698 if (fProtocol == 1) {
1699 Error("StartSlaves",
1700 "client and remote protocols not compatible (%d and %d)",
1702 slave->Close("S");
1703 delete slave;
1704 return kFALSE;
1705 }
1706
1707 fSlaves->Add(slave);
1708 fAllMonitor->Add(slave->GetSocket());
1709
1710 // Unset worker interrupt handler
1712
1713 // Set interrupt PROOF handler from now on
1715
1716 // Give-up after 5 minutes
1717 Int_t rc = Collect(slave, 300);
1718 Int_t slStatus = slave->GetStatus();
1719 if (slStatus == -99 || slStatus == -98 || rc == 0) {
1720 fSlaves->Remove(slave);
1721 fAllMonitor->Remove(slave->GetSocket());
1722 if (slStatus == -99)
1723 Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1724 else if (slStatus == -98)
1725 Error("StartSlaves", "could not setup output redirection on master");
1726 else
1727 Error("StartSlaves", "setting up master");
1728 slave->Close("S");
1729 delete slave;
1730 return 0;
1731 }
1732
1733 if (!slave->IsValid()) {
1734 fSlaves->Remove(slave);
1735 fAllMonitor->Remove(slave->GetSocket());
1736 slave->Close("S");
1737 delete slave;
1738 Error("StartSlaves",
1739 "failed to setup connection with PROOF master server");
1740 return kFALSE;
1741 }
1742
1743 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1744 if ((fProgressDialog =
1745 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1746 if (fProgressDialog->LoadPlugin() == -1)
1747 fProgressDialog = 0;
1748 }
1749 } else {
1750 // Notify
1751 Printf("Starting master: failure");
1752 }
1753 } else {
1754
1755 // Notify
1756 Printf("Starting master: OK ");
1757 StartupMessage("Master attached", kTRUE, 1, 1);
1758
1759 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1760 if ((fProgressDialog =
1761 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1762 if (fProgressDialog->LoadPlugin() == -1)
1763 fProgressDialog = 0;
1764 }
1765
1766 fSlaves->Add(slave);
1768 }
1769
1770 } else {
1771 delete slave;
1772 // Notify only if verbosity is on: most likely the failure has already been notified
1773 if (gDebug > 0)
1774 Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1775 return kFALSE;
1776 }
1777 }
1778
1779 return kTRUE;
1780}
1781
1782////////////////////////////////////////////////////////////////////////////////
1783/// Close all open slave servers.
1784/// Client can decide to shutdown the remote session by passing option is 'S'
1785/// or 's'. Default for clients is detach, if supported. Masters always
1786/// shutdown the remote counterpart.
1787
1789{
1790 { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1791
1792 fValid = kFALSE;
1793 if (fSlaves) {
1794 if (fIntHandler)
1796
1797 TIter nxs(fSlaves);
1798 TSlave *sl = 0;
1799 while ((sl = (TSlave *)nxs()))
1800 sl->Close(opt);
1801
1802 fActiveSlaves->Clear("nodelete");
1803 fUniqueSlaves->Clear("nodelete");
1804 fAllUniqueSlaves->Clear("nodelete");
1805 fNonUniqueMasters->Clear("nodelete");
1806 fBadSlaves->Clear("nodelete");
1807 fInactiveSlaves->Clear("nodelete");
1808 fSlaves->Delete();
1809 }
1810 }
1811
1813 gROOT->GetListOfSockets()->Remove(this);
1814
1815 if (fChains) {
1816 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1817 // remove "chain" from list
1818 chain->SetProof(0);
1819 RemoveChain(chain);
1820 }
1821 }
1822
1823 if (IsProofd()) {
1824
1825 gROOT->GetListOfProofs()->Remove(this);
1826 if (gProof && gProof == this) {
1827 // Set previous proofd-related as default
1828 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1829 while ((gProof = (TProof *)pvp())) {
1830 if (gProof->IsProofd())
1831 break;
1832 }
1833 }
1834 }
1835 }
1836}
1837
1838////////////////////////////////////////////////////////////////////////////////
1839/// Create a new TSlave of type TSlave::kSlave.
1840/// Note: creation of TSlave is private with TProof as a friend.
1841/// Derived classes must use this function to create slaves.
1842
1843TSlave *TProof::CreateSlave(const char *url, const char *ord,
1844 Int_t perf, const char *image, const char *workdir)
1845{
1846 TSlave* sl = TSlave::Create(url, ord, perf, image,
1847 this, TSlave::kSlave, workdir, 0);
1848
1849 if (sl->IsValid()) {
1850 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1851 // must set fParallel to 1 for slaves since they do not
1852 // report their fParallel with a LOG_DONE message
1853 sl->fParallel = 1;
1854 }
1855
1856 return sl;
1857}
1858
1859
1860////////////////////////////////////////////////////////////////////////////////
1861/// Create a new TSlave of type TSlave::kMaster.
1862/// Note: creation of TSlave is private with TProof as a friend.
1863/// Derived classes must use this function to create slaves.
1864
1865TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1866 const char *image, const char *msd, Int_t nwk)
1867{
1868 TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1869 TSlave::kMaster, 0, msd, nwk);
1870
1871 if (sl->IsValid()) {
1872 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1873 }
1874
1875 return sl;
1876}
1877
1878////////////////////////////////////////////////////////////////////////////////
1879/// Find slave that has TSocket s. Returns 0 in case slave is not found.
1880
1882{
1883 TSlave *sl;
1884 TIter next(fSlaves);
1885
1886 while ((sl = (TSlave *)next())) {
1887 if (sl->IsValid() && sl->GetSocket() == s)
1888 return sl;
1889 }
1890 return 0;
1891}
1892
1893////////////////////////////////////////////////////////////////////////////////
1894/// Add to the fUniqueSlave list the active slaves that have a unique
1895/// (user) file system image. This information is used to transfer files
1896/// only once to nodes that share a file system (an image). Submasters
1897/// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1898/// list. That list is used to trigger the transferring of files to
1899/// the submaster's unique slaves without the need to transfer the file
1900/// to the submaster.
1901
1903{
1909
1910 TIter next(fActiveSlaves);
1911
1912 while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1913 if (fImage == sl->fImage) {
1914 if (sl->GetSlaveType() == TSlave::kMaster) {
1916 fAllUniqueSlaves->Add(sl);
1917 fAllUniqueMonitor->Add(sl->GetSocket());
1918 }
1919 continue;
1920 }
1921
1922 TIter next2(fUniqueSlaves);
1923 TSlave *replace_slave = 0;
1924 Bool_t add = kTRUE;
1925 while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1926 if (sl->fImage == sl2->fImage) {
1927 add = kFALSE;
1928 if (sl->GetSlaveType() == TSlave::kMaster) {
1929 if (sl2->GetSlaveType() == TSlave::kSlave) {
1930 // give preference to master
1931 replace_slave = sl2;
1932 add = kTRUE;
1933 } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1935 fAllUniqueSlaves->Add(sl);
1936 fAllUniqueMonitor->Add(sl->GetSocket());
1937 } else {
1938 Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1939 R__ASSERT(0);
1940 }
1941 }
1942 break;
1943 }
1944 }
1945
1946 if (add) {
1947 fUniqueSlaves->Add(sl);
1948 fAllUniqueSlaves->Add(sl);
1949 fUniqueMonitor->Add(sl->GetSocket());
1950 fAllUniqueMonitor->Add(sl->GetSocket());
1951 if (replace_slave) {
1952 fUniqueSlaves->Remove(replace_slave);
1953 fAllUniqueSlaves->Remove(replace_slave);
1954 fUniqueMonitor->Remove(replace_slave->GetSocket());
1955 fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1956 }
1957 }
1958 }
1959
1960 // will be actiavted in Collect()
1963}
1964
1965////////////////////////////////////////////////////////////////////////////////
1966/// Return number of slaves as described in the config file.
1967
1969{
1970 return fSlaves->GetSize();
1971}
1972
1973////////////////////////////////////////////////////////////////////////////////
1974/// Return number of active slaves, i.e. slaves that are valid and in
1975/// the current computing group.
1976
1978{
1979 return fActiveSlaves->GetSize();
1980}
1981
1982////////////////////////////////////////////////////////////////////////////////
1983/// Return number of inactive slaves, i.e. slaves that are valid but not in
1984/// the current computing group.
1985
1987{
1988 return fInactiveSlaves->GetSize();
1989}
1990
1991////////////////////////////////////////////////////////////////////////////////
1992/// Return number of unique slaves, i.e. active slaves that have each a
1993/// unique different user files system.
1994
1996{
1997 return fUniqueSlaves->GetSize();
1998}
1999
2000////////////////////////////////////////////////////////////////////////////////
2001/// Return number of bad slaves. This are slaves that we in the config
2002/// file, but refused to startup or that died during the PROOF session.
2003
2005{
2006 return fBadSlaves->GetSize();
2007}
2008
2009////////////////////////////////////////////////////////////////////////////////
2010/// Ask the for the statistics of the slaves.
2011
2013{
2014 if (!IsValid()) return;
2015
2018}
2019
2020////////////////////////////////////////////////////////////////////////////////
2021/// Get statistics about CPU time, real time and bytes read.
2022/// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2023/// and GetBytesRead()
2024
2026{
2027 if (fProtocol > 27) {
2028 // This returns the correct result
2029 AskStatistics();
2030 } else {
2031 // AskStatistics is buggy: parse the output of Print()
2034 Print();
2035 gSystem->RedirectOutput(0, 0, &rh);
2036 TMacro *mp = GetLastLog();
2037 if (mp) {
2038 // Look for global directories
2039 TIter nxl(mp->GetListOfLines());
2040 TObjString *os = 0;
2041 while ((os = (TObjString *) nxl())) {
2042 TString s(os->GetName());
2043 if (s.Contains("Total MB's processed:")) {
2044 s.ReplaceAll("Total MB's processed:", "");
2045 if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2046 } else if (s.Contains("Total real time used (s):")) {
2047 s.ReplaceAll("Total real time used (s):", "");
2048 if (s.IsFloat()) fRealTime = s.Atof();
2049 } else if (s.Contains("Total CPU time used (s):")) {
2050 s.ReplaceAll("Total CPU time used (s):", "");
2051 if (s.IsFloat()) fCpuTime = s.Atof();
2052 }
2053 }
2054 delete mp;
2055 }
2056 }
2057
2058 if (verbose) {
2059 Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2060 GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2061 }
2062}
2063
2064////////////////////////////////////////////////////////////////////////////////
2065/// Ask the for the number of parallel slaves.
2066
2068{
2069 if (!IsValid()) return;
2070
2073}
2074
2075////////////////////////////////////////////////////////////////////////////////
2076/// Ask the master for the list of queries.
2077
2079{
2080 if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2081
2082 Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2084 m << all;
2087
2088 // This should have been filled by now
2089 return fQueries;
2090}
2091
2092////////////////////////////////////////////////////////////////////////////////
2093/// Number of queries processed by this session
2094
2096{
2097 if (fQueries)
2098 return fQueries->GetSize() - fOtherQueries;
2099 return 0;
2100}
2101
2102////////////////////////////////////////////////////////////////////////////////
2103/// Set max number of draw queries whose results are saved
2104
2106{
2107 if (max > 0) {
2108 if (fPlayer)
2110 fMaxDrawQueries = max;
2111 }
2112}
2113
2114////////////////////////////////////////////////////////////////////////////////
2115/// Get max number of queries whose full results are kept in the
2116/// remote sandbox
2117
2119{
2121 m << kFALSE;
2124}
2125
2126////////////////////////////////////////////////////////////////////////////////
2127/// Return pointer to the list of query results in the player
2128
2130{
2131 return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2132}
2133
2134////////////////////////////////////////////////////////////////////////////////
2135/// Return pointer to the full TQueryResult instance owned by the player
2136/// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2137
2139{
2140 return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2141}
2142
2143////////////////////////////////////////////////////////////////////////////////
2144/// Ask the master for the list of queries.
2145/// Options:
2146/// "A" show information about all the queries known to the
2147/// server, i.e. even those processed by other sessions
2148/// "L" show only information about queries locally available
2149/// i.e. already retrieved. If "L" is specified, "A" is
2150/// ignored.
2151/// "F" show all details available about queries
2152/// "H" print help menu
2153/// Default ""
2154
2156{
2157 Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2158 if (help) {
2159
2160 // Help
2161
2162 Printf("+++");
2163 Printf("+++ Options: \"A\" show all queries known to server");
2164 Printf("+++ \"L\" show retrieved queries");
2165 Printf("+++ \"F\" full listing of query info");
2166 Printf("+++ \"H\" print this menu");
2167 Printf("+++");
2168 Printf("+++ (case insensitive)");
2169 Printf("+++");
2170 Printf("+++ Use Retrieve(<#>) to retrieve the full"
2171 " query results from the master");
2172 Printf("+++ e.g. Retrieve(8)");
2173
2174 Printf("+++");
2175
2176 return;
2177 }
2178
2179 if (!IsValid()) return;
2180
2181 Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2182
2183 TObject *pq = 0;
2184 if (!local) {
2185 GetListOfQueries(opt);
2186
2187 if (!fQueries) return;
2188
2189 TIter nxq(fQueries);
2190
2191 // Queries processed by other sessions
2192 if (fOtherQueries > 0) {
2193 Printf("+++");
2194 Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2195 Int_t nq = 0;
2196 while (nq++ < fOtherQueries && (pq = nxq()))
2197 pq->Print(opt);
2198 }
2199
2200 // Queries processed by this session
2201 Printf("+++");
2202 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2204 while ((pq = nxq()))
2205 pq->Print(opt);
2206
2207 } else {
2208
2209 // Queries processed by this session
2210 Printf("+++");
2211 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2213
2214 // Queries available locally
2215 TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2216 if (listlocal) {
2217 Printf("+++");
2218 Printf("+++ Queries available locally: %d", listlocal->GetSize());
2219 TIter nxlq(listlocal);
2220 while ((pq = nxlq()))
2221 pq->Print(opt);
2222 }
2223 }
2224 Printf("+++");
2225}
2226
2227////////////////////////////////////////////////////////////////////////////////
2228/// See if the data is ready to be analyzed.
2229
2231{
2232 if (!IsValid()) return kFALSE;
2233
2234 TList submasters;
2235 TIter nextSlave(GetListOfActiveSlaves());
2236 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2237 if (sl->GetSlaveType() == TSlave::kMaster) {
2238 submasters.Add(sl);
2239 }
2240 }
2241
2242 fDataReady = kTRUE; //see if any submasters set it to false
2243 fBytesReady = 0;
2244 fTotalBytes = 0;
2245 //loop over submasters and see if data is ready
2246 if (submasters.GetSize() > 0) {
2247 Broadcast(kPROOF_DATA_READY, &submasters);
2248 Collect(&submasters);
2249 }
2250
2251 bytesready = fBytesReady;
2252 totalbytes = fTotalBytes;
2253
2254 EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2255
2256 PDB(kGlobal,2)
2257 Info("IsDataReady", "%lld / %lld (%s)",
2258 bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2259
2260 return fDataReady;
2261}
2262
2263////////////////////////////////////////////////////////////////////////////////
2264/// Send interrupt to master or slave servers.
2265
2267{
2268 if (!IsValid()) return;
2269
2270 TList *slaves = 0;
2271 if (list == kAll) slaves = fSlaves;
2272 if (list == kActive) slaves = fActiveSlaves;
2273 if (list == kUnique) slaves = fUniqueSlaves;
2274 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2275
2276 if (slaves->GetSize() == 0) return;
2277
2278 TSlave *sl;
2279 TIter next(slaves);
2280
2281 while ((sl = (TSlave *)next())) {
2282 if (sl->IsValid()) {
2283
2284 // Ask slave to progate the interrupt request
2285 sl->Interrupt((Int_t)type);
2286 }
2287 }
2288}
2289
2290////////////////////////////////////////////////////////////////////////////////
2291/// Returns number of slaves active in parallel mode. Returns 0 in case
2292/// there are no active slaves. Returns -1 in case of error.
2293
2295{
2296 if (!IsValid()) return -1;
2297
2298 // iterate over active slaves and return total number of slaves
2299 TIter nextSlave(GetListOfActiveSlaves());
2300 Int_t nparallel = 0;
2301 while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2302 if (sl->GetParallel() >= 0)
2303 nparallel += sl->GetParallel();
2304
2305 return nparallel;
2306}
2307
2308////////////////////////////////////////////////////////////////////////////////
2309/// Returns list of TSlaveInfo's. In case of error return 0.
2310
2312{
2313 if (!IsValid()) return 0;
2314
2315 if (fSlaveInfo == 0) {
2318 } else {
2319 fSlaveInfo->Delete();
2320 }
2321
2322 TList masters;
2323 TIter next(GetListOfSlaves());
2324 TSlave *slave;
2325
2326 while ((slave = (TSlave *) next()) != 0) {
2327 if (slave->GetSlaveType() == TSlave::kSlave) {
2328 const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2329 TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2330 name,
2331 slave->GetPerfIdx());
2332 fSlaveInfo->Add(slaveinfo);
2333
2334 TIter nextactive(GetListOfActiveSlaves());
2335 TSlave *activeslave;
2336 while ((activeslave = (TSlave *) nextactive())) {
2337 if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2338 slaveinfo->SetStatus(TSlaveInfo::kActive);
2339 break;
2340 }
2341 }
2342
2343 TIter nextbad(GetListOfBadSlaves());
2344 TSlave *badslave;
2345 while ((badslave = (TSlave *) nextbad())) {
2346 if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2347 slaveinfo->SetStatus(TSlaveInfo::kBad);
2348 break;
2349 }
2350 }
2351 // Get system info if supported
2352 if (slave->IsValid()) {
2353 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2354 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2355 else
2356 masters.Add(slave);
2357 }
2358
2359 } else if (slave->GetSlaveType() == TSlave::kMaster) {
2360 if (slave->IsValid()) {
2361 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2362 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2363 else
2364 masters.Add(slave);
2365 }
2366 } else {
2367 Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2368 R__ASSERT(0);
2369 }
2370 }
2371 if (masters.GetSize() > 0) Collect(&masters);
2372
2373 return fSlaveInfo;
2374}
2375
2376////////////////////////////////////////////////////////////////////////////////
2377/// Activate slave server list.
2378
2380{
2381 TMonitor *mon = fAllMonitor;
2382 mon->DeActivateAll();
2383
2384 slaves = !slaves ? fActiveSlaves : slaves;
2385
2386 TIter next(slaves);
2387 TSlave *sl;
2388 while ((sl = (TSlave*) next())) {
2389 if (sl->IsValid())
2390 mon->Activate(sl->GetSocket());
2391 }
2392}
2393
2394////////////////////////////////////////////////////////////////////////////////
2395/// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2396/// monitored by 'mon'.
2397
2399{
2400 TMonitor *m = (mon) ? mon : fCurrentMonitor;
2401 if (m) {
2402 if (on)
2403 m->ActivateAll();
2404 else
2405 m->DeActivateAll();
2406 }
2407}
2408
2409////////////////////////////////////////////////////////////////////////////////
2410/// Broadcast the group priority to all workers in the specified list. Returns
2411/// the number of workers the message was successfully sent to.
2412/// Returns -1 in case of error.
2413
2414Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2415{
2416 if (!IsValid()) return -1;
2417
2418 if (workers->GetSize() == 0) return 0;
2419
2420 int nsent = 0;
2421 TIter next(workers);
2422
2423 TSlave *wrk;
2424 while ((wrk = (TSlave *)next())) {
2425 if (wrk->IsValid()) {
2426 if (wrk->SendGroupPriority(grp, priority) == -1)
2427 MarkBad(wrk, "could not send group priority");
2428 else
2429 nsent++;
2430 }
2431 }
2432
2433 return nsent;
2434}
2435
2436////////////////////////////////////////////////////////////////////////////////
2437/// Broadcast the group priority to all workers in the specified list. Returns
2438/// the number of workers the message was successfully sent to.
2439/// Returns -1 in case of error.
2440
2441Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2442{
2443 TList *workers = 0;
2444 if (list == kAll) workers = fSlaves;
2445 if (list == kActive) workers = fActiveSlaves;
2446 if (list == kUnique) workers = fUniqueSlaves;
2447 if (list == kAllUnique) workers = fAllUniqueSlaves;
2448
2449 return BroadcastGroupPriority(grp, priority, workers);
2450}
2451
2452////////////////////////////////////////////////////////////////////////////////
2453/// Reset the merge progress notificator
2454
2456{
2458}
2459
2460////////////////////////////////////////////////////////////////////////////////
2461/// Broadcast a message to all slaves in the specified list. Returns
2462/// the number of slaves the message was successfully sent to.
2463/// Returns -1 in case of error.
2464
2466{
2467 if (!IsValid()) return -1;
2468
2469 if (!slaves || slaves->GetSize() == 0) return 0;
2470
2471 int nsent = 0;
2472 TIter next(slaves);
2473
2474 TSlave *sl;
2475 while ((sl = (TSlave *)next())) {
2476 if (sl->IsValid()) {
2477 if (sl->GetSocket()->Send(mess) == -1)
2478 MarkBad(sl, "could not broadcast request");
2479 else
2480 nsent++;
2481 }
2482 }
2483
2484 return nsent;
2485}
2486
2487////////////////////////////////////////////////////////////////////////////////
2488/// Broadcast a message to all slaves in the specified list (either
2489/// all slaves or only the active slaves). Returns the number of slaves
2490/// the message was successfully sent to. Returns -1 in case of error.
2491
2493{
2494 TList *slaves = 0;
2495 if (list == kAll) slaves = fSlaves;
2496 if (list == kActive) slaves = fActiveSlaves;
2497 if (list == kUnique) slaves = fUniqueSlaves;
2498 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2499
2500 return Broadcast(mess, slaves);
2501}
2502
2503////////////////////////////////////////////////////////////////////////////////
2504/// Broadcast a character string buffer to all slaves in the specified
2505/// list. Use kind to set the TMessage what field. Returns the number of
2506/// slaves the message was sent to. Returns -1 in case of error.
2507
2508Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2509{
2510 TMessage mess(kind);
2511 if (str) mess.WriteString(str);
2512 return Broadcast(mess, slaves);
2513}
2514
2515////////////////////////////////////////////////////////////////////////////////
2516/// Broadcast a character string buffer to all slaves in the specified
2517/// list (either all slaves or only the active slaves). 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
2521Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2522{
2523 TMessage mess(kind);
2524 if (str) mess.WriteString(str);
2525 return Broadcast(mess, list);
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, slaves);
2538}
2539
2540////////////////////////////////////////////////////////////////////////////////
2541/// Broadcast an object to all slaves in the specified list. Use kind to
2542/// set the TMEssage what field. Returns the number of slaves the message
2543/// was sent to. Returns -1 in case of error.
2544
2546{
2547 TMessage mess(kind);
2548 mess.WriteObject(obj);
2549 return Broadcast(mess, list);
2550}
2551
2552////////////////////////////////////////////////////////////////////////////////
2553/// Broadcast a raw buffer of specified length to all slaves in the
2554/// specified list. Returns the number of slaves the buffer was sent to.
2555/// Returns -1 in case of error.
2556
2557Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2558{
2559 if (!IsValid()) return -1;
2560
2561 if (slaves->GetSize() == 0) return 0;
2562
2563 int nsent = 0;
2564 TIter next(slaves);
2565
2566 TSlave *sl;
2567 while ((sl = (TSlave *)next())) {
2568 if (sl->IsValid()) {
2569 if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2570 MarkBad(sl, "could not send broadcast-raw request");
2571 else
2572 nsent++;
2573 }
2574 }
2575
2576 return nsent;
2577}
2578
2579////////////////////////////////////////////////////////////////////////////////
2580/// Broadcast a raw buffer of specified length to all slaves in the
2581/// specified list. Returns the number of slaves the buffer was sent to.
2582/// Returns -1 in case of error.
2583
2584Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2585{
2586 TList *slaves = 0;
2587 if (list == kAll) slaves = fSlaves;
2588 if (list == kActive) slaves = fActiveSlaves;
2589 if (list == kUnique) slaves = fUniqueSlaves;
2590 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2591
2592 return BroadcastRaw(buffer, length, slaves);
2593}
2594
2595////////////////////////////////////////////////////////////////////////////////
2596/// Broadcast file to all workers in the specified list. Returns the number of workers
2597/// the buffer was sent to.
2598/// Returns -1 in case of error.
2599
2600Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2601{
2602 if (!IsValid()) return -1;
2603
2604 if (wrks->GetSize() == 0) return 0;
2605
2606 int nsent = 0;
2607 TIter next(wrks);
2608
2609 TSlave *wrk;
2610 while ((wrk = (TSlave *)next())) {
2611 if (wrk->IsValid()) {
2612 if (SendFile(file, opt, rfile, wrk) < 0)
2613 Error("BroadcastFile",
2614 "problems sending file to worker %s (%s)",
2615 wrk->GetOrdinal(), wrk->GetName());
2616 else
2617 nsent++;
2618 }
2619 }
2620
2621 return nsent;
2622}
2623
2624////////////////////////////////////////////////////////////////////////////////
2625/// Broadcast file to all workers in the specified list. Returns the number of workers
2626/// the buffer was sent to.
2627/// Returns -1 in case of error.
2628
2629Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2630{
2631 TList *wrks = 0;
2632 if (list == kAll) wrks = fSlaves;
2633 if (list == kActive) wrks = fActiveSlaves;
2634 if (list == kUnique) wrks = fUniqueSlaves;
2635 if (list == kAllUnique) wrks = fAllUniqueSlaves;
2636
2637 return BroadcastFile(file, opt, rfile, wrks);
2638}
2639
2640////////////////////////////////////////////////////////////////////////////////
2641/// Release the used monitor to be used, making sure to delete newly created
2642/// monitors.
2643
2645{
2646 if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2647 && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2648 delete mon;
2649 }
2650}
2651
2652////////////////////////////////////////////////////////////////////////////////
2653/// Collect responses from slave sl. Returns the number of slaves that
2654/// responded (=1).
2655/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2656/// which means wait forever).
2657/// If defined (>= 0) endtype is the message that stops this collection.
2658
2659Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2660{
2661 Int_t rc = 0;
2662
2663 TMonitor *mon = 0;
2664 if (!sl->IsValid()) return 0;
2665
2667 mon = new TMonitor;
2668 } else {
2669 mon = fAllMonitor;
2670 mon->DeActivateAll();
2671 }
2672 mon->Activate(sl->GetSocket());
2673
2674 rc = Collect(mon, timeout, endtype, deactonfail);
2675 ReleaseMonitor(mon);
2676 return rc;
2677}
2678
2679////////////////////////////////////////////////////////////////////////////////
2680/// Collect responses from the slave servers. Returns the number of slaves
2681/// that responded.
2682/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2683/// which means wait forever).
2684/// If defined (>= 0) endtype is the message that stops this collection.
2685
2686Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2687{
2688 Int_t rc = 0;
2689
2690 TMonitor *mon = 0;
2691
2693 mon = new TMonitor;
2694 } else {
2695 mon = fAllMonitor;
2696 mon->DeActivateAll();
2697 }
2698 TIter next(slaves);
2699 TSlave *sl;
2700 while ((sl = (TSlave*) next())) {
2701 if (sl->IsValid())
2702 mon->Activate(sl->GetSocket());
2703 }
2704
2705 rc = Collect(mon, timeout, endtype, deactonfail);
2706 ReleaseMonitor(mon);
2707 return rc;
2708}
2709
2710////////////////////////////////////////////////////////////////////////////////
2711/// Collect responses from the slave servers. Returns the number of slaves
2712/// that responded.
2713/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2714/// which means wait forever).
2715/// If defined (>= 0) endtype is the message that stops this collection.
2716
2717Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2718{
2719 Int_t rc = 0;
2720 TMonitor *mon = 0;
2721
2722 if (list == kAll) mon = fAllMonitor;
2723 if (list == kActive) mon = fActiveMonitor;
2724 if (list == kUnique) mon = fUniqueMonitor;
2725 if (list == kAllUnique) mon = fAllUniqueMonitor;
2726 if (fCurrentMonitor == mon) {
2727 // Get a copy
2728 mon = new TMonitor(*mon);
2729 }
2730 mon->ActivateAll();
2731
2732 rc = Collect(mon, timeout, endtype, deactonfail);
2733 ReleaseMonitor(mon);
2734 return rc;
2735}
2736
2737////////////////////////////////////////////////////////////////////////////////
2738/// Collect responses from the slave servers. Returns the number of messages
2739/// received. Can be 0 if there are no active slaves.
2740/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2741/// which means wait forever).
2742/// If defined (>= 0) endtype is the message that stops this collection.
2743/// Collect also stops its execution from time to time to check for new
2744/// workers in Dynamic Startup mode.
2745
2746Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2747{
2748 Int_t collectId = gRandom->Integer(9999);
2749
2750 PDB(kCollect, 3)
2751 Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2752
2753 // Reset the status flag and clear the messages in the list, if any
2754 fStatus = 0;
2756
2757 Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2758
2759 if (!mon->GetActive(actto)) return 0;
2760
2762
2763 // Used by external code to know what we are monitoring
2764 TMonitor *savedMonitor = 0;
2765 if (fCurrentMonitor) {
2766 savedMonitor = fCurrentMonitor;
2767 fCurrentMonitor = mon;
2768 } else {
2769 fCurrentMonitor = mon;
2770 fBytesRead = 0;
2771 fRealTime = 0.0;
2772 fCpuTime = 0.0;
2773 }
2774
2775 // We want messages on the main window during synchronous collection,
2776 // but we save the present status to restore it at the end
2777 Bool_t saveRedirLog = fRedirLog;
2778 if (!IsIdle() && !IsSync())
2779 fRedirLog = kFALSE;
2780
2781 int cnt = 0, rc = 0;
2782
2783 // Timeout counter
2784 Long_t nto = timeout;
2785 PDB(kCollect, 2)
2786 Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2787
2788 // On clients, handle Ctrl-C during collection
2789 if (fIntHandler)
2790 fIntHandler->Add();
2791
2792 // Sockets w/o activity during the last 'sto' millisecs are deactivated
2793 Int_t nact = 0;
2794 Long_t sto = -1;
2795 Int_t nsto = 60;
2796 Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2797 mon->ResetInterrupt();
2798 while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2799
2800 // Dump last waiting sockets, if in debug mode
2801 PDB(kCollect, 2) {
2802 if (nact < 4) {
2803 TList *al = mon->GetListOfActives();
2804 if (al && al->GetSize() > 0) {
2805 Info("Collect"," %d node(s) still active:", al->GetSize());
2806 TIter nxs(al);
2807 TSocket *xs = 0;
2808 while ((xs = (TSocket *)nxs())) {
2809 TSlave *wrk = FindSlave(xs);
2810 if (wrk)
2811 Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2812 else
2813 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2814 xs->GetInetAddress().GetPort());
2815 }
2816 }
2817 delete al;
2818 }
2819 }
2820
2821 // Preemptive poll for new workers on the master only in Dynamic Mode and only
2822 // during processing (TODO: should work on Top Master only)
2824 ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2827 fLastPollWorkers_s = time(0);
2829 PDB(kCollect, 1)
2830 Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2831 }
2832
2833 // Wait for a ready socket
2834 PDB(kCollect, 3)
2835 Info("Collect", "Will invoke Select() #%04d", collectId);
2836 TSocket *s = mon->Select(1000);
2837
2838 if (s && s != (TSocket *)(-1)) {
2839 // Get and analyse the info it did receive
2840 rc = CollectInputFrom(s, endtype, deactonfail);
2841 if (rc == 1 || (rc == 2 && !savedMonitor)) {
2842 // Deactivate it if we are done with it
2843 mon->DeActivate(s);
2844 TList *al = mon->GetListOfActives();
2845 PDB(kCollect, 2)
2846 Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2847 s, mon->GetActive(),
2848 al->First());
2849 delete al;
2850 } else if (rc == 2) {
2851 // This end message was for the saved monitor
2852 // Deactivate it if we are done with it
2853 if (savedMonitor) {
2854 savedMonitor->DeActivate(s);
2855 TList *al = mon->GetListOfActives();
2856 PDB(kCollect, 2)
2857 Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2858 s, savedMonitor->GetActive(),
2859 al->First());
2860 delete al;
2861 }
2862 }
2863
2864 // Update counter (if no error occured)
2865 if (rc >= 0)
2866 cnt++;
2867 } else {
2868 // If not timed-out, exit if not stopped or not aborted
2869 // (player exits status is finished in such a case); otherwise,
2870 // we still need to collect the partial output info
2871 if (!s)
2873 mon->DeActivateAll();
2874 // Decrease the timeout counter if requested
2875 if (s == (TSocket *)(-1) && nto > 0)
2876 nto--;
2877 }
2878
2879 // Check if there are workers with ready output to be sent and ask the first to send it
2881 // Maximum number of concurrent sendings
2882 Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2883 if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2884 mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2885 TIter nxwr(fWrksOutputReady);
2886 TSlave *wrk = 0;
2887 while (mxws && (wrk = (TSlave *) nxwr())) {
2888 if (!wrk->TestBit(TSlave::kOutputRequested)) {
2889 // Ask worker for output
2890 TMessage sendoutput(kPROOF_SENDOUTPUT);
2891 PDB(kCollect, 2)
2892 Info("Collect", "worker %s was asked to send its output to master",
2893 wrk->GetOrdinal());
2894 if (wrk->GetSocket()->Send(sendoutput) != 1) {
2896 mxws--;
2897 }
2898 } else {
2899 // Count
2900 mxws--;
2901 }
2902 }
2903 }
2904
2905 // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2906 sto = -1;
2907 if (--nsto <= 0) {
2908 sto = (Long_t) actto;
2909 nsto = 60;
2910 }
2911
2912 } // end loop over active monitors
2913
2914 // If timed-out, deactivate the remaining sockets
2915 if (nto == 0) {
2916 TList *al = mon->GetListOfActives();
2917 if (al && al->GetSize() > 0) {
2918 // Notify the name of those which did timeout
2919 Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2920 TIter nxs(al);
2921 TSocket *xs = 0;
2922 while ((xs = (TSocket *)nxs())) {
2923 TSlave *wrk = FindSlave(xs);
2924 if (wrk)
2925 Info("Collect"," %s", wrk->GetName());
2926 else
2927 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2928 xs->GetInetAddress().GetPort());
2929 }
2930 }
2931 delete al;
2932 mon->DeActivateAll();
2933 }
2934
2935 // Deactivate Ctrl-C special handler
2936 if (fIntHandler)
2938
2939 // make sure group view is up to date
2940 SendGroupView();
2941
2942 // Restore redirection setting
2943 fRedirLog = saveRedirLog;
2944
2945 // Restore the monitor
2946 fCurrentMonitor = savedMonitor;
2947
2949
2950 PDB(kCollect, 3)
2951 Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2952
2953 return cnt;
2954}
2955
2956////////////////////////////////////////////////////////////////////////////////
2957/// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2958/// them. Returns the number of new workers found, or <0 on errors.
2959
2961{
2962 // Requests for worker updates
2963 Int_t dummy = 0;
2964 TList *reqWorkers = new TList();
2965 reqWorkers->SetOwner(kFALSE);
2966
2967 if (!TestBit(TProof::kIsMaster)) {
2968 Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2969 return -1;
2970 }
2971 if (!gProofServ) {
2972 Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2973 return -1;
2974 }
2975
2976 gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2977
2978 // List of new workers only (TProofNodeInfo)
2979 TList *newWorkers = new TList();
2980 newWorkers->SetOwner(kTRUE);
2981
2982 TIter next(reqWorkers);
2983 TProofNodeInfo *ni;
2984 TString fullOrd;
2985 while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2986
2987 // Form the full ordinal
2988 fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2989
2990 TIter nextInner(fSlaves);
2991 TSlave *sl;
2992 Bool_t found = kFALSE;
2993 while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
2994 if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
2995 found = kTRUE;
2996 break;
2997 }
2998 }
2999
3000 if (found) delete ni;
3001 else {
3002 newWorkers->Add(ni);
3003 PDB(kGlobal, 1)
3004 Info("PollForNewWorkers", "New worker found: %s:%s",
3005 ni->GetNodeName().Data(), fullOrd.Data());
3006 }
3007 }
3008
3009 delete reqWorkers; // not owner
3010
3011 Int_t nNewWorkers = newWorkers->GetEntries();
3012
3013 // Add the new workers
3014 if (nNewWorkers > 0) {
3015 PDB(kGlobal, 1)
3016 Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
3017 Int_t rv = AddWorkers(newWorkers);
3018 if (rv < 0) {
3019 Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3020 return -1;
3021 }
3022 // Don't delete newWorkers: AddWorkers() will do that
3023 }
3024 else {
3025 PDB(kGlobal, 2)
3026 Info("PollForNewWorkers", "No new worker found");
3027 delete newWorkers;
3028 }
3029
3030 return nNewWorkers;
3031}
3032
3033////////////////////////////////////////////////////////////////////////////////
3034/// Remove links to objects in list 'ol' from gDirectory
3035
3037{
3038 if (ol) {
3039 TIter nxo(ol);
3040 TObject *o = 0;
3041 while ((o = nxo()))
3043 }
3044}
3045
3046////////////////////////////////////////////////////////////////////////////////
3047/// Collect and analyze available input from socket s.
3048/// Returns 0 on success, -1 if any failure occurs.
3049
3051{
3052 TMessage *mess;
3053
3054 Int_t recvrc = 0;
3055 if ((recvrc = s->Recv(mess)) < 0) {
3056 PDB(kCollect,2)
3057 Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3058 Bool_t bad = kTRUE;
3059 if (recvrc == -5) {
3060 // Broken connection: try reconnection
3062 if (s->Reconnect() == 0) {
3064 bad = kFALSE;
3065 }
3066 }
3067 if (bad)
3068 MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3069 // Ignore this wake up
3070 return -1;
3071 }
3072 if (!mess) {
3073 // we get here in case the remote server died
3074 MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3075 return -1;
3076 }
3077 Int_t rc = 0;
3078
3079 Int_t what = mess->What();
3080 TSlave *sl = FindSlave(s);
3081 rc = HandleInputMessage(sl, mess, deactonfail);
3082 if (rc == 1 && (endtype >= 0) && (what != endtype))
3083 // This message was for the base monitor in recursive case
3084 rc = 2;
3085
3086 // We are done successfully
3087 return rc;
3088}
3089
3090////////////////////////////////////////////////////////////////////////////////
3091/// Analyze the received message.
3092/// Returns 0 on success (1 if this the last message from this socket), -1 if
3093/// any failure occurs.
3094
3096{
3097 char str[512];
3098 TObject *obj;
3099 Int_t rc = 0;
3100
3101 if (!mess || !sl) {
3102 Warning("HandleInputMessage", "given an empty message or undefined worker");
3103 return -1;
3104 }
3105 Bool_t delete_mess = kTRUE;
3106 TSocket *s = sl->GetSocket();
3107 if (!s) {
3108 Warning("HandleInputMessage", "worker socket is undefined");
3109 return -1;
3110 }
3111
3112 // The message type
3113 Int_t what = mess->What();
3114
3115 PDB(kCollect,3)
3116 Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3117
3118 switch (what) {
3119
3120 case kMESS_OK:
3121 // Add the message to the list
3122 fRecvMessages->Add(mess);
3123 delete_mess = kFALSE;
3124 break;
3125
3126 case kMESS_OBJECT:
3127 if (fPlayer) fPlayer->HandleRecvHisto(mess);
3128 break;
3129
3130 case kPROOF_FATAL:
3131 { TString msg;
3132 if ((mess->BufferSize() > mess->Length()))
3133 (*mess) >> msg;
3134 if (msg.IsNull()) {
3135 MarkBad(s, "received kPROOF_FATAL");
3136 } else {
3137 MarkBad(s, msg);
3138 }
3139 }
3141 // Finalize the progress dialog
3142 Emit("StopProcess(Bool_t)", kTRUE);
3143 }
3144 break;
3145
3146 case kPROOF_STOP:
3147 // Stop collection from this worker
3148 Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3149 sl->GetOrdinal());
3150 rc = 1;
3151 break;
3152
3154 // Add the message to the list
3155 fRecvMessages->Add(mess);
3156 delete_mess = kFALSE;
3157 rc = 1;
3158 break;
3159
3160 case kPROOF_TOUCH:
3161 // send a request for touching the remote admin file
3162 {
3163 sl->Touch();
3164 }
3165 break;
3166
3167 case kPROOF_GETOBJECT:
3168 // send slave object it asks for
3169 mess->ReadString(str, sizeof(str));
3170 obj = gDirectory->Get(str);
3171 if (obj)
3172 s->SendObject(obj);
3173 else
3174 s->Send(kMESS_NOTOK);
3175 break;
3176
3177 case kPROOF_GETPACKET:
3178 {
3179 PDB(kGlobal,2)
3180 Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3181 TDSetElement *elem = 0;
3182 elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3183
3184 if (elem != (TDSetElement*) -1) {
3186 answ << elem;
3187 s->Send(answ);
3188
3189 while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3190 TPair *p = (TPair*) fWaitingSlaves->First();
3191 s = (TSocket*) p->Key();
3192 TMessage *m = (TMessage*) p->Value();
3193
3194 elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3195 if (elem != (TDSetElement*) -1) {
3197 a << elem;
3198 s->Send(a);
3199 // remove has to happen via Links because TPair does not have
3200 // a Compare() function and therefore RemoveFirst() and
3201 // Remove(TObject*) do not work
3203 delete p;
3204 delete m;
3205 } else {
3206 break;
3207 }
3208 }
3209 } else {
3210 if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3211 fWaitingSlaves->Add(new TPair(s, mess));
3212 delete_mess = kFALSE;
3213 }
3214 }
3215 break;
3216
3217 case kPROOF_LOGFILE:
3218 {
3219 Int_t size;
3220 (*mess) >> size;
3221 PDB(kGlobal,2)
3222 Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3223 RecvLogFile(s, size);
3224 }
3225 break;
3226
3227 case kPROOF_LOGDONE:
3228 (*mess) >> sl->fStatus >> sl->fParallel;
3229 PDB(kCollect,2)
3230 Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3231 sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3232 if (sl->fStatus != 0) {
3233 // Return last nonzero status
3234 fStatus = sl->fStatus;
3235 // Deactivate the worker, if required
3236 if (deactonfail) DeactivateWorker(sl->fOrdinal);
3237 }
3238 // Remove from the workers-ready list
3242 }
3243 rc = 1;
3244 break;
3245
3246 case kPROOF_GETSTATS:
3247 {
3248 (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3249 >> sl->fWorkDir >> sl->fProofWorkDir;
3250 PDB(kCollect,2)
3251 Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3252 TString img;
3253 if ((mess->BufferSize() > mess->Length()))
3254 (*mess) >> img;
3255 // Set image
3256 if (img.IsNull()) {
3257 if (sl->fImage.IsNull())
3258 sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3259 sl->fProofWorkDir.Data());
3260 } else {
3261 sl->fImage = img;
3262 }
3263 PDB(kGlobal,2)
3264 Info("HandleInputMessage",
3265 "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3266
3267 fBytesRead += sl->fBytesRead;
3268 fRealTime += sl->fRealTime;
3269 fCpuTime += sl->fCpuTime;
3270 rc = 1;
3271 }
3272 break;
3273
3274 case kPROOF_GETPARALLEL:
3275 {
3276 Bool_t async = kFALSE;
3277 (*mess) >> sl->fParallel;
3278 if ((mess->BufferSize() > mess->Length()))
3279 (*mess) >> async;
3280 rc = (async) ? 0 : 1;
3281 }
3282 break;
3283
3284 case kPROOF_CHECKFILE:
3285 { // New servers (>= 5.22) send the status
3286 if ((mess->BufferSize() > mess->Length())) {
3287 (*mess) >> fCheckFileStatus;
3288 } else {
3289 // Form old servers this meant success (failure was signaled with the
3290 // dangerous kPROOF_FATAL)
3291 fCheckFileStatus = 1;
3292 }
3293 rc = 1;
3294 }
3295 break;
3296
3297 case kPROOF_SENDFILE:
3298 { // New server: signals ending of sendfile operation
3299 rc = 1;
3300 }
3301 break;
3302
3304 {
3305 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3306 Int_t type = 0;
3307 (*mess) >> type;
3308 switch (type) {
3311 fEnabledPackages = (TList *) mess->ReadObject(TList::Class());
3312 if (fEnabledPackages) {
3314 } else {
3315 Error("HandleInputMessage",
3316 "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3317 }
3318 break;
3321 fAvailablePackages = (TList *) mess->ReadObject(TList::Class());
3322 if (fAvailablePackages) {
3324 } else {
3325 Error("HandleInputMessage",
3326 "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3327 }
3328 break;
3329 default:
3330 Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3331 }
3332 }
3333 break;
3334
3335 case kPROOF_SENDOUTPUT:
3336 {
3337 // We start measuring the merging time
3339
3340 // Worker is ready to send output: make sure the relevant bit is reset
3342 PDB(kGlobal,2)
3343 Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3344 // Create the list if not yet done
3345 if (!fWrksOutputReady) {
3346 fWrksOutputReady = new TList;
3348 }
3349 fWrksOutputReady->Add(sl);
3350 }
3351 break;
3352
3354 {
3355 // We start measuring the merging time
3357
3358 PDB(kGlobal,2)
3359 Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3360 Int_t type = 0;
3361 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3363 Info("HandleInputMessage", "finalization on %s started ...", prefix);
3365 }
3366
3367 while ((mess->BufferSize() > mess->Length())) {
3368 (*mess) >> type;
3369 // If a query result header, add it to the player list
3370 if (fPlayer) {
3371 if (type == 0) {
3372 // Retrieve query result instance (output list not filled)
3373 TQueryResult *pq =
3374 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
3375 if (pq) {
3376 // Add query to the result list in TProofPlayer
3379 // And clear the output list, as we start merging a new set of results
3380 if (fPlayer->GetOutputList())
3382 // Add the unique query tag as TNamed object to the input list
3383 // so that it is available in TSelectors for monitoring
3384 TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3385 if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3386 fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3387 fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3388 } else {
3389 Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3390 }
3391 } else if (type > 0) {
3392 // Read object
3393 TObject *o = mess->ReadObject(TObject::Class());
3394 // Increment counter on the client side
3396 TString msg;
3397 Bool_t changed = kFALSE;
3398 msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3399 if (gProofServ) {
3401 } else if (IsTty() || changed) {
3402 fprintf(stderr, "%s\r", msg.Data());
3403 }
3404 // Add or merge it
3405 if ((fPlayer->AddOutputObject(o) == 1)) {
3406 // Remove the object if it has been merged
3407 SafeDelete(o);
3408 }
3409 if (type > 1) {
3410 // Update the merger progress info
3412 if (TestBit(TProof::kIsClient) && !IsLite()) {
3413 // In PROOFLite this has to be done once only in TProofLite::Process
3415 if (pq) {
3417 // Add input objects (do not override remote settings, if any)
3418 TObject *xo = 0;
3419 TIter nxin(fPlayer->GetInputList());
3420 // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3421 if (!pq->GetInputList()) pq->SetInputList(new TList());
3422 while ((xo = nxin()))
3423 if (!pq->GetInputList()->FindObject(xo->GetName()))
3424 pq->AddInput(xo->Clone());
3425 // If the last object, notify the GUI that the result arrived
3426 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3427 }
3428 // Processing is over
3429 UpdateDialog();
3430 }
3431 }
3432 }
3433 } else {
3434 Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3435 }
3436 }
3437 }
3438 break;
3439
3440 case kPROOF_OUTPUTLIST:
3441 {
3442 // We start measuring the merging time
3443
3444 PDB(kGlobal,2)
3445 Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3446 TList *out = 0;
3447 if (fPlayer) {
3449 if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3450 out = (TList *) mess->ReadObject(TList::Class());
3451 } else {
3452 TQueryResult *pq =
3453 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
3454 if (pq) {
3455 // Add query to the result list in TProofPlayer
3458 // To avoid accidental cleanups from anywhere else
3459 // remove objects from gDirectory and clone the list
3460 out = pq->GetOutputList();
3461 CleanGDirectory(out);
3462 out = (TList *) out->Clone();
3463 // Notify the GUI that the result arrived
3464 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3465 } else {
3466 PDB(kGlobal,2)
3467 Info("HandleInputMessage",
3468 "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3469 }
3470 }
3471 if (out) {
3472 out->SetOwner();
3473 fPlayer->AddOutput(out); // Incorporate the list
3474 SafeDelete(out);
3475 } else {
3476 PDB(kGlobal,2)
3477 Info("HandleInputMessage",
3478 "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3479 }
3480 } else {
3481 Warning("HandleInputMessage",
3482 "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3483 }
3484 // On clients at this point processing is over
3485 if (TestBit(TProof::kIsClient) && !IsLite())
3486 UpdateDialog();
3487 }
3488 break;
3489
3490 case kPROOF_QUERYLIST:
3491 {
3492 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3493 (*mess) >> fOtherQueries >> fDrawQueries;
3494 if (fQueries) {
3495 fQueries->Delete();
3496 delete fQueries;
3497 fQueries = 0;
3498 }
3499 fQueries = (TList *) mess->ReadObject(TList::Class());
3500 }
3501 break;
3502
3503 case kPROOF_RETRIEVE:
3504 {
3505 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3506 TQueryResult *pq =
3507 (TQueryResult *) mess->ReadObject(TQueryResult::Class());
3508 if (pq && fPlayer) {
3510 // Notify the GUI that the result arrived
3511 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3512 } else {
3513 PDB(kGlobal,2)
3514 Info("HandleInputMessage",
3515 "kPROOF_RETRIEVE: query result missing or player undefined");
3516 }
3517 }
3518 break;
3519
3520 case kPROOF_MAXQUERIES:
3521 {
3522 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3523 Int_t max = 0;
3524
3525 (*mess) >> max;
3526 Printf("Number of queries fully kept remotely: %d", max);
3527 }
3528 break;
3529
3531 {
3532 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3533
3534 UInt_t tot = 0, done = 0;
3535 TString action;
3536 Bool_t st = kTRUE;
3537
3538 (*mess) >> action >> tot >> done >> st;
3539
3541 if (tot) {
3542 TString type = (action.Contains("submas")) ? "submasters"
3543 : "workers";
3544 Int_t frac = (Int_t) (done*100.)/tot;
3545 char msg[512] = {0};
3546 if (frac >= 100) {
3547 snprintf(msg, 512, "%s: OK (%d %s) \n",
3548 action.Data(),tot, type.Data());
3549 } else {
3550 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3551 action.Data(), done, tot, frac);
3552 }
3553 if (fSync)
3554 fprintf(stderr,"%s", msg);
3555 else
3556 NotifyLogMsg(msg, 0);
3557 }
3558 // Notify GUIs
3559 StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3560 } else {
3561
3562 // Just send the message one level up
3564 m << action << tot << done << st;
3566 }
3567 }
3568 break;
3569
3571 {
3572 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3573
3574 UInt_t tot = 0, done = 0;
3575 TString action;
3576 Bool_t st = kTRUE;
3577
3578 (*mess) >> action >> tot >> done >> st;
3579
3581 if (tot) {
3582 TString type = "files";
3583 Int_t frac = (Int_t) (done*100.)/tot;
3584 char msg[512] = {0};
3585 if (frac >= 100) {
3586 snprintf(msg, 512, "%s: OK (%d %s) \n",
3587 action.Data(),tot, type.Data());
3588 } else {
3589 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3590 action.Data(), done, tot, frac);
3591 }
3592 if (fSync)
3593 fprintf(stderr,"%s", msg);
3594 else
3595 NotifyLogMsg(msg, 0);
3596 }
3597 // Notify GUIs
3598 DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3599 } else {
3600
3601 // Just send the message one level up
3603 m << action << tot << done << st;
3605 }
3606 }
3607 break;
3608
3610 {
3611 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3612
3613 // For Proof-Lite this variable is the number of workers and is set
3614 // by the player
3615 if (!IsLite()) {
3616 fNotIdle = 1;
3618 }
3619
3620 // Redirect the output, if needed
3622
3623 // The signal is used on masters by XrdProofdProtocol to catch
3624 // the start of processing; on clients it allows to update the
3625 // progress dialog
3626 if (!TestBit(TProof::kIsMaster)) {
3627
3628 // This is the end of preparation
3629 fQuerySTW.Stop();
3631 PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3632
3633 TString selec;
3634 Int_t dsz = -1;
3635 Long64_t first = -1, nent = -1;
3636 (*mess) >> selec >> dsz >> first >> nent;
3637 // Start or reset the progress dialog
3638 if (!gROOT->IsBatch()) {
3639 if (fProgressDialog &&
3642 fProgressDialog->ExecPlugin(5, this,
3643 selec.Data(), dsz, first, nent);
3645 } else {
3646 ResetProgressDialog(selec, dsz, first, nent);
3647 }
3648 }
3650 }
3651 }
3652 }
3653 break;
3654
3655 case kPROOF_ENDINIT:
3656 {
3657 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3658
3660 if (fPlayer)
3662 }
3663 }
3664 break;
3665
3666 case kPROOF_SETIDLE:
3667 {
3668 PDB(kGlobal,2)
3669 Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3670
3671 // The session is idle
3672 if (IsLite()) {
3673 if (fNotIdle > 0) {
3674 fNotIdle--;
3675 PDB(kGlobal,2)
3676 Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3677 } else {
3678 Warning("HandleInputMessage",
3679 "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3680 sl->GetOrdinal());
3681 }
3682 } else {
3683 fNotIdle = 0;
3684 // Check if the query has been enqueued
3685 if ((mess->BufferSize() > mess->Length()))
3686 (*mess) >> fIsWaiting;
3687 }
3688 }
3689 break;
3690
3692 {
3693 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3694
3695 // We have received the sequential number
3696 (*mess) >> fSeqNum;
3697 Bool_t sync = fSync;
3698 if ((mess->BufferSize() > mess->Length()))
3699 (*mess) >> sync;
3700 if (sync != fSync && fSync) {
3701 // The server required to switch to asynchronous mode
3702 Activate();
3703 fSync = kFALSE;
3704 }
3705 DisableGoAsyn();
3706 // Check if the query has been enqueued
3707 fIsWaiting = kTRUE;
3708 // For Proof-Lite this variable is the number of workers and is set by the player
3709 if (!IsLite())
3710 fNotIdle = 1;
3711
3712 rc = 1;
3713 }
3714 break;
3715
3716 case kPROOF_SESSIONTAG:
3717 {
3718 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3719
3720 // We have received the unique tag and save it as name of this object
3721 TString stag;
3722 (*mess) >> stag;
3723 SetName(stag);
3724 // In the TSlave object
3725 sl->SetSessionTag(stag);
3726 // Server may have also sent the group
3727 if ((mess->BufferSize() > mess->Length()))
3728 (*mess) >> fGroup;
3729 // Server may have also sent the user
3730 if ((mess->BufferSize() > mess->Length())) {
3731 TString usr;
3732 (*mess) >> usr;
3733 if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3734 }
3735 }
3736 break;
3737
3738 case kPROOF_FEEDBACK:
3739 {
3740 PDB(kGlobal,2)
3741 Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3742 TList *out = (TList *) mess->ReadObject(TList::Class());
3743 out->SetOwner();
3744 if (fPlayer)
3745 fPlayer->StoreFeedback(sl, out); // Adopts the list
3746 else
3747 // Not yet ready: stop collect asap
3748 rc = 1;
3749 }
3750 break;
3751
3752 case kPROOF_AUTOBIN:
3753 {
3754 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3755
3756 TString name;
3757 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3758
3759 (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3760
3762
3764
3765 answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3766
3767 s->Send(answ);
3768 }
3769 break;
3770
3771 case kPROOF_PROGRESS:
3772 {
3773 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3774
3775 if (GetRemoteProtocol() > 25) {
3776 // New format
3777 TProofProgressInfo *pi = 0;
3778 (*mess) >> pi;
3779 fPlayer->Progress(sl,pi);
3780 } else if (GetRemoteProtocol() > 11) {
3781 Long64_t total, processed, bytesread;
3782 Float_t initTime, procTime, evtrti, mbrti;
3783 (*mess) >> total >> processed >> bytesread
3784 >> initTime >> procTime
3785 >> evtrti >> mbrti;
3786 if (fPlayer)
3787 fPlayer->Progress(sl, total, processed, bytesread,
3788 initTime, procTime, evtrti, mbrti);
3789
3790 } else {
3791 // Old format
3792 Long64_t total, processed;
3793 (*mess) >> total >> processed;
3794 if (fPlayer)
3795 fPlayer->Progress(sl, total, processed);
3796 }
3797 }
3798 break;
3799
3800 case kPROOF_STOPPROCESS:
3801 {
3802 // This message is sent from a worker that finished processing.
3803 // We determine whether it was asked to finish by the
3804 // packetizer or stopped during processing a packet
3805 // (by TProof::RemoveWorkers() or by an external signal).
3806 // In the later case call packetizer->MarkBad.
3807 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3808
3809 Long64_t events = 0;
3810 Bool_t abort = kFALSE;
3811 TProofProgressStatus *status = 0;
3812
3813 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3814 (*mess) >> status >> abort;
3815 } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3816 (*mess) >> events >> abort;
3817 } else {
3818 (*mess) >> events;
3819 }
3820 if (fPlayer) {
3821 if (fProtocol > 18) {
3822 TList *listOfMissingFiles = 0;
3823 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3824 listOfMissingFiles = new TList();
3825 listOfMissingFiles->SetName("MissingFiles");
3826 if (fPlayer)
3827 fPlayer->AddOutputObject(listOfMissingFiles);
3828 }
3829 if (fPlayer->GetPacketizer()) {
3830 Int_t ret =
3831 fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3832 if (ret > 0)
3833 fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3834 // This object is now owned by the packetizer
3835 status = 0;
3836 }
3837 if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3838 } else {
3839 fPlayer->AddEventsProcessed(events);
3840 }
3841 }
3842 SafeDelete(status);
3844 Emit("StopProcess(Bool_t)", abort);
3845 break;
3846 }
3847
3848 case kPROOF_SUBMERGER:
3849 {
3850 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3851 HandleSubmerger(mess, sl);
3852 }
3853 break;
3854
3856 {
3857 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3858
3859 Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3860 Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3861 TList* tmpinfo = 0;
3862 (*mess) >> tmpinfo;
3863 if (tmpinfo == 0) {
3864 Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3865 } else {
3866 tmpinfo->SetOwner(kFALSE);
3867 Int_t nentries = tmpinfo->GetSize();
3868 for (Int_t i=0; i<nentries; i++) {
3869 TSlaveInfo* slinfo =
3870 dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3871 if (slinfo) {
3872 // If PROOF-Lite
3873 if (IsLite()) slinfo->fHostName = gSystem->HostName();
3874 // Check if we have already a instance for this worker
3875 TIter nxw(fSlaveInfo);
3876 TSlaveInfo *ourwi = 0;
3877 while ((ourwi = (TSlaveInfo *)nxw())) {
3878 if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3879 ourwi->SetSysInfo(slinfo->GetSysInfo());
3880 ourwi->fHostName = slinfo->GetName();
3881 if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3882 ourwi->fDataDir = slinfo->GetDataDir();
3883 break;
3884 }
3885 }
3886 if (!ourwi) {
3887 fSlaveInfo->Add(slinfo);
3888 } else {
3889 slinfo = ourwi;
3890 }
3891 if (slinfo->fStatus != TSlaveInfo::kBad) {
3892 if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3893 if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3894 }
3895 if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3896 slinfo->fMsd = sl->GetMsd();
3897 }
3898 }
3899 delete tmpinfo;
3900 rc = 1;
3901 }
3902 }
3903 break;
3904
3906 {
3907 PDB(kGlobal,2)
3908 Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3909 TDSet* dset = 0;
3910 (*mess) >> dset;
3911 if (!fDSet)
3912 Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3913 else
3914 fDSet->Validate(dset);
3915 delete dset;
3916 }
3917 break;
3918
3919 case kPROOF_DATA_READY:
3920 {
3921 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3922 Bool_t dataready = kFALSE;
3923 Long64_t totalbytes, bytesready;
3924 (*mess) >> dataready >> totalbytes >> bytesready;
3925 fTotalBytes += totalbytes;
3926 fBytesReady += bytesready;
3927 if (dataready == kFALSE) fDataReady = dataready;
3928 }
3929 break;
3930
3931 case kPROOF_PING:
3932 // do nothing (ping is already acknowledged)
3933 break;
3934
3935 case kPROOF_MESSAGE:
3936 {
3937 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3938
3939 // We have received the unique tag and save it as name of this object
3940 TString msg;
3941 (*mess) >> msg;
3942 Bool_t lfeed = kTRUE;
3943 if ((mess->BufferSize() > mess->Length()))
3944 (*mess) >> lfeed;
3945
3947
3948 if (fSync) {
3949 // Notify locally
3950 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3951 } else {
3952 // Notify locally taking care of redirection, windows logs, ...
3953 NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3954 }
3955 } else {
3956
3957 // The message is logged for debugging purposes.
3958 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3959 if (gProofServ) {
3960 // We hide it during normal operations
3962
3963 // And send the message one level up
3964 gProofServ->SendAsynMessage(msg, lfeed);
3965 }
3966 }
3967 }
3968 break;
3969
3971 {
3972 TString vac;
3973 (*mess) >> vac;
3974 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3975 Int_t from = 0;
3976 TString vers, archcomp;
3977 if (vac.Tokenize(vers, from, "|"))
3978 vac.Tokenize(archcomp, from, "|");
3979 sl->SetArchCompiler(archcomp);
3980 vers.ReplaceAll(":","|");
3981 sl->SetROOTVersion(vers);
3982 }
3983 break;
3984
3985 default:
3986 {
3987 Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3988 sl->GetOrdinal(), what);
3989 }
3990 break;
3991 }
3992
3993 // Cleanup
3994 if (delete_mess)
3995 delete mess;
3996
3997 // We are done successfully
3998 return rc;
3999}
4000
4001////////////////////////////////////////////////////////////////////////////////
4002/// Process a message of type kPROOF_SUBMERGER
4003
4005{
4006 // Message sub-type
4007 Int_t type = 0;
4008 (*mess) >> type;
4009 TSocket *s = sl->GetSocket();
4010
4011 switch (type) {
4012 case kOutputSent:
4013 {
4014 if (IsEndMaster()) {
4015 Int_t merger_id = -1;
4016 (*mess) >> merger_id;
4017
4018 PDB(kSubmerger, 2)
4019 Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4020 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4021
4022 if (!fMergers || fMergers->GetSize() <= merger_id) {
4023 Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4024 break;
4025 }
4026 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4027 mi->SetMergedWorker();
4028 if (mi->AreAllWorkersMerged()) {
4029 mi->Deactivate();
4030 if (GetActiveMergersCount() == 0) {
4031 fMergers->Clear();
4032 delete fMergers;
4034 fMergersCount = -1;
4036 PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4037 }
4038 }
4039 } else {
4040 PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4041 }
4042 }
4043 break;
4044
4045 case kMergerDown:
4046 {
4047 Int_t merger_id = -1;
4048 (*mess) >> merger_id;
4049
4050 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4051
4052 if (!fMergers || fMergers->GetSize() <= merger_id) {
4053 Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4054 break;
4055 }
4056
4057 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4058 if (!mi->IsActive()) {
4059 break;
4060 } else {
4061 mi->Deactivate();
4062 }
4063
4064 // Stop the invalid merger in the case it is still listening
4066 stop << Int_t(kStopMerging);
4067 stop << 0;
4068 s->Send(stop);
4069
4070 // Ask for results from merger (only original results from this node as worker are returned)
4071 AskForOutput(mi->GetMerger());
4072
4073 // Ask for results from all workers assigned to this merger
4074 TIter nxo(mi->GetWorkers());
4075 TObject * o = 0;
4076 while ((o = nxo())) {
4077 AskForOutput((TSlave *)o);
4078 }
4079 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4080 }
4081 break;
4082
4083 case kOutputSize:
4084 {
4085 if (IsEndMaster()) {
4086 PDB(kSubmerger, 2)
4087 Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4088
4089 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4090 if (!fFinalizationRunning) {
4091 Info("HandleSubmerger", "finalization on %s started ...", prefix);
4093 }
4094
4095 Int_t output_size = 0;
4096 Int_t merging_port = 0;
4097 (*mess) >> output_size >> merging_port;
4098
4099 PDB(kSubmerger, 2) Info("HandleSubmerger",
4100 "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4101 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4102 TString msg;
4103 if (!fMergersSet) {
4104
4106
4107 // First pass - setting number of mergers according to user or dynamically
4108 fMergersCount = -1; // No mergers used if not set by user
4109 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4110 if (mc) fMergersCount = mc->GetVal(); // Value set by user
4111 TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4112 if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4113
4114 // Mergers count specified by user but not valid
4115 if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4116 msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4117 prefix, fMergersCount, activeWorkers);
4118 if (gProofServ)
4120 else
4121 Printf("%s",msg.Data());
4122 fMergersCount = 0;
4123 }
4124 // Mergers count will be set dynamically
4125 if ((fMergersCount == 0) && (!fMergersByHost)) {
4126 if (activeWorkers > 1) {
4127 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4128 if (activeWorkers / fMergersCount < 2)
4129 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4130 }
4131 if (fMergersCount > 1)
4132 msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4133 prefix, fMergersCount, activeWorkers);
4134 else {
4135 msg.Form("%s: No mergers will be used for %d workers",
4136 prefix, activeWorkers);
4137 fMergersCount = -1;
4138 }
4139 if (gProofServ)
4141 else
4142 Printf("%s",msg.Data());
4143 } else if (fMergersByHost) {
4144 // We force mergers at host level to minimize network traffic
4145 if (activeWorkers > 1) {
4146 fMergersCount = 0;
4147 THashList hosts;
4148 TIter nxwk(fSlaves);
4149 TObject *wrk = 0;
4150 while ((wrk = nxwk())) {
4151 if (!hosts.FindObject(wrk->GetName())) {
4152 hosts.Add(new TObjString(wrk->GetName()));
4153 fMergersCount++;
4154 }
4155 }
4156 }
4157 if (fMergersCount > 1)
4158 msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4159 prefix, fMergersCount, activeWorkers);
4160 else {
4161 msg.Form("%s: No mergers will be used for %d workers",
4162 prefix, activeWorkers);
4163 fMergersCount = -1;
4164 }
4165 if (gProofServ)
4167 else
4168 Printf("%s",msg.Data());
4169 } else {
4170 msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4171 prefix, fMergersCount, activeWorkers);
4172 if (gProofServ)
4174 else
4175 Printf("%s",msg.Data());
4176 }
4177
4178 // We started merging; we call it here because fMergersCount is still the original number
4179 // and can be saved internally
4181
4182 // Update merger counters (new workers are not yet active)
4184
4185 if (fMergersCount > 0) {
4186
4187 fMergers = new TList();
4189 // Total number of workers, which will not act as mergers ('pure workers')
4190 fWorkersToMerge = (activeWorkers - fMergersCount);
4191 // Establish the first merger
4192 if (!CreateMerger(sl, merging_port)) {
4193 // Cannot establish first merger
4194 AskForOutput(sl);
4196 fMergersCount--;
4197 }
4199 } else {
4200 AskForOutput(sl);
4201 }
4203 } else {
4204 // Multiple pass
4205 if (fMergersCount == -1) {
4206 // No mergers. Workers send their outputs directly to master
4207 AskForOutput(sl);
4208 } else {
4209 if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4210 RedirectWorker(s, sl, output_size);
4211 fRedirectNext--;
4212 } else {
4213 Bool_t newMerger = kTRUE;
4214 if (fMergersByHost) {
4215 TIter nxmg(fMergers);
4216 TMergerInfo *mgi = 0;
4217 while ((mgi = (TMergerInfo *) nxmg())) {
4218 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4219 newMerger = kFALSE;
4220 break;
4221 }
4222 }
4223 }
4224 if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4225 // Still not enough mergers established
4226 if (!CreateMerger(sl, merging_port)) {
4227 // Cannot establish a merger
4228 AskForOutput(sl);
4230 fMergersCount--;
4231 }
4232 } else
4233 RedirectWorker(s, sl, output_size);
4234 }
4235 }
4236 }
4237 } else {
4238 Error("HandleSubMerger","kOutputSize received not on endmaster!");
4239 }
4240 }
4241 break;
4242 }
4243}
4244
4245////////////////////////////////////////////////////////////////////////////////
4246/// Redirect output of worker sl to some merger
4247
4248void TProof::RedirectWorker(TSocket *s, TSlave * sl, Int_t output_size)
4249{
4250 Int_t merger_id = -1;
4251
4252 if (fMergersByHost) {
4253 for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4254 TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4255 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4256 merger_id = i;
4257 break;
4258 }
4259 }
4260 } else {
4261 merger_id = FindNextFreeMerger();
4262 }
4263
4264 if (merger_id == -1) {
4265 // No free merger (probably it had crashed before)
4266 AskForOutput(sl);
4267 } else {
4268 TMessage sendoutput(kPROOF_SUBMERGER);
4269 sendoutput << Int_t(kSendOutput);
4270 PDB(kSubmerger, 2)
4271 Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4272
4273 PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4274 if (!fMergers || fMergers->GetSize() <= merger_id) {
4275 Error("RedirectWorker", "#%d not in list ", merger_id);
4276 return;
4277 }
4278 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4279
4280 TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4281 sendoutput << merger_id;
4282 sendoutput << hname;
4283 sendoutput << mi->GetPort();
4284 s->Send(sendoutput);
4285 mi->AddMergedObjects(output_size);
4286 mi->AddWorker(sl);
4287 }
4288}
4289
4290////////////////////////////////////////////////////////////////////////////////
4291/// Return a merger, which is both active and still accepts some workers to be
4292/// assigned to it. It works on the 'round-robin' basis.
4293
4295{
4296 while (fLastAssignedMerger < fMergers->GetSize() &&
4297 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4298 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4300 }
4301
4304 } else {
4305 return fLastAssignedMerger++;
4306 }
4307
4308 while (fLastAssignedMerger < fMergers->GetSize() &&
4309 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4310 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4312 }
4313
4315 return -1;
4316 } else {
4317 return fLastAssignedMerger++;
4318 }
4319}
4320
4321////////////////////////////////////////////////////////////////////////////////
4322/// Master asks for output from worker sl
4323
4325{
4326 TMessage sendoutput(kPROOF_SUBMERGER);
4327 sendoutput << Int_t(kSendOutput);
4328
4329 PDB(kSubmerger, 2) Info("AskForOutput",
4330 "worker %s was asked to send its output to master",
4331 sl->GetOrdinal());
4332
4333 sendoutput << -1;
4334 sendoutput << TString("master");
4335 sendoutput << -1;
4336 sl->GetSocket()->Send(sendoutput);
4338}
4339
4340////////////////////////////////////////////////////////////////////////////////
4341/// Final update of the progress dialog
4342
4344{
4345 if (!fPlayer) return;
4346
4347 // Handle abort ...
4349 if (fSync)
4350 Info("UpdateDialog",
4351 "processing was aborted - %lld events processed",
4353
4354 if (GetRemoteProtocol() > 11) {
4355 // New format
4356 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4357 } else {
4359 }
4360 Emit("StopProcess(Bool_t)", kTRUE);
4361 }
4362
4363 // Handle stop ...
4365 if (fSync)
4366 Info("UpdateDialog",
4367 "processing was stopped - %lld events processed",
4369
4370 if (GetRemoteProtocol() > 25) {
4371 // New format
4372 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4373 } else if (GetRemoteProtocol() > 11) {
4374 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4375 } else {
4377 }
4378 Emit("StopProcess(Bool_t)", kFALSE);
4379 }
4380
4381 // Final update of the dialog box
4382 if (GetRemoteProtocol() > 25) {
4383 // New format
4384 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4385 10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4386 (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4387 } else if (GetRemoteProtocol() > 11) {
4388 // New format
4389 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4390 7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4391 (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4392 } else {
4393 EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4394 }
4395}
4396
4397////////////////////////////////////////////////////////////////////////////////
4398/// Activate the a-sync input handler.
4399
4401{
4402 TIter next(fSlaves);
4403 TSlave *sl;
4404
4405 while ((sl = (TSlave*) next()))
4406 if (sl->GetInputHandler())
4407 sl->GetInputHandler()->Add();
4408}
4409
4410////////////////////////////////////////////////////////////////////////////////
4411/// De-activate a-sync input handler.
4412
4414{
4415 TIter next(fSlaves);
4416 TSlave *sl;
4417
4418 while ((sl = (TSlave*) next()))
4419 if (sl->GetInputHandler())
4420 sl->GetInputHandler()->Remove();
4421}
4422
4423////////////////////////////////////////////////////////////////////////////////
4424/// Get the active mergers count
4425
4427{
4428 if (!fMergers) return 0;
4429
4430 Int_t active_mergers = 0;
4431
4432 TIter mergers(fMergers);
4433 TMergerInfo *mi = 0;
4434 while ((mi = (TMergerInfo *)mergers())) {
4435 if (mi->IsActive()) active_mergers++;
4436 }
4437
4438 return active_mergers;
4439}
4440
4441////////////////////////////////////////////////////////////////////////////////
4442/// Create a new merger
4443
4445{
4446 PDB(kSubmerger, 2)
4447 Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4448
4449 PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4450
4451 if (port <= 0) {
4452 PDB(kSubmerger,2)
4453 Info("CreateMerger", "cannot create merger on port %d - exit", port);
4454 return kFALSE;
4455 }
4456
4457 Int_t workers = -1;
4458 if (!fMergersByHost) {
4459 Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4460 // Number of pure workers, which are not simply divisible by mergers
4461 Int_t rest = fWorkersToMerge % mergersToCreate;
4462 // We add one more worker for each of the first 'rest' mergers being established
4463 if (rest > 0 && fMergers->GetSize() < rest) {
4464 rest = 1;
4465 } else {
4466 rest = 0;
4467 }
4468 workers = (fWorkersToMerge / mergersToCreate) + rest;
4469 } else {
4470 Int_t workersOnHost = 0;
4471 for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4472 if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4473 }
4474 workers = workersOnHost - 1;
4475 }
4476
4477 TString msg;
4478 msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4479
4480 if (gProofServ) {
4482 } else {
4483 Printf("%s",msg.Data());
4484 }
4485 TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4486
4487 TMessage bemerger(kPROOF_SUBMERGER);
4488 bemerger << Int_t(kBeMerger);
4489 bemerger << fMergers->GetSize();
4490 bemerger << workers;
4491 sl->GetSocket()->Send(bemerger);
4492
4493 PDB(kSubmerger,2) Info("CreateMerger",
4494 "merger #%d (port: %d) for %d workers started",
4495 fMergers->GetSize(), port, workers);
4496
4497 fMergers->Add(merger);
4498 fWorkersToMerge = fWorkersToMerge - workers;
4499
4500 fRedirectNext = workers / 2;
4501
4502 PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4503 return kTRUE;
4504}
4505
4506////////////////////////////////////////////////////////////////////////////////
4507/// Add a bad slave server to the bad slave list and remove it from
4508/// the active list and from the two monitor objects. Assume that the work
4509/// done by this worker was lost and ask packerizer to reassign it.
4510
4511void TProof::MarkBad(TSlave *wrk, const char *reason)
4512{
4513 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4514
4515 // We may have been invalidated in the meanwhile: nothing to do in such a case
4516 if (!IsValid()) return;
4517
4518 if (!wrk) {
4519 Error("MarkBad", "worker instance undefined: protocol error? ");
4520 return;
4521 }
4522
4523 // Local URL
4524 static TString thisurl;
4525 if (thisurl.IsNull()) {
4526 if (IsMaster()) {
4527 Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4528 thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4529 if (port > 0) thisurl += TString::Format(":%d", port);
4530 } else {
4531 thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4532 }
4533 }
4534
4535 if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4536 // Message for notification
4537 const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4538 TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4539 TString msg;
4540 msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4541 src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4542 (reason && strlen(reason)) ? reason : "unknown");
4543 Info("MarkBad", "%s", msg.Data());
4544 // Notify one level up, if the case
4545 // Add some hint for diagnostics
4546 if (gProofServ) {
4547 msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4548 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4549 } else {
4550 msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4551 }
4552 msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4553 msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4554 msg += TString::Format(" +++\n");
4555 if (gProofServ) {
4556 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4557 "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4559 } else {
4560 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4561 "Display(\"*\")\n\n", thisurl.Data());
4562 Printf("%s", msg.Data());
4563 }
4564 } else if (reason) {
4565 if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4566 Info("MarkBad", "worker %s at %s:%d asked to terminate",
4567 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4568 }
4569 }
4570
4571 if (IsMaster() && reason) {
4572 if (strcmp(reason, kPROOF_TerminateWorker)) {
4573 // if the reason was not a planned termination
4574 TList *listOfMissingFiles = 0;
4575 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4576 listOfMissingFiles = new TList();
4577 listOfMissingFiles->SetName("MissingFiles");
4578 if (fPlayer)
4579 fPlayer->AddOutputObject(listOfMissingFiles);
4580 }
4581 // If a query is being processed, assume that the work done by
4582 // the worker was lost and needs to be reassigned.
4583 TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4584 if (packetizer) {
4585 // the worker was lost so do resubmit the packets
4586 packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4587 }
4588 } else {
4589 // Tell the coordinator that we are gone
4590 if (gProofServ) {
4591 TString ord(wrk->GetOrdinal());
4592 Int_t id = ord.Last('.');
4593 if (id != kNPOS) ord.Remove(0, id+1);
4595 }
4596 }
4597 } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4598 // We are invalid after this
4599 fValid = kFALSE;
4600 }
4601
4602 fActiveSlaves->Remove(wrk);
4604
4605 fAllMonitor->Remove(wrk->GetSocket());
4607
4609
4610 if (IsMaster()) {
4611 if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4612 // if the reason was a planned termination then delete the worker and
4613 // remove it from all the lists
4614 fSlaves->Remove(wrk);
4615 fBadSlaves->Remove(wrk);
4616 fActiveSlaves->Remove(wrk);
4617 fInactiveSlaves->Remove(wrk);
4618 fUniqueSlaves->Remove(wrk);
4621
4622 // we add it to the list of terminated slave infos instead, so that it
4623 // stays available in the .workers persistent file
4624 TSlaveInfo *si = new TSlaveInfo(
4625 wrk->GetOrdinal(),
4626 Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4627 0, "", wrk->GetWorkDir());
4629 else delete si;
4630
4631 delete wrk;
4632 } else {
4633 fBadSlaves->Add(wrk);
4634 fActiveSlaves->Remove(wrk);
4635 fUniqueSlaves->Remove(wrk);
4639 wrk->Close();
4640 // Update the mergers count, if needed
4641 if (fMergersSet) {
4642 Int_t mergersCount = -1;
4643 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4644 if (mc) mergersCount = mc->GetVal(); // Value set by user
4645 // Mergers count is set dynamically: recalculate it
4646 if (mergersCount == 0) {
4648 if (activeWorkers > 1) {
4649 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4650 if (activeWorkers / fMergersCount < 2)
4651 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4652 }
4653 }
4654 }
4655 }
4656
4657 // Update session workers files
4659 } else {
4660 // On clients the proof session should be removed from the lists
4661 // and deleted, since it is not valid anymore
4662 fSlaves->Remove(wrk);
4663 if (fManager)
4664 fManager->DiscardSession(this);
4665 }
4666}
4667
4668////////////////////////////////////////////////////////////////////////////////
4669/// Add slave with socket s to the bad slave list and remove if from
4670/// the active list and from the two monitor objects.
4671
4672void TProof::MarkBad(TSocket *s, const char *reason)
4673{
4674 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4675
4676 // We may have been invalidated in the meanwhile: nothing to do in such a case
4677 if (!IsValid()) return;
4678
4679 TSlave *wrk = FindSlave(s);
4680 MarkBad(wrk, reason);
4681}
4682
4683////////////////////////////////////////////////////////////////////////////////
4684/// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4685
4687{
4688 if (!wrk) {
4689 Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4690 return;
4691 }
4692
4693 // Send stop message
4694 if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4695 TMessage mess(kPROOF_STOP);
4696 wrk->GetSocket()->Send(mess);
4697 } else {
4698 if (gDebug > 0)
4699 Info("TerminateWorker", "connection to worker is already down: cannot"
4700 " send termination message");
4701 }
4702
4703 // This is a bad worker from now on
4705}
4706
4707////////////////////////////////////////////////////////////////////////////////
4708/// Ask an active worker 'ord' to terminate, i.e. to shutdown
4709
4710void TProof::TerminateWorker(const char *ord)
4711{
4712 if (ord && strlen(ord) > 0) {
4713 Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4714 if (IsMaster()) {
4715 TIter nxw(fSlaves);
4716 TSlave *wrk = 0;
4717 while ((wrk = (TSlave *)nxw())) {
4718 if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4719 TerminateWorker(wrk);
4720 if (!all) break;
4721 }
4722 }
4723 } else {
4724 TMessage mess(kPROOF_STOP);
4725 mess << TString(ord);
4726 Broadcast(mess);
4727 }
4728 }
4729}
4730
4731////////////////////////////////////////////////////////////////////////////////
4732/// Ping PROOF. Returns 1 if master server responded.
4733
4735{
4736 return Ping(kActive);
4737}
4738
4739////////////////////////////////////////////////////////////////////////////////
4740/// Ping PROOF slaves. Returns the number of slaves that responded.
4741
4743{
4744 TList *slaves = 0;
4745 if (list == kAll) slaves = fSlaves;
4746 if (list == kActive) slaves = fActiveSlaves;
4747 if (list == kUnique) slaves = fUniqueSlaves;
4748 if (list == kAllUnique) slaves = fAllUniqueSlaves;
4749
4750 if (slaves->GetSize() == 0) return 0;
4751
4752 int nsent = 0;
4753 TIter next(slaves);
4754
4755 TSlave *sl;
4756 while ((sl = (TSlave *)next())) {
4757 if (sl->IsValid()) {
4758 if (sl->Ping() == -1) {
4759 MarkBad(sl, "ping unsuccessful");
4760 } else {
4761 nsent++;
4762 }
4763 }
4764 }
4765
4766 return nsent;
4767}
4768
4769////////////////////////////////////////////////////////////////////////////////
4770/// Ping PROOF slaves. Returns the number of slaves that responded.
4771
4773{
4774 TList *slaves = fSlaves;
4775
4776 if (slaves->GetSize() == 0) return;
4777
4778 TIter next(slaves);
4779
4780 TSlave *sl;
4781 while ((sl = (TSlave *)next())) {
4782 if (sl->IsValid()) {
4783 sl->Touch();
4784 }
4785 }
4786
4787 return;
4788}
4789
4790////////////////////////////////////////////////////////////////////////////////
4791/// Print status of PROOF cluster.
4792
4793void TProof::Print(Option_t *option) const
4794{
4795 TString secCont;
4796
4798 Printf("Connected to: %s (%s)", GetMaster(),
4799 IsValid() ? "valid" : "invalid");
4800 Printf("Port number: %d", GetPort());
4801 Printf("User: %s", GetUser());
4802 Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4803 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4805 TSlave *sl = (TSlave *)fActiveSlaves->First();
4806 if (sl) {
4807 TString sc;
4808 if (sl->GetSocket()->GetSecContext())
4809 Printf("Security context: %s",
4810 sl->GetSocket()->GetSecContext()->AsString(sc));
4811 Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4812 } else {
4813 Printf("Security context: Error - No connection");
4814 Printf("Proofd protocol version: Error - No connection");
4815 }
4816 Printf("Client protocol version: %d", GetClientProtocol());
4817 Printf("Remote protocol version: %d", GetRemoteProtocol());
4818 Printf("Log level: %d", GetLogLevel());
4819 Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4820 Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4821 if (IsValid())
4822 const_cast<TProof*>(this)->SendPrint(option);
4823 } else {
4824 const_cast<TProof*>(this)->AskStatistics();
4825 if (IsParallel())
4826 Printf("*** Master server %s (parallel mode, %d workers):",
4828 else
4829 Printf("*** Master server %s (sequential mode):",
4831
4832 Printf("Master host name: %s", gSystem->HostName());
4833 Printf("Port number: %d", GetPort());
4834 if (strlen(gProofServ->GetGroup()) > 0) {
4835 Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4836 } else {
4837 Printf("User: %s", GetUser());
4838 }
4839 TString ver;
4840 ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4841 if (gSystem->Getenv("ROOTVERSIONTAG"))
4842 ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4843 Printf("ROOT version|rev|tag: %s", ver.Data());
4844 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4846 Printf("Protocol version: %d", GetClientProtocol());
4847 Printf("Image name: %s", GetImage());
4848 Printf("Working directory: %s", gSystem->WorkingDirectory());
4849 Printf("Config directory: %s", GetConfDir());
4850 Printf("Config file: %s", GetConfFile());
4851 Printf("Log level: %d", GetLogLevel());
4852 Printf("Number of workers: %d", GetNumberOfSlaves());
4853 Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4854 Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4855 Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4856 Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4857 Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4858 Printf("Total real time used (s): %.3f", GetRealTime());
4859 Printf("Total CPU time used (s): %.3f", GetCpuTime());
4860 if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4861 Printf("List of workers:");
4862 TList masters;
4863 TIter nextslave(fSlaves);
4864 while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4865 if (!sl->IsValid()) continue;
4866
4867 if (sl->GetSlaveType() == TSlave::kSlave) {
4868 sl->Print(option);
4869 } else if (sl->GetSlaveType() == TSlave::kMaster) {
4870 TMessage mess(kPROOF_PRINT);
4871 mess.WriteString(option);
4872 if (sl->GetSocket()->Send(mess) == -1)
4873 const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4874 else
4875 masters.Add(sl);
4876 } else {
4877 Error("Print", "TSlave is neither Master nor Worker");
4878 R__ASSERT(0);
4879 }
4880 }
4881 const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4882 }
4883 }
4884}
4885
4886////////////////////////////////////////////////////////////////////////////////
4887/// Extract from opt information about output handling settings.
4888/// The understood keywords are:
4889/// of=<file>, outfile=<file> output file location
4890/// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4891/// mutually exclusive,execution stops
4892/// if both are found)
4893/// sft[=<opt>], savetofile[=<opt>] control saving to file
4894///
4895/// For 'mvf', the <opt> integer has the following meaning:
4896/// <opt> = <how>*10 + <force>
4897/// <force> = 0 save to file if memory threshold is reached
4898/// (the memory threshold is set by the cluster
4899/// admin); in case an output file is defined, the
4900/// files are merged at the end;
4901/// 1 save results to file.
4902/// <how> = 0 save at the end of the query
4903/// 1 save results after each packet (to reduce the
4904/// loss in case of crash).
4905///
4906/// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4907/// to save results after each packet.
4908///
4909/// The separator from the next option is either a ' ' or a ';'
4910///
4911/// All recognized settings are removed from the input string opt.
4912/// If action == 0, set up the output file accordingly, if action == 1 clean related
4913/// output file settings.
4914/// If the final target file is local then 'target' is set to the final local path
4915/// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4916///
4917/// Output file settings are in the form
4918///
4919/// <previous_option>of=name <next_option>
4920/// <previous_option>outfile=name,...;<next_option>
4921///
4922/// The separator from the next option is either a ' ' or a ';'
4923/// Called interanally by TProof::Process.
4924///
4925/// Returns 0 on success, -1 on error.
4926
4928{
4929 TString outfile, dsname, stfopt;
4930 if (action == 0) {
4931 TString tagf, tagd, tags, oo;
4932 Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4933 while (opt.Tokenize(oo, from, "[; ]")) {
4934 if (oo.BeginsWith("of=")) {
4935 tagf = "of=";
4936 iof = opt.Index(tagf);
4937 } else if (oo.BeginsWith("outfile=")) {
4938 tagf = "outfile=";
4939 iof = opt.Index(tagf);
4940 } else if (oo.BeginsWith("ds")) {
4941 tagd = "ds";
4942 iod = opt.Index(tagd);
4943 } else if (oo.BeginsWith("dataset")) {
4944 tagd = "dataset";
4945 iod = opt.Index(tagd);
4946 } else if (oo.BeginsWith("stf")) {
4947 tags = "stf";
4948 ios = opt.Index(tags);
4949 } else if (oo.BeginsWith("savetofile")) {
4950 tags = "savetofile";
4951 ios = opt.Index(tags);
4952 }
4953 }
4954 // Check consistency
4955 if (iof != kNPOS && iod != kNPOS) {
4956 Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4957 return -1;
4958 }
4959
4960 // Check output file first
4961 if (iof != kNPOS) {
4962 from = iof + tagf.Length();
4963 if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4964 Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4965 return -1;
4966 }
4967 // For removal from original options string
4968 tagf += outfile;
4969 }
4970 // Check dataset
4971 if (iod != kNPOS) {
4972 from = iod + tagd.Length();
4973 if (!opt.Tokenize(dsname, from, "[; ]"))
4974 if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4975 // For removal from original options string
4976 tagd += dsname;
4977 // The name may be empty or beginning with a '='
4978 if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4979 if (dsname.Contains("|V")) {
4980 target = "ds|V";
4981 dsname.ReplaceAll("|V", "");
4982 }
4983 if (dsname.IsNull()) dsname = "dataset_<qtag>";
4984 }
4985 // Check stf
4986 if (ios != kNPOS) {
4987 from = ios + tags.Length();
4988 if (!opt.Tokenize(stfopt, from, "[; ]"))
4989 if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
4990 // For removal from original options string
4991 tags += stfopt;
4992 // It must be digit
4993 if (!stfopt.IsNull()) {
4994 if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
4995 if (!stfopt.IsNull()) {
4996 if (!stfopt.IsDigit()) {
4997 Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
4998 return -1;
4999 }
5000 } else {
5001 // Default
5002 stfopt = "1";
5003 }
5004 } else {
5005 // Default
5006 stfopt = "1";
5007 }
5008 }
5009 // Remove from original options string
5010 opt.ReplaceAll(tagf, "");
5011 opt.ReplaceAll(tagd, "");
5012 opt.ReplaceAll(tags, "");
5013 }
5014
5015 // Parse now
5016 if (action == 0) {
5017 // Output file
5018 if (!outfile.IsNull()) {
5019 if (!outfile.BeginsWith("master:")) {
5021 Warning("HandleOutputOptions",
5022 "directory '%s' for the output file does not exists or is not writable:"
5023 " saving to master", gSystem->GetDirName(outfile.Data()).Data());
5024 outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5025 } else {
5026 if (!IsLite()) {
5027 // The target file is local, so we need to retrieve it
5028 target = outfile;
5029 if (!stfopt.IsNull()) {
5030 outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5031 } else {
5032 outfile = "";
5033 }
5034 }
5035 }
5036 }
5037 if (outfile.BeginsWith("master:")) {
5038 outfile.ReplaceAll("master:", "");
5039 if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5040 // Get the master data dir
5041 TString ddir, emsg;
5042 if (!IsLite()) {
5043 if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5044 TObjString *os = fMacroLog.GetLineWith("const char");
5045 if (os) {
5046 Ssiz_t fst = os->GetString().First('\"');
5047 Ssiz_t lst = os->GetString().Last('\"');
5048 ddir = os->GetString()(fst+1, lst-fst-1);
5049 } else {
5050 emsg = "could not find 'const char *' string in macro log! cannot continue";
5051 }
5052 } else {
5053 emsg = "could not retrieve master data directory info! cannot continue";
5054 }
5055 if (!emsg.IsNull()) {
5056 Error("HandleOutputOptions", "%s", emsg.Data());
5057 return -1;
5058 }
5059 }
5060 if (!ddir.IsNull()) ddir += "/";
5061 if (outfile.IsNull()) {
5062 outfile.Form("%s<file>", ddir.Data());
5063 } else {
5064 outfile.Insert(0, TString::Format("%s", ddir.Data()));
5065 }
5066 }
5067 }
5068 // Set the parameter
5069 if (!outfile.IsNull()) {
5070 if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5071 SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5072 }
5073 }
5074 // Dataset creation
5075 if (!dsname.IsNull()) {
5076 dsname.Insert(0, "ds:");
5077 // Set the parameter
5078 SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5079 // Check the Save-To-File option
5080 if (!stfopt.IsNull()) {
5081 Int_t ostf = (Int_t) stfopt.Atoi();
5082 if (ostf%10 <= 0) {
5083 Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5084 stfopt.Form("%d", ostf+1);
5085 }
5086 } else {
5087 // Minimal setting
5088 stfopt = "1";
5089 }
5090 }
5091 // Save-To-File options
5092 if (!stfopt.IsNull()) {
5093 // Set the parameter
5094 SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5095 }
5096 } else {
5097 // Retrieve the file, if required
5098 if (GetOutputList()) {
5099 if (target == "ds|V") {
5100 // Find the dataset
5101 dsname = "";
5102 TIter nxo(GetOutputList());
5103 TObject *o = 0;
5104 while ((o = nxo())) {
5105 if (o->InheritsFrom(TFileCollection::Class())) {
5106 VerifyDataSet(o->GetName());
5107 dsname = o->GetName();
5108 break;
5109 }
5110 }
5111 if (!dsname.IsNull()) {
5112 TFileCollection *fc = GetDataSet(dsname);
5113 if (fc) {
5114 fc->Print();
5115 } else {
5116 Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5117 }
5118 } else {
5119 Warning("HandleOutputOptions", "dataset not found!");
5120 }
5121 } else {
5122 Bool_t targetcopied = kFALSE;
5123 TProofOutputFile *pf = 0;
5124 if (!target.IsNull())
5126 if (pf) {
5127 // Copy the file
5128 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5129 TUrl(target, kTRUE).GetUrl())) {
5130 if (TFile::Cp(pf->GetOutputFileName(), target)) {
5131 Printf(" Output successfully copied to %s", target.Data());
5132 targetcopied = kTRUE;
5133 } else {
5134 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5135 }
5136 }
5137 }
5138 TFile *fout = 0;
5139 TObject *o = 0;
5140 TIter nxo(GetOutputList());
5141 Bool_t swapcopied = kFALSE;
5142 while ((o = nxo())) {
5143 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5144 if (pof) {
5145 if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5146 if (pof == pf && targetcopied) continue;
5147 // Copy the file
5148 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5149 TUrl(target, kTRUE).GetUrl())) {
5150 if (TFile::Cp(pof->GetOutputFileName(), target)) {
5151 Printf(" Output successfully copied to %s", target.Data());
5152 swapcopied = kTRUE;
5153 } else {
5154 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5155 }
5156 }
5157 } else if (pof->IsRetrieve()) {
5158 // Retrieve this file to the local path indicated in the title
5159 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5160 TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5161 if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5162 Printf(" Output successfully copied to %s", pof->GetTitle());
5163 } else {
5164 Warning("HandleOutputOptions",
5165 "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5166 }
5167 }
5168 }
5169 }
5170 }
5171 if (!target.IsNull() && !swapcopied) {
5172 if (!fout && !pf) {
5173 fout = TFile::Open(target, "RECREATE");
5174 if (!fout || (fout && fout->IsZombie())) {
5175 SafeDelete(fout);
5176 Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5177 }
5178 }
5179 if (fout) {
5180 nxo.Reset();
5181 while ((o = nxo())) {
5182 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5183 if (!pof) {
5184 // Write the object to the open output file
5185 o->Write();
5186 }
5187 }
5188 }
5189 }
5190 // Clean-up
5191 if (fout) {
5192 fout->Close();
5193 SafeDelete(fout);
5194 Printf(" Output saved to %s", target.Data());
5195 }
5196 }
5197 }
5198 // Remove the parameter
5199 DeleteParameters("PROOF_DefaultOutputOption");
5200 // Remove the parameter
5201 DeleteParameters("PROOF_SavePartialResults");
5202 }
5203 // Done
5204 return 0;
5205}
5206
5207////////////////////////////////////////////////////////////////////////////////
5208/// Extract from opt in optfb information about wanted feedback settings.
5209/// Feedback are removed from the input string opt.
5210/// If action == 0, set up feedback accordingly, if action == 1 clean related
5211/// feedback settings (using info in optfb, if available, or reparsing opt).
5212///
5213/// Feedback requirements are in the form
5214///
5215/// <previous_option>fb=name1,name2,name3,... <next_option>
5216/// <previous_option>feedback=name1,name2,name3,...;<next_option>
5217///
5218/// The special name 'stats' triggers feedback about events and packets.
5219/// The separator from the next option is either a ' ' or a ';'.
5220/// Called interanally by TProof::Process.
5221
5222void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5223{
5224 Ssiz_t from = 0;
5225 if (action == 0 || (action == 1 && optfb.IsNull())) {
5226 TString tag("fb=");
5227 Ssiz_t ifb = opt.Index(tag);
5228 if (ifb == kNPOS) {
5229 tag = "feedback=";
5230 ifb = opt.Index(tag);
5231 }
5232 if (ifb == kNPOS) return;
5233 from = ifb + tag.Length();
5234
5235 if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5236 Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5237 return;
5238 }
5239 // Remove from original options string
5240 tag += optfb;
5241 opt.ReplaceAll(tag, "");
5242 }
5243
5244 // Parse now
5245 TString nm, startdraw, stopdraw;
5246 from = 0;
5247 while (optfb.Tokenize(nm, from, ",")) {
5248 // Special name first
5249 if (nm == "stats") {
5250 if (action == 0) {
5251 startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5252 gROOT->ProcessLine(startdraw.Data());
5253 SetParameter("PROOF_StatsHist", "");
5254 AddFeedback("PROOF_EventsHist");
5255 AddFeedback("PROOF_PacketsHist");
5256 AddFeedback("PROOF_ProcPcktHist");
5257 } else {
5258 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5259 " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5260 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5261 gROOT->ProcessLine(stopdraw.Data());
5262 DeleteParameters("PROOF_StatsHist");
5263 RemoveFeedback("PROOF_EventsHist");
5264 RemoveFeedback("PROOF_PacketsHist");
5265 RemoveFeedback("PROOF_ProcPcktHist");
5266 }
5267 } else {
5268 if (action == 0) {
5269 // Enable or
5270 AddFeedback(nm);
5271 startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5272 gROOT->ProcessLine(startdraw.Data());
5273 } else {
5274 // ... or disable
5275 RemoveFeedback(nm);
5276 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5277 " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5278 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5279 gROOT->ProcessLine(stopdraw.Data());
5280 }
5281 }
5282 }
5283}
5284
5285////////////////////////////////////////////////////////////////////////////////
5286/// Process a data set (TDSet) using the specified selector (.C) file or
5287/// Tselector object
5288/// Entry- or event-lists should be set in the data set object using
5289/// TDSet::SetEntryList.
5290/// The return value is -1 in case of error and TSelector::GetStatus() in
5291/// in case of success.
5292
5293Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5295{
5296 if (!IsValid() || !fPlayer) return -1;
5297
5298 // Set PROOF to running state
5300
5301 TString opt(option), optfb, outfile;
5302 // Enable feedback, if required
5303 if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5304 // Define output file, either from 'opt' or the default one
5305 if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5306
5307 // Resolve query mode
5308 fSync = (GetQueryMode(opt) == kSync);
5309
5310 if (fSync && (!IsIdle() || IsWaiting())) {
5311 // Already queued or processing queries: switch to asynchronous mode
5312 Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5313 fSync = kFALSE;
5314 opt.ReplaceAll("SYNC","");
5315 opt += "ASYN";
5316 }
5317
5318 // Cleanup old temporary datasets
5319 if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5322 }
5323
5324 // deactivate the default application interrupt handler
5325 // ctrl-c's will be forwarded to PROOF to stop the processing
5326 TSignalHandler *sh = 0;
5327 if (fSync) {
5328 if (gApplication)
5330 }
5331
5332 // Make sure we get a fresh result
5334
5335 // Make sure that the workers ready list is empty
5336 if (fWrksOutputReady) {
5339 }
5340
5341 // Make sure the selector path is in the macro path
5342 TProof::AssertMacroPath(selector);
5343
5344 // Reset time measurements
5345 fQuerySTW.Reset();
5346
5347 Long64_t rv = -1;
5348 if (selector && strlen(selector)) {
5349 rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5350 } else if (fSelector) {
5351 rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5352 } else {
5353 Error("Process", "neither a selecrot file nor a selector object have"
5354 " been specified: cannot process!");
5355 }
5356
5357 // This is the end of merging
5358 fQuerySTW.Stop();
5359 Float_t rt = fQuerySTW.RealTime();
5360 // Update the query content
5362 if (qr) {
5363 qr->SetTermTime(rt);
5365 }
5366
5367 // Disable feedback, if required
5368 if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5369 // Finalise output file settings (opt is ignored in here)
5370 if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5371
5372 // Retrieve status from the output list
5373 if (rv >= 0) {
5375 (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5376 if (sst) rv = sst->GetVal();
5377 }
5378
5379 if (fSync) {
5380 // reactivate the default application interrupt handler
5381 if (sh)
5383 // Save the performance info, if required
5384 if (!fPerfTree.IsNull()) {
5385 if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5386 // Must be re-enabled each time
5387 SetPerfTree(0);
5388 }
5389 }
5390
5391 return rv;
5392}
5393
5394////////////////////////////////////////////////////////////////////////////////
5395/// Process a data set (TFileCollection) using the specified selector (.C) file
5396/// or TSelector object.
5397/// The default tree is analyzed (i.e. the first one found). To specify another
5398/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5399/// The return value is -1 in case of error and TSelector::GetStatus() in
5400/// in case of success.
5401
5404{
5405 if (!IsValid() || !fPlayer) return -1;
5406
5407 if (fProtocol < 17) {
5408 Info("Process", "server version < 5.18/00:"
5409 " processing of TFileCollection not supported");
5410 return -1;
5411 }
5412
5413 // We include the TFileCollection to the input list and we create a
5414 // fake TDSet with infor about it
5415 TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5417
5418
5419 Long64_t retval = -1;
5420 if (selector && strlen(selector)) {
5421 retval = Process(dset, selector, option, nentries, first);
5422 } else if (fSelector) {
5423 retval = Process(dset, fSelector, option, nentries, first);
5424 } else {
5425 Error("Process", "neither a selecrot file nor a selector object have"
5426 " been specified: cannot process!");
5427 }
5428 fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5429
5430 // Cleanup
5431 if (IsLite() && !fSync) {
5432 if (!fRunningDSets) fRunningDSets = new TList;
5433 fRunningDSets->Add(dset);
5434 } else {
5435 delete dset;
5436 }
5437
5438 return retval;
5439}
5440
5441////////////////////////////////////////////////////////////////////////////////
5442/// Process a dataset which is stored on the master with name 'dsetname'.
5443/// The syntax for dsetname is name[#[dir/]objname], e.g.
5444/// "mydset" analysis of the first tree in the top dir of the dataset
5445/// named "mydset"
5446/// "mydset#T" analysis tree "T" in the top dir of the dataset
5447/// named "mydset"
5448/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5449/// named "mydset"
5450/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5451/// dataset named "mydset"
5452/// The component 'name' in its more general form contains also the group and
5453/// user name following "/<group>/<user>/<dsname>". Each of these components
5454/// can contain one or more wildcards '*', in which case all the datasets matching
5455/// the expression are added together as a global dataset (wildcard support has
5456/// been added in version 5.27/02).
5457/// The last argument 'elist' specifies an entry- or event-list to be used as
5458/// event selection.
5459/// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5460/// at once in a more flexible way that the one provided by wildcarding. There
5461/// are three possibilities:
5462/// 1) specifying the dataset names separated by the OR operator '|', e.g.
5463/// dsetname = "<dset1>|<dset2>|<dset3>|..."
5464/// in this case the datasets are a seen as a global unique dataset
5465/// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5466/// dsetname = "<dset1>,<dset2> <dset3>,..."
5467/// in this case the datasets are processed one after the other and the
5468/// selector is notified when switching dataset via a bit in the current
5469/// processed element.
5470/// 3) giving the path of a textfile where the dataset names are specified
5471/// on one or multiple lines; the lines found are joined as in 1), unless
5472/// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5473/// with the dataset names listed in 'datasets.txt') in which case they are
5474/// treated as in 2); the file is open in raw mode with TFile::Open and
5475/// therefore it cane be remote, e.g. on a Web server.
5476/// Each <dsetj> has the format specified above for the single dataset processing,
5477/// included wildcarding (the name of the tree and subdirectory must be same for
5478/// all the datasets).
5479/// In the case of multiple datasets, 'elist' is treated a global entry list.
5480/// It is possible to specify per-dataset entry lists using the syntax
5481/// "mydset[#adir/[T]]?enl=entrylist"
5482/// or
5483/// "mydset[#adir/[T]]<<entrylist"
5484/// Here 'entrylist' is a tag identifying, in the order :
5485/// i. a named entry-list in the input list or in the input data list
5486/// ii. a named entry-list in memory (in gDirectory)
5487/// iii. the path of a file containing the entry-list to be used
5488/// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5489/// data list.
5490/// The return value is -1 in case of error and TSelector::GetStatus() in
5491/// in case of success.
5492
5493Long64_t TProof::Process(const char *dsetname, const char *selector,
5494 Option_t *option, Long64_t nentries,
5495 Long64_t first, TObject *elist)
5496{
5497 if (fProtocol < 13) {
5498 Info("Process", "processing 'by name' not supported by the server");
5499 return -1;
5500 }
5501
5502 TString dsname, fname(dsetname);
5503 // If the 'dsetname' corresponds to an existing and readable file we will try to
5504 // interpretate its content as names of datasets to be processed. One line can contain
5505 // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5506 // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5507 // joined with ','.
5508 const char *separator = (fname.EndsWith(",")) ? "," : "|";
5509 if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5510 if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5511 TUrl uf(fname, kTRUE);
5512 uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5513 TFile *f = TFile::Open(uf.GetUrl());
5514 if (f && !(f->IsZombie())) {
5515 const Int_t blen = 8192;
5516 char buf[blen];
5517 Long64_t rest = f->GetSize();
5518 while (rest > 0) {
5519 Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5520 if (f->ReadBuffer(buf, len)) {
5521 Error("Process", "problems reading from file '%s'", fname.Data());
5522 dsname = "";
5523 break;
5524 }
5525 buf[len] = '\0';
5526 dsname += buf;
5527 rest -= len;
5528 }
5529 f->Close();
5530 SafeDelete(f);
5531 // We fail if a failure occured
5532 if (rest > 0) return -1;
5533 } else {
5534 Error("Process", "could not open file '%s'", fname.Data());
5535 return -1;
5536 }
5537 }
5538 if (dsname.IsNull()) {
5539 dsname = dsetname;
5540 } else {
5541 // Remove trailing '\n'
5542 if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5543 // Replace all '\n' with the proper separator
5544 dsname.ReplaceAll("\n", separator);
5545 if (gDebug > 0) {
5546 Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5547 Info("Process", " '%s'", dsname.Data());
5548 }
5549 }
5550
5551 TString names(dsname), name, enl, newname;
5552 // If multi-dataset check if server supports it
5553 if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5554 Info("Process", "multi-dataset processing not supported by the server");
5555 return -1;
5556 }
5557
5558 TEntryList *el = 0;
5559 TString dsobj, dsdir;
5560 Int_t from = 0;
5561 while (names.Tokenize(name, from, "[, |]")) {
5562
5563 newname = name;
5564 // Extract the specific entry-list, if any
5565 enl = "";
5566 Int_t ienl = name.Index("?enl=");
5567 if (ienl == kNPOS) {
5568 ienl = name.Index("<<");
5569 if (ienl != kNPOS) {
5570 newname.Remove(ienl);
5571 ienl += strlen("<<");
5572 }
5573 } else {
5574 newname.Remove(ienl);
5575 ienl += strlen("?enl=");
5576 }
5577
5578 // Check the name syntax first
5579 TString obj, dir("/");
5580 Int_t idxc = newname.Index("#");
5581 if (idxc != kNPOS) {
5582 Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5583 if (idxs != kNPOS) {
5584 obj = newname(idxs+1, newname.Length());
5585 dir = newname(idxc+1, newname.Length());
5586 dir.Remove(dir.Index("/") + 1);
5587 newname.Remove(idxc);
5588 } else {
5589 obj = newname(idxc+1, newname.Length());
5590 newname.Remove(idxc);
5591 }
5592 } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5593 // protection against using ':' instead of '#'
5594 Error("Process", "bad name syntax (%s): please use"
5595 " a '#' after the dataset name", name.Data());
5596 dsname.ReplaceAll(name, "");
5597 continue;
5598 }
5599 if (dsobj.IsNull() && dsdir.IsNull()) {
5600 // The first one specifies obj and dir
5601 dsobj = obj;
5602 dsdir = dir;
5603 } else if (obj != dsobj || dir != dsdir) {
5604 // Inconsistent specification: not supported
5605 Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5606 }
5607 // Process the entry-list name, if any
5608 if (ienl != kNPOS) {
5609 // Get entrylist name or path
5610 enl = name(ienl, name.Length());
5611 el = 0;
5612 TObject *oel = 0;
5613 // If not in the input list ...
5614 TList *inpl = GetInputList();
5615 if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5616 // ... check the heap
5617 if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5618 if ((el = dynamic_cast<TEntryList *>(oel))) {
5619 // Add to the input list (input data not available on master where
5620 // this info will be processed)
5621 if (fProtocol >= 28)
5622 if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5623 }
5624 }
5625 // If not in the heap, check a file, if any
5626 if (!el) {
5627 if (!gSystem->AccessPathName(enl)) {
5628 TFile *f = TFile::Open(enl);
5629 if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5630 TIter nxk(f->GetListOfKeys());
5631 TKey *k = 0;
5632 while ((k = (TKey *) nxk())) {
5633 if (!strcmp(k->GetClassName(), "TEntryList")) {
5634 if (!el) {
5635 if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5636 // Add to the input list (input data not available on master where
5637 // this info will be processed)
5638 if (fProtocol >= 28) {
5639 if (!(inpl->FindObject(el->GetName()))) {
5640 el = (TEntryList *) el->Clone();
5641 AddInput(el);
5642 }
5643 } else {
5644 el = (TEntryList *) el->Clone();
5645 }
5646 }
5647 } else if (strcmp(el->GetName(), k->GetName())) {
5648 Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5649 "if this is not what you want, load first the content in memory"
5650 "and select it by name ", enl.Data());
5651 }
5652 }
5653 }
5654 } else {
5655 Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5656 }
5657 }
5658 }
5659 // Transmit the information
5660 if (fProtocol >= 28) {
5661 newname += "?enl=";
5662 if (el) {
5663 // An entry list object is avalaible in the input list: add its name
5664 newname += el->GetName();
5665 } else {
5666 // The entry list object was not found: send the name, the future entry list manager will
5667 // find it on the server side
5668 newname += enl;
5669 }
5670 }
5671 }
5672 // Adjust the name for this dataset
5673 dsname.ReplaceAll(name, newname);
5674 }
5675
5676 // Create the dataset object
5677 TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5678 // Set entry list
5679 if (el && fProtocol < 28) {
5680 dset->SetEntryList(el);
5681 } else {
5682 dset->SetEntryList(elist);
5683 }
5684 // Run
5685 Long64_t retval = -1;
5686 if (selector && strlen(selector)) {
5687 retval = Process(dset, selector, option, nentries, first);
5688 } else if (fSelector) {
5689 retval = Process(dset, fSelector, option, nentries, first);
5690 } else {
5691 Error("Process", "neither a selector file nor a selector object have"
5692 " been specified: cannot process!");
5693 }
5694 // Cleanup
5695 if (IsLite() && !fSync) {
5696 if (!fRunningDSets) fRunningDSets = new TList;
5697 fRunningDSets->Add(dset);
5698 } else {
5699 delete dset;
5700 }
5701
5702 return retval;
5703}
5704
5705////////////////////////////////////////////////////////////////////////////////
5706/// Generic (non-data based) selector processing: the Process() method of the
5707/// specified selector (.C) or TSelector object is called 'n' times.
5708/// The return value is -1 in case of error and TSelector::GetStatus() in
5709/// in case of success.
5710
5711Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5712{
5713 if (!IsValid()) return -1;
5714
5715 if (fProtocol < 16) {
5716 Info("Process", "server version < 5.17/04: generic processing not supported");
5717 return -1;
5718 }
5719
5720 // Fake data set
5721 TDSet *dset = new TDSet;
5722 dset->SetBit(TDSet::kEmpty);
5723
5724 Long64_t retval = -1;
5725 if (selector && strlen(selector)) {
5726 retval = Process(dset, selector, option, n);
5727 } else if (fSelector) {
5728 retval = Process(dset, fSelector, option, n);
5729 } else {
5730 Error("Process", "neither a selector file nor a selector object have"
5731 " been specified: cannot process!");
5732 }
5733
5734 // Cleanup
5735 if (IsLite() && !fSync) {
5736 if (!fRunningDSets) fRunningDSets = new TList;
5737 fRunningDSets->Add(dset);
5738 } else {
5739 delete dset;
5740 }
5741 return retval;
5742}
5743
5744////////////////////////////////////////////////////////////////////////////////
5745/// Process a data set (TDSet) using the specified selector object.
5746/// Entry- or event-lists should be set in the data set object using
5747/// TDSet::SetEntryList.
5748/// The return value is -1 in case of error and TSelector::GetStatus() in
5749/// in case of success.
5750
5753{
5754 if (fProtocol < 34) {
5755 Error("Process", "server version < 5.33/02:"
5756 "processing by object not supported");
5757 return -1;
5758 }
5759 if (!selector) {
5760 Error("Process", "selector object undefined!");
5761 return -1;
5762 }
5763 fSelector = selector;
5764 Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5765 fSelector = 0;
5766 // Done
5767 return rc;
5768}
5769
5770////////////////////////////////////////////////////////////////////////////////
5771/// Process a data set (TFileCollection) using the specified selector object
5772/// The default tree is analyzed (i.e. the first one found). To specify another
5773/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5774/// The return value is -1 in case of error and TSelector::GetStatus() in
5775/// in case of success.
5776
5779{
5780 if (fProtocol < 34) {
5781 Error("Process", "server version < 5.33/02:"
5782 "processing by object not supported");
5783 return -1;
5784 }
5785 if (!selector) {
5786 Error("Process", "selector object undefined!");
5787 return -1;
5788 }
5789 fSelector = selector;
5790 Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5791 fSelector = 0;
5792 // Done
5793 return rc;
5794}
5795
5796////////////////////////////////////////////////////////////////////////////////
5797/// Process with name of dataset and TSelector object
5798
5799Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5800 Option_t *option, Long64_t nentries,
5801 Long64_t first, TObject *elist)
5802{
5803 if (fProtocol < 34) {
5804 Error("Process", "server version < 5.33/02:"
5805 "processing by object not supported");
5806 return -1;
5807 }
5808 if (!selector) {
5809 Error("Process", "selector object undefined!");
5810 return -1;
5811 }
5812 fSelector = selector;
5813 Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5814 fSelector = 0;
5815 // Done
5816 return rc;
5817}
5818
5819////////////////////////////////////////////////////////////////////////////////
5820/// Generic (non-data based) selector processing: the Process() method of the
5821/// specified selector is called 'n' times.
5822/// The return value is -1 in case of error and TSelector::GetStatus() in
5823/// in case of success.
5824
5826{
5827 if (fProtocol < 34) {
5828 Error("Process", "server version < 5.33/02:"
5829 "processing by object not supported");
5830 return -1;
5831 }
5832 if (!selector) {
5833 Error("Process", "selector object undefined!");
5834 return -1;
5835 }
5836 fSelector = selector;
5837 Long64_t rc = Process((const char*)0, n, option);
5838 fSelector = 0;
5839 // Done
5840 return rc;
5841}
5842
5843////////////////////////////////////////////////////////////////////////////////
5844/// Get reference for the qry-th query in fQueries (as
5845/// displayed by ShowQueries).
5846
5848{
5849 ref = "";
5850 if (qry > 0) {
5851 if (!fQueries)
5853 if (fQueries) {
5854 TIter nxq(fQueries);
5855 TQueryResult *qr = 0;
5856 while ((qr = (TQueryResult *) nxq()))
5857 if (qr->GetSeqNum() == qry) {
5858 ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5859 return 0;
5860 }
5861 }
5862 }
5863 return -1;
5864}
5865
5866////////////////////////////////////////////////////////////////////////////////
5867/// Finalize the qry-th query in fQueries.
5868/// If force, force retrieval if the query is found in the local list
5869/// but has already been finalized (default kFALSE).
5870/// If query < 0, finalize current query.
5871/// Return 0 on success, -1 on error
5872
5874{
5875 if (fPlayer) {
5876 if (qry > 0) {
5877 TString ref;
5878 if (GetQueryReference(qry, ref) == 0) {
5879 return Finalize(ref, force);
5880 } else {
5881 Info("Finalize", "query #%d not found", qry);
5882 }
5883 } else {
5884 // The last query
5885 return Finalize("", force);
5886 }
5887 }
5888 return -1;
5889}
5890
5891////////////////////////////////////////////////////////////////////////////////
5892/// Finalize query with reference ref.
5893/// If force, force retrieval if the query is found in the local list
5894/// but has already been finalized (default kFALSE).
5895/// If ref = 0, finalize current query.
5896/// Return 0 on success, -1 on error
5897
5898Long64_t TProof::Finalize(const char *ref, Bool_t force)
5899{
5900 if (fPlayer) {
5901 // Get the pointer to the query
5902 TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5903 : GetQueryResult();
5905 TString xref(ref);
5906 if (!qr) {
5907 if (!xref.IsNull()) {
5908 retrieve = kTRUE;
5909 }
5910 } else {
5911 if (qr->IsFinalized()) {
5912 if (force) {
5913 retrieve = kTRUE;
5914 } else {
5915 Info("Finalize","query already finalized:"
5916 " use Finalize(<qry>,kTRUE) to force new retrieval");
5917 qr = 0;
5918 }
5919 } else {
5920 retrieve = kTRUE;
5921 xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5922 }
5923 }
5924 if (retrieve) {
5925 Retrieve(xref.Data());
5926 qr = fPlayer->GetQueryResult(xref.Data());
5927 }
5928 if (qr)
5929 return fPlayer->Finalize(qr);
5930 }
5931 return -1;
5932}
5933
5934////////////////////////////////////////////////////////////////////////////////
5935/// Send retrieve request for the qry-th query in fQueries.
5936/// If path is defined save it to path.
5937
5938Int_t TProof::Retrieve(Int_t qry, const char *path)
5939{
5940 if (qry > 0) {
5941 TString ref;
5942 if (GetQueryReference(qry, ref) == 0)
5943 return Retrieve(ref, path);
5944 else
5945 Info("Retrieve", "query #%d not found", qry);
5946 } else {
5947 Info("Retrieve","positive argument required - do nothing");
5948 }
5949 return -1;
5950}
5951
5952////////////////////////////////////////////////////////////////////////////////
5953/// Send retrieve request for the query specified by ref.
5954/// If path is defined save it to path.
5955/// Generic method working for all queries known by the server.
5956
5957Int_t TProof::Retrieve(const char *ref, const char *path)
5958{
5959 if (ref) {
5961 m << TString(ref);
5964
5965 // Archive it locally, if required
5966 if (path) {
5967
5968 // Get pointer to query
5969 TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5970
5971 if (qr) {
5972
5973 TFile *farc = TFile::Open(path,"UPDATE");
5974 if (!farc || (farc && !(farc->IsOpen()))) {
5975 Info("Retrieve", "archive file cannot be open (%s)", path);
5976 return 0;
5977 }
5978 farc->cd();
5979
5980 // Update query status
5981 qr->SetArchived(path);
5982
5983 // Write to file
5984 qr->Write();
5985
5986 farc->Close();
5987 SafeDelete(farc);
5988
5989 } else {
5990 Info("Retrieve", "query not found after retrieve");
5991 return -1;
5992 }
5993 }
5994
5995 return 0;
5996 }
5997 return -1;
5998}
5999
6000////////////////////////////////////////////////////////////////////////////////
6001/// Send remove request for the qry-th query in fQueries.
6002
6004{
6005 if (qry > 0) {
6006 TString ref;
6007 if (GetQueryReference(qry, ref) == 0)
6008 return Remove(ref, all);
6009 else
6010 Info("Remove", "query #%d not found", qry);
6011 } else {
6012 Info("Remove","positive argument required - do nothing");
6013 }
6014 return -1;
6015}
6016
6017////////////////////////////////////////////////////////////////////////////////
6018/// Send remove request for the query specified by ref.
6019/// If all = TRUE remove also local copies of the query, if any.
6020/// Generic method working for all queries known by the server.
6021/// This method can be also used to reset the list of queries
6022/// waiting to be processed: for that purpose use ref == "cleanupqueue".
6023
6024Int_t TProof::Remove(const char *ref, Bool_t all)
6025{
6026 if (all) {
6027 // Remove also local copies, if any
6028 if (fPlayer)
6030 }
6031
6032 if (IsLite()) return 0;
6033
6034 if (ref) {
6036 m << TString(ref);
6039 return 0;
6040 }
6041 return -1;
6042}
6043
6044////////////////////////////////////////////////////////////////////////////////
6045/// Send archive request for the qry-th query in fQueries.
6046
6047Int_t TProof::Archive(Int_t qry, const char *path)
6048{
6049 if (qry > 0) {
6050 TString ref;
6051 if (GetQueryReference(qry, ref) == 0)
6052 return Archive(ref, path);
6053 else
6054 Info("Archive", "query #%d not found", qry);
6055 } else {
6056 Info("Archive","positive argument required - do nothing");
6057 }
6058 return -1;
6059}
6060
6061////////////////////////////////////////////////////////////////////////////////
6062/// Send archive request for the query specified by ref.
6063/// Generic method working for all queries known by the server.
6064/// If ref == "Default", path is understood as a default path for
6065/// archiving.
6066
6067Int_t TProof::Archive(const char *ref, const char *path)
6068{
6069 if (ref) {
6071 m << TString(ref) << TString(path);
6074 return 0;
6075 }
6076 return -1;
6077}
6078
6079////////////////////////////////////////////////////////////////////////////////
6080/// Send cleanup request for the session specified by tag.
6081
6082Int_t TProof::CleanupSession(const char *sessiontag)
6083{
6084 if (sessiontag) {
6086 m << TString(sessiontag);
6089 return 0;
6090 }
6091 return -1;
6092}
6093
6094////////////////////////////////////////////////////////////////////////////////
6095/// Change query running mode to the one specified by 'mode'.
6096
6098{
6099 fQueryMode = mode;
6100
6101 if (gDebug > 0)
6102 Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6103 "Sync" : "Async");
6104}
6105
6106////////////////////////////////////////////////////////////////////////////////
6107/// Find out the query mode based on the current setting and 'mode'.
6108
6110{
6111 EQueryMode qmode = fQueryMode;
6112
6113 if (mode && (strlen(mode) > 0)) {
6114 TString m(mode);
6115 m.ToUpper();
6116 if (m.Contains("ASYN")) {
6117 qmode = kAsync;
6118 } else if (m.Contains("SYNC")) {
6119 qmode = kSync;
6120 }
6121 }
6122
6123 if (gDebug > 0)
6124 Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6125 "Sync" : "Async");
6126
6127 return qmode;
6128}
6129
6130////////////////////////////////////////////////////////////////////////////////
6131/// Execute the specified drawing action on a data set (TDSet).
6132/// Event- or Entry-lists should be set in the data set object using
6133/// TDSet::SetEntryList.
6134/// Returns -1 in case of error or number of selected events otherwise.
6135
6136Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6137 const char *selection, Option_t *option,
6139{
6140 if (!IsValid() || !fPlayer) return -1;
6141
6142 // Make sure that asynchronous processing is not active
6143 if (!IsIdle()) {
6144 Info("DrawSelect","not idle, asynchronous Draw not supported");
6145 return -1;
6146 }
6147 TString opt(option);
6148 Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6149 if (idx != kNPOS)
6150 opt.Replace(idx,4,"");
6151
6152 return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6153}
6154
6155////////////////////////////////////////////////////////////////////////////////
6156/// Execute the specified drawing action on a data set which is stored on the
6157/// master with name 'dsetname'.
6158/// The syntax for dsetname is name[#[dir/]objname], e.g.
6159/// "mydset" analysis of the first tree in the top dir of the dataset
6160/// named "mydset"
6161/// "mydset#T" analysis tree "T" in the top dir of the dataset
6162/// named "mydset"
6163/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6164/// named "mydset"
6165/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6166/// dataset named "mydset"
6167/// The last argument 'enl' specifies an entry- or event-list to be used as
6168/// event selection.
6169/// The return value is -1 in case of error and TSelector::GetStatus() in
6170/// in case of success.
6171
6172Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6173 const char *selection, Option_t *option,
6175{
6176 if (fProtocol < 13) {
6177 Info("Process", "processing 'by name' not supported by the server");
6178 return -1;
6179 }
6180
6181 TString name(dsetname);
6182 TString obj;
6183 TString dir = "/";
6184 Int_t idxc = name.Index("#");
6185 if (idxc != kNPOS) {
6186 Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6187 if (idxs != kNPOS) {
6188 obj = name(idxs+1, name.Length());
6189 dir = name(idxc+1, name.Length());
6190 dir.Remove(dir.Index("/") + 1);
6191 name.Remove(idxc);
6192 } else {
6193 obj = name(idxc+1, name.Length());
6194 name.Remove(idxc);
6195 }
6196 } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6197 // protection against using ':' instead of '#'
6198 Error("DrawSelect", "bad name syntax (%s): please use"
6199 " a '#' after the dataset name", dsetname);
6200 return -1;
6201 }
6202
6203 TDSet *dset = new TDSet(name, obj, dir);
6204 // Set entry-list, if required
6205 dset->SetEntryList(enl);
6206 Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6207 delete dset;
6208 return retval;
6209}
6210
6211////////////////////////////////////////////////////////////////////////////////
6212/// Send STOPPROCESS message to master and workers.
6213
6215{
6216 PDB(kGlobal,2)
6217 Info("StopProcess","enter %d", abort);
6218
6219 if (!IsValid())
6220 return;
6221
6222 // Flag that we have been stopped
6224 SetRunStatus(rst);
6225
6226 if (fPlayer)
6227 fPlayer->StopProcess(abort, timeout);
6228
6229 // Stop any blocking 'Collect' request; on masters we do this only if
6230 // aborting; when stopping, we still need to receive the results
6231 if (TestBit(TProof::kIsClient) || abort)
6233
6234 if (fSlaves->GetSize() == 0)
6235 return;
6236
6237 // Notify the remote counterpart
6238 TSlave *sl;
6239 TIter next(fSlaves);
6240 while ((sl = (TSlave *)next()))
6241 if (sl->IsValid())
6242 // Ask slave to progate the stop/abort request
6243 sl->StopProcess(abort, timeout);
6244}
6245
6246////////////////////////////////////////////////////////////////////////////////
6247/// Signal to disable related switches
6248
6250{
6251 Emit("DisableGoAsyn()");
6252}
6253
6254////////////////////////////////////////////////////////////////////////////////
6255/// Send GOASYNC message to the master.
6256
6258{
6259 if (!IsValid()) return;
6260
6261 if (GetRemoteProtocol() < 22) {
6262 Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6263 return;
6264 }
6265
6266 if (fSync && !IsIdle()) {
6268 Broadcast(m);
6269 } else {
6270 Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6271 }
6272}
6273
6274////////////////////////////////////////////////////////////////////////////////
6275/// Receive the log file of the slave with socket s.
6276
6278{
6279 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6280 char buf[kMAXBUF];
6281
6282 // If macro saving is enabled prepare macro
6286 }
6287
6288 // Append messages to active logging unit
6289 Int_t fdout = -1;
6290 if (!fLogToWindowOnly) {
6291 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6292 if (fdout < 0) {
6293 Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6294 " will not log msgs", fdout);
6295 return;
6296 }
6297 lseek(fdout, (off_t) 0, SEEK_END);
6298 }
6299
6300 Int_t left, rec, r;
6301 Long_t filesize = 0;
6302
6303 while (filesize < size) {
6304 left = Int_t(size - filesize);
6305 if (left >= kMAXBUF)
6306 left = kMAXBUF-1;
6307 rec = s->RecvRaw(&buf, left);
6308 filesize = (rec > 0) ? (filesize + rec) : filesize;
6310 if (rec > 0) {
6311
6312 char *p = buf;
6313 r = rec;
6314 while (r) {
6315 Int_t w;
6316
6317 w = write(fdout, p, r);
6318
6319 if (w < 0) {
6320 SysError("RecvLogFile", "error writing to unit: %d", fdout);
6321 break;
6322 }
6323 r -= w;
6324 p += w;
6325 }
6326 } else if (rec < 0) {
6327 Error("RecvLogFile", "error during receiving log file");
6328 break;
6329 }
6330 }
6331 if (rec > 0) {
6332 buf[rec] = 0;
6333 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6334 // If macro saving is enabled add to TMacro
6336 }
6337 }
6338
6339 // If idle restore logs to main session window
6341 fRedirLog = kFALSE;
6342}
6343
6344////////////////////////////////////////////////////////////////////////////////
6345/// Notify locally 'msg' to the appropriate units (file, stdout, window)
6346/// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6347
6348void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6349{
6350 // Must have somenthing to notify
6351 Int_t len = 0;
6352 if (!msg || (len = strlen(msg)) <= 0)
6353 return;
6354
6355 // Get suffix length if any
6356 Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6357
6358 // Append messages to active logging unit
6359 Int_t fdout = -1;
6360 if (!fLogToWindowOnly) {
6361 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6362 if (fdout < 0) {
6363 Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6364 " will not notify msgs", fdout);
6365 return;
6366 }
6367 lseek(fdout, (off_t) 0, SEEK_END);
6368 }
6369
6370 if (!fLogToWindowOnly) {
6371 // Write to output unit (stdout or a log file)
6372 if (len > 0) {
6373 char *p = (char *)msg;
6374 Int_t r = len;
6375 while (r) {
6376 Int_t w = write(fdout, p, r);
6377 if (w < 0) {
6378 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6379 break;
6380 }
6381 r -= w;
6382 p += w;
6383 }
6384 // Add a suffix, if requested
6385 if (lsfx > 0)
6386 if (write(fdout, sfx, lsfx) != lsfx)
6387 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6388 }
6389 }
6390 if (len > 0) {
6391 // Publish the message to the separate window (if the latter is missing
6392 // the message will just get lost)
6393 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6394 }
6395
6396 // If idle restore logs to main session window
6397 if (fRedirLog && IsIdle())
6398 fRedirLog = kFALSE;
6399}
6400
6401////////////////////////////////////////////////////////////////////////////////
6402/// Log a message into the appropriate window by emitting a signal.
6403
6404void TProof::LogMessage(const char *msg, Bool_t all)
6405{
6406 PDB(kGlobal,1)
6407 Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6408 all ? "true" : "false");
6409
6410 if (gROOT->IsBatch()) {
6411 PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6412 return;
6413 }
6414
6415 if (msg)
6416 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6417
6418 // Re-position at the beginning of the file, if requested.
6419 // This is used by the dialog when it re-opens the log window to
6420 // provide all the session messages
6421 if (all)
6422 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6423
6424 const Int_t kMAXBUF = 32768;
6425 char buf[kMAXBUF];
6426 Int_t len;
6427 do {
6428 while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6429 TSystem::GetErrno() == EINTR)
6431
6432 if (len < 0) {
6433 Error("LogMessage", "error reading log file");
6434 break;
6435 }
6436
6437 if (len > 0) {
6438 buf[len] = 0;
6439 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6440 }
6441
6442 } while (len > 0);
6443}
6444
6445////////////////////////////////////////////////////////////////////////////////
6446/// Send to all active slaves servers the current slave group size
6447/// and their unique id. Returns number of active slaves.
6448/// Returns -1 in case of error.
6449
6451{
6452 if (!IsValid()) return -1;
6453 if (TestBit(TProof::kIsClient)) return 0;
6454 if (!fSendGroupView) return 0;
6456
6457 TIter next(fActiveSlaves);
6458 TSlave *sl;
6459
6460 int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6461 char str[32];
6462
6463 while ((sl = (TSlave *)next())) {
6464 snprintf(str, 32, "%d %d", cnt, size);
6465 if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6466 MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6467 bad++;
6468 } else
6469 cnt++;
6470 }
6471
6472 // Send the group view again in case there was a change in the
6473 // group size due to a bad slave
6474
6475 if (bad) SendGroupView();
6476
6477 return GetNumberOfActiveSlaves();
6478}
6479
6480////////////////////////////////////////////////////////////////////////////////
6481/// Static method to extract the filename (if any) form a CINT command.
6482/// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6483/// appliable.
6484
6486{
6487 TString s = cmd;
6488 s = s.Strip(TString::kBoth);
6489
6490 if (s.Length() > 0 &&
6491 (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6492 TString file = s(2, s.Length());
6493 TString acm, arg, io;
6494 fn = gSystem->SplitAclicMode(file, acm, arg, io);
6495 if (!fn.IsNull())
6496 return kTRUE;
6497 }
6498
6499 // Not found
6500 return kFALSE;
6501}
6502
6503////////////////////////////////////////////////////////////////////////////////
6504/// Send command to be executed on the PROOF master and/or slaves.
6505/// If plusMaster is kTRUE then exeucte on slaves and master too.
6506/// Command can be any legal command line command. Commands like
6507/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6508/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6509/// succes.
6510
6511Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6512{
6513 return Exec(cmd, kActive, plusMaster);
6514}
6515
6516////////////////////////////////////////////////////////////////////////////////
6517/// Send command to be executed on the PROOF master and/or slaves.
6518/// Command can be any legal command line command. Commands like
6519/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6520/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6521/// succes.
6522
6523Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6524{
6525 if (!IsValid()) return -1;
6526
6527 TString s = cmd;
6528 s = s.Strip(TString::kBoth);
6529
6530 if (!s.Length()) return 0;
6531
6532 // check for macro file and make sure the file is available on all slaves
6533 TString filename;
6534 if (TProof::GetFileInCmd(s.Data(), filename)) {
6535 char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6536 if (fn) {
6537 if (GetNumberOfUniqueSlaves() > 0) {
6538 if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6539 Error("Exec", "file %s could not be transfered", fn);
6540 delete [] fn;
6541 return -1;
6542 }
6543 } else {
6544 TString scmd = s(0,3) + fn;
6545 Int_t n = SendCommand(scmd, list);
6546 delete [] fn;
6547 return n;
6548 }
6549 } else {
6550 Error("Exec", "macro %s not found", filename.Data());
6551 return -1;
6552 }
6553 delete [] fn;
6554 }
6555
6556 if (plusMaster) {
6557 if (IsLite()) {
6558 gROOT->ProcessLine(cmd);
6559 } else {
6560 DeactivateWorker("*");
6561 Int_t res = SendCommand(cmd, list);
6562 ActivateWorker("restore");
6563 if (res < 0)
6564 return res;
6565 }
6566 }
6567 return SendCommand(cmd, list);
6568}
6569
6570////////////////////////////////////////////////////////////////////////////////
6571/// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6572/// Command can be any legal command line command. Commands like
6573/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6574/// to the PROOF cluster.
6575/// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6576/// TMacro, accessible via TMacro::GetMacroLog();
6577/// Returns -1 in case of error, >=0 in case of succes.
6578
6579Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6580{
6581 if (!IsValid()) return -1;
6582
6583 TString s = cmd;
6584 s = s.Strip(TString::kBoth);
6585
6586 if (!s.Length()) return 0;
6587
6588 Int_t res = 0;
6589 if (IsLite()) {
6590 gROOT->ProcessLine(cmd);
6591 } else {
6592 Bool_t oldRedirLog = fRedirLog;
6593 fRedirLog = kTRUE;
6594 // Deactivate all workers
6595 DeactivateWorker("*");
6596 fRedirLog = kFALSE;
6597 // Reactivate the target ones, if needed
6598 if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6599 // Honour log-to-macro-saving settings
6600 Bool_t oldSaveLog = fSaveLogToMacro;
6601 fSaveLogToMacro = logtomacro;
6602 res = SendCommand(cmd, kActive);
6603 fSaveLogToMacro = oldSaveLog;
6604 fRedirLog = kTRUE;
6605 ActivateWorker("restore");
6606 fRedirLog = oldRedirLog;
6607 }
6608 // Done
6609 return res;
6610}
6611
6612////////////////////////////////////////////////////////////////////////////////
6613/// Send command to be executed on the PROOF master and/or slaves.
6614/// Command can be any legal command line command, however commands
6615/// like ".x file.C" or ".L file.C" will not cause the file.C to be
6616/// transfered to the PROOF cluster. In that case use TProof::Exec().
6617/// Returns the status send by the remote server as part of the
6618/// kPROOF_LOGDONE message. Typically this is the return code of the
6619/// command on the remote side. Returns -1 in case of error.
6620
6621Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6622{
6623 if (!IsValid()) return -1;
6624
6625 Broadcast(cmd, kMESS_CINT, list);
6626 Collect(list);
6627
6628 return fStatus;
6629}
6630
6631////////////////////////////////////////////////////////////////////////////////
6632/// Get value of environment variable 'env' on node 'ord'
6633
6634TString TProof::Getenv(const char *env, const char *ord)
6635{
6636 // The command to be executed
6637 TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6638 if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6639 // Get the line
6640 TObjString *os = fMacroLog.GetLineWith("const char");
6641 if (os) {
6642 TString info;
6643 Ssiz_t from = 0;
6644 os->GetString().Tokenize(info, from, "\"");
6645 os->GetString().Tokenize(info, from, "\"");
6646 if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6647 return info;
6648 }
6649 return TString("");
6650}
6651
6652////////////////////////////////////////////////////////////////////////////////
6653/// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6654
6655Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6656{
6657 // The command to be executed
6658 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6659 // Exectute the command saving the logs to macro
6660 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6661 // Get the line
6662 TObjString *os = fMacroLog.GetLineWith("const char");
6663 Int_t rc = -1;
6664 if (os) {
6665 Ssiz_t fst = os->GetString().First('\"');
6666 Ssiz_t lst = os->GetString().Last('\"');
6667 TString info = os->GetString()(fst+1, lst-fst-1);
6668 if (info.IsDigit()) {
6669 env = info.Atoi();
6670 rc = 0;
6671 if (gDebug > 0)
6672 Printf("%s: %d", rcenv, env);
6673 }
6674 }
6675 return rc;
6676}
6677
6678////////////////////////////////////////////////////////////////////////////////
6679/// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6680
6681Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6682{
6683 // The command to be executed
6684 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6685 // Exectute the command saving the logs to macro
6686 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6687 // Get the line
6688 TObjString *os = fMacroLog.GetLineWith("const char");
6689 Int_t rc = -1;
6690 if (os) {
6691 Ssiz_t fst = os->GetString().First('\"');
6692 Ssiz_t lst = os->GetString().Last('\"');
6693 TString info = os->GetString()(fst+1, lst-fst-1);
6694 if (info.IsFloat()) {
6695 env = info.Atof();
6696 rc = 0;
6697 if (gDebug > 0)
6698 Printf("%s: %f", rcenv, env);
6699 }
6700 }
6701 return rc;
6702}
6703
6704////////////////////////////////////////////////////////////////////////////////
6705/// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6706
6707Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6708{
6709 // The command to be executed
6710 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6711 // Exectute the command saving the logs to macro
6712 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6713 // Get the line
6714 TObjString *os = fMacroLog.GetLineWith("const char");
6715 Int_t rc = -1;
6716 if (os) {
6717 Ssiz_t fst = os->GetString().First('\"');
6718 Ssiz_t lst = os->GetString().Last('\"');
6719 env = os->GetString()(fst+1, lst-fst-1);
6720 rc = 0;
6721 if (gDebug > 0)
6722 Printf("%s: %s", rcenv, env.Data());
6723 }
6724 return rc;
6725}
6726
6727////////////////////////////////////////////////////////////////////////////////
6728/// Transfer the current state of the master to the active slave servers.
6729/// The current state includes: the current working directory, etc.
6730/// Returns the number of active slaves. Returns -1 in case of error.
6731
6733{
6734 if (!IsValid()) return -1;
6735
6736 // Go to the new directory, reset the interpreter environment and
6737 // tell slave to delete all objects from its new current directory.
6738 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6739
6740 return GetParallel();
6741}
6742
6743////////////////////////////////////////////////////////////////////////////////
6744/// Transfer the current state of the master to the active slave servers.
6745/// The current state includes: the current working directory, etc.
6746/// Returns the number of active slaves. Returns -1 in case of error.
6747
6749{
6750 if (!IsValid()) return -1;
6751
6752 // Go to the new directory, reset the interpreter environment and
6753 // tell slave to delete all objects from its new current directory.
6754 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6755
6756 return GetParallel();
6757}
6758
6759////////////////////////////////////////////////////////////////////////////////
6760/// Transfer the initial (i.e. current) state of the master to all
6761/// slave servers. Currently the initial state includes: log level.
6762/// Returns the number of active slaves. Returns -1 in case of error.
6763
6765{
6766 if (!IsValid()) return -1;
6767
6769
6770 return GetNumberOfActiveSlaves();
6771}
6772
6773////////////////////////////////////////////////////////////////////////////////
6774/// Check if a file needs to be send to the slave. Use the following
6775/// algorithm:
6776/// - check if file appears in file map
6777/// - if yes, get file's modtime and check against time in map,
6778/// if modtime not same get md5 and compare against md5 in map,
6779/// if not same return kTRUE.
6780/// - if no, get file's md5 and modtime and store in file map, ask
6781/// slave if file exists with specific md5, if yes return kFALSE,
6782/// if no return kTRUE.
6783/// The options 'cpopt' define if to copy things from cache to sandbox and what.
6784/// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6785/// must be set in cpopt; the default is copy everything.
6786/// Returns kTRUE in case file needs to be send, returns kFALSE in case
6787/// file is already on remote node.
6788
6789Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6790{
6791 Bool_t sendto = kFALSE;
6792
6793 // create worker based filename
6794 TString sn = slave->GetName();
6795 sn += ":";
6796 sn += slave->GetOrdinal();
6797 sn += ":";
6798 sn += gSystem->BaseName(file);
6799
6800 // check if file is in map
6801 FileMap_t::const_iterator it;
6802 if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6803 // file in map
6804 MD5Mod_t md = (*it).second;
6805 if (md.fModtime != modtime) {
6807 if (md5) {
6808 if ((*md5) != md.fMD5) {
6809 sendto = kTRUE;
6810 md.fMD5 = *md5;
6811 md.fModtime = modtime;
6812 fFileMap[sn] = md;
6813 // When on the master, the master and/or slaves may share
6814 // their file systems and cache. Therefore always make a
6815 // check for the file. If the file already exists with the
6816 // expected md5 the kPROOF_CHECKFILE command will cause the
6817 // file to be copied from cache to slave sandbox.
6819 sendto = kFALSE;
6821 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6822 slave->GetSocket()->Send(mess);
6823
6824 fCheckFileStatus = 0;
6826 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6827 }
6828 }
6829 delete md5;
6830 } else {
6831 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6832 return kFALSE;
6833 }
6834 }
6835 } else {
6836 // file not in map
6838 MD5Mod_t md;
6839 if (md5) {
6840 md.fMD5 = *md5;
6841 md.fModtime = modtime;
6842 fFileMap[sn] = md;
6843 delete md5;
6844 } else {
6845 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6846 return kFALSE;
6847 }
6849 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6850 slave->GetSocket()->Send(mess);
6851
6852 fCheckFileStatus = 0;
6854 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6855 }
6856
6857 return sendto;
6858}
6859
6860////////////////////////////////////////////////////////////////////////////////
6861/// Send a file to master or slave servers. Returns number of slaves
6862/// the file was sent to, maybe 0 in case master and slaves have the same
6863/// file system image, -1 in case of error.
6864/// If defined, send to worker 'wrk' only.
6865/// If defined, the full path of the remote path will be rfile.
6866/// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6867/// (to copy to the cache on a different name use rfile = "cache:newname").
6868/// The mask 'opt' is an or of ESendFileOpt:
6869///
6870/// kAscii (0x0) if set true ascii file transfer is used
6871/// kBinary (0x1) if set true binary file transfer is used
6872/// kForce (0x2) if not set an attempt is done to find out
6873/// whether the file really needs to be downloaded
6874/// (a valid copy may already exist in the cache
6875/// from a previous run); the bit is set by
6876/// UploadPackage, since the check is done elsewhere.
6877/// kForward (0x4) if set, ask server to forward the file to slave
6878/// or submaster (meaningless for slave servers).
6879/// kCpBin (0x8) Retrieve from the cache the binaries associated
6880/// with the file
6881/// kCp (0x10) Retrieve the files from the cache
6882///
6883
6884Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6885{
6886 if (!IsValid()) return -1;
6887
6888 // Use the active slaves list ...
6889 TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6890 // ... or the specified slave, if any
6891 if (wrk) {
6892 slaves = new TList();
6893 slaves->Add(wrk);
6894 }
6895
6896 if (slaves->GetSize() == 0) return 0;
6897
6898#ifndef R__WIN32
6899 Int_t fd = open(file, O_RDONLY);
6900#else
6901 Int_t fd = open(file, O_RDONLY | O_BINARY);
6902#endif
6903 if (fd < 0) {
6904 SysError("SendFile", "cannot open file %s", file);
6905 return -1;
6906 }
6907
6908 // Get info about the file
6909 Long64_t size = -1;
6910 Long_t id, flags, modtime = 0;
6911 if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6912 Error("SendFile", "cannot stat file %s", file);
6913 close(fd);
6914 return -1;
6915 }
6916 if (size == 0) {
6917 Error("SendFile", "empty file %s", file);
6918 close(fd);
6919 return -1;
6920 }
6921
6922 // Decode options
6923 Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6924 Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6925 Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6926
6927 // Copy options
6928 Int_t cpopt = 0;
6929 if ((opt & kCp)) cpopt |= kCp;
6930 if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6931
6932 const Int_t kMAXBUF = 32768; //16384 //65536;
6933 char buf[kMAXBUF];
6934 Int_t nsl = 0;
6935
6936 TIter next(slaves);
6937 TSlave *sl;
6938 TString fnam(rfile);
6939 if (fnam == "cache") {
6940 fnam += TString::Format(":%s", gSystem->BaseName(file));
6941 } else if (fnam.IsNull()) {
6942 fnam = gSystem->BaseName(file);
6943 }
6944 // List on which we will collect the results
6945 fStatus = 0;
6946 while ((sl = (TSlave *)next())) {
6947 if (!sl->IsValid())
6948 continue;
6949
6950 Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6951 // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6952 // is false. Masters might still need to send the file to newly added
6953 // slaves.
6954 PDB(kPackage,2) {
6955 const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6956 Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6957 file, sl->GetName(), sl->GetOrdinal(), sendto);
6958 }
6959 if (sl->fSlaveType == TSlave::kSlave && !sendto)
6960 continue;
6961 // The value of 'size' is used as flag remotely, so we need to
6962 // reset it to 0 if we are not going to send the file
6963 Long64_t siz = sendto ? size : 0;
6964 snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6965 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6966 MarkBad(sl, "could not send kPROOF_SENDFILE request");
6967 continue;
6968 }
6969
6970 if (sendto) {
6971
6972 lseek(fd, 0, SEEK_SET);
6973
6974 Int_t len;
6975 do {
6976 while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6978
6979 if (len < 0) {
6980 SysError("SendFile", "error reading from file %s", file);
6982 close(fd);
6983 return -1;
6984 }
6985
6986 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6987 SysError("SendFile", "error writing to slave %s:%s (now offline)",
6988 sl->GetName(), sl->GetOrdinal());
6989 MarkBad(sl, "sendraw failure");
6990 sl = 0;
6991 break;
6992 }
6993
6994 } while (len > 0);
6995
6996 nsl++;
6997 }
6998 // Wait for the operation to be done
6999 if (sl)
7001 }
7002
7003 close(fd);
7004
7005 // Cleanup temporary list, if any
7006 if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
7007 SafeDelete(slaves);
7008
7009 // We return failure is at least one unique worker failed
7010 return (fStatus != 0) ? -1 : nsl;
7011}
7012
7013////////////////////////////////////////////////////////////////////////////////
7014/// Sends an object to master and workers and expect them to send back a
7015/// message with the output of its TObject::Print(). Returns -1 on error, the
7016/// number of workers that received the objects on success.
7017
7019{
7020 if (!IsValid() || !obj) return -1;
7021 TMessage mess(kPROOF_ECHO);
7022 mess.WriteObject(obj);
7023 return Broadcast(mess);
7024}
7025
7026////////////////////////////////////////////////////////////////////////////////
7027/// Sends a string to master and workers and expect them to echo it back to
7028/// the client via a message. It is a special case of the generic Echo()
7029/// that works with TObjects. Returns -1 on error, the number of workers that
7030/// received the message on success.
7031
7032Int_t TProof::Echo(const char *str)
7033{
7034 TObjString *os = new TObjString(str);
7035 Int_t rv = Echo(os);
7036 delete os;
7037 return rv;
7038}
7039
7040////////////////////////////////////////////////////////////////////////////////
7041/// Send object to master or slave servers. Returns number of slaves object
7042/// was sent to, -1 in case of error.
7043
7045{
7046 if (!IsValid() || !obj) return -1;
7047
7048 TMessage mess(kMESS_OBJECT);
7049
7050 mess.WriteObject(obj);
7051 return Broadcast(mess, list);
7052}
7053
7054////////////////////////////////////////////////////////////////////////////////
7055/// Send print command to master server. Returns number of slaves message
7056/// was sent to. Returns -1 in case of error.
7057
7059{
7060 if (!IsValid()) return -1;
7061
7062 Broadcast(option, kPROOF_PRINT, kActive);
7064}
7065
7066////////////////////////////////////////////////////////////////////////////////
7067/// Set server logging level.
7068
7070{
7071 char str[32];
7072 fLogLevel = level;
7073 gProofDebugLevel = level;
7075 snprintf(str, 32, "%d %u", level, mask);
7077}
7078
7079////////////////////////////////////////////////////////////////////////////////
7080/// Switch ON/OFF the real-time logging facility. When this option is
7081/// ON, log messages from processing are sent back as they come, instead of
7082/// being sent back at the end in one go. This may help debugging or monitoring
7083/// in some cases, but, depending on the amount of log, it may have significant
7084/// consequencies on the load over the network, so it must be used with care.
7085
7087{
7088 if (IsValid()) {
7090 mess << on;
7091 Broadcast(mess);
7092 } else {
7093 Warning("SetRealTimeLog","session is invalid - do nothing");
7094 }
7095}
7096
7097////////////////////////////////////////////////////////////////////////////////
7098/// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7099/// selection is done (if nodes is less than the available nodes).
7100/// Returns the number of parallel slaves. Returns -1 in case of error.
7101
7103{
7104 if (!IsValid()) return -1;
7105
7107 if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7108 return SendCurrentState();
7109 } else {
7110 if (nodes < 0) {
7111 PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7112 } else {
7113 PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7114 nodes == 1 ? "" : "s");
7115 }
7117 mess << nodes << random;
7118 Broadcast(mess);
7120 Int_t n = GetParallel();
7121 PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7122 return n;
7123 }
7124}
7125
7126////////////////////////////////////////////////////////////////////////////////
7127/// Tell PROOF how many slaves to use in parallel. Returns the number of
7128/// parallel slaves. Returns -1 in case of error.
7129
7131{
7132 // If delayed startup reset settings, if required
7133 if (fDynamicStartup && nodes < 0) {
7134 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7135 }
7136
7137 Int_t n = SetParallelSilent(nodes, random);
7139 if (n < 1) {
7140 Printf("PROOF set to sequential mode");
7141 } else {
7142 TString subfix = (n == 1) ? "" : "s";
7143 if (random)
7144 subfix += ", randomly selected";
7145 Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7146 }
7147 } else if (fDynamicStartup && nodes >= 0) {
7148 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7149 gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7150 }
7151 return n;
7152}
7153
7154////////////////////////////////////////////////////////////////////////////////
7155/// Add nWorkersToAdd workers to current list of workers. This function is
7156/// works on the master only, and only when an analysis is ongoing. A message
7157/// is sent back to the client when we go "more" parallel.
7158/// Returns -1 on error, number of total (not added!) workers on success.
7159
7161{
7162 if (!IsValid() || !IsMaster() || IsIdle()) {
7163 Error("GoMoreParallel", "can't invoke here -- should not happen!");
7164 return -1;
7165 }
7166 if (!gProofServ && !IsLite()) {
7167 Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7168 return -1;
7169 }
7170
7171 TSlave *sl = 0x0;
7172 TIter next( fSlaves );
7173 Int_t nAddedWorkers = 0;
7174
7175 while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7176 (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7177
7178 // If worker is of an invalid type, break everything: it should not happen!
7179 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7180 (sl->GetSlaveType() != TSlave::kMaster)) {
7181 Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7182 sl->GetName(), sl->GetOrdinal());
7183 R__ASSERT(0);
7184 }
7185
7186 // Skip current worker if it is not a good candidate
7187 if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7188 (strcmp("IGNORE", sl->GetImage()) == 0)) {
7189 PDB(kGlobal, 2)
7190 Info("GoMoreParallel", "Worker %s:%s won't be considered",
7191 sl->GetName(), sl->GetOrdinal());
7192 continue;
7193 }
7194
7195 // Worker is good but it is already active: skip it
7196 if (fActiveSlaves->FindObject(sl)) {
7197 Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7198 sl->GetName(), sl->GetOrdinal());
7199 continue;
7200 }
7201
7202 //
7203 // From here on: worker is a good candidate
7204 //
7205
7206 if (sl->GetSlaveType() == TSlave::kSlave) {
7208 fActiveSlaves->Add(sl);
7211 nAddedWorkers++;
7212 PDB(kGlobal, 2)
7213 Info("GoMoreParallel", "Worker %s:%s marked as active!",
7214 sl->GetName(), sl->GetOrdinal());
7215 }
7216 else {
7217 // Can't add masters dynamically: this should not happen!
7218 Error("GoMoreParallel", "Dynamic addition of master is not supported");
7219 R__ASSERT(0);
7220 }
7221
7222 } // end loop over all slaves
7223
7224 // Get slave status (will set the slaves fWorkDir correctly)
7225 PDB(kGlobal, 3)
7226 Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7227 AskStatistics();
7228
7229 // Find active slaves with unique image
7230 PDB(kGlobal, 3)
7231 Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7233
7234 // Send new group-view to slaves
7235 PDB(kGlobal, 3)
7236 Info("GoMoreParallel", "Will invoke SendGroupView()");
7237 SendGroupView();
7238
7239 PDB(kGlobal, 3)
7240 Info("GoMoreParallel", "Will invoke GetParallel()");
7241 Int_t nTotalWorkers = GetParallel();
7242
7243 // Notify the client that we've got more workers, and print info on
7244 // Master's log as well
7245 TString s;
7246 s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7247 nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7248 nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7250 Info("GoMoreParallel", "%s", s.Data());
7251
7252 return nTotalWorkers;
7253}
7254
7255////////////////////////////////////////////////////////////////////////////////
7256/// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7257/// list is sorted by slave performace the active list will contain first
7258/// the most performant nodes. Returns the number of active slaves.
7259/// If random is TRUE, and nodes is less than the number of available workers,
7260/// a random selection is done.
7261/// Returns -1 in case of error.
7262
7264{
7265 if (!IsValid()) return -1;
7266
7269
7270 // Prepare the list of candidates first.
7271 // Algorithm depends on random option.
7272 TSlave *sl = 0;
7273 TList *wlst = new TList;
7274 TIter nxt(fSlaves);
7276 while ((sl = (TSlave *)nxt())) {
7277 if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7278 if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7279 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7280 (sl->GetSlaveType() != TSlave::kMaster)) {
7281 Error("GoParallel", "TSlave is neither Master nor Slave");
7282 R__ASSERT(0);
7283 }
7284 // Good candidate
7285 wlst->Add(sl);
7286 // Set it inactive
7287 fInactiveSlaves->Add(sl);
7289 }
7290 }
7291 Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7292 int cnt = 0;
7294 while (cnt < nwrks) {
7295 // Random choice, if requested
7296 if (random) {
7297 Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7298 sl = (TSlave *) wlst->At(iwrk);
7299 } else {
7300 // The first available
7301 sl = (TSlave *) wlst->First();
7302 }
7303 if (!sl) {
7304 Error("GoParallel", "attaching to candidate!");
7305 break;
7306 }
7307 // Remove from the list
7308 wlst->Remove(sl);
7309
7310 Int_t slavenodes = 0;
7311 if (sl->GetSlaveType() == TSlave::kSlave) {
7313 fActiveSlaves->Add(sl);
7316 slavenodes = 1;
7317 } else if (sl->GetSlaveType() == TSlave::kMaster) {
7320 if (!attach) {
7321 Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7322 mess << nn;
7323 } else {
7324 // To get the number of slaves
7325 mess.SetWhat(kPROOF_LOGFILE);
7326 mess << -1 << -1;
7327 }
7328 if (sl->GetSocket()->Send(mess) == -1) {
7329 MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7330 slavenodes = 0;
7331 } else {
7333 if (sl->IsValid()) {
7335 fActiveSlaves->Add(sl);
7338 if (sl->GetParallel() > 0) {
7339 slavenodes = sl->GetParallel();
7340 } else {
7341 // Sequential mode: the master acts as a worker
7342 slavenodes = 1;
7343 }
7344 } else {
7345 MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7346 slavenodes = 0;
7347 }
7348 }
7349 }
7350 // 'slavenodes' may be different than 1 in multimaster setups
7351 cnt += slavenodes;
7352 }
7353
7354 // Cleanup list
7355 wlst->SetOwner(0);
7356 SafeDelete(wlst);
7357
7358 // Get slave status (will set the slaves fWorkDir correctly)
7359 AskStatistics();
7360
7361 // Find active slaves with unique image
7363
7364 // Send new group-view to slaves
7365 if (!attach)
7366 SendGroupView();
7367
7368 Int_t n = GetParallel();
7369
7371 if (n < 1)
7372 printf("PROOF set to sequential mode\n");
7373 else
7374 printf("PROOF set to parallel mode (%d worker%s)\n",
7375 n, n == 1 ? "" : "s");
7376 }
7377
7378 PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7379 return n;
7380}
7381
7382////////////////////////////////////////////////////////////////////////////////
7383/// List contents of the data directory in the sandbox.
7384/// This is the place where files produced by the client queries are kept
7385
7387{
7388 if (!IsValid() || !fManager) return;
7389
7390 // This is run via the manager
7391 fManager->Find("~/data", "-type f", "all");
7392}
7393
7394////////////////////////////////////////////////////////////////////////////////
7395/// Remove files for the data directory.
7396/// The option 'what' can take the values:
7397/// kPurge remove all files and directories under '~/data'
7398/// kUnregistered remove only files not in registered datasets (default)
7399/// kDataset remove files belonging to dataset 'dsname'
7400/// User is prompt for confirmation, unless kForceClear is ORed with the option
7401
7402void TProof::ClearData(UInt_t what, const char *dsname)
7403{
7404 if (!IsValid() || !fManager) return;
7405
7406 // Check whether we need to prompt
7407 TString prompt, a("Y");
7408 Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7409 Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7410
7411 // If all just send the request
7412 if ((what & TProof::kPurge)) {
7413 // Prompt, if requested
7414 if (doask && !Prompt("Do you really want to remove all data files")) return;
7415 if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7416 Warning("ClearData", "problems purging data directory");
7417 return;
7418 } else if ((what & TProof::kDataset)) {
7419 // We must have got a name
7420 if (!dsname || strlen(dsname) <= 0) {
7421 Error("ClearData", "dataset name mandatory when removing a full dataset");
7422 return;
7423 }
7424 // Check if the dataset is registered
7425 if (!ExistsDataSet(dsname)) {
7426 Error("ClearData", "dataset '%s' does not exists", dsname);
7427 return;
7428 }
7429 // Get the file content
7430 TFileCollection *fc = GetDataSet(dsname);
7431 if (!fc) {
7432 Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7433 return;
7434 }
7435 // Prompt, if requested
7436 TString pmpt = TString::Format("Do you really want to remove all data files"
7437 " of dataset '%s'", dsname);
7438 if (doask && !Prompt(pmpt.Data())) return;
7439
7440 // Loop through the files
7441 Bool_t rmds = kTRUE;
7442 TIter nxf(fc->GetList());
7443 TFileInfo *fi = 0;
7444 Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7445 while ((fi = (TFileInfo *) nxf())) {
7446 // Fill the host info
7447 TString host, file;
7448 // Take info from the current url
7449 if (!(fi->GetFirstUrl())) {
7450 Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7451 fi->GetName());
7452 continue;
7453 }
7454 TUrl uf(*(fi->GetFirstUrl()));
7455 file = uf.GetFile();
7456 host = uf.GetHost();
7457 // Now search for any "file:" url
7458 Int_t nurl = fi->GetNUrls();
7459 fi->ResetUrl();
7460 TUrl *up = 0;
7461 while (nurl-- && fi->NextUrl()) {
7462 up = fi->GetCurrentUrl();
7463 if (!strcmp(up->GetProtocol(), "file")) {
7464 TString opt(up->GetOptions());
7465 if (opt.BeginsWith("node=")) {
7466 host=opt;
7467 host.ReplaceAll("node=","");
7468 file = up->GetFile();
7469 break;
7470 }
7471 }
7472 }
7473 // Issue a remove request now
7474 if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7475 Error("ClearData", "problems removing '%s'", file.Data());
7476 // Some files not removed: keep the meta info about this dataset
7477 rmds = kFALSE;
7478 }
7479 rfiles++;
7480 ClearDataProgress(rfiles, nfiles);
7481 }
7482 fprintf(stderr, "\n");
7483 if (rmds) {
7484 // All files were removed successfully: remove also the dataset meta info
7485 RemoveDataSet(dsname);
7486 }
7487 } else if (what & TProof::kUnregistered) {
7488
7489 // Get the existing files
7490 TString outtmp("ProofClearData_");
7491 FILE *ftmp = gSystem->TempFileName(outtmp);
7492 if (!ftmp) {
7493 Error("ClearData", "cannot create temp file for logs");
7494 return;
7495 }
7496 fclose(ftmp);
7498 gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7499 ShowData();
7500 gSystem->RedirectOutput(0, 0, &h);
7501 // Parse the output file now
7502 std::ifstream in;
7503 in.open(outtmp.Data());
7504 if (!in.is_open()) {
7505 Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7506 gSystem->Unlink(outtmp);
7507 return;
7508 }
7509 // Go through
7510 Int_t nfiles = 0;
7511 TMap *afmap = new TMap;
7512 TString line, host, file;
7513 Int_t from = 0;
7514 while (in.good()) {
7515 line.ReadLine(in);
7516 if (line.IsNull()) continue;
7517 while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7518 from = 0;
7519 host = "";
7520 if (!line.Tokenize(host, from, "| ")) continue;
7521 file = "";
7522 if (!line.Tokenize(file, from, "| ")) continue;
7523 if (!host.IsNull() && !file.IsNull()) {
7524 TList *fl = (TList *) afmap->GetValue(host.Data());
7525 if (!fl) {
7526 fl = new TList();
7527 fl->SetName(host);
7528 afmap->Add(new TObjString(host), fl);
7529 }
7530 fl->Add(new TObjString(file));
7531 nfiles++;
7532 PDB(kDataset,2)
7533 Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7534 } else {
7535 Warning("ClearData", "found incomplete line: '%s'", line.Data());
7536 }
7537 }
7538 // Close and remove the file
7539 in.close();
7540 gSystem->Unlink(outtmp);
7541
7542 // Get registered data files
7543 TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7544 TMap *fcmap = GetDataSets(sel);
7545 if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7546 PDB(kDataset,1)
7547 Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7548 SafeDelete(fcmap);
7549 }
7550
7551 // Go thorugh and prepare the lists per node
7552 TString opt;
7553 TObjString *os = 0;
7554 if (fcmap) {
7555 TIter nxfc(fcmap);
7556 while ((os = (TObjString *) nxfc())) {
7557 TFileCollection *fc = 0;
7558 if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7559 TFileInfo *fi = 0;
7560 TIter nxfi(fc->GetList());
7561 while ((fi = (TFileInfo *) nxfi())) {
7562 // Get special "file:" url
7563 fi->ResetUrl();
7564 Int_t nurl = fi->GetNUrls();
7565 TUrl *up = 0;
7566 while (nurl-- && fi->NextUrl()) {
7567 up = fi->GetCurrentUrl();
7568 if (!strcmp(up->GetProtocol(), "file")) {
7569 opt = up->GetOptions();
7570 if (opt.BeginsWith("node=")) {
7571 host=opt;
7572 host.ReplaceAll("node=","");
7573 file = up->GetFile();
7574 PDB(kDataset,2)
7575 Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7576 // Remove this from the full list, if there
7577 TList *fl = (TList *) afmap->GetValue(host.Data());
7578 if (fl) {
7579 TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7580 if (fn) {
7581 fl->Remove(fn);
7582 SafeDelete(fn);
7583 nfiles--;
7584 } else {
7585 Warning("ClearData",
7586 "registered file '%s' not found in the full list!",
7587 file.Data());
7588 }
7589 }
7590 break;
7591 }
7592 }
7593 }
7594 }
7595 }
7596 }
7597 // Clean up the the received map
7598 if (fcmap) fcmap->SetOwner(kTRUE);
7599 SafeDelete(fcmap);
7600 }
7601 // List of the files to be removed
7602 Info("ClearData", "%d unregistered files to be removed:", nfiles);
7603 afmap->Print();
7604 // Prompt, if requested
7605 TString pmpt = TString::Format("Do you really want to remove all %d"
7606 " unregistered data files", nfiles);
7607 if (doask && !Prompt(pmpt.Data())) return;
7608
7609 // Remove one by one; we may implement a bloc remove in the future
7610 Int_t rfiles = 0;
7611 TIter nxls(afmap);
7612 while ((os = (TObjString *) nxls())) {
7613 TList *fl = 0;
7614 if ((fl = (TList *) afmap->GetValue(os))) {
7615 TIter nxf(fl);
7616 TObjString *fn = 0;
7617 while ((fn = (TObjString *) nxf())) {
7618 // Issue a remove request now
7619 if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7620 Error("ClearData", "problems removing '%s' on host '%s'",
7621 fn->GetName(), os->GetName());
7622 }
7623 rfiles++;
7624 ClearDataProgress(rfiles, nfiles);
7625 }
7626 }
7627 }
7628 fprintf(stderr, "\n");
7629 // Final cleanup
7630 afmap->SetOwner(kTRUE);
7631 SafeDelete(afmap);
7632 }
7633}
7634
7635////////////////////////////////////////////////////////////////////////////////
7636/// Prompt the question 'p' requiring an answer y,Y,n,N
7637/// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7638
7640{
7641 TString pp(p);
7642 if (!pp.Contains("?")) pp += "?";
7643 if (!pp.Contains("[y/N]")) pp += " [y/N]";
7644 TString a = Getline(pp.Data());
7645 if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7646 Printf("Please answer y, Y, n or N");
7647 // Unclear answer: assume negative
7648 return kFALSE;
7649 } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7650 // Explicitly Negative answer
7651 return kFALSE;
7652 }
7653 // Explicitly Positive answer
7654 return kTRUE;
7655}
7656
7657////////////////////////////////////////////////////////////////////////////////
7658/// Progress bar for clear data
7659
7661{
7662 fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7663 for (Int_t l = 0; l < 20; l++) {
7664 if (r > 0 && t > 0) {
7665 if (l < 20*r/t)
7666 fprintf(stderr, "=");
7667 else if (l == 20*r/t)
7668 fprintf(stderr, ">");
7669 else if (l > 20*r/t)
7670 fprintf(stderr, ".");
7671 } else
7672 fprintf(stderr, "=");
7673 }
7674 fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7675}
7676
7677////////////////////////////////////////////////////////////////////////////////
7678/// List contents of file cache. If all is true show all caches also on
7679/// slaves. If everything is ok all caches are to be the same.
7680
7682{
7683 if (!IsValid()) return;
7684
7685 TMessage mess(kPROOF_CACHE);
7686 mess << Int_t(kShowCache) << all;
7687 Broadcast(mess, kUnique);
7688
7689 if (all) {
7690 TMessage mess2(kPROOF_CACHE);
7691 mess2 << Int_t(kShowSubCache) << all;
7693
7695 } else {
7697 }
7698}
7699
7700////////////////////////////////////////////////////////////////////////////////
7701/// Remove file from all file caches. If file is 0 or "" or "*", remove all
7702/// the files
7703
7704void TProof::ClearCache(const char *file)
7705{
7706 if (!IsValid()) return;
7707
7708 TMessage mess(kPROOF_CACHE);
7709 mess << Int_t(kClearCache) << TString(file);
7710 Broadcast(mess, kUnique);
7711
7712 TMessage mess2(kPROOF_CACHE);
7713 mess2 << Int_t(kClearSubCache) << TString(file);
7715
7717
7718 // clear file map so files get send again to remote nodes
7719 fFileMap.clear();
7720}
7721
7722////////////////////////////////////////////////////////////////////////////////
7723/// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7724
7725void TProof::SystemCmd(const char *cmd, Int_t fdout)
7726{
7727 if (fdout < 0) {
7728 // Exec directly the command
7729 gSystem->Exec(cmd);
7730 } else {
7731 // Exec via a pipe
7732 FILE *fin = gSystem->OpenPipe(cmd, "r");
7733 if (fin) {
7734 // Now we go
7735 char line[2048];
7736 while (fgets(line, 2048, fin)) {
7737 Int_t r = strlen(line);
7738 if (r > 0) {
7739 if (write(fdout, line, r) < 0) {
7740 ::Warning("TProof::SystemCmd",
7741 "errno %d writing to file descriptor %d",
7742 TSystem::GetErrno(), fdout);
7743 }
7744 } else {
7745 // Done
7746 break;
7747 }
7748 }
7749 gSystem->ClosePipe(fin);
7750 }
7751 }
7752}
7753
7754////////////////////////////////////////////////////////////////////////////////
7755/// List contents of package directory. If all is true show all package
7756/// directories also on slaves. If everything is ok all package directories
7757/// should be the same. If redir is kTRUE the result is redirected to the log
7758/// file (option available for internal actions).
7759
7761{
7762 if (!IsValid()) return;
7763
7764 Bool_t oldredir = fRedirLog;
7765 if (redirlog) fRedirLog = kTRUE;
7766
7767 // Active logging unit
7768 FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7769 if (!fout) {
7770 Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7771 " will not log msgs", fout);
7772 return;
7773 }
7774 lseek(fileno(fout), (off_t) 0, SEEK_END);
7775
7777 fPackMgr->Show();
7778 }
7779
7780 // Nothing more to do if we are a Lite-session
7781 if (IsLite()) {
7782 fRedirLog = oldredir;
7783 return;
7784 }
7785
7786 TMessage mess(kPROOF_CACHE);
7787 mess << Int_t(kShowPackages) << all;
7788 Broadcast(mess, kUnique);
7789
7790 if (all) {
7791 TMessage mess2(kPROOF_CACHE);
7792 mess2 << Int_t(kShowSubPackages) << all;
7794
7796 } else {
7798 }
7799 // Restore logging option
7800 fRedirLog = oldredir;
7801}
7802
7803////////////////////////////////////////////////////////////////////////////////
7804/// List which packages are enabled. If all is true show enabled packages
7805/// for all active slaves. If everything is ok all active slaves should
7806/// have the same packages enabled.
7807
7809{
7810 if (!IsValid()) return;
7811
7813 fPackMgr->ShowEnabled(TString::Format("*** Enabled packages on client on %s\n",
7814 gSystem->HostName()));
7815 }
7816
7817 // Nothing more to do if we are a Lite-session
7818 if (IsLite()) return;
7819
7820 TMessage mess(kPROOF_CACHE);
7821 mess << Int_t(kShowEnabledPackages) << all;
7822 Broadcast(mess);
7824}
7825
7826////////////////////////////////////////////////////////////////////////////////
7827/// Remove all packages.
7828/// Returns 0 in case of success and -1 in case of error.
7829
7831{
7832 if (!IsValid()) return -1;
7833
7834 if (UnloadPackages() == -1)
7835 return -1;
7836
7837 if (DisablePackages() == -1)
7838 return -1;
7839
7840 return fStatus;
7841}
7842
7843////////////////////////////////////////////////////////////////////////////////
7844/// Remove a specific package.
7845/// Returns 0 in case of success and -1 in case of error.
7846
7847Int_t TProof::ClearPackage(const char *package)
7848{
7849 if (!IsValid()) return -1;
7850
7851 if (!package || !package[0]) {
7852 Error("ClearPackage", "need to specify a package name");
7853 return -1;
7854 }
7855
7856 // if name, erroneously, is a par pathname strip off .par and path
7857 TString pac = package;
7858 if (pac.EndsWith(".par"))
7859 pac.Remove(pac.Length()-4);
7860 pac = gSystem->BaseName(pac);
7861
7862 if (UnloadPackage(pac) == -1)
7863 return -1;
7864
7865 if (DisablePackage(pac) == -1)
7866 return -1;
7867
7868 return fStatus;
7869}
7870
7871////////////////////////////////////////////////////////////////////////////////
7872/// Remove a specific package.
7873/// Returns 0 in case of success and -1 in case of error.
7874
7876{
7877 if (!IsValid()) return -1;
7878
7879 if (!pack || strlen(pack) <= 0) {
7880 Error("DisablePackage", "need to specify a package name");
7881 return -1;
7882 }
7883
7884 // if name, erroneously, is a par pathname strip off .par and path
7885 TString pac = pack;
7886 if (pac.EndsWith(".par"))
7887 pac.Remove(pac.Length()-4);
7888 pac = gSystem->BaseName(pac);
7889
7890 if (fPackMgr->Remove(pack) < 0)
7891 Warning("DisablePackage", "problem removing locally package '%s'", pack);
7892
7893 // Nothing more to do if we are a Lite-session
7894 if (IsLite()) return 0;
7895
7896 Int_t st = -1;
7897 Bool_t done = kFALSE;
7898 if (fManager) {
7899 // Try to do it via XROOTD (new way)
7900 TString path;
7901 path.Form("~/packages/%s", pack);
7902 if (fManager->Rm(path, "-rf", "all") != -1) {
7903 path.Append(".par");
7904 if (fManager->Rm(path, "-f", "all") != -1) {
7905 done = kTRUE;
7906 st = 0;
7907 }
7908 }
7909 }
7910 if (!done) {
7911 // Try via TProofServ (old way)
7912 TMessage mess(kPROOF_CACHE);
7913 mess << Int_t(kDisablePackage) << pac;
7914 Broadcast(mess, kUnique);
7915
7916 TMessage mess2(kPROOF_CACHE);
7917 mess2 << Int_t(kDisableSubPackage) << pac;
7919
7921 st = fStatus;
7922 }
7923
7924 // Done
7925 return st;
7926}
7927
7928////////////////////////////////////////////////////////////////////////////////
7929/// Remove all packages.
7930/// Returns 0 in case of success and -1 in case of error.
7931
7933{
7934 if (!IsValid()) return -1;
7935
7936 // remove all packages on client
7937 if (fPackMgr->Remove(nullptr) < 0)
7938 Warning("DisablePackages", "problem removing packages locally");
7939
7940 // Nothing more to do if we are a Lite-session
7941 if (IsLite()) return 0;
7942
7943 Int_t st = -1;
7944 Bool_t done = kFALSE;
7945 if (fManager) {
7946 // Try to do it via XROOTD (new way)
7947 if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
7948 done = kTRUE;
7949 st = 0;
7950 }
7951 }
7952 if (!done) {
7953
7954 TMessage mess(kPROOF_CACHE);
7955 mess << Int_t(kDisablePackages);
7956 Broadcast(mess, kUnique);
7957
7958 TMessage mess2(kPROOF_CACHE);
7959 mess2 << Int_t(kDisableSubPackages);
7961
7963 st = fStatus;
7964 }
7965
7966 // Done
7967 return st;
7968}
7969
7970////////////////////////////////////////////////////////////////////////////////
7971/// Build specified package. Executes the PROOF-INF/BUILD.sh
7972/// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
7973/// then submit build command to slaves, but don't wait
7974/// for results. If opt is kCollectBuildResults then collect result
7975/// from slaves. To be used on the master.
7976/// If opt = kBuildAll (default) then submit and wait for results
7977/// (to be used on the client).
7978/// Returns 0 in case of success and -1 in case of error.
7979
7980Int_t TProof::BuildPackage(const char *package,
7981 EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
7982{
7983 if (!IsValid()) return -1;
7984
7985 if (!package || !package[0]) {
7986 Error("BuildPackage", "need to specify a package name");
7987 return -1;
7988 }
7989
7990 // if name, erroneously, is a par pathname strip off .par and path
7991 TString pac = package;
7992 if (pac.EndsWith(".par"))
7993 pac.Remove(pac.Length()-4);
7994 pac = gSystem->BaseName(pac);
7995
7996 Bool_t buildOnClient = kTRUE;
7997 if (opt == kDontBuildOnClient) {
7998 buildOnClient = kFALSE;
7999 opt = kBuildAll;
8000 }
8001 // Prepare the local package
8002 TString pdir;
8003 Int_t st = 0;
8004
8005 if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
8006 if (workers) {
8007 TMessage mess(kPROOF_CACHE);
8008 mess << Int_t(kBuildPackage) << pac << chkveropt;
8009 Broadcast(mess, workers);
8010
8011 } else {
8012 TMessage mess(kPROOF_CACHE);
8013 mess << Int_t(kBuildPackage) << pac << chkveropt;
8014 Broadcast(mess, kUnique);
8015
8016 TMessage mess2(kPROOF_CACHE);
8017 mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8019 }
8020 }
8021
8022 if (opt >= kBuildAll) {
8023 // by first forwarding the build commands to the master and slaves
8024 // and only then building locally we build in parallel
8025 if (buildOnClient) {
8026 st = fPackMgr->Build(pac, chkveropt);
8027 }
8028
8029
8030 fStatus = 0;
8031 if (!IsLite() || !buildOnClient) {
8032
8033 // On the master, workers that fail are deactivated
8034 // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8035 if (workers) {
8036// Collect(workers, -1, -1, deactivateOnFailure);
8037 Collect(workers);
8038 } else {
8040 }
8041 }
8042
8043 if (fStatus < 0 || st < 0)
8044 return -1;
8045 }
8046
8047 return 0;
8048}
8049
8050////////////////////////////////////////////////////////////////////////////////
8051/// Load specified package. Executes the PROOF-INF/SETUP.C script
8052/// on all active nodes. If notOnClient = true, don't load package
8053/// on the client. The default is to load the package also on the client.
8054/// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8055/// The objects in the list must be streamable; the SETUP macro will be executed
8056/// like this: SETUP.C(loadopts).
8057/// Returns 0 in case of success and -1 in case of error.
8058
8059Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8060 TList *loadopts, TList *workers)
8061{
8062 if (!IsValid()) return -1;
8063
8064 if (!package || !package[0]) {
8065 Error("LoadPackage", "need to specify a package name");
8066 return -1;
8067 }
8068
8069 // if name, erroneously, is a par pathname strip off .par and path
8070 TString pac = package;
8071 if (pac.EndsWith(".par"))
8072 pac.Remove(pac.Length()-4);
8073 pac = gSystem->BaseName(pac);
8074
8075 if (!notOnClient && TestBit(TProof::kIsClient))
8076 if (fPackMgr->Load(package, loadopts) == -1) return -1;
8077
8078 TMessage mess(kPROOF_CACHE);
8079 mess << Int_t(kLoadPackage) << pac;
8080 if (loadopts) mess << loadopts;
8081
8082 // On the master, workers that fail are deactivated
8083 Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8084
8085 Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8086
8087 if (workers) {
8088 PDB(kPackage, 3)
8089 Info("LoadPackage", "Sending load message to selected workers only");
8090 Broadcast(mess, workers);
8091 if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8092 } else {
8093 Broadcast(mess);
8094 Collect(kActive, -1, -1, deactivateOnFailure);
8095 }
8096
8097 return fStatus;
8098}
8099
8100////////////////////////////////////////////////////////////////////////////////
8101/// Unload specified package.
8102/// Returns 0 in case of success and -1 in case of error.
8103
8104Int_t TProof::UnloadPackage(const char *package)
8105{
8106 if (!IsValid()) return -1;
8107
8108 if (!package || !package[0]) {
8109 Error("UnloadPackage", "need to specify a package name");
8110 return -1;
8111 }
8112
8113 // if name, erroneously, is a par pathname strip off .par and path
8114 TString pac = package;
8115 if (pac.EndsWith(".par"))
8116 pac.Remove(pac.Length()-4);
8117 pac = gSystem->BaseName(pac);
8118
8119 if (fPackMgr->Unload(package) < 0)
8120 Warning("UnloadPackage", "unable to remove symlink to %s", package);
8121
8122 // Nothing more to do if we are a Lite-session
8123 if (IsLite()) return 0;
8124
8125 TMessage mess(kPROOF_CACHE);
8126 mess << Int_t(kUnloadPackage) << pac;
8127 Broadcast(mess);
8128 Collect();
8129
8130 return fStatus;
8131}
8132
8133////////////////////////////////////////////////////////////////////////////////
8134/// Unload all packages.
8135/// Returns 0 in case of success and -1 in case of error.
8136
8138{
8139 if (!IsValid()) return -1;
8140
8142 if (fPackMgr->Unload(0) < 0) return -1;
8143 }
8144
8145 // Nothing more to do if we are a Lite-session
8146 if (IsLite()) return 0;
8147
8148 TMessage mess(kPROOF_CACHE);
8149 mess << Int_t(kUnloadPackages);
8150 Broadcast(mess);
8151 Collect();
8152
8153 return fStatus;
8154}
8155
8156////////////////////////////////////////////////////////////////////////////////
8157/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8158/// script if it exists followed by the PROOF-INF/SETUP.C script.
8159/// In case notOnClient = true, don't enable the package on the client.
8160/// The default is to enable packages also on the client.
8161/// If specified, enables packages only on the specified workers.
8162/// Returns 0 in case of success and -1 in case of error.
8163/// Provided for backward compatibility.
8164
8165Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8166 TList *workers)
8167{
8168 return EnablePackage(package, (TList *)0, notOnClient, workers);
8169}
8170
8171////////////////////////////////////////////////////////////////////////////////
8172/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8173/// script if it exists followed by the PROOF-INF/SETUP.C script.
8174/// In case notOnClient = true, don't enable the package on the client.
8175/// The default is to enable packages also on the client.
8176/// It is is possible to specify options for the loading step via 'loadopts';
8177/// the string will be passed passed as argument to SETUP.
8178/// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8179/// plugin version checking during building: possible choices are:
8180/// off no check; failure may occur at loading
8181/// on check ROOT version [default]
8182/// svn check ROOT version and Git commit SHA1.
8183/// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8184/// If specified, enables packages only on the specified workers.
8185/// Returns 0 in case of success and -1 in case of error.
8186
8187Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8188 Bool_t notOnClient, TList *workers)
8189{
8190 TList *optls = 0;
8191 if (loadopts && strlen(loadopts)) {
8192 if (fProtocol > 28) {
8193 TObjString *os = new TObjString(loadopts);
8194 // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8195 os->String().ReplaceAll("checkversion=", "chkv=");
8196 Ssiz_t fcv = kNPOS, lcv = kNPOS;
8197 if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8198 TRegexp re("[; |]");
8199 if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8200 lcv = os->String().Length();
8201 }
8202 TString ocv = os->String()(fcv, lcv - fcv);
8203 Int_t cvopt = -1;
8204 if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8205 cvopt = (Int_t) TPackMgr::kDontCheck;
8206 else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8207 cvopt = (Int_t) TPackMgr::kCheckROOT;
8208 else
8209 Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8210 if (cvopt > -1) {
8211 if (gDebug > 0)
8212 Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8213 optls = new TList;
8214 optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8215 // Remove the special option from; we leave a separator if there were two (one before and one after)
8216 if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8217 if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8218 os->String().ReplaceAll(ocv.Data(), "");
8219 }
8220 }
8221 if (!os->String().IsNull()) {
8222 if (!optls) optls = new TList;
8223 optls->Add(new TObjString(os->String().Data()));
8224 }
8225 if (optls) optls->SetOwner(kTRUE);
8226 } else {
8227 // Notify
8228 Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8229 }
8230 }
8231 // Run
8232 Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8233 // Clean up
8234 SafeDelete(optls);
8235 // Done
8236 return rc;
8237}
8238
8239////////////////////////////////////////////////////////////////////////////////
8240/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8241/// script if it exists followed by the PROOF-INF/SETUP.C script.
8242/// In case notOnClient = true, don't enable the package on the client.
8243/// The default is to enable packages also on the client.
8244/// It is is possible to specify a list of objects to be passed to the SETUP
8245/// functions via 'loadopts'; the objects must be streamable.
8246/// Returns 0 in case of success and -1 in case of error.
8247
8248Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8249 Bool_t notOnClient, TList *workers)
8250{
8251 if (!IsValid()) return -1;
8252
8253 if (!package || !package[0]) {
8254 Error("EnablePackage", "need to specify a package name");
8255 return -1;
8256 }
8257
8258 // if name, erroneously, is a par pathname strip off .par and path
8259 TString pac = package;
8260 if (pac.EndsWith(".par"))
8261 pac.Remove(pac.Length()-4);
8262 pac = gSystem->BaseName(pac);
8263
8265 if (notOnClient)
8266 opt = kDontBuildOnClient;
8267
8268 // Get check version option; user settings have priority
8269 Int_t chkveropt = TPackMgr::kCheckROOT;
8270 TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8271 if (!ocv.IsNull()) {
8272 if (ocv == "off" || ocv == "0")
8273 chkveropt = (Int_t) TPackMgr::kDontCheck;
8274 else if (ocv == "on" || ocv == "1")
8275 chkveropt = (Int_t) TPackMgr::kCheckROOT;
8276 else
8277 Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8278 }
8279 if (loadopts) {
8280 TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8281 if (pcv) {
8282 chkveropt = pcv->GetVal();
8283 loadopts->Remove(pcv);
8284 delete pcv;
8285 }
8286 }
8287 if (gDebug > 0)
8288 Info("EnablePackage", "using check version option: %d", chkveropt);
8289
8290 if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8291 return -1;
8292
8293 TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8294 if (optls && fProtocol <= 28) {
8295 Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8296 optls = 0;
8297 }
8298
8299 if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8300 return -1;
8301
8302 // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8306 }
8308 TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8309 : new TPair(new TObjString(pac), 0);
8311 }
8312
8313 return 0;
8314}
8315
8316////////////////////////////////////////////////////////////////////////////////
8317/// Download a PROOF archive (PAR file) from the master package repository.
8318/// The PAR file is downloaded in the current directory or in the directory
8319/// specified by 'dstdir'. If a package with the same name already exists
8320/// at destination, a check on the MD5 sum is done and the user warned or
8321/// prompted for action, depending is the file is equal or different.
8322/// Returns 0 in case of success and -1 in case of error.
8323
8324Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8325{
8326 if (!fManager || !(fManager->IsValid())) {
8327 Error("DownloadPackage", "the manager is undefined!");
8328 return -1;
8329 }
8330
8331 // Create the default source and destination paths
8332 TString parname(gSystem->BaseName(pack)), src, dst;
8333 if (!parname.EndsWith(".par")) parname += ".par";
8334 src.Form("packages/%s", parname.Data());
8335 if (!dstdir || strlen(dstdir) <= 0) {
8336 dst.Form("./%s", parname.Data());
8337 } else {
8338 // Check the destination directory
8339 FileStat_t st;
8340 if (gSystem->GetPathInfo(dstdir, st) != 0) {
8341 // Directory does not exit: create it
8342 if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8343 Error("DownloadPackage",
8344 "could not create the destination directory '%s' (errno: %d)",
8345 dstdir, TSystem::GetErrno());
8346 return -1;
8347 }
8348 } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8349 Error("DownloadPackage",
8350 "destination path '%s' exist but is not a directory!", dstdir);
8351 return -1;
8352 }
8353 dst.Form("%s/%s", dstdir, parname.Data());
8354 }
8355
8356 // Make sure the source file exists
8357 FileStat_t stsrc;
8359 if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8360 Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8361 Int_t rc = fManager->Stat(src, stsrc);
8362 if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8363 Warning("DownloadPackage", "problems restoring output");
8364 if (rc != 0) {
8365 // Check if there is another possible source
8367 TMacro *mp = GetLastLog();
8368 if (mp) {
8369 // Look for global directories
8370 Bool_t isGlobal = kFALSE;
8371 TIter nxl(mp->GetListOfLines());
8372 TObjString *os = 0;
8373 TString globaldir;
8374 while ((os = (TObjString *) nxl())) {
8375 TString s(os->GetName());
8376 if (s.Contains("*** Global Package cache")) {
8377 // Get the directory
8378 s.Remove(0, s.Last(':') + 1);
8379 s.Remove(s.Last(' '));
8380 globaldir = s;
8381 isGlobal = kTRUE;
8382 } else if (s.Contains("*** Package cache")) {
8383 isGlobal = kFALSE;
8384 globaldir = "";
8385 }
8386 // Check for the package
8387 if (isGlobal && s.Contains(parname)) {
8388 src.Form("%s/%s", globaldir.Data(), parname.Data());
8389 break;
8390 }
8391 }
8392 // Cleanup
8393 delete mp;
8394 }
8395 }
8396
8397 // Do it via the manager
8398 if (fManager->GetFile(src, dst, "silent") != 0) {
8399 Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8400 pack, src.Data(), dst.Data());
8401 return -1;
8402 } else {
8403 Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8404 pack, dst.Data());
8405 }
8406 // Done
8407 return 0;
8408}
8409
8410////////////////////////////////////////////////////////////////////////////////
8411/// Upload a PROOF archive (PAR file). A PAR file is a compressed
8412/// tar file with one special additional directory, PROOF-INF
8413/// (blatantly copied from Java's jar format). It must have the extension
8414/// .par. A PAR file can be directly a binary or a source with a build
8415/// procedure. In the PROOF-INF directory there can be a build script:
8416/// BUILD.sh to be called to build the package, in case of a binary PAR
8417/// file don't specify a build script or make it a no-op. Then there is
8418/// SETUP.C which sets the right environment variables to use the package,
8419/// like LD_LIBRARY_PATH, etc.
8420/// The 'opt' allows to specify whether the .PAR should be just unpacked
8421/// in the existing dir (opt = kUntar, default) or a remove of the existing
8422/// directory should be executed (opt = kRemoveOld), so triggering a full
8423/// re-build. The option if effective only for PROOF protocol > 8 .
8424/// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8425/// an alternative global directory for global usage. This may require special
8426/// privileges.
8427/// If download is kTRUE and the package is not found locally, then it is downloaded
8428/// from the master repository.
8429/// Returns 0 in case of success and -1 in case of error.
8430
8432 TList *workers)
8433{
8434 if (!IsValid()) return -1;
8435
8436 // Remote PAR ?
8438 Bool_t remotepar = (ft == TFile::kWeb || ft == TFile::kNet) ? kTRUE : kFALSE;
8439
8440 TString par(pack), base, name;
8441 if (par.EndsWith(".par")) {
8442 base = gSystem->BaseName(par);
8443 name = base(0, base.Length() - strlen(".par"));
8444 } else {
8445 name = gSystem->BaseName(par);
8446 base.Form("%s.par", name.Data());
8447 par += ".par";
8448 }
8449
8450 // Default location is the local working dir; then the package dir
8451 gSystem->ExpandPathName(par);
8453 Int_t xrc = -1;
8454 if (!remotepar) xrc = TPackMgr::FindParPath(fPackMgr, name, par);
8455 if (xrc == 0) {
8456 // Package is in the global dirs
8457 if (gDebug > 0)
8458 Info("UploadPackage", "global package found (%s): no upload needed",
8459 par.Data());
8460 return 0;
8461 } else if (xrc < 0) {
8462 Error("UploadPackage", "PAR file '%s' not found", par.Data());
8463 return -1;
8464 }
8465 }
8466
8467 // Strategy:
8468 // On the client:
8469 // get md5 of package and check if it is different
8470 // from the one stored in the local package directory. If it is lock
8471 // the package directory and copy the package, unlock the directory.
8472 // On the masters:
8473 // get md5 of package and check if it is different from the
8474 // one stored on the remote node. If it is different lock the remote
8475 // package directory and use TFTP or SendFile to ftp the package to the
8476 // remote node, unlock the directory.
8477
8478
8480 Bool_t rmold = (opt == TProof::kRemoveOld) ? kTRUE : kFALSE;
8481 if (fPackMgr->Install(par, rmold) < 0) {
8482 Error("UploadPackage", "installing '%s' failed", gSystem->BaseName(par));
8483 return -1;
8484 }
8485 }
8486
8487 // Nothing more to do if we are a Lite-session
8488 if (IsLite()) return 0;
8489
8490 TMD5 *md5 = fPackMgr->ReadMD5(name);
8491
8492 TString smsg;
8493 if (remotepar && GetRemoteProtocol() > 36) {
8494 smsg.Form("+%s", par.Data());
8495 } else {
8496 smsg.Form("+%s", base.Data());
8497 }
8498
8500 mess << smsg << (*md5);
8502 smsg.Replace(0, 1, "-");
8503 mess2 << smsg << (*md5);
8505 smsg.Replace(0, 1, "=");
8506 mess3 << smsg << (*md5);
8507
8508 delete md5;
8509
8510 if (fProtocol > 8) {
8511 // Send also the option
8512 mess << (UInt_t) opt;
8513 mess2 << (UInt_t) opt;
8514 mess3 << (UInt_t) opt;
8515 }
8516
8517 // Loop over all slaves with unique fs image, or to a selected
8518 // list of workers, if specified
8519 if (!workers)
8520 workers = fUniqueSlaves;
8521 TIter next(workers);
8522 TSlave *sl = 0;
8523 while ((sl = (TSlave *) next())) {
8524 if (!sl->IsValid())
8525 continue;
8526
8527 sl->GetSocket()->Send(mess);
8528
8529 fCheckFileStatus = 0;
8531 if (fCheckFileStatus == 0) {
8532
8533 if (fProtocol > 5) {
8534 // remote directory is locked, upload file over the open channel
8535 smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
8536 if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
8537 Error("UploadPackage", "%s: problems uploading file %s",
8538 sl->GetOrdinal(), par.Data());
8539 return -1;
8540 }
8541 } else {
8542 // old servers receive it via TFTP
8543 TFTP ftp(TString("root://")+sl->GetName(), 1);
8544 if (!ftp.IsZombie()) {
8545 smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
8546 ftp.cd(smsg.Data());
8547 ftp.put(par, base.Data());
8548 }
8549 }
8550
8551 // install package and unlock dir
8552 sl->GetSocket()->Send(mess2);
8553 fCheckFileStatus = 0;
8555 if (fCheckFileStatus == 0) {
8556 Error("UploadPackage", "%s: unpacking of package %s failed",
8557 sl->GetOrdinal(), base.Data());
8558 return -1;
8559 }
8560 }
8561 }
8562
8563 // loop over all other master nodes
8564 TIter nextmaster(fNonUniqueMasters);
8565 TSlave *ma;
8566 while ((ma = (TSlave *) nextmaster())) {
8567 if (!ma->IsValid())
8568 continue;
8569
8570 ma->GetSocket()->Send(mess3);
8571
8572 fCheckFileStatus = 0;
8574 if (fCheckFileStatus == 0) {
8575 // error -> package should have been found
8576 Error("UploadPackage", "package %s did not exist on submaster %s",
8577 base.Data(), ma->GetOrdinal());
8578 return -1;
8579 }
8580 }
8581
8582 return 0;
8583}
8584
8585
8586////////////////////////////////////////////////////////////////////////////////
8587/// Make sure that the directory path contained by macro is in the macro path
8588
8589void TProof::AssertMacroPath(const char *macro)
8590{
8591 static TString macrop(gROOT->GetMacroPath());
8592 if (macro && strlen(macro) > 0) {
8593 TString dirn = gSystem->GetDirName(macro);
8594 if (!macrop.Contains(dirn)) {
8595 macrop += TString::Format("%s:", dirn.Data());
8596 gROOT->SetMacroPath(macrop);
8597 }
8598 }
8599}
8600
8601
8602////////////////////////////////////////////////////////////////////////////////
8603/// Load the specified macro on master, workers and, if notOnClient is
8604/// kFALSE, on the client. The macro file is uploaded if new or updated.
8605/// Additional files to be uploaded (or updated, if needed) can be specified
8606/// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
8607/// If existing in the same directory, a header basename(macro).h or .hh, is also
8608/// uploaded.
8609/// The default is to load the macro also on the client; notOnClient can be used
8610/// to avoid loading on the client.
8611/// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
8612/// only, and collection is not done; if uniqueWorkers is kFALSE, collection
8613/// from the previous request is done, and broadcasting + collection from the
8614/// other workers is done.
8615/// The wrks arg can be used on the master to limit the set of workers.
8616/// Returns 0 in case of success and -1 in case of error.
8617
8618Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
8619 TList *wrks)
8620{
8621 if (!IsValid()) return -1;
8622
8623 if (!macro || !macro[0]) {
8624 Error("Load", "need to specify a macro name");
8625 return -1;
8626 }
8627
8628 // Make sure the path is in the macro path
8630
8631 if (TestBit(TProof::kIsClient) && !wrks) {
8632
8633 // Extract the file implementation name first
8634 TString addsname, implname = macro;
8635 Ssiz_t icom = implname.Index(",");
8636 if (icom != kNPOS) {
8637 addsname = implname(icom + 1, implname.Length());
8638 implname.Remove(icom);
8639 }
8640 TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
8641 TString bmsg(basemacro), acmode, args, io;
8642 implname = gSystem->SplitAclicMode(implname, acmode, args, io);
8643
8644 // Macro names must have a standard format
8645 Int_t dot = implname.Last('.');
8646 if (dot == kNPOS) {
8647 Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
8648 return -1;
8649 }
8650
8651 // Is there any associated header file
8652 Bool_t hasHeader = kTRUE;
8653 TString headname = implname;
8654 headname.Remove(dot);
8655 headname += ".h";
8656 if (gSystem->AccessPathName(headname, kReadPermission)) {
8657 TString h = headname;
8658 headname.Remove(dot);
8659 headname += ".hh";
8660 if (gSystem->AccessPathName(headname, kReadPermission)) {
8661 hasHeader = kFALSE;
8662 if (gDebug > 0)
8663 Info("Load", "no associated header file found: tried: %s %s",
8664 h.Data(), headname.Data());
8665 }
8666 }
8667
8668 // Is there any additional file ?
8669 TString addincs;
8670 TList addfiles;
8671 if (!addsname.IsNull()) {
8672 TString fn;
8673 Int_t from = 0;
8674 while (addsname.Tokenize(fn, from, ",")) {
8676 Error("Load", "additional file '%s' not found", fn.Data());
8677 return -1;
8678 }
8679 // Create the additional include statement
8680 if (!notOnClient) {
8681 TString dirn = gSystem->GetDirName(fn);
8682 if (addincs.IsNull()) {
8683 addincs.Form("-I%s", dirn.Data());
8684 } else if (!addincs.Contains(dirn)) {
8685 addincs += TString::Format(" -I%s", dirn.Data());
8686 }
8687 }
8688 // Remember these files ...
8689 addfiles.Add(new TObjString(fn));
8690 }
8691 }
8692
8693 // Send files now; the md5 check is run here; see SendFile for more
8694 // details.
8695 if (SendFile(implname, kAscii | kForward , "cache") == -1) {
8696 Error("Load", "problems sending implementation file %s", implname.Data());
8697 return -1;
8698 }
8699 if (hasHeader)
8700 if (SendFile(headname, kAscii | kForward , "cache") == -1) {
8701 Error("Load", "problems sending header file %s", headname.Data());
8702 return -1;
8703 }
8704 // Additional files
8705 if (addfiles.GetSize() > 0) {
8706 TIter nxfn(&addfiles);
8707 TObjString *os = 0;
8708 while ((os = (TObjString *) nxfn())) {
8709 // These files need to be available everywhere, cache and sandbox
8710 if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
8711 Error("Load", "problems sending additional file %s", os->GetName());
8712 return -1;
8713 }
8714 // Add the base names to the message broadcasted
8715 bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
8716 }
8717 addfiles.SetOwner(kTRUE);
8718 }
8719
8720 // The files are now on the workers: now we send the loading request
8721 TMessage mess(kPROOF_CACHE);
8722 if (GetRemoteProtocol() < 34) {
8723 mess << Int_t(kLoadMacro) << basemacro;
8724 // This may be needed
8725 AddIncludePath("../../cache");
8726 } else {
8727 mess << Int_t(kLoadMacro) << bmsg;
8728 }
8729 Broadcast(mess, kActive);
8730
8731 // Load locally, if required
8732 if (!notOnClient) {
8733 // Mofify the include path
8734 TString oldincs = gSystem->GetIncludePath();
8735 if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
8736
8737 // By first forwarding the load command to the master and workers
8738 // and only then loading locally we load/build in parallel
8739 gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
8740
8741 // Restore include path
8742 if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
8743
8744 // Update the macro path
8746 TString np = gSystem->GetDirName(macro);
8747 if (!np.IsNull()) {
8748 np += ":";
8749 if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
8750 Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
8751 mp.Insert(ip, np);
8753 if (gDebug > 0)
8754 Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
8755 }
8756 }
8757 }
8758
8759 // Wait for master and workers to be done
8761
8762 if (IsLite()) {
8763 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8764 if (!fLoadedMacros) {
8765 fLoadedMacros = new TList();
8767 }
8768 // if wrks is specified the macro should already be loaded on the master.
8769 fLoadedMacros->Add(new TObjString(macro));
8770 }
8771
8772 } else {
8773 // On master
8774
8775 // The files are now on the workers: now we send the loading request first
8776 // to the unique workers, so that the eventual compilation occurs only once.
8777 TString basemacro = gSystem->BaseName(macro);
8778 TMessage mess(kPROOF_CACHE);
8779
8780 if (uniqueWorkers) {
8781 mess << Int_t(kLoadMacro) << basemacro;
8782 if (wrks) {
8783 Broadcast(mess, wrks);
8784 Collect(wrks);
8785 } else {
8786 Broadcast(mess, kUnique);
8787 }
8788 } else {
8789 // Wait for the result of the previous sending
8791
8792 // We then send a tuned loading request to the other workers
8793 TList others;
8794 TSlave *wrk = 0;
8795 TIter nxw(fActiveSlaves);
8796 while ((wrk = (TSlave *)nxw())) {
8797 if (!fUniqueSlaves->FindObject(wrk)) {
8798 others.Add(wrk);
8799 }
8800 }
8801
8802 // Do not force compilation, if it was requested
8803 Int_t ld = basemacro.Last('.');
8804 if (ld != kNPOS) {
8805 Int_t lpp = basemacro.Index("++", ld);
8806 if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
8807 }
8808 mess << Int_t(kLoadMacro) << basemacro;
8809 Broadcast(mess, &others);
8810 Collect(&others);
8811 }
8812
8813 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8814 if (!fLoadedMacros) {
8815 fLoadedMacros = new TList();
8817 }
8818 // if wrks is specified the macro should already be loaded on the master.
8819 if (!wrks)
8820 fLoadedMacros->Add(new TObjString(macro));
8821 }
8822
8823 // Done
8824 return 0;
8825}
8826
8827////////////////////////////////////////////////////////////////////////////////
8828/// Add 'libpath' to the lib path search.
8829/// Multiple paths can be specified at once separating them with a comma or
8830/// a blank.
8831/// Return 0 on success, -1 otherwise
8832
8833Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
8834 Bool_t doCollect)
8835{
8836 if ((!libpath || !libpath[0])) {
8837 if (gDebug > 0)
8838 Info("AddDynamicPath", "list is empty - nothing to do");
8839 return 0;
8840 }
8841
8842 // Do it also on clients, if required
8843 if (onClient)
8844 HandleLibIncPath("lib", kTRUE, libpath);
8845
8847 m << TString("lib") << (Bool_t)kTRUE;
8848
8849 // Add paths
8850 if (libpath && strlen(libpath)) {
8851 m << TString(libpath);
8852 } else {
8853 m << TString("-");
8854 }
8855
8856 // Tell the server to send back or not
8857 m << (Int_t)doCollect;
8858
8859 // Forward the request
8860 if (wrks) {
8861 Broadcast(m, wrks);
8862 if (doCollect)
8863 Collect(wrks, fCollectTimeout);
8864 } else {
8865 Broadcast(m);
8867 }
8868
8869 return 0;
8870}
8871
8872////////////////////////////////////////////////////////////////////////////////
8873/// Add 'incpath' to the inc path search.
8874/// Multiple paths can be specified at once separating them with a comma or
8875/// a blank.
8876/// Return 0 on success, -1 otherwise
8877
8878Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
8879 Bool_t doCollect)
8880{
8881 if ((!incpath || !incpath[0])) {
8882 if (gDebug > 0)
8883 Info("AddIncludePath", "list is empty - nothing to do");
8884 return 0;
8885 }
8886
8887 // Do it also on clients, if required
8888 if (onClient)
8889 HandleLibIncPath("inc", kTRUE, incpath);
8890
8892 m << TString("inc") << (Bool_t)kTRUE;
8893
8894 // Add paths
8895 if (incpath && strlen(incpath)) {
8896 m << TString(incpath);
8897 } else {
8898 m << TString("-");
8899 }
8900
8901 // Tell the server to send back or not
8902 m << (Int_t)doCollect;
8903
8904 // Forward the request
8905 if (wrks) {
8906 Broadcast(m, wrks);
8907 if (doCollect)
8908 Collect(wrks, fCollectTimeout);
8909 } else {
8910 Broadcast(m);
8912 }
8913
8914 return 0;
8915}
8916
8917////////////////////////////////////////////////////////////////////////////////
8918/// Remove 'libpath' from the lib path search.
8919/// Multiple paths can be specified at once separating them with a comma or
8920/// a blank.
8921/// Return 0 on success, -1 otherwise
8922
8923Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
8924{
8925 if ((!libpath || !libpath[0])) {
8926 if (gDebug > 0)
8927 Info("RemoveDynamicPath", "list is empty - nothing to do");
8928 return 0;
8929 }
8930
8931 // Do it also on clients, if required
8932 if (onClient)
8933 HandleLibIncPath("lib", kFALSE, libpath);
8934
8936 m << TString("lib") <<(Bool_t)kFALSE;
8937
8938 // Add paths
8939 if (libpath && strlen(libpath))
8940 m << TString(libpath);
8941 else
8942 m << TString("-");
8943
8944 // Forward the request
8945 Broadcast(m);
8947
8948 return 0;
8949}
8950
8951////////////////////////////////////////////////////////////////////////////////
8952/// Remove 'incpath' from the inc path search.
8953/// Multiple paths can be specified at once separating them with a comma or
8954/// a blank.
8955/// Return 0 on success, -1 otherwise
8956
8957Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
8958{
8959 if ((!incpath || !incpath[0])) {
8960 if (gDebug > 0)
8961 Info("RemoveIncludePath", "list is empty - nothing to do");
8962 return 0;
8963 }
8964
8965 // Do it also on clients, if required
8966 if (onClient)
8967 HandleLibIncPath("in", kFALSE, incpath);
8968
8970 m << TString("inc") << (Bool_t)kFALSE;
8971
8972 // Add paths
8973 if (incpath && strlen(incpath))
8974 m << TString(incpath);
8975 else
8976 m << TString("-");
8977
8978 // Forward the request
8979 Broadcast(m);
8981
8982 return 0;
8983}
8984
8985////////////////////////////////////////////////////////////////////////////////
8986/// Handle lib, inc search paths modification request
8987
8988void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
8989{
8990 TString type(what);
8991 TString path(dirs);
8992
8993 // Check type of action
8994 if ((type != "lib") && (type != "inc")) {
8995 Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
8996 return;
8997 }
8998
8999 // Separators can be either commas or blanks
9000 path.ReplaceAll(","," ");
9001
9002 // Decompose lists
9003 TObjArray *op = 0;
9004 if (path.Length() > 0 && path != "-") {
9005 if (!(op = path.Tokenize(" "))) {
9006 Warning("HandleLibIncPath","decomposing path %s", path.Data());
9007 return;
9008 }
9009 }
9010
9011 if (add) {
9012
9013 if (type == "lib") {
9014
9015 // Add libs
9016 TIter nxl(op, kIterBackward);
9017 TObjString *lib = 0;
9018 while ((lib = (TObjString *) nxl())) {
9019 // Expand path
9020 TString xlib = lib->GetName();
9021 gSystem->ExpandPathName(xlib);
9022 // Add to the dynamic lib search path if it exists and can be read
9023 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9024 TString newlibpath = gSystem->GetDynamicPath();
9025 // In the first position after the working dir
9026 Int_t pos = 0;
9027 if (newlibpath.BeginsWith(".:"))
9028 pos = 2;
9029 if (newlibpath.Index(xlib) == kNPOS) {
9030 newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9031 gSystem->SetDynamicPath(newlibpath);
9032 }
9033 } else {
9034 if (gDebug > 0)
9035 Info("HandleLibIncPath",
9036 "libpath %s does not exist or cannot be read - not added", xlib.Data());
9037 }
9038 }
9039
9040 } else {
9041
9042 // Add incs
9043 TIter nxi(op);
9044 TObjString *inc = 0;
9045 while ((inc = (TObjString *) nxi())) {
9046 // Expand path
9047 TString xinc = inc->GetName();
9048 gSystem->ExpandPathName(xinc);
9049 // Add to the dynamic lib search path if it exists and can be read
9050 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9051 TString curincpath = gSystem->GetIncludePath();
9052 if (curincpath.Index(xinc) == kNPOS)
9053 gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9054 } else
9055 if (gDebug > 0)
9056 Info("HandleLibIncPath",
9057 "incpath %s does not exist or cannot be read - not added", xinc.Data());
9058 }
9059 }
9060
9061
9062 } else {
9063
9064 if (type == "lib") {
9065
9066 // Remove libs
9067 TIter nxl(op);
9068 TObjString *lib = 0;
9069 while ((lib = (TObjString *) nxl())) {
9070 // Expand path
9071 TString xlib = lib->GetName();
9072 gSystem->ExpandPathName(xlib);
9073 // Remove from the dynamic lib search path
9074 TString newlibpath = gSystem->GetDynamicPath();
9075 newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9076 gSystem->SetDynamicPath(newlibpath);
9077 }
9078
9079 } else {
9080
9081 // Remove incs
9082 TIter nxi(op);
9083 TObjString *inc = 0;
9084 while ((inc = (TObjString *) nxi())) {
9085 TString newincpath = gSystem->GetIncludePath();
9086 newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9087 // Remove the interpreter path (added anyhow internally)
9088 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9089 gSystem->SetIncludePath(newincpath);
9090 }
9091 }
9092 }
9093}
9094
9095////////////////////////////////////////////////////////////////////////////////
9096/// Get from the master the list of names of the packages available.
9097
9099{
9100 if (!IsValid())
9101 return (TList *)0;
9102
9103 TMessage mess(kPROOF_CACHE);
9104 mess << Int_t(kListPackages);
9105 Broadcast(mess);
9107
9108 return fAvailablePackages;
9109}
9110
9111////////////////////////////////////////////////////////////////////////////////
9112/// Get from the master the list of names of the packages enabled.
9113
9115{
9116 if (!IsValid())
9117 return (TList *)0;
9118
9119 TMessage mess(kPROOF_CACHE);
9120 mess << Int_t(kListEnabledPackages);
9121 Broadcast(mess);
9123
9124 return fEnabledPackages;
9125}
9126
9127////////////////////////////////////////////////////////////////////////////////
9128/// Print a progress bar on stderr. Used in batch mode.
9129
9131 Float_t procTime, Long64_t bytesread)
9132{
9133 if (fPrintProgress) {
9134 Bool_t redirlog = fRedirLog;
9135 fRedirLog = kFALSE;
9136 // Call the external function
9137 (*fPrintProgress)(total, processed, procTime, bytesread);
9138 fRedirLog = redirlog;
9139 return;
9140 }
9141
9142 fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9143
9144 for (int l = 0; l < 20; l++) {
9145 if (total > 0) {
9146 if (l < 20*processed/total)
9147 fprintf(stderr, "=");
9148 else if (l == 20*processed/total)
9149 fprintf(stderr, ">");
9150 else if (l > 20*processed/total)
9151 fprintf(stderr, ".");
9152 } else
9153 fprintf(stderr, "=");
9154 }
9155 Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9156 Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9157 TString sunit("B/s");
9158 if (evtrti > 0.) {
9159 Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9160 if (mbsrti > 0.) {
9161 const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9162 if (mbsrti >= toG) {
9163 mbsrti /= toG;
9164 sunit = "GB/s";
9165 } else if (mbsrti >= toM) {
9166 mbsrti /= toM;
9167 sunit = "MB/s";
9168 } else if (mbsrti >= toK) {
9169 mbsrti /= toK;
9170 sunit = "kB/s";
9171 }
9172 fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9173 (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9174 } else {
9175 fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9176 (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9177 }
9178 } else {
9179 fprintf(stderr, "| %.02f %%\r",
9180 (total ? ((100.0*processed)/total) : 100.0));
9181 }
9182 if (processed >= total) {
9183 fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9184 }
9185}
9186
9187////////////////////////////////////////////////////////////////////////////////
9188/// Get query progress information. Connect a slot to this signal
9189/// to track progress.
9190
9192{
9193 if (fPrintProgress) {
9194 // Call the external function
9195 return (*fPrintProgress)(total, processed, -1., -1);
9196 }
9197
9198 PDB(kGlobal,1)
9199 Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9200
9201 if (gROOT->IsBatch()) {
9202 // Simple progress bar
9203 if (total > 0)
9204 PrintProgress(total, processed);
9205 } else {
9206 EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9207 }
9208}
9209
9210////////////////////////////////////////////////////////////////////////////////
9211/// Get query progress information. Connect a slot to this signal
9212/// to track progress.
9213
9215 Float_t initTime, Float_t procTime,
9216 Float_t evtrti, Float_t mbrti)
9217{
9218 PDB(kGlobal,1)
9219 Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9220 initTime, procTime, evtrti, mbrti);
9221
9222 if (gROOT->IsBatch()) {
9223 // Simple progress bar
9224 if (total > 0)
9225 PrintProgress(total, processed, procTime, bytesread);
9226 } else {
9227 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9228 7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9229 }
9230}
9231
9232////////////////////////////////////////////////////////////////////////////////
9233/// Get query progress information. Connect a slot to this signal
9234/// to track progress.
9235
9237 Float_t initTime, Float_t procTime,
9238 Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9239{
9240 PDB(kGlobal,1)
9241 Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9242 initTime, procTime, evtrti, mbrti, actw, eses);
9243
9244 if (gROOT->IsBatch()) {
9245 // Simple progress bar
9246 if (total > 0)
9247 PrintProgress(total, processed, procTime, bytesread);
9248 } else {
9249 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9250 10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9251 }
9252}
9253
9254////////////////////////////////////////////////////////////////////////////////
9255/// Get list of feedback objects. Connect a slot to this signal
9256/// to monitor the feedback object.
9257
9259{
9260 PDB(kGlobal,1)
9261 Info("Feedback","%d objects", objs->GetSize());
9262 PDB(kFeedback,1) {
9263 Info("Feedback","%d objects", objs->GetSize());
9264 objs->ls();
9265 }
9266
9267 Emit("Feedback(TList *objs)", (Long_t) objs);
9268}
9269
9270////////////////////////////////////////////////////////////////////////////////
9271/// Close progress dialog.
9272
9274{
9275 PDB(kGlobal,1)
9276 Info("CloseProgressDialog",
9277 "called: have progress dialog: %d", fProgressDialogStarted);
9278
9279 // Nothing to do if not there
9281 return;
9282
9283 Emit("CloseProgressDialog()");
9284}
9285
9286////////////////////////////////////////////////////////////////////////////////
9287/// Reset progress dialog.
9288
9289void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9290 Long64_t ent)
9291{
9292 PDB(kGlobal,1)
9293 Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9294
9295 EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9296 4, sel, sz, fst, ent);
9297}
9298
9299////////////////////////////////////////////////////////////////////////////////
9300/// Send startup message.
9301
9302void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9303{
9304 PDB(kGlobal,1)
9305 Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9306
9307 EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9308 4, msg, st, done, total);
9309}
9310
9311////////////////////////////////////////////////////////////////////////////////
9312/// Send dataset preparation status.
9313
9314void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9315{
9316 PDB(kGlobal,1)
9317 Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9318
9319 EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9320 4, msg, st, done, total);
9321}
9322
9323////////////////////////////////////////////////////////////////////////////////
9324/// Send or notify data set status
9325
9326void TProof::SendDataSetStatus(const char *action, UInt_t done,
9327 UInt_t tot, Bool_t st)
9328{
9329 if (IsLite()) {
9330 if (tot) {
9331 TString type = "files";
9332 Int_t frac = (Int_t) (done*100.)/tot;
9333 char msg[512] = {0};
9334 if (frac >= 100) {
9335 snprintf(msg, 512, "%s: OK (%d %s) \n",
9336 action,tot, type.Data());
9337 } else {
9338 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9339 action, done, tot, frac);
9340 }
9341 if (fSync)
9342 fprintf(stderr,"%s", msg);
9343 else
9344 NotifyLogMsg(msg, 0);
9345 }
9346 return;
9347 }
9348
9351 mess << TString(action) << tot << done << st;
9352 gProofServ->GetSocket()->Send(mess);
9353 }
9354}
9355
9356////////////////////////////////////////////////////////////////////////////////
9357/// Notify availability of a query result.
9358
9359void TProof::QueryResultReady(const char *ref)
9360{
9361 PDB(kGlobal,1)
9362 Info("QueryResultReady","ref: %s", ref);
9363
9364 Emit("QueryResultReady(const char*)",ref);
9365}
9366
9367////////////////////////////////////////////////////////////////////////////////
9368/// Validate a TDSet.
9369
9371{
9372 if (dset->ElementsValid()) return;
9373
9374 TList nodes;
9375 nodes.SetOwner();
9376
9377 TList slholder;
9378 slholder.SetOwner();
9379 TList elemholder;
9380 elemholder.SetOwner();
9381
9382 // build nodelist with slaves and elements
9383 TIter nextSlave(GetListOfActiveSlaves());
9384 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9385 TList *sllist = 0;
9386 TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9387 if (!p) {
9388 sllist = new TList;
9389 sllist->SetName(sl->GetName());
9390 slholder.Add(sllist);
9391 TList *elemlist = new TList;
9392 elemlist->SetName(TString(sl->GetName())+"_elem");
9393 elemholder.Add(elemlist);
9394 nodes.Add(new TPair(sllist, elemlist));
9395 } else {
9396 sllist = dynamic_cast<TList*>(p->Key());
9397 }
9398 if (sllist) sllist->Add(sl);
9399 }
9400
9401 // add local elements to nodes
9402 TList nonLocal; // list of nonlocal elements
9403 // make two iterations - first add local elements - then distribute nonlocals
9404 for (Int_t i = 0; i < 2; i++) {
9405 Bool_t local = i>0?kFALSE:kTRUE;
9406 TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9407 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9408 if (elem->GetValid()) continue;
9409 TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9410 if (p) {
9411 TList *eli = dynamic_cast<TList*>(p->Value());
9412 TList *sli = dynamic_cast<TList*>(p->Key());
9413 if (eli && sli) {
9414 eli->Add(elem);
9415
9416 // order list by elements/slave
9417 TPair *p2 = p;
9418 Bool_t stop = kFALSE;
9419 while (!stop) {
9420 TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9421 if (p3) {
9422 TList *p3v = dynamic_cast<TList*>(p3->Value());
9423 TList *p3k = dynamic_cast<TList*>(p3->Key());
9424 if (p3v && p3k) {
9425 Int_t nelem = p3v->GetSize();
9426 Int_t nsl = p3k->GetSize();
9427 if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
9428 else stop = kTRUE;
9429 }
9430 } else {
9431 stop = kTRUE;
9432 }
9433 }
9434
9435 if (p2!=p) {
9436 nodes.Remove(p->Key());
9437 nodes.AddAfter(p2->Key(), p);
9438 }
9439 } else {
9440 Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
9441 continue;
9442 }
9443
9444 } else {
9445 if (local) {
9446 nonLocal.Add(elem);
9447 } else {
9448 Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
9449 }
9450 }
9451 }
9452 }
9453
9454 // send to slaves
9455 TList usedslaves;
9456 TIter nextNode(&nodes);
9457 SetDSet(dset); // set dset to be validated in Collect()
9458 while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
9459 TList *slaves = dynamic_cast<TList*>(node->Key());
9460 TList *setelements = dynamic_cast<TList*>(node->Value());
9461 if (!slaves || !setelements) continue;
9462 // distribute elements over the slaves
9463 Int_t nslaves = slaves->GetSize();
9464 Int_t nelements = setelements->GetSize();
9465 for (Int_t i=0; i<nslaves; i++) {
9466
9467 TDSet copyset(dset->GetType(), dset->GetObjName(),
9468 dset->GetDirectory());
9469 for (Int_t j = (i*nelements)/nslaves;
9470 j < ((i+1)*nelements)/nslaves;
9471 j++) {
9472 TDSetElement *elem =
9473 dynamic_cast<TDSetElement*>(setelements->At(j));
9474 if (elem) {
9475 copyset.Add(elem->GetFileName(), elem->GetObjName(),
9476 elem->GetDirectory(), elem->GetFirst(),
9477 elem->GetNum(), elem->GetMsd());
9478 }
9479 }
9480
9481 if (copyset.GetListOfElements()->GetSize()>0) {
9483 mesg << &copyset;
9484
9485 TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
9486 if (sl) {
9487 PDB(kGlobal,1) Info("ValidateDSet",
9488 "Sending TDSet with %d elements to slave %s"
9489 " to be validated",
9490 copyset.GetListOfElements()->GetSize(),
9491 sl->GetOrdinal());
9492 sl->GetSocket()->Send(mesg);
9493 usedslaves.Add(sl);
9494 }
9495 }
9496 }
9497 }
9498
9499 PDB(kGlobal,1)
9500 Info("ValidateDSet","Calling Collect");
9501 Collect(&usedslaves);
9502 SetDSet(0);
9503}
9504
9505////////////////////////////////////////////////////////////////////////////////
9506/// Add data objects that might be needed during the processing of
9507/// the selector (see Process()). This object can be very large, so they
9508/// are distributed in an optimized way using a dedicated file.
9509/// If push is TRUE the input data are sent over even if no apparent change
9510/// occured to the list.
9511
9513{
9514 if (obj) {
9515 if (!fInputData) fInputData = new TList;
9516 if (!fInputData->FindObject(obj)) {
9517 fInputData->Add(obj);
9519 }
9520 }
9521 if (push) SetBit(TProof::kNewInputData);
9522}
9523
9524////////////////////////////////////////////////////////////////////////////////
9525/// Remove obj form the input data list; if obj is null (default), clear the
9526/// input data info.
9527
9529{
9530 if (!obj) {
9531 if (fInputData) {
9534 }
9536
9537 // Also remove any info about input data in the input list
9538 TObject *o = 0;
9539 TList *in = GetInputList();
9540 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9541 in->Remove(o);
9542 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9543 in->Remove(o);
9544
9545 // ... and reset the file
9546 fInputDataFile = "";
9548
9549 } else if (fInputData) {
9550 Int_t sz = fInputData->GetSize();
9551 while (fInputData->FindObject(obj))
9552 fInputData->Remove(obj);
9553 // Flag for update, if anything changed
9554 if (sz != fInputData->GetSize())
9556 }
9557}
9558
9559////////////////////////////////////////////////////////////////////////////////
9560/// Remove obj 'name' form the input data list;
9561
9563{
9564 TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
9565 if (obj) ClearInputData(obj);
9566}
9567
9568////////////////////////////////////////////////////////////////////////////////
9569/// Set the file to be used to optimally distribute the input data objects.
9570/// If the file exists the object in the file are added to those in the
9571/// fInputData list. If the file path is null, a default file will be created
9572/// at the moment of sending the processing request with the content of
9573/// the fInputData list. See also SendInputDataFile.
9574
9575void TProof::SetInputDataFile(const char *datafile)
9576{
9577 if (datafile && strlen(datafile) > 0) {
9578 if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
9580 fInputDataFile = datafile;
9581 } else {
9582 if (!fInputDataFile.IsNull())
9584 fInputDataFile = "";
9585 }
9586 // Make sure that the chosen file is readable
9589 fInputDataFile = "";
9590 }
9591}
9592
9593////////////////////////////////////////////////////////////////////////////////
9594/// Send the input data objects to the master; the objects are taken from the
9595/// dedicated list and / or the specified file.
9596/// If the fInputData is empty the specified file is sent over.
9597/// If there is no specified file, a file named "inputdata.root" is created locally
9598/// with the content of fInputData and sent over to the master.
9599/// If both fInputData and the specified file are not empty, a copy of the file
9600/// is made locally and augmented with the content of fInputData.
9601
9603{
9604 // Prepare the file
9605 TString dataFile;
9606 PrepareInputDataFile(dataFile);
9607
9608 // Send it, if not empty
9609 if (dataFile.Length() > 0) {
9610
9611 Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
9612 BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
9613
9614 // Set the name in the input list
9615 TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
9616 AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
9617 }
9618}
9619
9620////////////////////////////////////////////////////////////////////////////////
9621/// Prepare the file with the input data objects to be sent the master; the
9622/// objects are taken from the dedicated list and / or the specified file.
9623/// If the fInputData is empty the specified file is sent over.
9624/// If there is no specified file, a file named "inputdata.root" is created locally
9625/// with the content of fInputData and sent over to the master.
9626/// If both fInputData and the specified file are not empty, a copy of the file
9627/// is made locally and augmented with the content of fInputData.
9628
9630{
9631 // Save info about new data for usage in this call;
9633 // Next time we need some change
9635
9636 // Check the list
9637 Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
9638 // Check the file
9639 Bool_t file_ok = kFALSE;
9642 // It must contain something
9644 if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
9645 file_ok = kTRUE;
9646 }
9647
9648 // Remove any info about input data in the input list
9649 TObject *o = 0;
9650 TList *in = GetInputList();
9651 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9652 in->Remove(o);
9653 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9654 in->Remove(o);
9655
9656 // We must have something to send
9657 dataFile = "";
9658 if (!list_ok && !file_ok) return;
9659
9660 // Three cases:
9661 if (file_ok && !list_ok) {
9662 // Just send the file
9663 dataFile = fInputDataFile;
9664 } else if (!file_ok && list_ok) {
9666 // Nothing to do, if no new data
9667 if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
9668 // Create the file first
9669 TFile *f = TFile::Open(fInputDataFile, "RECREATE");
9670 if (f) {
9671 f->cd();
9672 TIter next(fInputData);
9673 TObject *obj;
9674 while ((obj = next())) {
9675 obj->Write(0, TObject::kSingleKey, 0);
9676 }
9677 f->Close();
9678 SafeDelete(f);
9679 } else {
9680 Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
9681 return;
9682 }
9683 dataFile = fInputDataFile;
9684 } else if (file_ok && list_ok) {
9685 dataFile = kPROOF_InputDataFile;
9686 // Create the file if not existing or there are new data
9687 if (newdata || gSystem->AccessPathName(dataFile)) {
9688 // Cleanup previous file if obsolete
9689 if (!gSystem->AccessPathName(dataFile))
9690 gSystem->Unlink(dataFile);
9691 if (dataFile != fInputDataFile) {
9692 // Make a local copy first
9693 if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
9694 Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
9695 return;
9696 }
9697 }
9698 // Add the input data list
9699 TFile *f = TFile::Open(dataFile, "UPDATE");
9700 if (f) {
9701 f->cd();
9702 TIter next(fInputData);
9703 TObject *obj = 0;
9704 while ((obj = next())) {
9705 obj->Write(0, TObject::kSingleKey, 0);
9706 }
9707 f->Close();
9708 SafeDelete(f);
9709 } else {
9710 Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
9711 return;
9712 }
9713 }
9714 }
9715
9716 // Done
9717 return;
9718}
9719
9720////////////////////////////////////////////////////////////////////////////////
9721/// Add objects that might be needed during the processing of
9722/// the selector (see Process()).
9723
9725{
9726 if (fPlayer) fPlayer->AddInput(obj);
9727}
9728
9729////////////////////////////////////////////////////////////////////////////////
9730/// Clear input object list.
9731
9733{
9734 if (fPlayer) fPlayer->ClearInput();
9735
9736 // the system feedback list is always in the input list
9738}
9739
9740////////////////////////////////////////////////////////////////////////////////
9741/// Get input list.
9742
9744{
9745 return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
9746}
9747
9748////////////////////////////////////////////////////////////////////////////////
9749/// Get specified object that has been produced during the processing
9750/// (see Process()).
9751
9753{
9754
9756 // Can be called by MarkBad on the master before the player is initialized
9757 return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
9758
9759 // This checks also associated output files
9760 return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
9761}
9762
9763////////////////////////////////////////////////////////////////////////////////
9764/// Find object 'name' in list 'out' or in the files specified in there
9765
9767{
9768 TObject *o = 0;
9769 if (!name || (name && strlen(name) <= 0) ||
9770 !out || (out && out->GetSize() <= 0)) return o;
9771 if ((o = out->FindObject(name))) return o;
9772
9773 // For the time being we always check for all the files; this may require
9774 // some caching
9775 TProofOutputFile *pf = 0;
9776 TIter nxo(out);
9777 while ((o = nxo())) {
9778 if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
9779 TFile *f = 0;
9780 if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
9781 TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
9782 f = TFile::Open(fn.Data());
9783 if (!f || (f && f->IsZombie())) {
9784 ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
9785 }
9786 }
9787 if (f && (o = f->Get(name))) return o;
9788 }
9789 }
9790
9791 // Done, unsuccessfully
9792 return o;
9793}
9794
9795////////////////////////////////////////////////////////////////////////////////
9796/// Get list with all object created during processing (see Process()).
9797
9799{
9800 if (fOutputList.GetSize() > 0) return &fOutputList;
9801 if (fPlayer) {
9803 return &fOutputList;
9804 }
9805 return (TList *)0;
9806}
9807
9808////////////////////////////////////////////////////////////////////////////////
9809/// Set input list parameter. If the parameter is already
9810/// set it will be set to the new value.
9811
9812void TProof::SetParameter(const char *par, const char *value)
9813{
9814 if (!fPlayer) {
9815 Warning("SetParameter", "player undefined! Ignoring");
9816 return;
9817 }
9818
9819 TList *il = fPlayer->GetInputList();
9820 TObject *item = il->FindObject(par);
9821 if (item) {
9822 il->Remove(item);
9823 delete item;
9824 }
9825 il->Add(new TNamed(par, value));
9826}
9827
9828////////////////////////////////////////////////////////////////////////////////
9829/// Set an input list parameter.
9830
9831void TProof::SetParameter(const char *par, Int_t value)
9832{
9833 if (!fPlayer) {
9834 Warning("SetParameter", "player undefined! Ignoring");
9835 return;
9836 }
9837
9838 TList *il = fPlayer->GetInputList();
9839 TObject *item = il->FindObject(par);
9840 if (item) {
9841 il->Remove(item);
9842 delete item;
9843 }
9844 il->Add(new TParameter<Int_t>(par, value));
9845}
9846
9847////////////////////////////////////////////////////////////////////////////////
9848/// Set an input list parameter.
9849
9850void TProof::SetParameter(const char *par, Long_t value)
9851{
9852 if (!fPlayer) {
9853 Warning("SetParameter", "player undefined! Ignoring");
9854 return;
9855 }
9856
9857 TList *il = fPlayer->GetInputList();
9858 TObject *item = il->FindObject(par);
9859 if (item) {
9860 il->Remove(item);
9861 delete item;
9862 }
9863 il->Add(new TParameter<Long_t>(par, value));
9864}
9865
9866////////////////////////////////////////////////////////////////////////////////
9867/// Set an input list parameter.
9868
9869void TProof::SetParameter(const char *par, Long64_t value)
9870{
9871 if (!fPlayer) {
9872 Warning("SetParameter", "player undefined! Ignoring");
9873 return;
9874 }
9875
9876 TList *il = fPlayer->GetInputList();
9877 TObject *item = il->FindObject(par);
9878 if (item) {
9879 il->Remove(item);
9880 delete item;
9881 }
9882 il->Add(new TParameter<Long64_t>(par, value));
9883}
9884
9885////////////////////////////////////////////////////////////////////////////////
9886/// Set an input list parameter.
9887
9888void TProof::SetParameter(const char *par, Double_t value)
9889{
9890 if (!fPlayer) {
9891 Warning("SetParameter", "player undefined! Ignoring");
9892 return;
9893 }
9894
9895 TList *il = fPlayer->GetInputList();
9896 TObject *item = il->FindObject(par);
9897 if (item) {
9898 il->Remove(item);
9899 delete item;
9900 }
9901 il->Add(new TParameter<Double_t>(par, value));
9902}
9903
9904////////////////////////////////////////////////////////////////////////////////
9905/// Get specified parameter. A parameter set via SetParameter() is either
9906/// a TParameter or a TNamed or 0 in case par is not defined.
9907
9908TObject *TProof::GetParameter(const char *par) const
9909{
9910 if (!fPlayer) {
9911 Warning("GetParameter", "player undefined! Ignoring");
9912 return (TObject *)0;
9913 }
9914
9915 TList *il = fPlayer->GetInputList();
9916 return il->FindObject(par);
9917}
9918
9919////////////////////////////////////////////////////////////////////////////////
9920/// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
9921/// or exact name (e.g. PROOF_MaxSlavesPerNode).
9922
9923void TProof::DeleteParameters(const char *wildcard)
9924{
9925 if (!fPlayer) return;
9926
9927 if (!wildcard) wildcard = "";
9928 TRegexp re(wildcard, kTRUE);
9929 Int_t nch = strlen(wildcard);
9930
9931 TList *il = fPlayer->GetInputList();
9932 if (il) {
9933 TObject *p = 0;
9934 TIter next(il);
9935 while ((p = next())) {
9936 TString s = p->GetName();
9937 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9938 il->Remove(p);
9939 delete p;
9940 }
9941 }
9942}
9943
9944////////////////////////////////////////////////////////////////////////////////
9945/// Show the input list parameters specified by the wildcard.
9946/// Default is the special PROOF control parameters (PROOF_*).
9947
9948void TProof::ShowParameters(const char *wildcard) const
9949{
9950 if (!fPlayer) return;
9951
9952 if (!wildcard) wildcard = "";
9953 TRegexp re(wildcard, kTRUE);
9954 Int_t nch = strlen(wildcard);
9955
9956 TList *il = fPlayer->GetInputList();
9957 TObject *p;
9958 TIter next(il);
9959 while ((p = next())) {
9960 TString s = p->GetName();
9961 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9962 if (p->IsA() == TNamed::Class()) {
9963 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9964 } else if (p->IsA() == TParameter<Long_t>::Class()) {
9965 Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
9966 } else if (p->IsA() == TParameter<Long64_t>::Class()) {
9967 Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
9968 } else if (p->IsA() == TParameter<Double_t>::Class()) {
9969 Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
9970 } else {
9971 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9972 }
9973 }
9974}
9975
9976////////////////////////////////////////////////////////////////////////////////
9977/// Add object to feedback list.
9978
9979void TProof::AddFeedback(const char *name)
9980{
9981 PDB(kFeedback, 3)
9982 Info("AddFeedback", "Adding object \"%s\" to feedback", name);
9983 if (fFeedback->FindObject(name) == 0)
9985}
9986
9987////////////////////////////////////////////////////////////////////////////////
9988/// Remove object from feedback list.
9989
9991{
9993 if (obj != 0) {
9994 fFeedback->Remove(obj);
9995 delete obj;
9996 }
9997}
9998
9999////////////////////////////////////////////////////////////////////////////////
10000/// Clear feedback list.
10001
10003{
10004 fFeedback->Delete();
10005}
10006
10007////////////////////////////////////////////////////////////////////////////////
10008/// Show items in feedback list.
10009
10011{
10012 if (fFeedback->GetSize() == 0) {
10013 Info("","no feedback requested");
10014 return;
10015 }
10016
10017 fFeedback->Print();
10018}
10019
10020////////////////////////////////////////////////////////////////////////////////
10021/// Return feedback list.
10022
10024{
10025 return fFeedback;
10026}
10027
10028////////////////////////////////////////////////////////////////////////////////
10029/// Creates a tree header (a tree with nonexisting files) object for
10030/// the DataSet.
10031
10033{
10035 TSlave *sl = (TSlave*) l->First();
10036 if (sl == 0) {
10037 Error("GetTreeHeader", "No connection");
10038 return 0;
10039 }
10040
10041 TSocket *soc = sl->GetSocket();
10043
10044 msg << dset;
10045
10046 soc->Send(msg);
10047
10048 TMessage *reply;
10049 Int_t d = -1;
10050 if (fProtocol >= 20) {
10052 reply = (TMessage *) fRecvMessages->First();
10053 } else {
10054 d = soc->Recv(reply);
10055 }
10056 if (!reply) {
10057 Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10058 return 0;
10059 }
10060
10061 TString s1;
10062 TTree *t = 0;
10063 (*reply) >> s1;
10064 if (s1 == "Success")
10065 (*reply) >> t;
10066
10067 PDB(kGlobal, 1) {
10068 if (t) {
10069 Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10070 s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10071 } else {
10072 Info("GetTreeHeader", "tree header retrieval failed");
10073 }
10074 }
10075 delete reply;
10076
10077 return t;
10078}
10079
10080////////////////////////////////////////////////////////////////////////////////
10081/// Draw feedback creation proxy. When accessed via TProof avoids
10082/// link dependency on libProofPlayer.
10083
10085{
10086 return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10087}
10088
10089////////////////////////////////////////////////////////////////////////////////
10090/// Set draw feedback option.
10091
10093{
10095}
10096
10097////////////////////////////////////////////////////////////////////////////////
10098/// Delete draw feedback object.
10099
10101{
10103}
10104
10105////////////////////////////////////////////////////////////////////////////////
10106/// FIXME: to be written
10107
10109{
10110 return 0;
10111/*
10112 TMessage msg(kPROOF_GETOUTPUTLIST);
10113 TList* slaves = fActiveSlaves;
10114 Broadcast(msg, slaves);
10115 TMonitor mon;
10116 TList* outputList = new TList();
10117
10118 TIter si(slaves);
10119 TSlave *slave;
10120 while ((slave = (TSlave*)si.Next()) != 0) {
10121 PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10122 slave->GetSocket(), slave->GetName());
10123 mon.Add(slave->GetSocket());
10124 }
10125 mon.ActivateAll();
10126 ((TProof*)gProof)->DeActivateAsyncInput();
10127 ((TProof*)gProof)->fCurrentMonitor = &mon;
10128
10129 while (mon.GetActive() != 0) {
10130 TSocket *sock = mon.Select();
10131 if (!sock) {
10132 Error("GetOutputList","TMonitor::.Select failed!");
10133 break;
10134 }
10135 mon.DeActivate(sock);
10136 TMessage *reply;
10137 if (sock->Recv(reply) <= 0) {
10138 MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10139// Error("GetOutputList","Recv failed! for slave-%d (%s)",
10140// slave->GetOrdinal(), slave->GetName());
10141 continue;
10142 }
10143 if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10144// Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10145// slave->GetOrdinal(), slave->GetName());
10146 MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10147 continue;
10148 }
10149 TList* l;
10150
10151 (*reply) >> l;
10152 TIter next(l);
10153 TNamed *n;
10154 while ( (n = dynamic_cast<TNamed*> (next())) ) {
10155 if (!outputList->FindObject(n->GetName()))
10156 outputList->Add(n);
10157 }
10158 delete reply;
10159 }
10160 ((TProof*)gProof)->fCurrentMonitor = 0;
10161
10162 return outputList;
10163*/
10164}
10165
10166////////////////////////////////////////////////////////////////////////////////
10167/// Build the PROOF's structure in the browser.
10168
10170{
10171 b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10172 b->Add(&fMaster, fMaster.Class(), "fMaster");
10173 b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10174 b->Add(fChains, fChains->Class(), "fChains");
10175
10176 if (fPlayer) {
10177 b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10178 if (fPlayer->GetOutputList())
10179 b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10181 b->Add(fPlayer->GetListOfResults(),
10182 fPlayer->GetListOfResults()->Class(), "ListOfResults");
10183 }
10184}
10185
10186////////////////////////////////////////////////////////////////////////////////
10187/// Set a new PROOF player.
10188
10190{
10191 if (fPlayer)
10192 delete fPlayer;
10193 fPlayer = player;
10194};
10195
10196////////////////////////////////////////////////////////////////////////////////
10197/// Construct a TProofPlayer object. The player string specifies which
10198/// player should be created: remote, slave, sm (supermaster) or base.
10199/// Default is remote. Socket is needed in case a slave player is created.
10200
10202{
10203 if (!player)
10204 player = "remote";
10205
10206 SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10207 return GetPlayer();
10208}
10209
10210////////////////////////////////////////////////////////////////////////////////
10211/// Add chain to data set
10212
10214{
10215 fChains->Add(chain);
10216}
10217
10218////////////////////////////////////////////////////////////////////////////////
10219/// Remove chain from data set
10220
10222{
10223 fChains->Remove(chain);
10224}
10225
10226////////////////////////////////////////////////////////////////////////////////
10227/// Ask for remote logs in the range [start, end]. If start == -1 all the
10228/// messages not yet received are sent back.
10229
10231{
10232 if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10233
10235
10236 msg << start << end;
10237
10238 Broadcast(msg, kActive);
10240}
10241
10242////////////////////////////////////////////////////////////////////////////////
10243/// Fill a TMacro with the log lines since the last reading (fLogFileR)
10244/// Return (TMacro *)0 if no line was logged.
10245/// The returned TMacro must be deleted by the caller.
10246
10248{
10249 TMacro *maclog = 0;
10250
10251 // Save present offset
10252 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10253 if (nowlog < 0) {
10254 SysError("GetLastLog",
10255 "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10256 return maclog;
10257 }
10258
10259 // Get extremes
10260 off_t startlog = nowlog;
10261 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10262 if (endlog < 0) {
10263 SysError("GetLastLog",
10264 "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10265 return maclog;
10266 }
10267
10268 // Perhaps nothing to log
10269 UInt_t tolog = (UInt_t)(endlog - startlog);
10270 if (tolog <= 0) return maclog;
10271
10272 // Set starting point
10273 if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10274 SysError("GetLastLog",
10275 "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10276 return maclog;
10277 }
10278
10279 // Create the output object
10280 maclog = new TMacro;
10281
10282 // Now we go
10283 char line[2048];
10284 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10285 while (fgets(line, wanted, fLogFileR)) {
10286 Int_t r = strlen(line);
10287 if (r > 0) {
10288 if (line[r-1] == '\n') line[r-1] = '\0';
10289 maclog->AddLine(line);
10290 } else {
10291 // Done
10292 break;
10293 }
10294 tolog -= r;
10295 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10296 }
10297
10298 // Restore original pointer
10299 if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10300 Warning("GetLastLog",
10301 "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10302 }
10303
10304 // Done
10305 return maclog;
10306}
10307
10308////////////////////////////////////////////////////////////////////////////////
10309/// Display log of query pq into the log window frame
10310
10312{
10313 if (!pq) return;
10314
10315 TList *lines = pq->GetLogFile()->GetListOfLines();
10316 if (lines) {
10317 TIter nxl(lines);
10318 TObjString *l = 0;
10319 while ((l = (TObjString *)nxl()))
10320 EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10321 }
10322}
10323
10324////////////////////////////////////////////////////////////////////////////////
10325/// Display on screen the content of the temporary log file for query
10326/// in reference
10327
10328void TProof::ShowLog(const char *queryref)
10329{
10330 // Make sure we have all info (GetListOfQueries retrieves the
10331 // head info only)
10332 Retrieve(queryref);
10333
10334 if (fPlayer) {
10335 if (queryref) {
10336 if (fPlayer->GetListOfResults()) {
10338 TQueryResult *qr = 0;
10339 while ((qr = (TQueryResult *) nxq()))
10340 if (strstr(queryref, qr->GetTitle()) &&
10341 strstr(queryref, qr->GetName()))
10342 break;
10343 if (qr) {
10344 PutLog(qr);
10345 return;
10346 }
10347
10348 }
10349 }
10350 }
10351}
10352
10353////////////////////////////////////////////////////////////////////////////////
10354/// Display on screen the content of the temporary log file.
10355/// If qry == -2 show messages from the last (current) query.
10356/// If qry == -1 all the messages not yet displayed are shown (default).
10357/// If qry == 0, all the messages in the file are shown.
10358/// If qry > 0, only the messages related to query 'qry' are shown.
10359/// For qry != -1 the original file offset is restored at the end
10360
10362{
10363 // Save present offset
10364 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10365 if (nowlog < 0) {
10366 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10367 return;
10368 }
10369
10370 // Get extremes
10371 off_t startlog = nowlog;
10372 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10373 if (endlog < 0) {
10374 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10375 return;
10376 }
10377
10378 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10379 if (qry == 0) {
10380 startlog = 0;
10381 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10382 } else if (qry != -1) {
10383
10384 TQueryResult *pq = 0;
10385 if (qry == -2) {
10386 // Pickup the last one
10387 pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10388 if (!pq) {
10390 if (fQueries)
10391 pq = (TQueryResult *)(fQueries->Last());
10392 }
10393 } else if (qry > 0) {
10394 TList *queries = GetQueryResults();
10395 if (queries) {
10396 TIter nxq(queries);
10397 while ((pq = (TQueryResult *)nxq()))
10398 if (qry == pq->GetSeqNum())
10399 break;
10400 }
10401 if (!pq) {
10402 queries = GetListOfQueries();
10403 TIter nxq(queries);
10404 while ((pq = (TQueryResult *)nxq()))
10405 if (qry == pq->GetSeqNum())
10406 break;
10407 }
10408 }
10409 if (pq) {
10410 PutLog(pq);
10411 return;
10412 } else {
10413 if (gDebug > 0)
10414 Info("ShowLog","query %d not found in list", qry);
10415 qry = -1;
10416 }
10417 }
10418
10419 // Number of bytes to log
10420 UInt_t tolog = (UInt_t)(endlog - startlog);
10421
10422 // Perhaps nothing
10423 if (tolog <= 0) {
10424 // Set starting point
10425 lseek(fileno(fLogFileR), startlog, SEEK_SET);
10426 }
10427
10428 // Now we go
10429 Int_t np = 0;
10430 char line[2048];
10431 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10432 while (fgets(line, wanted, fLogFileR)) {
10433
10434 Int_t r = strlen(line);
10435 if (!SendingLogToWindow()) {
10436 if (line[r-1] != '\n') line[r-1] = '\n';
10437 if (r > 0) {
10438 char *p = line;
10439 while (r) {
10440 Int_t w = write(fileno(stdout), p, r);
10441 if (w < 0) {
10442 SysError("ShowLog", "error writing to stdout");
10443 break;
10444 }
10445 r -= w;
10446 p += w;
10447 }
10448 }
10449 tolog -= strlen(line);
10450 np++;
10451
10452 // Ask if more is wanted
10453 if (!(np%10)) {
10454 const char *opt = Getline("More (y/n)? [y]");
10455 if (opt[0] == 'n')
10456 break;
10457 }
10458
10459 // We may be over
10460 if (tolog <= 0)
10461 break;
10462
10463 // Update wanted bytes
10464 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10465 } else {
10466 // Log to window
10467 if (line[r-1] == '\n') line[r-1] = 0;
10469 }
10470 }
10471 if (!SendingLogToWindow()) {
10472 // Avoid screwing up the prompt
10473 if (write(fileno(stdout), "\n", 1) != 1)
10474 SysError("ShowLog", "error writing to stdout");
10475 }
10476
10477 // Restore original pointer
10478 if (qry > -1)
10479 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10480}
10481
10482////////////////////////////////////////////////////////////////////////////////
10483/// Set session with 'id' the default one. If 'id' is not found in the list,
10484/// the current session is set as default
10485
10487{
10488 if (GetManager()) {
10490 if (d) {
10491 if (d->GetProof()) {
10492 gProof = d->GetProof();
10493 return;
10494 }
10495 }
10496
10497 // Id not found or undefined: set as default this session
10498 gProof = this;
10499 }
10500
10501 return;
10502}
10503
10504////////////////////////////////////////////////////////////////////////////////
10505/// Detach this instance to its proofserv.
10506/// If opt is 'S' or 's' the remote server is shutdown
10507
10509{
10510 // Nothing to do if not in contact with proofserv
10511 if (!IsValid()) return;
10512
10513 // Get worker and socket instances
10514 TSlave *sl = (TSlave *) fActiveSlaves->First();
10515 TSocket *s = 0;
10516 if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
10517 Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
10518 return;
10519 }
10520
10521 Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
10522
10523 // If processing, try to stop processing first
10524 if (shutdown && !IsIdle()) {
10525 // Remove pending requests
10526 Remove("cleanupqueue");
10527 // Do not wait for ever, but al least 20 seconds
10528 Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
10529 timeout = (timeout > 20) ? timeout : 20;
10530 // Send stop signal
10531 StopProcess(kFALSE, (Long_t) (timeout / 2));
10532 // Receive results
10533 Collect(kActive, timeout);
10534 }
10535
10536 // Avoid spurious messages: deactivate new inputs ...
10538
10539 // ... and discard existing ones
10540 sl->FlushSocket();
10541
10542 // Close session (we always close the connection)
10543 Close(opt);
10544
10545 // Close the progress dialog, if any
10548
10549 // Update info in the table of our manager, if any
10550 if (GetManager() && GetManager()->QuerySessions("L")) {
10551 TIter nxd(GetManager()->QuerySessions("L"));
10552 TProofDesc *d = 0;
10553 while ((d = (TProofDesc *)nxd())) {
10554 if (d->GetProof() == this) {
10555 d->SetProof(0);
10556 GetManager()->QuerySessions("L")->Remove(d);
10557 break;
10558 }
10559 }
10560 }
10561
10562 // Invalidate this instance
10563 fValid = kFALSE;
10564
10565 return;
10566}
10567
10568////////////////////////////////////////////////////////////////////////////////
10569/// Set an alias for this session. If reconnection is supported, the alias
10570/// will be communicated to the remote coordinator so that it can be recovered
10571/// when reconnecting
10572
10573void TProof::SetAlias(const char *alias)
10574{
10575 // Set it locally
10576 TNamed::SetTitle(alias);
10578 // Set the name at the same value
10579 TNamed::SetName(alias);
10580
10581 // Nothing to do if not in contact with coordinator
10582 if (!IsValid()) return;
10583
10584 if (!IsProofd() && TestBit(TProof::kIsClient)) {
10585 TSlave *sl = (TSlave *) fActiveSlaves->First();
10586 if (sl)
10587 sl->SetAlias(alias);
10588 }
10589
10590 return;
10591}
10592
10593////////////////////////////////////////////////////////////////////////////////
10594/// *** This function is deprecated and will disappear in future versions ***
10595/// *** It is just a wrapper around TFile::Cp.
10596/// *** Please use TProofMgr::UploadFiles.
10597///
10598/// Upload a set of files and save the list of files by name dataSetName.
10599/// The 'files' argument is a list of TFileInfo objects describing the files
10600/// as first url.
10601/// The mask 'opt' is a combination of EUploadOpt:
10602/// kAppend (0x1) if set true files will be appended to
10603/// the dataset existing by given name
10604/// kOverwriteDataSet (0x2) if dataset with given name exited it
10605/// would be overwritten
10606/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10607/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10608/// kOverwriteNoFiles (0x10) overwrite none
10609/// kAskUser (0x0) ask user before overwriteng dataset/files
10610/// The default value is kAskUser.
10611/// The user will be asked to confirm overwriting dataset or files unless
10612/// specified opt provides the answer!
10613/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10614/// skippedFiles argument. The function will add to this list TFileInfo
10615/// objects describing all files that existed on the cluster and were
10616/// not uploaded.
10617///
10618/// Communication Summary
10619/// Client Master
10620/// |------------>DataSetName----------->|
10621/// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
10622/// (*)|-------> call RegisterDataSet ------->|
10623/// (*) - optional
10624
10625Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
10626{
10627 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10628
10629 return -1;
10630}
10631
10632////////////////////////////////////////////////////////////////////////////////
10633/// *** This function is deprecated and will disappear in future versions ***
10634/// *** It is just a wrapper around TFile::Cp.
10635/// *** Please use TProofMgr::UploadFiles.
10636///
10637/// Upload a set of files and save the list of files by name dataSetName.
10638/// The mask 'opt' is a combination of EUploadOpt:
10639/// kAppend (0x1) if set true files will be appended to
10640/// the dataset existing by given name
10641/// kOverwriteDataSet (0x2) if dataset with given name exited it
10642/// would be overwritten
10643/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10644/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10645/// kOverwriteNoFiles (0x10) overwrite none
10646/// kAskUser (0x0) ask user before overwriteng dataset/files
10647/// The default value is kAskUser.
10648/// The user will be asked to confirm overwriting dataset or files unless
10649/// specified opt provides the answer!
10650/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10651/// skippedFiles argument. The function will add to this list TFileInfo
10652/// objects describing all files that existed on the cluster and were
10653/// not uploaded.
10654///
10655
10656Int_t TProof::UploadDataSet(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 return -1;
10661}
10662
10663////////////////////////////////////////////////////////////////////////////////
10664/// *** This function is deprecated and will disappear in future versions ***
10665/// *** It is just a wrapper around TFile::Cp.
10666/// *** Please use TProofMgr::UploadFiles.
10667///
10668/// Upload files listed in "file" to PROOF cluster.
10669/// Where file = name of file containing list of files and
10670/// dataset = dataset name and opt is a combination of EUploadOpt bits.
10671/// Each file description (line) can include wildcards.
10672/// Check TFileInfo compatibility
10673
10674Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
10675{
10676 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10677
10678 // Done
10679 return -1;
10680}
10681
10682////////////////////////////////////////////////////////////////////////////////
10683/// Register the 'dataSet' on the cluster under the current
10684/// user, group and the given 'dataSetName'.
10685/// If a dataset with the same name already exists the action fails unless 'opts'
10686/// contains 'O', in which case the old dataset is overwritten, or contains 'U',
10687/// in which case 'newDataSet' is added to the existing dataset (duplications are
10688/// ignored, if any).
10689/// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
10690/// is configured to allow so). By default the dataset is not verified.
10691/// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
10692/// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
10693/// If 'opts' contains 'S' validation would be run serially (meaningful only if
10694/// validation is required).
10695/// Returns kTRUE on success.
10696
10697Bool_t TProof::RegisterDataSet(const char *dataSetName,
10698 TFileCollection *dataSet, const char *optStr)
10699{
10700 // Check TFileInfo compatibility
10701 if (fProtocol < 17) {
10702 Info("RegisterDataSet",
10703 "functionality not available: the server does not have dataset support");
10704 return kFALSE;
10705 }
10706
10707 if (!dataSetName || strlen(dataSetName) <= 0) {
10708 Info("RegisterDataSet", "specifying a dataset name is mandatory");
10709 return kFALSE;
10710 }
10711
10712 Bool_t parallelverify = kFALSE;
10713 TString sopt(optStr);
10714 if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
10715 // We do verification in parallel later on; just register for now
10716 parallelverify = kTRUE;
10717 sopt.ReplaceAll("V", "");
10718 }
10719 // This would screw up things remotely, make sure is not there
10720 sopt.ReplaceAll("S", "");
10721
10723 mess << Int_t(kRegisterDataSet);
10724 mess << TString(dataSetName);
10725 mess << sopt;
10726 mess.WriteObject(dataSet);
10727 Broadcast(mess);
10728
10729 Bool_t result = kTRUE;
10730 Collect();
10731 if (fStatus != 0) {
10732 Error("RegisterDataSet", "dataset was not saved");
10733 result = kFALSE;
10734 return result;
10735 }
10736
10737 // If old server or not verifying in parallel we are done
10738 if (!parallelverify) return result;
10739
10740 // If we are here it means that we will verify in parallel
10741 sopt += "V";
10742 if (VerifyDataSet(dataSetName, sopt) < 0){
10743 Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
10744 return kFALSE;
10745 }
10746
10747 // We are done
10748 return kTRUE;
10749}
10750
10751////////////////////////////////////////////////////////////////////////////////
10752/// Set/Change the name of the default tree. The tree name may contain
10753/// subdir specification in the form "subdir/name".
10754/// Returns 0 on success, -1 otherwise.
10755
10756Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
10757{
10758 // Check TFileInfo compatibility
10759 if (fProtocol < 23) {
10760 Info("SetDataSetTreeName", "functionality not supported by the server");
10761 return -1;
10762 }
10763
10764 if (!dataset || strlen(dataset) <= 0) {
10765 Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
10766 return -1;
10767 }
10768
10769 if (!treename || strlen(treename) <= 0) {
10770 Info("SetDataSetTreeName", "specifying a tree name is mandatory");
10771 return -1;
10772 }
10773
10774 TUri uri(dataset);
10775 TString fragment(treename);
10776 if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
10777 uri.SetFragment(fragment);
10778
10780 mess << Int_t(kSetDefaultTreeName);
10781 mess << uri.GetUri();
10782 Broadcast(mess);
10783
10784 Collect();
10785 if (fStatus != 0) {
10786 Error("SetDataSetTreeName", "some error occured: default tree name not changed");
10787 return -1;
10788 }
10789 return 0;
10790}
10791
10792////////////////////////////////////////////////////////////////////////////////
10793/// Lists all datasets that match given uri.
10794/// The 'optStr' can contain a comma-separated list of servers for which the
10795/// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
10796/// only the global information in the TFileCollection is retrieved; useful to only
10797/// get the list of available datasets.
10798
10799TMap *TProof::GetDataSets(const char *uri, const char *optStr)
10800{
10801 if (fProtocol < 15) {
10802 Info("GetDataSets",
10803 "functionality not available: the server does not have dataset support");
10804 return 0;
10805 }
10806 if (fProtocol < 31 && strstr(optStr, ":lite:"))
10807 Warning("GetDataSets", "'lite' option not supported by the server");
10808
10810 mess << Int_t(kGetDataSets);
10811 mess << TString(uri ? uri : "");
10812 mess << TString(optStr ? optStr : "");
10813 Broadcast(mess);
10815
10816 TMap *dataSetMap = 0;
10817 if (fStatus != 0) {
10818 Error("GetDataSets", "error receiving datasets information");
10819 } else {
10820 // Look in the list
10821 TMessage *retMess = (TMessage *) fRecvMessages->First();
10822 if (retMess && retMess->What() == kMESS_OK) {
10823 if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
10824 Error("GetDataSets", "error receiving datasets");
10825 } else
10826 Error("GetDataSets", "message not found or wrong type (%p)", retMess);
10827 }
10828
10829 return dataSetMap;
10830}
10831
10832////////////////////////////////////////////////////////////////////////////////
10833/// Shows datasets in locations that match the uri.
10834/// By default shows the user's datasets and global ones
10835
10836void TProof::ShowDataSets(const char *uri, const char* optStr)
10837{
10838 if (fProtocol < 15) {
10839 Info("ShowDataSets",
10840 "functionality not available: the server does not have dataset support");
10841 return;
10842 }
10843
10845 mess << Int_t(kShowDataSets);
10846 mess << TString(uri ? uri : "");
10847 mess << TString(optStr ? optStr : "");
10848 Broadcast(mess);
10849
10851 if (fStatus != 0)
10852 Error("ShowDataSets", "error receiving datasets information");
10853}
10854
10855////////////////////////////////////////////////////////////////////////////////
10856/// Returns kTRUE if 'dataset' exists, kFALSE otherwise
10857
10858Bool_t TProof::ExistsDataSet(const char *dataset)
10859{
10860 if (fProtocol < 15) {
10861 Info("ExistsDataSet", "functionality not available: the server has an"
10862 " incompatible version of TFileInfo");
10863 return kFALSE;
10864 }
10865
10866 if (!dataset || strlen(dataset) <= 0) {
10867 Error("ExistsDataSet", "dataset name missing");
10868 return kFALSE;
10869 }
10870
10872 msg << Int_t(kCheckDataSetName) << TString(dataset);
10873 Broadcast(msg);
10875 if (fStatus == -1) {
10876 // The dataset exists
10877 return kTRUE;
10878 }
10879 // The dataset does not exists
10880 return kFALSE;
10881}
10882
10883////////////////////////////////////////////////////////////////////////////////
10884/// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
10885
10886void TProof::ClearDataSetCache(const char *dataset)
10887{
10888 if (fProtocol < 28) {
10889 Info("ClearDataSetCache", "functionality not available on server");
10890 return;
10891 }
10892
10894 msg << Int_t(kCache) << TString(dataset) << TString("clear");
10895 Broadcast(msg);
10897 // Done
10898 return;
10899}
10900
10901////////////////////////////////////////////////////////////////////////////////
10902/// Display the content of the dataset cache, if any (matching 'dataset', if defined).
10903
10904void TProof::ShowDataSetCache(const char *dataset)
10905{
10906 if (fProtocol < 28) {
10907 Info("ShowDataSetCache", "functionality not available on server");
10908 return;
10909 }
10910
10912 msg << Int_t(kCache) << TString(dataset) << TString("show");
10913 Broadcast(msg);
10915 // Done
10916 return;
10917}
10918
10919////////////////////////////////////////////////////////////////////////////////
10920/// Get a list of TFileInfo objects describing the files of the specified
10921/// dataset.
10922/// To get the short version (containing only the global meta information)
10923/// specify optStr = "S:" or optStr = "short:".
10924/// To get the sub-dataset of files located on a given server(s) specify
10925/// the list of servers (comma-separated) in the 'optStr' field.
10926
10927TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10928{
10929 if (fProtocol < 15) {
10930 Info("GetDataSet", "functionality not available: the server has an"
10931 " incompatible version of TFileInfo");
10932 return 0;
10933 }
10934
10935 if (!uri || strlen(uri) <= 0) {
10936 Info("GetDataSet", "specifying a dataset name is mandatory");
10937 return 0;
10938 }
10939
10940 TMessage nameMess(kPROOF_DATASETS);
10941 nameMess << Int_t(kGetDataSet);
10942 nameMess << TString(uri);
10943 nameMess << TString(optStr ? optStr: "");
10944 if (Broadcast(nameMess) < 0)
10945 Error("GetDataSet", "sending request failed");
10946
10948 TFileCollection *fileList = 0;
10949 if (fStatus != 0) {
10950 Error("GetDataSet", "error receiving datasets information");
10951 } else {
10952 // Look in the list
10953 TMessage *retMess = (TMessage *) fRecvMessages->First();
10954 if (retMess && retMess->What() == kMESS_OK) {
10955 if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10956 Error("GetDataSet", "error reading list of files");
10957 } else
10958 Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10959 }
10960
10961 return fileList;
10962}
10963
10964////////////////////////////////////////////////////////////////////////////////
10965/// display meta-info for given dataset usi
10966
10967void TProof::ShowDataSet(const char *uri, const char* opt)
10968{
10969 TFileCollection *fileList = 0;
10970 if ((fileList = GetDataSet(uri))) {
10971 fileList->Print(opt);
10972 delete fileList;
10973 } else
10974 Warning("ShowDataSet","no such dataset: %s", uri);
10975}
10976
10977////////////////////////////////////////////////////////////////////////////////
10978/// Remove the specified dataset from the PROOF cluster.
10979/// Files are not deleted.
10980
10981Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10982{
10983 TMessage nameMess(kPROOF_DATASETS);
10984 nameMess << Int_t(kRemoveDataSet);
10985 nameMess << TString(uri?uri:"");
10986 nameMess << TString(optStr?optStr:"");
10987 if (Broadcast(nameMess) < 0)
10988 Error("RemoveDataSet", "sending request failed");
10990
10991 if (fStatus != 0)
10992 return -1;
10993 else
10994 return 0;
10995}
10996
10997////////////////////////////////////////////////////////////////////////////////
10998/// Find datasets, returns in a TList all found datasets.
10999
11000TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
11001{
11002 Error ("FindDataSets", "not yet implemented");
11003 return (TList *) 0;
11004}
11005
11006////////////////////////////////////////////////////////////////////////////////
11007/// Allows users to request staging of a particular dataset. Requests are
11008/// saved in a special dataset repository and must be honored by the endpoint.
11009
11011{
11012 if (fProtocol < 35) {
11013 Error("RequestStagingDataSet",
11014 "functionality not supported by the server");
11015 return kFALSE;
11016 }
11017
11019 mess << Int_t(kRequestStaging);
11020 mess << TString(dataset);
11021 Broadcast(mess);
11022
11023 Collect();
11024 if (fStatus != 0) {
11025 Error("RequestStagingDataSet", "staging request was unsuccessful");
11026 return kFALSE;
11027 }
11028
11029 return kTRUE;
11030}
11031
11032////////////////////////////////////////////////////////////////////////////////
11033/// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11034/// failure. Dataset not found equals to a failure.
11035
11037{
11038 if (fProtocol < 36) {
11039 Error("CancelStagingDataSet",
11040 "functionality not supported by the server");
11041 return kFALSE;
11042 }
11043
11045 mess << Int_t(kCancelStaging);
11046 mess << TString(dataset);
11047 Broadcast(mess);
11048
11049 Collect();
11050 if (fStatus != 0) {
11051 Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11052 return kFALSE;
11053 }
11054
11055 return kTRUE;
11056}
11057
11058////////////////////////////////////////////////////////////////////////////////
11059/// Obtains a TFileCollection showing the staging status of the specified
11060/// dataset. A valid dataset manager and dataset staging requests repository
11061/// must be present on the endpoint.
11062
11064{
11065 if (fProtocol < 35) {
11066 Error("GetStagingStatusDataSet",
11067 "functionality not supported by the server");
11068 return NULL;
11069 }
11070
11071 TMessage nameMess(kPROOF_DATASETS);
11072 nameMess << Int_t(kStagingStatus);
11073 nameMess << TString(dataset);
11074 if (Broadcast(nameMess) < 0) {
11075 Error("GetStagingStatusDataSet", "sending request failed");
11076 return NULL;
11077 }
11078
11080 TFileCollection *fc = NULL;
11081
11082 if (fStatus < 0) {
11083 Error("GetStagingStatusDataSet", "problem processing the request");
11084 }
11085 else if (fStatus == 0) {
11086 TMessage *retMess = (TMessage *)fRecvMessages->First();
11087 if (retMess && (retMess->What() == kMESS_OK)) {
11088 fc = (TFileCollection *)(
11089 retMess->ReadObject(TFileCollection::Class()) );
11090 if (!fc)
11091 Error("GetStagingStatusDataSet", "error reading list of files");
11092 }
11093 else {
11094 Error("GetStagingStatusDataSet",
11095 "response message not found or wrong type (%p)", retMess);
11096 }
11097 }
11098 //else {}
11099
11100 return fc;
11101}
11102
11103////////////////////////////////////////////////////////////////////////////////
11104/// Like GetStagingStatusDataSet, but displays results immediately.
11105
11106void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11107{
11109 if (fc) {
11110 fc->Print(opt);
11111 delete fc;
11112 }
11113}
11114
11115////////////////////////////////////////////////////////////////////////////////
11116/// Verify if all files in the specified dataset are available.
11117/// Print a list and return the number of missing files.
11118/// Returns -1 in case of error.
11119
11120Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11121{
11122 if (fProtocol < 15) {
11123 Info("VerifyDataSet", "functionality not available: the server has an"
11124 " incompatible version of TFileInfo");
11125 return -1;
11126 }
11127
11128 // Sanity check
11129 if (!uri || (uri && strlen(uri) <= 0)) {
11130 Error("VerifyDataSet", "dataset name is is mandatory");
11131 return -1;
11132 }
11133
11134 Int_t nmissingfiles = 0;
11135
11136 TString sopt(optStr);
11137 if (fProtocol < 34 || sopt.Contains("S")) {
11138 sopt.ReplaceAll("S", "");
11139 Info("VerifyDataSet", "Master-only verification");
11140 TMessage nameMess(kPROOF_DATASETS);
11141 nameMess << Int_t(kVerifyDataSet);
11142 nameMess << TString(uri);
11143 nameMess << sopt;
11144 Broadcast(nameMess);
11145
11147
11148 if (fStatus < 0) {
11149 Info("VerifyDataSet", "no such dataset %s", uri);
11150 return -1;
11151 } else
11152 nmissingfiles = fStatus;
11153 return nmissingfiles;
11154 }
11155
11156 // Request for parallel verification: can only be done if we have workers
11157 if (!IsParallel() && !fDynamicStartup) {
11158 Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11159 Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11160 return -1;
11161 }
11162
11163 // Do parallel verification
11164 return VerifyDataSetParallel(uri, optStr);
11165}
11166
11167////////////////////////////////////////////////////////////////////////////////
11168/// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11169/// TProofLite::VerifyDataSet
11170
11171Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11172{
11173 Int_t nmissingfiles = 0;
11174
11175 // Let PROOF master prepare node-files map
11176 SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11177
11178 // Use TPacketizerFile
11179 TString oldpack;
11180 if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11181 SetParameter("PROOF_Packetizer", "TPacketizerFile");
11182
11183 // Add dataset name
11184 SetParameter("PROOF_VerifyDataSet", uri);
11185 // Add options
11186 SetParameter("PROOF_VerifyDataSetOption", optStr);
11187 SetParameter("PROOF_SavePartialResults", (Int_t)0);
11188 Int_t oldifiip = -1;
11189 if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11190 SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11191
11192 // TO DO : figure out mss and stageoption
11193 const char* mss="";
11194 SetParameter("PROOF_MSS", mss);
11195 const char* stageoption="";
11196 SetParameter("PROOF_StageOption", stageoption);
11197
11198 // Process verification in parallel
11199 Process("TSelVerifyDataSet", (Long64_t) 1);
11200
11201 // Restore packetizer
11202 if (!oldpack.IsNull())
11203 SetParameter("PROOF_Packetizer", oldpack);
11204 else
11205 DeleteParameters("PROOF_Packetizer");
11206
11207 // Delete or restore parameters
11208 DeleteParameters("PROOF_FilesToProcess");
11209 DeleteParameters("PROOF_VerifyDataSet");
11210 DeleteParameters("PROOF_VerifyDataSetOption");
11211 DeleteParameters("PROOF_MSS");
11212 DeleteParameters("PROOF_StageOption");
11213 if (oldifiip > -1) {
11214 SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11215 } else {
11216 DeleteParameters("PROOF_IncludeFileInfoInPacket");
11217 }
11218 DeleteParameters("PROOF_SavePartialResults");
11219
11220 // Merge outputs
11221 Int_t nopened = 0;
11222 Int_t ntouched = 0;
11223 Bool_t changed_ds = kFALSE;
11224
11225 TIter nxtout(GetOutputList());
11226 TObject* obj;
11227 TList *lfiindout = new TList;
11228 while ((obj = nxtout())) {
11229 TList *l = dynamic_cast<TList *>(obj);
11230 if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11231 TIter nxt(l);
11232 TFileInfo *fiindout = 0;
11233 while ((fiindout = (TFileInfo*) nxt())) {
11234 lfiindout->Add(fiindout);
11235 }
11236 }
11237 // Add up number of disppeared files
11238 TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11239 if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11240 nmissingfiles += pdisappeared->GetVal();
11241 }
11242 TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11243 if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11244 nopened += pnopened->GetVal();
11245 }
11246 TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11247 if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11248 ntouched += pntouched->GetVal();
11249 }
11250 TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11251 if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11252 if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11253 }
11254 }
11255
11256 Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11257 " # missing files = %d)",
11258 uri, changed_ds, nopened, ntouched, nmissingfiles);
11259 // Done
11260 return nmissingfiles;
11261}
11262
11263////////////////////////////////////////////////////////////////////////////////
11264/// returns a map of the quotas of all groups
11265
11266TMap *TProof::GetDataSetQuota(const char* optStr)
11267{
11268 if (IsLite()) {
11269 Info("UploadDataSet", "Lite-session: functionality not implemented");
11270 return (TMap *)0;
11271 }
11272
11274 mess << Int_t(kGetQuota);
11275 mess << TString(optStr?optStr:"");
11276 Broadcast(mess);
11277
11279 TMap *groupQuotaMap = 0;
11280 if (fStatus < 0) {
11281 Info("GetDataSetQuota", "could not receive quota");
11282 } else {
11283 // Look in the list
11284 TMessage *retMess = (TMessage *) fRecvMessages->First();
11285 if (retMess && retMess->What() == kMESS_OK) {
11286 if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11287 Error("GetDataSetQuota", "error getting quotas");
11288 } else
11289 Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11290 }
11291
11292 return groupQuotaMap;
11293}
11294
11295////////////////////////////////////////////////////////////////////////////////
11296/// shows the quota and usage of all groups
11297/// if opt contains "U" shows also distribution of usage on user-level
11298
11300{
11301 if (fProtocol < 15) {
11302 Info("ShowDataSetQuota",
11303 "functionality not available: the server does not have dataset support");
11304 return;
11305 }
11306
11307 if (IsLite()) {
11308 Info("UploadDataSet", "Lite-session: functionality not implemented");
11309 return;
11310 }
11311
11313 mess << Int_t(kShowQuota);
11314 mess << TString(opt?opt:"");
11315 Broadcast(mess);
11316
11317 Collect();
11318 if (fStatus != 0)
11319 Error("ShowDataSetQuota", "error receiving quota information");
11320}
11321
11322////////////////////////////////////////////////////////////////////////////////
11323/// If in active in a monitor set ready state
11324
11326{
11327 if (fCurrentMonitor)
11329}
11330
11331////////////////////////////////////////////////////////////////////////////////
11332/// Make sure that the worker identified by the ordinal number 'ord' is
11333/// in the active list. The request will be forwarded to the master
11334/// in direct contact with the worker. If needed, this master will move
11335/// the worker from the inactive to the active list and rebuild the list
11336/// of unique workers.
11337/// Use ord = "*" to activate all inactive workers.
11338/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11339/// status of which will be modified at once.
11340/// Return <0 if something went wrong (-2 if at least one worker was not found)
11341/// or the number of workers with status change (on master; 0 on client).
11342
11344{
11345 return ModifyWorkerLists(ord, kTRUE, save);
11346}
11347
11348////////////////////////////////////////////////////////////////////////////////
11349/// Remove the worker identified by the ordinal number 'ord' from the
11350/// the active list. The request will be forwarded to the master
11351/// in direct contact with the worker. If needed, this master will move
11352/// the worker from the active to the inactive list and rebuild the list
11353/// of unique workers.
11354/// Use ord = "*" to deactivate all active workers.
11355/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11356/// status of which will be modified at once.
11357/// Return <0 if something went wrong (-2 if at least one worker was not found)
11358/// or the number of workers with status change (on master; 0 on client).
11359
11361{
11362 return ModifyWorkerLists(ord, kFALSE, save);
11363}
11364
11365////////////////////////////////////////////////////////////////////////////////
11366/// Modify the worker active/inactive list by making the worker identified by
11367/// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11368/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11369/// status of which will be modified at once.
11370/// If needed, the request will be forwarded to the master in direct contact
11371/// with the worker. The end-master will move the worker from one list to the
11372/// other active and rebuild the list of unique active workers.
11373/// Use ord = "*" to deactivate all active workers.
11374/// If save is TRUE the current active list is saved before any modification is
11375/// done; re-running with ord = "restore" restores the saved list
11376/// Return <0 if something went wrong (-2 if at least one worker was not found)
11377/// or the number of workers with status change (on master; 0 on client).
11378
11380{
11381 // Make sure the input make sense
11382 if (!ord || strlen(ord) <= 0) {
11383 Info("ModifyWorkerLists",
11384 "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11385 return -1;
11386 }
11387 if (gDebug > 0)
11388 Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11389
11390 Int_t nwc = 0;
11391 Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11392 if (IsEndMaster()) {
11393 if (restoring) {
11394 // We are asked to restore the previous settings
11395 nwc = RestoreActiveList();
11396 } else {
11397 if (save) SaveActiveList();
11398 }
11399 }
11400
11401 Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11402
11403 // Check if this is for us
11405 if (!allord &&
11406 strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11407 return 0;
11408 }
11409
11410 Bool_t fw = kTRUE; // Whether to forward one step down
11411 Bool_t rs = kFALSE; // Whether to rescan for unique workers
11412
11413 // Appropriate list pointing
11414 TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11415 TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11416
11417 if (IsEndMaster() && !restoring) {
11418 // Create the hash list of ordinal numbers
11419 THashList *ords = 0;
11420 if (!allord) {
11421 ords = new THashList();
11422 const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
11423 TString oo(ord), o;
11424 Int_t from = 0;
11425 while(oo.Tokenize(o, from, ","))
11426 if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
11427 }
11428 // We do not need to send forward
11429 fw = kFALSE;
11430 // Look for the worker in the initial list
11431 TObject *os = 0;
11432 TSlave *wrk = 0;
11433 if (in->GetSize() > 0) {
11434 TIter nxw(in);
11435 while ((wrk = (TSlave *) nxw())) {
11436 os = 0;
11437 if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
11438 // Add it to the final list
11439 if (!out->FindObject(wrk)) {
11440 out->Add(wrk);
11441 if (add)
11442 fActiveMonitor->Add(wrk->GetSocket());
11443 }
11444 // Remove it from the initial list
11445 in->Remove(wrk);
11446 if (!add) {
11449 } else
11451 // Count
11452 nwc++;
11453 // Nothing to forward (ord is unique)
11454 fw = kFALSE;
11455 // Rescan for unique workers (active list modified)
11456 rs = kTRUE;
11457 // We may be done, if not option 'all'
11458 if (!allord && ords) {
11459 if (os) ords->Remove(os);
11460 if (ords->GetSize() == 0) break;
11461 SafeDelete(os);
11462 }
11463 }
11464 }
11465 }
11466 // If some worker not found, notify it if at the end
11467 if (!fw && ords && ords->GetSize() > 0) {
11468 TString oo;
11469 TIter nxo(ords);
11470 while ((os = nxo())) {
11471 TIter nxw(out);
11472 while ((wrk = (TSlave *) nxw()))
11473 if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
11474 if (!wrk) {
11475 if (!oo.IsNull()) oo += ",";
11476 oo += os->GetName();
11477 }
11478 }
11479 if (!oo.IsNull()) {
11480 Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
11481 nwc = -2;
11482 }
11483 }
11484 // Cleanup hash list
11485 if (ords) {
11486 ords->Delete();
11487 SafeDelete(ords);
11488 }
11489 }
11490
11491 // Rescan for unique workers
11492 if (rs)
11494
11495 // Forward the request one step down, if needed
11496 Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
11497 if (fw) {
11498 if (fProtocol > 32) {
11500 mess << action << TString(ord);
11501 Broadcast(mess);
11503 if (fStatus != 0) {
11504 nwc = (fStatus < nwc) ? fStatus : nwc;
11505 if (fStatus == -2) {
11506 if (gDebug > 0)
11507 Warning("ModifyWorkerLists", "request not completely full filled");
11508 } else {
11509 Error("ModifyWorkerLists", "request failed");
11510 }
11511 }
11512 } else {
11513 TString oo(ord), o;
11514 if (oo.Contains(","))
11515 Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
11516 Int_t from = 0;
11517 while(oo.Tokenize(o, from, ",")) {
11519 mess << action << o;
11520 Broadcast(mess);
11522 }
11523 }
11524 }
11525 // Done
11526 return nwc;
11527}
11528
11529////////////////////////////////////////////////////////////////////////////////
11530/// Save current list of active workers
11531
11533{
11535 if (fInactiveSlaves->GetSize() == 0) {
11536 fActiveSlavesSaved = "*";
11537 } else {
11538 TIter nxw(fActiveSlaves);
11539 TSlave *wk = 0;
11540 while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
11541 }
11542}
11543
11544////////////////////////////////////////////////////////////////////////////////
11545/// Restore saved list of active workers
11546
11548{
11549 // Clear the current active list
11551 // Restore the previous active list
11554
11555 return 0;
11556}
11557
11558////////////////////////////////////////////////////////////////////////////////
11559/// Start a PROOF session on a specific cluster. If cluster is 0 (the
11560/// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
11561/// If cluster is "lite://" we start a PROOF-lite session.
11562/// If cluster is "" (empty string) then we connect to the cluster specified
11563/// by 'Proof.LocalDefault', defaulting to "lite://".
11564/// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
11565/// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
11566/// Via conffile a specific PROOF config file in the confir directory can be specified.
11567/// Use loglevel to set the default loging level for debugging.
11568/// The appropriate instance of TProofMgr is created, if not
11569/// yet existing. The instantiated TProof object is returned.
11570/// Use TProof::cd() to switch between PROOF sessions.
11571/// For more info on PROOF see the TProof ctor.
11572
11573TProof *TProof::Open(const char *cluster, const char *conffile,
11574 const char *confdir, Int_t loglevel)
11575{
11576 const char *pn = "TProof::Open";
11577
11578 // Make sure libProof and dependents are loaded and TProof can be created,
11579 // dependents are loaded via the information in the [system].rootmap file
11580 if (!cluster) {
11581
11582 TPluginManager *pm = gROOT->GetPluginManager();
11583 if (!pm) {
11584 ::Error(pn, "plugin manager not found");
11585 return 0;
11586 }
11587
11588 if (gROOT->IsBatch()) {
11589 ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
11590 return 0;
11591 }
11592 // start PROOF Session Viewer
11593 TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
11594 if (!sv) {
11595 ::Error(pn, "no plugin found for TSessionViewer");
11596 return 0;
11597 }
11598 if (sv->LoadPlugin() == -1) {
11599 ::Error(pn, "plugin for TSessionViewer could not be loaded");
11600 return 0;
11601 }
11602 sv->ExecPlugin(0);
11603 return 0;
11604
11605 } else {
11606
11607 TString clst(cluster);
11608
11609 // Check for PoD cluster
11610 if (PoDCheckUrl( &clst ) < 0) return 0;
11611
11612 if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
11613 if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
11614
11615 // Parse input URL
11616 TUrl u(clst);
11617
11618 // *** GG, 060711: this does not seem to work any more (at XrdClient level)
11619 // *** to be investigated (it is not really needed; static tunnels work).
11620 // Dynamic tunnel:
11621 // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
11622 TString opts(u.GetOptions());
11623 if (!opts.IsNull()) {
11624 Int_t it = opts.Index("tunnel=");
11625 if (it != kNPOS) {
11626 TString sport = opts(it + strlen("tunnel="), opts.Length());
11627 TString host("127.0.0.1");
11628 Int_t port = -1;
11629 Int_t ic = sport.Index(":");
11630 if (ic != kNPOS) {
11631 // Isolate the host
11632 host = sport(0, ic);
11633 sport.Remove(0, ic + 1);
11634 }
11635 if (!sport.IsDigit()) {
11636 // Remove the non digit part
11637 TRegexp re("[^0-9]");
11638 Int_t ind = sport.Index(re);
11639 if (ind != kNPOS)
11640 sport.Remove(ind);
11641 }
11642 // Set the port
11643 if (sport.IsDigit())
11644 port = sport.Atoi();
11645 if (port > 0) {
11646 // Set the relevant variables
11647 ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
11648 gEnv->SetValue("XNet.SOCKS4Host", host);
11649 gEnv->SetValue("XNet.SOCKS4Port", port);
11650 } else {
11651 // Warn parsing problems
11652 ::Warning("TProof::Open",
11653 "problems parsing tunnelling info from options: %s", opts.Data());
11654 }
11655 }
11656 }
11657
11658 // Find out if we are required to attach to a specific session
11659 Int_t locid = -1;
11660 Bool_t create = kFALSE;
11661 if (opts.Length() > 0) {
11662 if (opts.BeginsWith("N",TString::kIgnoreCase)) {
11663 create = kTRUE;
11664 opts.Remove(0,1);
11665 u.SetOptions(opts);
11666 } else if (opts.IsDigit()) {
11667 locid = opts.Atoi();
11668 }
11669 }
11670
11671 // Attach-to or create the appropriate manager
11673
11674 TProof *proof = 0;
11675 if (mgr && mgr->IsValid()) {
11676
11677 // If XProofd we always attempt an attach first (unless
11678 // explicitly not requested).
11679 Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
11680 if (attach) {
11681 TProofDesc *d = 0;
11682 if (locid < 0)
11683 // Get the list of sessions
11684 d = (TProofDesc *) mgr->QuerySessions("")->First();
11685 else
11686 d = (TProofDesc *) mgr->GetProofDesc(locid);
11687 if (d) {
11688 proof = (TProof*) mgr->AttachSession(d);
11689 if (!proof || !proof->IsValid()) {
11690 if (locid)
11691 ::Error(pn, "new session could not be attached");
11692 SafeDelete(proof);
11693 }
11694 }
11695 }
11696
11697 // start the PROOF session
11698 if (!proof) {
11699 proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
11700 if (!proof || !proof->IsValid()) {
11701 ::Error(pn, "new session could not be created");
11702 SafeDelete(proof);
11703 }
11704 }
11705 }
11706 return proof;
11707 }
11708}
11709
11710////////////////////////////////////////////////////////////////////////////////
11711/// Get instance of the effective manager for 'url'
11712/// Return 0 on failure.
11713
11714TProofMgr *TProof::Mgr(const char *url)
11715{
11716 if (!url)
11717 return (TProofMgr *)0;
11718
11719 // Attach or create the relevant instance
11720 return TProofMgr::Create(url);
11721}
11722
11723////////////////////////////////////////////////////////////////////////////////
11724/// Wrapper around TProofMgr::Reset(...).
11725
11726void TProof::Reset(const char *url, Bool_t hard)
11727{
11728 if (url) {
11729 TProofMgr *mgr = TProof::Mgr(url);
11730 if (mgr && mgr->IsValid())
11731 mgr->Reset(hard);
11732 else
11733 ::Error("TProof::Reset",
11734 "unable to initialize a valid manager instance");
11735 }
11736}
11737
11738////////////////////////////////////////////////////////////////////////////////
11739/// Get environemnt variables.
11740
11742{
11743 return fgProofEnvList;
11744}
11745
11746////////////////////////////////////////////////////////////////////////////////
11747/// Add an variable to the list of environment variables passed to proofserv
11748/// on the master and slaves
11749
11750void TProof::AddEnvVar(const char *name, const char *value)
11751{
11752 if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
11753
11754 if (fgProofEnvList == 0) {
11755 // initialize the list if needed
11756 fgProofEnvList = new TList;
11758 } else {
11759 // replace old entries with the same name
11761 if (o != 0) {
11763 }
11764 }
11765 fgProofEnvList->Add(new TNamed(name, value));
11766}
11767
11768////////////////////////////////////////////////////////////////////////////////
11769/// Remove an variable from the list of environment variables passed to proofserv
11770/// on the master and slaves
11771
11772void TProof::DelEnvVar(const char *name)
11773{
11774 if (fgProofEnvList == 0) return;
11775
11777 if (o != 0) {
11779 }
11780}
11781
11782////////////////////////////////////////////////////////////////////////////////
11783/// Clear the list of environment variables passed to proofserv
11784/// on the master and slaves
11785
11787{
11788 if (fgProofEnvList == 0) return;
11789
11791}
11792
11793////////////////////////////////////////////////////////////////////////////////
11794/// Save information about the worker set in the file .workers in the working
11795/// dir. Called each time there is a change in the worker setup, e.g. by
11796/// TProof::MarkBad().
11797
11799{
11800 // We must be masters
11802 return;
11803
11804 // We must have a server defined
11805 if (!gProofServ) {
11806 Error("SaveWorkerInfo","gProofServ undefined");
11807 return;
11808 }
11809
11810 // The relevant lists must be defined
11811 if (!fSlaves && !fBadSlaves) {
11812 Warning("SaveWorkerInfo","all relevant worker lists is undefined");
11813 return;
11814 }
11815
11816 // Create or truncate the file first
11817 TString fnwrk = gSystem->GetDirName(gProofServ->GetSessionDir())+"/.workers";
11818 FILE *fwrk = fopen(fnwrk.Data(),"w");
11819 if (!fwrk) {
11820 Error("SaveWorkerInfo",
11821 "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
11822 return;
11823 }
11824
11825 // Do we need to register an additional line for another log?
11826 TString addlogext;
11827 TString addLogTag;
11828 if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
11829 addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
11830 TPMERegexp reLogTag("^__(.*)__\\.log"); // $
11831 if (reLogTag.Match(addlogext) == 2) {
11832 addLogTag = reLogTag[1];
11833 }
11834 else {
11835 addLogTag = "+++";
11836 }
11837 if (gDebug > 0)
11838 Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
11839 }
11840
11841 // Used to eliminate datetime and PID from workdir to obtain log file name
11842 TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
11843
11844 // Loop over the list of workers (active is any worker not flagged as bad)
11845 TIter nxa(fSlaves);
11846 TSlave *wrk = 0;
11847 TString logfile;
11848 while ((wrk = (TSlave *) nxa())) {
11849 Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
11850 logfile = wrk->GetWorkDir();
11851 if (re.Match(logfile) == 2) logfile = re[1];
11852 else continue; // invalid (should not happen)
11853 // Write out record for this worker
11854 fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
11855 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11856 wrk->GetOrdinal(), logfile.Data());
11857 // Additional line, if required
11858 if (addlogext.Length() > 0) {
11859 fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
11860 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11861 wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
11862 }
11863
11864 }
11865
11866 // Loop also over the list of bad workers (if they failed to startup they are not in
11867 // the overall list
11868 TIter nxb(fBadSlaves);
11869 while ((wrk = (TSlave *) nxb())) {
11870 logfile = wrk->GetWorkDir();
11871 if (re.Match(logfile) == 2) logfile = re[1];
11872 else continue; // invalid (should not happen)
11873 if (!fSlaves->FindObject(wrk)) {
11874 // Write out record for this worker
11875 fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
11876 wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
11877 wrk->GetOrdinal(), logfile.Data());
11878 }
11879 }
11880
11881 // Eventually loop over the list of gracefully terminated workers: we'll get
11882 // logfiles from those workers as well. They'll be shown with a special
11883 // status of "2"
11885 TSlaveInfo *sli;
11886 while (( sli = (TSlaveInfo *)nxt() )) {
11887 logfile = sli->GetDataDir();
11888 if (re.Match(logfile) == 2) logfile = re[1];
11889 else continue; // invalid (should not happen)
11890 fprintf(fwrk, "%s 2 %s %s.log\n",
11891 sli->GetName(), sli->GetOrdinal(), logfile.Data());
11892 // Additional line, if required
11893 if (addlogext.Length() > 0) {
11894 fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
11895 sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
11896 logfile.Data(), addlogext.Data());
11897 }
11898 }
11899
11900 // Close file
11901 fclose(fwrk);
11902
11903 // We are done
11904 return;
11905}
11906
11907////////////////////////////////////////////////////////////////////////////////
11908/// Get the value from the specified parameter from the specified collection.
11909/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11910/// or value type does not match), 0 otherwise.
11911
11913{
11914 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11915 if (obj) {
11916 TNamed *p = dynamic_cast<TNamed*>(obj);
11917 if (p) {
11918 value = p->GetTitle();
11919 return 0;
11920 }
11921 }
11922 return -1;
11923
11924}
11925
11926////////////////////////////////////////////////////////////////////////////////
11927/// Get the value from the specified parameter from the specified collection.
11928/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11929/// or value type does not match), 0 otherwise.
11930
11932{
11933 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11934 if (obj) {
11935 TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
11936 if (p) {
11937 value = p->GetVal();
11938 return 0;
11939 }
11940 }
11941 return -1;
11942}
11943
11944////////////////////////////////////////////////////////////////////////////////
11945/// Get the value from the specified parameter from the specified collection.
11946/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11947/// or value type does not match), 0 otherwise.
11948
11950{
11951 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11952 if (obj) {
11953 TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
11954 if (p) {
11955 value = p->GetVal();
11956 return 0;
11957 }
11958 }
11959 return -1;
11960}
11961
11962////////////////////////////////////////////////////////////////////////////////
11963/// Get the value from the specified parameter from the specified collection.
11964/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11965/// or value type does not match), 0 otherwise.
11966
11968{
11969 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11970 if (obj) {
11971 TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
11972 if (p) {
11973 value = p->GetVal();
11974 return 0;
11975 }
11976 }
11977 return -1;
11978}
11979
11980////////////////////////////////////////////////////////////////////////////////
11981/// Get the value from the specified parameter from the specified collection.
11982/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11983/// or value type does not match), 0 otherwise.
11984
11986{
11987 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11988 if (obj) {
11989 TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
11990 if (p) {
11991 value = p->GetVal();
11992 return 0;
11993 }
11994 }
11995 return -1;
11996}
11997
11998////////////////////////////////////////////////////////////////////////////////
11999/// Make sure that dataset is in the form to be processed. This may mean
12000/// retrieving the relevant info from the dataset manager or from the
12001/// attached input list.
12002/// Returns 0 on success, -1 on error
12003
12005 TDataSetManager *mgr, TString &emsg)
12006{
12007 emsg = "";
12008
12009 // We must have something to process
12010 if (!dset || !input || !mgr) {
12011 emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
12012 return -1;
12013 }
12014
12015 TList *datasets = new TList;
12016 TFileCollection *dataset = 0;
12017 TString lookupopt;
12018 TString dsname(dset->GetName());
12019
12020 // First extract the "entry list" part on the global name, if any
12021 TString dsns(dsname), enlname;
12022 Ssiz_t eli = dsns.Index("?enl=");
12023 if (eli != kNPOS) {
12024 enlname = dsns(eli + strlen("?enl="), dsns.Length());
12025 dsns.Remove(eli, dsns.Length()-eli);
12026 }
12027
12028 // The dataset maybe in the form of a TFileCollection in the input list
12029 if (dsname.BeginsWith("TFileCollection:")) {
12030 // Isolate the real name
12031 dsname.ReplaceAll("TFileCollection:", "");
12032 // Get the object
12033 dataset = (TFileCollection *) input->FindObject(dsname);
12034 if (!dataset) {
12035 emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12036 return -1;
12037 }
12038 // Remove from everywhere
12039 input->RecursiveRemove(dataset);
12040 // Add it to the local list
12041 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12042 // Make sure we lookup everything (unless the client or the administrator
12043 // required something else)
12044 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12045 lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12046 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12047 }
12048 }
12049
12050 // This is the name we parse for additional specifications, such directory
12051 // and object name; for multiple datasets we assume that the directory and
12052 // and object name are the same for all datasets
12053 TString dsnparse;
12054 // The received message included an empty dataset, with only the name
12055 // defined: assume that a dataset, stored on the PROOF master by that
12056 // name, should be processed.
12057 if (!dataset) {
12058
12059 TFileCollection *fc = nullptr;
12060
12061 // Check if the entry list and dataset name are valid. If they have spaces,
12062 // commas, or pipes, they are not considered as valid and we revert to the
12063 // "multiple datasets" case
12064 TRegexp rg("[, |]");
12065 Bool_t validEnl = (enlname.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12066 Bool_t validSdsn = (dsns.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12067
12068 if (validEnl && validSdsn && (( fc = mgr->GetDataSet(dsns) ))) {
12069
12070 //
12071 // String corresponds to ONE dataset only
12072 //
12073
12074 TIter nxfi(fc->GetList());
12075 TFileInfo *fi;
12076 while (( fi = (TFileInfo *)nxfi() ))
12077 fi->SetTitle(dsns.Data());
12078 dataset = fc;
12079 dsnparse = dsns; // without entry list
12080
12081 // Adds the entry list (or empty string if not specified)
12082 datasets->Add( new TPair(dataset, new TObjString( enlname.Data() )) );
12083
12084 } else {
12085
12086 //
12087 // String does NOT correspond to one dataset: check if many datasets
12088 // were specified instead
12089 //
12090
12091 dsns = dsname.Data();
12092 TString dsn1;
12093 Int_t from1 = 0;
12094 while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12095 TString dsn2;
12096 Int_t from2 = 0;
12097 while (dsn1.Tokenize(dsn2, from2, "|")) {
12098 enlname = "";
12099 Int_t ienl = dsn2.Index("?enl=");
12100 if (ienl != kNPOS) {
12101 enlname = dsn2(ienl + 5, dsn2.Length());
12102 dsn2.Remove(ienl);
12103 }
12104 if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12105 // Save dataset name in TFileInfo's title to use it in TDset
12106 TIter nxfi(fc->GetList());
12107 TFileInfo *fi;
12108 while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12109 dsnparse = dsn2;
12110 if (!dataset) {
12111 // This is our dataset
12112 dataset = fc;
12113 } else {
12114 // Add it to the dataset
12115 dataset->Add(fc);
12116 SafeDelete(fc);
12117 }
12118 }
12119 }
12120 // The dataset name(s) in the first element
12121 if (dataset) {
12122 if (dataset->GetList()->First())
12123 ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12124 // Add it to the local list
12125 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12126 }
12127 // Reset the pointer
12128 dataset = 0;
12129 }
12130
12131 }
12132
12133 //
12134 // At this point the dataset(s) to be processed, if any, are found in the
12135 // "datasets" variable
12136 //
12137
12138 if (!datasets || datasets->GetSize() <= 0) {
12139 emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12140 return -1;
12141 } else {
12142 // Make 'dataset' to point to the first one in the list
12143 if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12144 emsg.Form("dataset pointer is null: corruption? - aborting");
12145 return -1;
12146 }
12147 }
12148 // Apply the lookup option requested by the client or the administartor
12149 // (by default we trust the information in the dataset)
12150 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12151 lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12152 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12153 }
12154 } else {
12155 // We were given a named, single, TFileCollection
12156 dsnparse = dsname;
12157 }
12158
12159 // Logic for the subdir/obj names: try first to see if the dataset name contains
12160 // some info; if not check the settings in the TDSet object itself; if still empty
12161 // check the default tree name / path in the TFileCollection object; if still empty
12162 // use the default as the flow will determine
12163 TString dsTree;
12164 // Get the [subdir/]tree, if any
12165 mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12166 if (dsTree.IsNull()) {
12167 // Use what we have in the original dataset; we need this to locate the
12168 // meta data information
12169 dsTree += dset->GetDirectory();
12170 dsTree += dset->GetObjName();
12171 }
12172 if (!dsTree.IsNull() && dsTree != "/") {
12173 TString tree(dsTree);
12174 Int_t idx = tree.Index("/");
12175 if (idx != kNPOS) {
12176 TString dir = tree(0, idx+1);
12177 tree.Remove(0, idx);
12178 dset->SetDirectory(dir);
12179 }
12180 dset->SetObjName(tree);
12181 } else {
12182 // Use the default obj name from the TFileCollection
12183 dsTree = dataset->GetDefaultTreeName();
12184 }
12185
12186 // Pass dataset server mapping instructions, if any
12188 TList *srvmapslist = srvmapsref;
12189 TString srvmaps;
12190 if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12191 srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12192 if (gProofServ) {
12193 TString msg;
12194 if (srvmapsref && !srvmapslist) {
12195 msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12196 } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12197 msg.Form("+++ Info: dataset server mapping(s) modified by user");
12198 } else if (!srvmapsref && srvmapslist) {
12199 msg.Form("+++ Info: dataset server mapping(s) added by user");
12200 }
12202 }
12203 }
12204
12205 // Flag multi-datasets
12206 if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12207 // Loop over the list of datasets
12208 TList *listOfMissingFiles = new TList;
12209 TEntryList *entrylist = 0;
12210 TPair *pair = 0;
12211 TIter nxds(datasets);
12212 while ((pair = (TPair *) nxds())) {
12213 // File Collection
12214 dataset = (TFileCollection *) pair->Key();
12215 // Entry list, if any
12216 TEntryList *enl = 0;
12217 TObjString *os = (TObjString *) pair->Value();
12218 if (strlen(os->GetName())) {
12219 if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12220 if (gProofServ)
12222 " entry list %s not found", os->GetName()));
12223 }
12224 if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12225 if (gProofServ)
12227 " no sub-lists in entry-list!"));
12228 }
12229 }
12230 TList *missingFiles = new TList;
12231 TSeqCollection* files = dataset->GetList();
12232 if (gDebug > 0) files->Print();
12233 Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12234 if (dset->TestBit(TDSet::kMultiDSet)) {
12235 TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12236 ds->SetSrvMaps(srvmapslist);
12237 if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12238 emsg.Form("error integrating dataset %s", dataset->GetName());
12239 continue;
12240 }
12241 // Add the TDSet object to the multi-dataset
12242 dset->Add(ds);
12243 // Add entry list if any
12244 if (enl) ds->SetEntryList(enl);
12245 } else {
12246 dset->SetSrvMaps(srvmapslist);
12247 if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12248 emsg.Form("error integrating dataset %s", dataset->GetName());
12249 continue;
12250 }
12251 if (enl) entrylist = enl;
12252 }
12253 if (missingFiles) {
12254 // The missing files objects have to be removed from the dataset
12255 // before delete.
12256 TIter next(missingFiles);
12257 TObject *file;
12258 while ((file = next())) {
12259 dataset->GetList()->Remove(file);
12260 listOfMissingFiles->Add(file);
12261 }
12262 missingFiles->SetOwner(kFALSE);
12263 missingFiles->Clear();
12264 }
12265 SafeDelete(missingFiles);
12266 }
12267 // Cleanup; we need to do this because pairs do no delete their content
12268 nxds.Reset();
12269 while ((pair = (TPair *) nxds())) {
12270 if (pair->Key()) delete pair->Key();
12271 if (pair->Value()) delete pair->Value();
12272 }
12273 datasets->SetOwner(kTRUE);
12274 SafeDelete(datasets);
12275
12276 // Cleanup the server mapping list, if created by the user
12277 if (srvmapslist && srvmapslist != srvmapsref) {
12278 srvmapslist->SetOwner(kTRUE);
12279 SafeDelete(srvmapslist);
12280 }
12281
12282 // Set the global entrylist, if required
12283 if (entrylist) dset->SetEntryList(entrylist);
12284
12285 // Make sure it will be sent back merged with other similar lists created
12286 // during processing; this list will be transferred by the player to the
12287 // output list, once the latter has been created (see TProofPlayerRemote::Process)
12288 if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12289 listOfMissingFiles->SetName("MissingFiles");
12290 input->Add(listOfMissingFiles);
12291 }
12292
12293 // Done
12294 return 0;
12295}
12296
12297////////////////////////////////////////////////////////////////////////////////
12298/// Save input data file from 'cachedir' into the sandbox or create a the file
12299/// with input data objects
12300
12301Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12302{
12303 TList *input = 0;
12304
12305 // We must have got something to process
12306 if (!qr || !(input = qr->GetInputList()) ||
12307 !cachedir || strlen(cachedir) <= 0) return 0;
12308
12309 // There must be some input data or input data file
12310 TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12311 TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12312 if (!data && !inputdata) return 0;
12313 // Default dstination filename
12314 if (!data)
12315 input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12316
12317 TString dstname(data->GetTitle()), srcname;
12318 Bool_t fromcache = kFALSE;
12319 if (dstname.BeginsWith("cache:")) {
12320 fromcache = kTRUE;
12321 dstname.ReplaceAll("cache:", "");
12322 srcname.Form("%s/%s", cachedir, dstname.Data());
12323 if (gSystem->AccessPathName(srcname)) {
12324 emsg.Form("input data file not found in cache (%s)", srcname.Data());
12325 return -1;
12326 }
12327 }
12328
12329 // If from cache, just move the cache file
12330 if (fromcache) {
12331 if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12332 emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12333 return -1;
12334 }
12335 } else {
12336 // Create the file
12337 if (inputdata && inputdata->GetSize() > 0) {
12338 TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12339 if (f) {
12340 f->cd();
12341 inputdata->Write();
12342 f->Close();
12343 delete f;
12344 } else {
12345 emsg.Form("could not create %s", dstname.Data());
12346 return -1;
12347 }
12348 } else {
12349 emsg.Form("no input data!");
12350 return -1;
12351 }
12352 }
12353 ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12354
12355 // Save the file name and clean up the data list
12356 data->SetTitle(dstname);
12357 if (inputdata) {
12358 input->Remove(inputdata);
12359 inputdata->SetOwner();
12360 delete inputdata;
12361 }
12362
12363 // Done
12364 return 0;
12365}
12366
12367////////////////////////////////////////////////////////////////////////////////
12368/// Send the input data file to the workers
12369
12371{
12372 TList *input = 0;
12373
12374 // We must have got something to process
12375 if (!qr || !(input = qr->GetInputList())) return 0;
12376
12377 // There must be some input data or input data file
12378 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12379 if (!inputdata) return 0;
12380
12381 TString fname(inputdata->GetTitle());
12382 if (gSystem->AccessPathName(fname)) {
12383 emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12384 return -1;
12385 }
12386
12387 // PROOF session must available
12388 if (!p || !p->IsValid()) {
12389 emsg.Form("TProof object undefined or invalid: protocol error!");
12390 return -1;
12391 }
12392
12393 // Send to unique workers and submasters
12394 p->BroadcastFile(fname, TProof::kBinary, "cache");
12395
12396 // Done
12397 return 0;
12398}
12399
12400////////////////////////////////////////////////////////////////////////////////
12401/// Get the input data from the file defined in the input list
12402
12403Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12404{
12405 // We must have got something to process
12406 if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12407
12408 // There must be some input data or input data file
12409 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12410 if (!inputdata) return 0;
12411
12412 TString fname;
12413 fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12414 if (gSystem->AccessPathName(fname)) {
12415 emsg.Form("input data file not found in cache (%s)", fname.Data());
12416 return -1;
12417 }
12418
12419 // List of added objects (for proper cleaning ...)
12420 TList *added = new TList;
12421 added->SetName("PROOF_InputObjsFromFile");
12422 // Read the input data into the input list
12423 TFile *f = TFile::Open(fname.Data());
12424 if (f) {
12425 TList *keys = (TList *) f->GetListOfKeys();
12426 if (!keys) {
12427 emsg.Form("could not get list of object keys from file");
12428 return -1;
12429 }
12430 TIter nxk(keys);
12431 TKey *k = 0;
12432 while ((k = (TKey *)nxk())) {
12433 TObject *o = f->Get(k->GetName());
12434 if (o) {
12435 input->Add(o);
12436 added->Add(o);
12437 }
12438 }
12439 // Add the file as last one
12440 if (added->GetSize() > 0) {
12441 added->Add(f);
12442 input->Add(added);
12443 } else {
12444 // Cleanup the file now
12445 f->Close();
12446 delete f;
12447 }
12448 } else {
12449 emsg.Form("could not open %s", fname.Data());
12450 return -1;
12451 }
12452
12453 // Done
12454 return 0;
12455}
12456
12457////////////////////////////////////////////////////////////////////////////////
12458/// Start the log viewer window usign the plugin manager
12459
12460void TProof::LogViewer(const char *url, Int_t idx)
12461{
12462 if (!gROOT->IsBatch()) {
12463 // Get the handler, if not yet done
12464 if (!fgLogViewer) {
12465 if ((fgLogViewer =
12466 gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
12467 if (fgLogViewer->LoadPlugin() == -1) {
12468 fgLogViewer = 0;
12469 ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
12470 return;
12471 }
12472 }
12473 }
12474 if (fgLogViewer) {
12475 // Execute the plug-in
12476 TString u = (url && strlen(url) <= 0) ? "lite" : url;
12477 fgLogViewer->ExecPlugin(2, u.Data(), idx);
12478 }
12479 } else {
12480 if (url && strlen(url) > 0) {
12481 ::Info("TProof::LogViewer",
12482 "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
12483 } else if (url && strlen(url) <= 0) {
12484 ::Info("TProof::LogViewer",
12485 "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
12486 } else {
12487 ::Info("TProof::LogViewer",
12488 "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
12489 }
12490 }
12491 // Done
12492 return;
12493}
12494
12495////////////////////////////////////////////////////////////////////////////////
12496/// Enable/Disable the graphic progress dialog.
12497/// By default the dialog is enabled
12498
12500{
12501 if (on)
12503 else
12505}
12506
12507////////////////////////////////////////////////////////////////////////////////
12508/// Show information about missing files during query described by 'qr' or the
12509/// last query if qr is null (default).
12510/// A short summary is printed in the end.
12511
12513{
12514 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12515 if (!xqr) {
12516 Warning("ShowMissingFiles", "no (last) query found: do nothing");
12517 return;
12518 }
12519
12520 // Get the list, if any
12521 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12522 if (!missing) {
12523 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12524 return;
12525 }
12526
12527 Int_t nmf = 0, ncf = 0;
12528 Long64_t msz = 0, mszzip = 0, mev = 0;
12529 // Scan the list
12530 TFileInfo *fi = 0;
12531 TIter nxf(missing);
12532 while ((fi = (TFileInfo *) nxf())) {
12533 char status = 'M';
12534 if (fi->TestBit(TFileInfo::kCorrupted)) {
12535 ncf++;
12536 status = 'C';
12537 } else {
12538 nmf++;
12539 }
12540 TFileInfoMeta *im = fi->GetMetaData();
12541 if (im) {
12542 if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
12543 if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
12544 mev += im->GetEntries();
12545 Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
12546 } else {
12547 Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
12548 }
12549 }
12550
12551 // Final notification
12552 if (msz <= 0) msz = -1;
12553 if (mszzip <= 0) mszzip = -1;
12554 Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
12555 if (msz > 0. || mszzip > 0.) {
12556 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12557 " about %.2f%% of the total (%lld bytes, %lld zipped)",
12558 nmf, ncf, mev, xf * 100., msz, mszzip);
12559 } else {
12560 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12561 " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
12562 }
12563}
12564
12565////////////////////////////////////////////////////////////////////////////////
12566/// Get a TFileCollection with the files missing in the query described by 'qr'
12567/// or the last query if qr is null (default).
12568/// Return a null pointer if none were found, for whatever reason.
12569/// The caller is responsible for the returned object.
12570
12572{
12573 TFileCollection *fc = 0;
12574
12575 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12576 if (!xqr) {
12577 Warning("GetMissingFiles", "no (last) query found: do nothing");
12578 return fc;
12579 }
12580
12581 // Get the list, if any
12582 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12583 if (!missing) {
12584 if (gDebug > 0)
12585 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12586 return fc;
12587 }
12588
12589 // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
12590 TString fcname("unknown");
12591 TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
12592 if (ds) {
12593 fcname.Form("%s.m0", ds->GetName());
12594 Int_t j = 1;
12595 while (gDirectory->FindObject(fcname) && j < 1000)
12596 fcname.Form("%s.m%d", ds->GetName(), j++);
12597 }
12598 fc = new TFileCollection(fcname, "Missing Files");
12599 if (ds) fc->SetDefaultTreeName(ds->GetObjName());
12600 // Scan the list
12601 TFileInfo *fi = 0;
12602 TIter nxf(missing);
12603 while ((fi = (TFileInfo *) nxf())) {
12604 fc->Add((TFileInfo *) fi->Clone());
12605 }
12606 fc->Update();
12607 // Done
12608 return fc;
12609}
12610
12611////////////////////////////////////////////////////////////////////////////////
12612/// Enable/Disable saving of the performance tree
12613
12614void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
12615{
12616 if (pf && strlen(pf) > 0) {
12617 fPerfTree = pf;
12618 SetParameter("PROOF_StatsHist", "");
12619 SetParameter("PROOF_StatsTrace", "");
12620 if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
12621 Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
12622 } else {
12623 fPerfTree = "";
12624 DeleteParameters("PROOF_StatsHist");
12625 DeleteParameters("PROOF_StatsTrace");
12626 DeleteParameters("PROOF_SlaveStatsTrace");
12627 Info("SetPerfTree", "saving of the performance tree disabled");
12628 }
12629}
12630
12631////////////////////////////////////////////////////////////////////////////////
12632/// Save performance information from TPerfStats to file 'pf'.
12633/// If 'ref' is defined, do it for query 'ref'.
12634/// Return 0 on sucecss, -1 in case of any error
12635
12636Int_t TProof::SavePerfTree(const char *pf, const char *ref)
12637{
12638 if (!IsValid()) {
12639 Error("SafePerfTree", "this TProof instance is invalid!");
12640 return -1;
12641 }
12642
12643 TList *outls = GetOutputList();
12644 TString sref;
12645 if (ref && strlen(ref) > 0) {
12646 if (!fPlayer) {
12647 Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
12648 return -1;
12649 }
12651 if (!qr) {
12652 Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
12653 return -1;
12654 }
12655 outls = qr->GetOutputList();
12656 sref.Form(" for requested query '%s'", ref);
12657 }
12658 if (!outls || (outls && outls->GetSize() <= 0)) {
12659 Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
12660 return -1;
12661 }
12662
12663 TString fn = fPerfTree;
12664 if (pf && strlen(pf)) fn = pf;
12665 if (fn.IsNull()) fn = "perftree.root";
12666
12667 TFile f(fn, "RECREATE");
12668 if (f.IsZombie()) {
12669 Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
12670 } else {
12671 f.cd();
12672 TIter nxo(outls);
12673 TObject* obj = 0;
12674 while ((obj = nxo())) {
12675 TString objname(obj->GetName());
12676 if (objname.BeginsWith("PROOF_")) {
12677 // Must list the objects since other PROOF_ objects exist
12678 // besides timing objects
12679 if (objname == "PROOF_PerfStats" ||
12680 objname == "PROOF_PacketsHist" ||
12681 objname == "PROOF_EventsHist" ||
12682 objname == "PROOF_NodeHist" ||
12683 objname == "PROOF_LatencyHist" ||
12684 objname == "PROOF_ProcTimeHist" ||
12685 objname == "PROOF_CpuTimeHist")
12686 obj->Write();
12687 }
12688 }
12689 f.Close();
12690 }
12691 Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
12692
12693 // Done
12694 return 0;
12695}
@ kPROOF_VALIDATE_DSET
@ kPROOF_PING
@ kMESS_OK
@ kPROOF_DATA_READY
@ kPROOF_GETSTATS
@ kPROOF_GETTREEHEADER
@ kPROOF_PROGRESS
@ kPROOF_QUERYLIST
@ kPROOF_CHECKFILE
@ kPROOF_GOASYNC
@ kPROOF_PARALLEL
@ kPROOF_LOGLEVEL
@ kMESS_NOTOK
@ kPROOF_SENDOUTPUT
@ kPROOF_SESSIONTAG
@ kPROOF_RETRIEVE
@ kPROOF_AUTOBIN
@ kPROOF_TOUCH
@ kPROOF_GETOBJECT
@ kMESS_OBJECT
@ kPROOF_STOPPROCESS
@ kPROOF_VERSARCHCOMP
@ kPROOF_LOGFILE
@ kPROOF_REMOVE
@ kPROOF_FATAL
@ kPROOF_OUTPUTOBJECT
@ kPROOF_REALTIMELOG
@ kPROOF_SUBMERGER
@ kPROOF_QUERYSUBMITTED
@ kPROOF_ARCHIVE
@ kPROOF_SENDFILE
@ kPROOF_ECHO
@ kPROOF_GETPACKET
@ kPROOF_WORKERLISTS
@ kPROOF_OUTPUTLIST
@ kPROOF_RESET
@ kPROOF_GETPARALLEL
@ kPROOF_PRINT
@ kPROOF_FEEDBACK
@ kPROOF_SERVERSTARTED
@ kPROOF_DATASET_STATUS
@ kPROOF_LIB_INC_PATH
@ kPROOF_CACHE
@ kPROOF_MESSAGE
@ kPROOF_LOGDONE
@ kPROOF_DATASETS
@ kMESS_CINT
@ kPROOF_ENDINIT
@ kPROOF_PACKAGE_LIST
@ kPROOF_SETIDLE
@ kPROOF_STARTPROCESS
@ kPROOF_GETSLAVEINFO
@ kPROOF_MAXQUERIES
@ kPROOF_CLEANUPSESSION
@ kPROOF_STOP
@ kPROOF_GROUPVIEW
ROOT::R::TRInterface & r
Definition Object.C:4
#define SafeDelete(p)
Definition RConfig.hxx:547
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
static void retrieve(const gsl_integration_workspace *workspace, double *a, double *b, double *r, double *e)
const Ssiz_t kNPOS
Definition RtypesCore.h:115
int Int_t
Definition RtypesCore.h:45
char Char_t
Definition RtypesCore.h:37
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:92
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:73
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:91
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
R__EXTERN TApplication * gApplication
const Bool_t kIterBackward
Definition TCollection.h:41
#define gDirectory
Definition TDirectory.h:290
R__EXTERN TEnv * gEnv
Definition TEnv.h:171
#define R__ASSERT(e)
Definition TError.h:120
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
static unsigned int total
XFontStruct * id
Definition TGX11.cxx:109
char name[80]
Definition TGX11.cxx:110
int type
Definition TGX11.cxx:121
float xmin
int nentries
float ymin
float xmax
float ymax
#define gInterpreter
const Bool_t kSortDescending
Definition TList.h: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:341
TProof * gProof
Definition TProof.cxx:102
const char *const kPROOF_WorkerIdleTO
Definition TProof.h:135
const char *const kPROOF_PackDir
Definition TProof.h:126
const char *const kPROOF_ConfFile
Definition TProof.h:122
const char *const kPROOF_WorkDir
Definition TProof.h:124
const Long64_t kPROOF_DynWrkPollInt_s
Definition TProof.h:138
const char *const kPROOF_InputDataFile
Definition TProof.h:136
R__EXTERN TProof * gProof
Definition TProof.h:1077
const char *const kPROOF_ConfDir
Definition TProof.h:123
const Int_t kPROOF_Protocol
Definition TProof.h:120
const char *const kPROOF_TerminateWorker
Definition TProof.h:134
Int_t gDebug
Definition TROOT.cxx:590
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:406
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
@ kFileExists
Definition TSystem.h:44
@ kReadPermission
Definition TSystem.h:47
@ kWritePermission
Definition TSystem.h:46
Bool_t R_ISLNK(Int_t mode)
Definition TSystem.h:119
Bool_t R_ISDIR(Int_t mode)
Definition TSystem.h:115
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
#define R__LOCKGUARD(mutex)
#define O_BINARY
Definition civetweb.c:799
#define snprintf
Definition civetweb.c:1540
static struct mg_connection * fc(struct mg_context *ctx)
Definition civetweb.c:3728
TSignalHandler * GetSignalHandler() const
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
TObject * ReadObject(const TClass *cl) override
Read object from I/O buffer.
void WriteString(const char *s) override
Write string to I/O buffer.
char * ReadString(char *s, Int_t max) override
Read string from I/O buffer.
void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
Int_t BufferSize() const
Definition TBuffer.h:98
Int_t Length() const
Definition TBuffer.h:100
A chain is a collection of files containing TTree objects.
Definition TChain.h:33
Collection abstract base class.
Definition TCollection.h: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)
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
Bool_t Contains(const char *name) const
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
Manages an element of a TDSet.
Definition TDSet.h:66
const char * GetObjName() const
Definition TDSet.h:120
Long64_t GetNum() const
Definition TDSet.h:114
const char * GetDirectory() const
Return directory where to look for object.
Definition TDSet.cxx:253
const char * GetMsd() const
Definition TDSet.h:117
const char * GetFileName() const
Definition TDSet.h:111
Long64_t GetFirst() const
Definition TDSet.h:112
This class implements a data set to be used for PROOF processing.
Definition TDSet.h:153
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition TDSet.cxx:1894
virtual Bool_t Add(const char *file, const char *objname=0, const char *dir=0, Long64_t first=0, Long64_t num=-1, const char *msd=0)
Add file to list of files to be analyzed.
Definition TDSet.cxx:1052
Bool_t ElementsValid()
Check if all elements are valid.
Definition TDSet.cxx:1556
void SetSrvMaps(TList *srvmaps=0)
Set (or unset) the list for mapping servers coordinate for files.
Definition TDSet.cxx:1172
void Validate()
Validate the TDSet by opening files.
Definition TDSet.cxx:1590
const char * GetType() const
Definition TDSet.h:228
TList * GetListOfElements() const
Definition TDSet.h:231
void SetDirectory(const char *dir)
Set/change directory.
Definition TDSet.cxx:1041
void SetObjName(const char *objname)
Set/change object name.
Definition TDSet.cxx:1026
const char * GetDirectory() const
Definition TDSet.h:230
const char * GetObjName() const
Definition TDSet.h:229
@ kEmpty
Definition TDSet.h:159
@ kMultiDSet
Definition TDSet.h:162
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
static TList * GetDataSetSrvMaps()
Static getter for server mapping list.
static TList * ParseDataSetSrvMaps(const TString &srvmaps)
Create a server mapping list from the content of 'srvmaps' Return the list (owned by the caller) or 0...
Bool_t ParseUri(const char *uri, TString *dsGroup=0, TString *dsUser=0, TString *dsName=0, TString *dsTree=0, Bool_t onlyCurrent=kFALSE, Bool_t wildcards=kFALSE)
Parses a (relative) URI that describes a DataSet on the cluster.
Bool_t cd(const char *path=nullptr) override
Change current directory to "this" directory.
Utility class to draw objects in the feedback list during queries.
A List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
virtual TList * GetLists() const
Definition TEntryList.h: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=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:736
Definition TFTP.h:34
void cd(const char *dir) const
Definition TFTP.h:113
void put(const char *file, const char *remoteName=0)
Definition TFTP.h:111
Class that contains a list of TFileInfo's and accumulated meta data information about its entries.
THashList * GetList()
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
const char * GetDefaultTreeName() const
Returns the tree set with SetDefaultTreeName if set Returns the name of the first tree in the meta da...
Int_t Add(TFileInfo *info)
Add TFileInfo to the collection.
virtual void Remove()
Remove file event handler from system file handler list.
virtual void Add()
Add file event handler to system file handler list.
Long64_t GetZipBytes() const
Definition TFileInfo.h:145
Long64_t GetTotBytes() const
Definition TFileInfo.h:144
Long64_t GetEntries() const
Definition TFileInfo.h:140
Class describing a generic file including meta information.
Definition TFileInfo.h:39
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
TUrl * GetFirstUrl() const
Definition TFileInfo.h:72
Int_t GetNUrls() const
Definition TFileInfo.h:75
void ResetUrl()
Definition TFileInfo.h:69
TUrl * GetCurrentUrl() const
Return the current url.
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition TFile.cxx:1385
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=nullptr)
Resolve the file type as a function of the protocol field in 'name'.
Definition TFile.cxx:4711
EFileType
File type.
Definition TFile.h:194
@ kWeb
Definition TFile.h:194
@ kNet
Definition TFile.h:194
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:4894
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:3997
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:879
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * FindObject(const char *name) const
Find object using its name.
TObject * Remove(TObject *obj)
Remove object from the list.
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Int_t GetPort() const
const char * GetHostName() const
void Reset()
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual const char * GetClassName() const
Definition TKey.h:76
Iterator of linked list.
Definition TList.h: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:330
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition TList.cxx:822
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
virtual TObjLink * FirstLink() const
Definition TList.h: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:357
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition TList.cxx:693
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition TList.cxx:250
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:764
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition TList.cxx:402
This code implements the MD5 message-digest algorithm.
Definition TMD5.h:44
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition TMD5.cxx:474
Class supporting a collection of lines with C++ code.
Definition TMacro.h:31
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition TMacro.cxx:141
TList * GetListOfLines() const
Definition TMacro.h:51
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition TMacro.cxx:303
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition TMap.h:40
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection).
Definition TMap.cxx:54
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition TMap.cxx:236
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition TProof.cxx:325
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job.
Definition TProof.cxx:317
TSlave * GetMerger()
Definition TProof.h:274
virtual ~TMergerInfo()
Destructor.
Definition TProof.cxx:281
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:292
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition TProof.cxx:303
void Deactivate()
Definition TProof.h:287
Int_t fMergedWorkers
Definition TProof.h:256
TList * GetWorkers()
Definition TProof.h:272
Int_t GetPort()
Definition TProof.h:275
void AddMergedObjects(Int_t objects)
Definition TProof.h:282
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition TMessage.cxx:116
UInt_t What() const
Definition TMessage.h:75
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriori In case you OR "what" with kMESS_ACK,...
Definition TMessage.cxx:222
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition TMonitor.cxx:241
virtual void ActivateAll()
Activate all de-activated sockets.
Definition TMonitor.cxx:268
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition TMonitor.cxx:322
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition TMonitor.cxx:250
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition TMonitor.cxx:168
void ResetInterrupt()
Definition TMonitor.h:72
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition TMonitor.cxx:438
virtual void DeActivateAll()
De-activate all activated sockets.
Definition TMonitor.cxx:302
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition TMonitor.cxx:284
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition TMonitor.cxx:498
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition TMonitor.cxx:214
void Interrupt()
Definition TMonitor.h:71
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
TNamed()
Definition TNamed.h:36
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:37
Collectable string class.
Definition TObjString.h:28
const char * GetName() const
Returns name of object.
Definition TObjString.h:38
const TString & GetString() const
Definition TObjString.h:46
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h: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:798
@ kSingleKey
write collection with single key
Definition TObject.h:87
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:359
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:187
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition TObject.cxx:574
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TObject.cxx:146
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition TObject.cxx:907
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:130
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:879
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:323
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:149
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:696
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:445
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:893
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:403
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:552
void ResetBit(UInt_t f)
Definition TObject.h:186
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:867
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:934
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition TPackMgr.cxx:872
Int_t Load(const char *pack, TList *optls=0)
Method to load a package taking an option list Return -1 on error, 0 otherwise.
Definition TPackMgr.cxx:220
Int_t Unload(const char *pack)
Method to unload a package.
Definition TPackMgr.cxx:411
TList * GetListOfEnabled() const
Get list of enabled packages Returns a pointer to a TList object, transferring ownership to the calle...
Definition TPackMgr.cxx:644
Int_t Remove(const char *pack=0, Bool_t dolock=kTRUE)
Remove package 'pack' If 'pack' is null or empty all packages are cleared.
Definition TPackMgr.cxx:593
TMD5 * ReadMD5(const char *pack)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition TPackMgr.cxx:708
Class used by TMap to store (key,value) pairs.
Definition TMap.h:102
TObject * Value() const
Definition TMap.h:121
const char * GetName() const
Returns name of object.
Definition TMap.h:116
TObject * Key() const
Definition TMap.h:120
Named parameter, streamable and storable.
Definition TParameter.h:35
const AParamType & GetVal() const
Definition TParameter.h:67
const char * GetName() const
Returns name of object.
Definition TParameter.h:66
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.
void SetProof(TProof *p)
Definition TProofMgr.h:179
TProofInputHandler(const TProofInputHandler &)
TProof * fProof
Definition TProof.h:201
Bool_t Notify()
Handle input.
Definition TProof.cxx:163
TSocket * fSocket
Definition TProof.h:200
Bool_t Notify()
TProof interrupt handler.
Definition TProof.cxx:116
void IncreaseIdx()
Definition TProof.h:311
void DecreaseNWrks()
Definition TProof.h:309
void Reset(Int_t n=-1)
Definition TProof.h:312
const char * Export(Bool_t &changed)
Definition TProof.h:304
static char fgCr[4]
Definition TProof.h:300
void IncreaseNWrks()
Definition TProof.h:310
void SetNWrks(Int_t n)
Definition TProof.h:313
The PROOF manager interacts with the PROOF server coordinator to create or destroy a PROOF session,...
Definition TProofMgr.h:43
virtual Int_t Reset(Bool_t hard=kFALSE, const char *usr=0)
Send a cleanup request for the sessions associated with the current user.
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
static TProofMgr * Create(const char *url, Int_t loglevel=-1, const char *alias=0, Bool_t xpd=kTRUE)
Static method returning the appropriate TProofMgr object using the plugin manager.
virtual Int_t Rm(const char *, const char *=0, const char *=0)
Run 'rm' on 'what'. Locally it is just a call to TSystem::Unlink .
virtual void Find(const char *="~/", const char *=0, const char *=0)
Definition TProofMgr.h:113
virtual TProof * CreateSession(const char *=0, const char *=0, Int_t=-1)
Create a new remote session (master and associated workers).
virtual Bool_t IsValid() const
Definition TProofMgr.h:77
virtual Int_t GetFile(const char *, const char *, const char *=0)
Definition TProofMgr.h:122
virtual TProof * AttachSession(Int_t, Bool_t=kFALSE)
Dummy version provided for completeness.
virtual Bool_t IsProofd() const
Definition TProofMgr.h:76
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to 'id'.
virtual Int_t Stat(const char *, FileStat_t &, const char *=0)
Definition TProofMgr.h:120
virtual Bool_t IsLite() const
Definition TProofMgr.h:75
virtual void DiscardSession(TProof *p)
Discard TProofDesc of session 'p' from the internal list.
The purpose of this class is to provide a complete node description for masters, submasters and worke...
const TString & GetMsd() const
Int_t GetNWrks() const
const TString & GetImage() const
Bool_t IsWorker() const
const TString & GetOrdinal() const
const TString & GetWorkDir() const
Int_t GetPerfIndex() const
const TString & GetNodeName() const
Int_t GetPort() const
const char * GetName() const
Returns name of object.
Class to steer the merging of files produced on the workers.
const char * GetDir(Bool_t raw=kFALSE) const
const char * GetOutputFileName() const
const char * GetFileName() const
Bool_t IsRetrieve() const
void AttachList(TList *alist)
Attach to list 'alist'.
Container class for processing statistics.
Long64_t GetEntries() const
const char * GetOrdinal() const
Definition TProofServ.h:253
const char * GetImage() const
Definition TProofServ.h:244
TList * GetEnabledPackages() const
Definition TProofServ.h:267
virtual EQueryAction GetWorkers(TList *workers, Int_t &prioritychange, Bool_t resume=kFALSE)
Get list of workers to be used from now on.
virtual void ReleaseWorker(const char *)
Definition TProofServ.h:305
const char * GetUser() const
Definition TProofServ.h:241
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
TSocket * GetSocket() const
Definition TProofServ.h:257
const char * GetGroup() const
Definition TProofServ.h:242
void SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
static void ResolveKeywords(TString &fname, const char *path=0)
Replace <ord>, <user>, <u>, <group>, <stag>, <qnum>, <file>, <rver> and <build> placeholders in fname...
TPackMgr * GetPackMgr() const
Definition TProofServ.h:249
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
const char * GetSessionDir() const
Definition TProofServ.h:247
const char * GetWorkDir() const
Definition TProofServ.h:243
const char * GetPrefix() const
Definition TProofServ.h:276
Bool_t IsTopMaster() const
Definition TProofServ.h:295
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition TProof.h:316
void HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
Handle lib, inc search paths modification request.
Definition TProof.cxx:8988
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:6523
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition TProof.cxx:1986
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition TProof.cxx:7760
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition TProof.cxx:7386
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:7058
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition TProof.cxx:11714
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition TProof.cxx:4444
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:2441
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:2095
TProofMgr * fManager
Definition TProof.h:587
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition TProof.cxx:4400
TList * GetOutputNames()
FIXME: to be written.
Definition TProof.cxx:10108
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:6249
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition TProof.cxx:10311
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:6348
void Activate(TList *slaves=0)
Activate slave server list.
Definition TProof.cxx:2379
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition TProof.cxx:8431
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:5222
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition TProof.cxx:6748
void Close(Option_t *option="")
Close all open slave servers.
Definition TProof.cxx:1788
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:7102
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:7932
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:8324
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:11266
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:12301
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:2155
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:7980
Bool_t IsTty() const
Definition TProof.h:938
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition TProof.cxx:4793
Int_t GetClientProtocol() const
Definition TProof.h:914
Int_t fCollectTimeout
Definition TProof.h:583
virtual ~TProof()
Clean up PROOF environment.
Definition TProof.cxx:646
EQueryMode fQueryMode
Definition TProof.h:588
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition TProof.cxx:10221
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition TProof.cxx:1518
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:12403
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:7044
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition TProof.cxx:4927
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:9979
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:12460
TVirtualProofPlayer * GetPlayer() const
Definition TProof.h:716
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition TProof.cxx:3036
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition TProof.cxx:4413
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:2557
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition TProof.cxx:11786
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:9512
void AskParallel()
Ask the for the number of parallel slaves.
Definition TProof.cxx:2067
FileMap_t fFileMap
Definition TProof.h:502
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition TProof.cxx:7704
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:10886
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:11343
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition TProof.cxx:6082
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition TProof.cxx:11036
TList * fChains
Definition TProof.h:496
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition TProof.cxx:9908
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:6047
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition TProof.cxx:4324
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition TProof.cxx:9098
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'.
Definition TProof.cxx:2138
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition TProof.cxx:1968
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition TProof.cxx:9302
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:8589
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:8878
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition TProof.cxx:10799
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:7681
void ClearFeedback()
Clear feedback list.
Definition TProof.cxx:10002
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:11573
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition TProof.cxx:10169
Int_t GetPort() const
Definition TProof.h:912
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition TProof.cxx:11325
void ResetMergePrg()
Reset the merge progress notificator.
Definition TProof.cxx:2455
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition TProof.cxx:12614
void ClearData(UInt_t what=kUnregistered, const char *dsname=0)
Remove files for the data directory.
Definition TProof.cxx:7402
Bool_t IsValid() const
Definition TProof.h:937
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition TProof.cxx:4772
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:1259
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition TProof.cxx:11106
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition TProof.cxx:11171
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:11379
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition TProof.cxx:7130
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition TProof.cxx:7160
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:10904
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:4294
@ 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:6655
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:11750
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:6485
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition TProof.cxx:10836
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:2659
Float_t GetCpuTime() const
Definition TProof.h:931
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition TProof.cxx:7660
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition TProof.cxx:12370
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition TProof.cxx:10189
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition TProof.cxx:7847
Int_t SendInitialState()
Transfer the initial (i.e.
Definition TProof.cxx:6764
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition TProof.cxx:1310
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition TProof.cxx:2025
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:10697
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition TProof.cxx:2465
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition TProof.cxx:9923
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:9629
void InitMembers()
Default initializations.
Definition TProof.cxx:521
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition TProof.cxx:4248
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition TProof.cxx:4004
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:9575
Int_t fStatus
Definition TProof.h:470
TList * fRunningDSets
Definition TProof.h:581
Int_t ClearPackages()
Remove all packages.
Definition TProof.cxx:7830
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition TProof.cxx:9812
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition TProof.cxx:1650
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition TProof.cxx:4734
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:1865
void SaveActiveList()
Save current list of active workers.
Definition TProof.cxx:11532
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:10756
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:12512
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition TProof.cxx:8957
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'.
Definition TProof.cxx:2398
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition TProof.cxx:2294
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:8104
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition TProof.cxx:9990
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition TProof.cxx:6003
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:4343
void AskStatistics()
Ask the for the statistics of the slaves.
Definition TProof.cxx:2012
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition TProof.cxx:10573
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:10508
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:9130
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:751
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:6136
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:11360
@ 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:7086
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition TProof.cxx:10486
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:12571
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning,...
Definition TProof.cxx:1037
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition TProof.cxx:2004
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition TProof.cxx:5938
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:2600
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:9948
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:9326
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:10981
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition TProof.cxx:6404
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition TProof.cxx:11726
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition TProof.cxx:2960
Int_t fLastAssignedMerger
Definition TProof.h:552
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition TProof.cxx:2129
void ShowFeedback() const
Show items in feedback list.
Definition TProof.cxx:10010
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:7263
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition TProof.cxx:6097
Int_t UnloadPackages()
Unload all packages.
Definition TProof.cxx:8137
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition TProof.cxx:10201
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:11000
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition TProof.cxx:12636
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:8618
@ 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:8833
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition TProof.cxx:507
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:1587
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition TProof.cxx:9191
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition TProof.cxx:5873
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition TProof.cxx:8923
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:11299
Bool_t fIsPollingWorkers
Definition TProof.h:475
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition TProof.cxx:10100
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:11063
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:6789
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:7639
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition TProof.cxx:12499
TString fLogFileName
Definition TProof.h:511
void GoAsynchronous()
Send GOASYNC message to the master.
Definition TProof.cxx:6257
Int_t fCheckFileStatus
Definition TProof.h:471
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition TProof.cxx:9798
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:1291
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition TProof.cxx:6634
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:6214
TList * GetEnabledPackages() const
Definition TProof.h:735
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition TProof.cxx:1977
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:1843
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition TProof.cxx:2118
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:6884
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:12004
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:2266
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:10625
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:4511
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition TProof.cxx:6450
Bool_t IsProofd() const
Definition TProof.h:934
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition TProof.cxx:11547
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:7018
void ShowLog(Int_t qry=-1)
Display on screen the content of the temporary log file.
Definition TProof.cxx:10361
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:9528
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition TProof.cxx:6621
void Feedback(TList *objs)
Get list of feedback objects.
Definition TProof.cxx:9258
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition TProof.cxx:11010
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:9752
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition TProof.cxx:2311
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition TProof.cxx:10032
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition TProof.cxx:9370
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:10674
@ 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:1902
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:4686
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition TProof.cxx:7725
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition TProof.cxx:6109
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:8059
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:9289
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition TProof.cxx:10092
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:10927
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:10084
void AddChain(TChain *chain)
Add chain to data set.
Definition TProof.cxx:10213
static const TList * GetEnvVars()
Get environemnt variables.
Definition TProof.cxx:11741
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition TProof.cxx:1881
TString fGroup
Definition TProof.h:468
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition TProof.cxx:9114
TList * GetFeedbackList() const
Return feedback list.
Definition TProof.cxx:10023
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:9602
TList * fEnabledPackages
Definition TProof.h:580
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition TProof.cxx:2078
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:11772
Int_t BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
Broadcast an object to all slaves in the specified list.
Definition TProof.cxx:2533
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition TProof.cxx:7069
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:5293
void ClearInput()
Clear input object list.
Definition TProof.cxx:9732
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:1010
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition TProof.cxx:7875
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition TProof.cxx:5847
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition TProof.cxx:1995
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition TProof.cxx:10858
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition TProof.cxx:10967
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition TProof.cxx:3095
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:9724
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:6277
Bool_t IsMaster() const
Definition TProof.h:936
void CloseProgressDialog()
Close progress dialog.
Definition TProof.cxx:9273
TProofOutputList fOutputList
Definition TProof.h:538
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition TProof.cxx:4426
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition TProof.cxx:9314
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition TProof.cxx:10247
TList * GetInputList()
Get input list.
Definition TProof.cxx:9743
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:2644
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition TProof.cxx:7808
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition TProof.cxx:2105
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition TProof.cxx:10230
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition TProof.cxx:3050
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:9359
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition TProof.cxx:11798
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition TProof.cxx:8165
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:2230
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:11120
TString fImage
Definition TProof.h:570
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition TQObject.h:164
void EmitVA(const char *signal_name, Int_t, const T &... params)
Emit a signal with a varying number of arguments.
Definition TQObject.h:100
A container class for query results.
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
Long64_t GetEntries() const
Int_t GetSeqNum() const
void SetTermTime(Float_t termtime)
void SetArchived(const char *archfile)
Set (or update) query in archived state.
TList * GetOutputList()
void SetPrepTime(Float_t preptime)
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
void AddInput(TObject *obj)
Add obj to the input list.
TList * GetInputList()
TMacro * GetLogFile() const
Bool_t IsFinalized() const
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2723
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition TROOT.cxx:2749
virtual Double_t Rndm()
Machine independent random number generator.
Definition TRandom.cxx:552
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition TRandom.cxx:360
Regular expression class.
Definition TRegexp.h:31
virtual const char * AsString(TString &out)
Returns short string with relevant information about this security context.
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition TSelector.h:31
Sequenceable collection abstract base class.
virtual void Add()
Add signal handler to system signal handler list.
virtual void Remove()
Remove signal handler from system signal handler list.
ESlaveStatus fStatus
Definition TProof.h:222
Int_t Compare(const TObject *obj) const
Used to sort slaveinfos by ordinal.
Definition TProof.cxx:177
TString fMsd
Definition TProof.h:218
SysInfo_t GetSysInfo() const
Definition TProof.h:233
TString fDataDir
Definition TProof.h:219
Int_t fPerfIndex
Definition TProof.h:220
void SetStatus(ESlaveStatus stat)
Definition TProof.h:234
@ kNotActive
Definition TProof.h:214
TString fOrdinal
Definition TProof.h:216
const char * GetOrdinal() const
Definition TProof.h:232
TString fHostName
Definition TProof.h:217
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition TProof.cxx:262
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:205
const char * GetDataDir() const
Definition TProof.h:229
void Print(Option_t *option="") const
Print slave info.
Definition TProof.cxx:219
Class describing a PROOF worker server.
Definition TSlave.h:46
Int_t fStatus
Definition TSlave.h:96
Int_t fParallel
Definition TSlave.h:97
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition TSlave.cxx:655
TString fImage
Definition TSlave.h:80
Float_t fRealTime
Definition TSlave.h:93
const char * GetWorkDir() const
Definition TSlave.h:127
ESlaveType fSlaveType
Definition TSlave.h:95
Int_t GetSlaveType() const
Definition TSlave.h:139
Int_t GetParallel() const
Definition TSlave.h:141
Float_t fCpuTime
Definition TSlave.h:94
const char * GetImage() const
Definition TSlave.h:125
void SetArchCompiler(const char *ac)
Definition TSlave.h:158
Int_t GetPort() const
Definition TSlave.h:130
@ kSlave
Definition TSlave.h:55
@ kMaster
Definition TSlave.h:55
TSocket * GetSocket() const
Definition TSlave.h:134
@ kOutputRequested
Definition TSlave.h:58
virtual void SetStatus(Int_t st)
Definition TSlave.h:113
virtual void StopProcess(Bool_t abort, Int_t timeout)
Sent stop/abort request to PROOF server.
Definition TSlave.cxx:629
virtual void FlushSocket()
Definition TSlave.h:105
const char * GetUser() const
Definition TSlave.h:128
TFileHandler * GetInputHandler() const
Definition TSlave.h:144
TString fWorkDir
Definition TSlave.h:82
const char * GetMsd() const
Definition TSlave.h:142
@ kActive
Definition TSlave.h:56
@ kInactive
Definition TSlave.h:56
TString fOrdinal
Definition TSlave.h:86
Long64_t fBytesRead
Definition TSlave.h:92
static TSlave * Create(const char *url, const char *ord, Int_t perf, const char *image, TProof *proof, Int_t stype, const char *workdir, const char *msd, Int_t nwk=1)
Static method returning the appropriate TSlave object for the remote server.
Definition TSlave.cxx:441
virtual void Touch()
Definition TSlave.h:165
TString fProofWorkDir
Definition TSlave.h:81
void SetInputHandler(TFileHandler *ih)
Adopt and register input handler for this slave.
Definition TSlave.cxx:393
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition TSlave.cxx:510
Int_t GetStatus() const
Definition TSlave.h:140
virtual void SetInterruptHandler(Bool_t)
Definition TSlave.h:156
virtual Int_t SetupServ(Int_t stype, const char *conffile)
Init a PROOF slave object.
Definition TSlave.cxx:178
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition TSlave.cxx:493
virtual Int_t SendGroupPriority(const char *, Int_t)
Definition TSlave.h:110
const char * GetName() const
Returns name of object.
Definition TSlave.h:124
TString fName
Definition TSlave.h:79
virtual Bool_t IsValid() const
Definition TSlave.h:150
void SetSessionTag(const char *st)
Definition TSlave.h:161
const char * GetOrdinal() const
Definition TSlave.h:131
const char * GetProofWorkDir() const
Definition TSlave.h:126
void SetROOTVersion(const char *rv)
Definition TSlave.h:159
virtual void Close(Option_t *opt="")
Close slave socket.
Definition TSlave.cxx:276
Int_t GetPerfIdx() const
Definition TSlave.h:132
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition TSocket.cxx:818
Int_t GetRemoteProtocol() const
Definition TSocket.h:126
TInetAddress GetInetAddress() const
Definition TSocket.h:113
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition TSocket.cxx:898
TSecContext * GetSecContext() const
Definition TSocket.h:127
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition TSocket.cxx:620
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition TSocket.cxx:600
virtual Bool_t IsValid() const
Definition TSocket.h:132
virtual Int_t Reconnect()
Definition TSocket.h:138
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition TSocket.cxx:522
A sorted doubly linked list.
Definition TSortedList.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Stop()
Stop the stopwatch.
void Reset()
Definition TStopwatch.h:52
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:438
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:649
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1941
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2197
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1126
Double_t Atof() const
Return floating-point value contained in string.
Definition TString.cxx:2007
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition TString.cxx:1811
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:682
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:519
const char * Data() const
Definition TString.h:369
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition TString.cxx:1783
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
@ kTrailing
Definition TString.h:267
@ kBoth
Definition TString.h:267
@ kIgnoreCase
Definition TString.h:268
@ kExact
Definition TString.h:268
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:912
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2217
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:615
TString & Prepend(const char *cs)
Definition TString.h:661
Bool_t IsNull() const
Definition TString.h:407
TString & Remove(Ssiz_t pos)
Definition TString.h:673
TString & Append(const char *cs)
Definition TString.h:564
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2331
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2309
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
Definition TSystem.cxx:1711
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition TSystem.cxx:3874
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:277
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1272
const char * pwd()
Definition TSystem.h:422
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:261
virtual void AddIncludePath(const char *includePath)
Add a directory to the already set include path.
Definition TSystem.cxx:4138
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:1504
virtual int GetPid()
Get process id.
Definition TSystem.cxx:708
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition TSystem.cxx:1339
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1661
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3956
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4237
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition TSystem.cxx:905
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:654
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:4173
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition TSystem.cxx:663
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:1396
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:1294
virtual FILE * TempFileName(TString &base, const char *dir=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition TSystem.cxx:1495
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition TSystem.cxx:672
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:933
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition TSystem.cxx:533
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1791
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition TSystem.cxx:681
virtual const char * HostName()
Return the system's host name.
Definition TSystem.cxx:304
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition TSystem.cxx:1653
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition TSystem.cxx:950
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition TSystem.cxx:1802
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:870
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1544
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition TSystem.cxx:2295
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition TSystem.cxx:543
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1645
virtual const char * GetBuildArch() const
Return the build architecture.
Definition TSystem.cxx:3858
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1030
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1379
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition TSystem.cxx:1597
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition TSystem.cxx:1480
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Long64_t GetMaxEntryLoop() const
Definition TTree.h:494
This class represents a RFC 3986 compatible URI.
Definition TUri.h:35
Bool_t SetFragment(const TString &fragment)
Set fragment component of URI:
Definition TUri.cxx:498
const TString GetUri() const
Returns the whole URI - an implementation of chapter 5.3 component recomposition.
Definition TUri.cxx:140
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:389
const char * GetFile() const
Definition TUrl.h:69
void SetUser(const char *user)
Definition TUrl.h:82
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition TUrl.cxx:522
const char * GetUser() const
Definition TUrl.h:65
const char * GetHost() const
Definition TUrl.h:67
void SetOptions(const char *opt)
Definition TUrl.h:87
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition TUrl.cxx:471
const char * GetOptions() const
Definition TUrl.h:71
void SetHost(const char *host)
Definition TUrl.h:84
const char * GetProtocol() const
Definition TUrl.h:64
void SetPort(Int_t port)
Definition TUrl.h:88
Int_t GetPort() const
Definition TUrl.h:78
void SetPasswd(const char *pw)
Definition TUrl.h:83
The packetizer is a load balancing object created for each query.
virtual Int_t AddProcessed(TSlave *, TProofProgressStatus *, Double_t, TList **)
virtual void MarkBad(TSlave *, TProofProgressStatus *, TList **)
Abstract interface for the PROOF player.
virtual TDSetElement * GetNextPacket(TSlave *slave, TMessage *r)=0
virtual void AddEventsProcessed(Long64_t ev)=0
virtual void AddInput(TObject *inp)=0
virtual TQueryResult * GetCurrentQuery() const =0
virtual void AddOutput(TList *out)=0
virtual TList * GetInputList() const =0
virtual TObject * GetOutput(const char *name) const =0
virtual void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)=0
virtual void SetMaxDrawQueries(Int_t max)=0
virtual Long64_t GetEventsProcessed() const =0
virtual Long64_t DrawSelect(TDSet *set, const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual TQueryResult * GetQueryResult(const char *ref)=0
virtual void SetMerging(Bool_t on=kTRUE)=0
virtual EExitStatus GetExitStatus() const =0
virtual void Progress(Long64_t total, Long64_t processed)=0
virtual void AddQueryResult(TQueryResult *q)=0
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
virtual void UpdateAutoBin(const char *name, Double_t &xmin, Double_t &xmax, Double_t &ymin, Double_t &ymax, Double_t &zmin, Double_t &zmax)=0
virtual Int_t AddOutputObject(TObject *obj)=0
virtual Bool_t JoinProcess(TList *workers)=0
virtual TList * GetListOfResults() const =0
virtual void ClearInput()=0
virtual void HandleRecvHisto(TMessage *mess)=0
virtual void RemoveQueryResult(const char *ref)=0
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual Long64_t Finalize(Bool_t force=kFALSE, Bool_t sync=kFALSE)=0
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual void StoreFeedback(TObject *slave, TList *out)=0
virtual TDrawFeedback * CreateDrawFeedback(TProof *p)=0
virtual TVirtualPacketizer * GetPacketizer() const
virtual void DeleteDrawFeedback(TDrawFeedback *f)=0
virtual TList * GetOutputList() const =0
virtual void SetInitTime()=0
virtual void SetCurrentQuery(TQueryResult *q)=0
TLine * line
const Int_t n
Definition legend1.C:16
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:713
Double_t Sqrt(Double_t x)
Definition TMath.h:691
Definition file.py:1
Definition first.py:1
Definition tree.py:1
static const char * what
Definition stlLoader.cc:6
Int_t fMode
Definition TSystem.h:127
Bool_t fIsLink
Definition TSystem.h:132
Int_t fCpuSpeed
Definition TSystem.h:155
Int_t fL2Cache
Definition TSystem.h:157
Int_t fBusSpeed
Definition TSystem.h:156
TString fCpuType
Definition TSystem.h:153
Int_t fCpus
Definition TSystem.h:154
Int_t fPhysRam
Definition TSystem.h:158
TString fOS
Definition TSystem.h:151
TString fModel
Definition TSystem.h:152
Long_t fModtime
Definition TProof.h:499
TString fUser
Definition TSystem.h:141
auto * m
Definition textangle.C:8
auto * l
Definition textangle.C:4