Logo ROOT   6.18/05
Reference Guide
TProof.cxx
Go to the documentation of this file.
1// @(#)root/proof:$Id: a2a50e759072c37ccbc65ecbcce735a76de86e95 $
2// Author: Fons Rademakers 13/02/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11/**
12 \defgroup proof PROOF
13
14 Classes defining the Parallel ROOT Facility, PROOF, a framework for parallel analysis of ROOT TTrees.
15
16*/
17
18/**
19 \defgroup proofkernel PROOF kernel Libraries
20 \ingroup proof
21
22 The PROOF kernel libraries (libProof, libProofPlayer, libProofDraw) contain the classes defining
23 the kernel of the PROOF facility, i.e. the protocol and the utilities to steer data processing
24 and handling of results.
25
26*/
27
28/** \class TProof
29\ingroup proofkernel
30
31This class controls a Parallel ROOT Facility, PROOF, cluster.
32It fires the worker servers, it keeps track of how many workers are
33running, it keeps track of the workers running status, it broadcasts
34messages to all workers, it collects results, etc.
35
36*/
37
38#include <stdlib.h>
39#include <fcntl.h>
40#include <errno.h>
41#ifdef WIN32
42# include <io.h>
43# include <sys/stat.h>
44# include <sys/types.h>
45# include "snprintf.h"
46#else
47# include <unistd.h>
48#endif
49#include <vector>
50
51#include "RConfigure.h"
52#include "Riostream.h"
53#include "Getline.h"
54#include "TBrowser.h"
55#include "TChain.h"
56#include "TCondor.h"
57#include "TDSet.h"
58#include "TError.h"
59#include "TEnv.h"
60#include "TEntryList.h"
61#include "TEventList.h"
62#include "TFile.h"
63#include "TFileInfo.h"
64#include "TFunction.h"
65#include "TFTP.h"
66#include "THashList.h"
67#include "TInterpreter.h"
68#include "TKey.h"
69#include "TMap.h"
70#include "TMath.h"
71#include "TMessage.h"
72#include "TMethodArg.h"
73#include "TMethodCall.h"
74#include "TMonitor.h"
75#include "TObjArray.h"
76#include "TObjString.h"
77#include "TParameter.h"
78#include "TProof.h"
79#include "TProofNodeInfo.h"
80#include "TProofOutputFile.h"
81#include "TVirtualProofPlayer.h"
82#include "TVirtualPacketizer.h"
83#include "TProofServ.h"
84#include "TPluginManager.h"
85#include "TQueryResult.h"
86#include "TRandom.h"
87#include "TRegexp.h"
88#include "TROOT.h"
89#include "TSlave.h"
90#include "TSocket.h"
91#include "TSortedList.h"
92#include "TSystem.h"
93#include "TTree.h"
94#include "TUrl.h"
95#include "TFileCollection.h"
96#include "TDataSetManager.h"
97#include "TDataSetManagerFile.h"
98#include "TMacro.h"
99#include "TSelector.h"
100#include "TPRegexp.h"
101#include "TPackMgr.h"
102
103#include <mutex>
104
106
107// Rotating indicator
108char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
109
110TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
111TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
112
114
115//----- PROOF Interrupt signal handler -----------------------------------------
116////////////////////////////////////////////////////////////////////////////////
117/// TProof interrupt handler.
118
120{
121 if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
122
123 // Cannot ask the user : abort any remote processing
125
126 } else {
127 // Real stop or request to switch to asynchronous?
128 const char *a = 0;
129 if (fProof->GetRemoteProtocol() < 22) {
130 a = Getline("\nSwitch to asynchronous mode not supported remotely:"
131 "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
132 } else {
133 a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
134 " any other key to continue: ");
135 }
136 if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
137
138 Info("Notify","Processing interrupt signal ... %c", a[0]);
139
140 // Stop or abort any remote processing
141 Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
142 fProof->StopProcess(abort);
143
144 } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
145 // Stop any remote processing
147 }
148 }
149
150 return kTRUE;
151}
152
153//----- Input handler for messages from TProofServ -----------------------------
154////////////////////////////////////////////////////////////////////////////////
155/// Constructor
156
158 : TFileHandler(s->GetDescriptor(),1),
159 fSocket(s), fProof(p)
160{
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Handle input
165
167{
169 return kTRUE;
170}
171
172
173//------------------------------------------------------------------------------
174
176
177////////////////////////////////////////////////////////////////////////////////
178/// Used to sort slaveinfos by ordinal.
179
181{
182 if (!obj) return 1;
183
184 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
185
186 if (!si) return fOrdinal.CompareTo(obj->GetName());
187
188 const char *myord = GetOrdinal();
189 const char *otherord = si->GetOrdinal();
190 while (myord && otherord) {
191 Int_t myval = atoi(myord);
192 Int_t otherval = atoi(otherord);
193 if (myval < otherval) return 1;
194 if (myval > otherval) return -1;
195 myord = strchr(myord, '.');
196 if (myord) myord++;
197 otherord = strchr(otherord, '.');
198 if (otherord) otherord++;
199 }
200 if (myord) return -1;
201 if (otherord) return 1;
202 return 0;
203}
204
205////////////////////////////////////////////////////////////////////////////////
206/// Used to compare slaveinfos by ordinal.
207
209{
210 if (!obj) return kFALSE;
211 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
212 if (!si) return kFALSE;
213 return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Print slave info. If opt = "active" print only the active
218/// slaves, if opt="notactive" print only the not active slaves,
219/// if opt = "bad" print only the bad slaves, else
220/// print all slaves.
221
223{
224 TString stat = fStatus == kActive ? "active" :
225 fStatus == kBad ? "bad" :
226 "not active";
227
228 Bool_t newfmt = kFALSE;
229 TString oo(opt);
230 if (oo.Contains("N")) {
231 newfmt = kTRUE;
232 oo.ReplaceAll("N","");
233 }
234 if (oo == "active" && fStatus != kActive) return;
235 if (oo == "notactive" && fStatus != kNotActive) return;
236 if (oo == "bad" && fStatus != kBad) return;
237
238 if (newfmt) {
239 TString msd, si, datadir;
240 if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
241 if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
242 if (fSysInfo.fCpus > 0) {
243 si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
245 } else {
246 si.Form("| %s", fHostName.Data());
247 }
248 Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
249
250 } else {
251 TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
252
253 std::cout << "Slave: " << fOrdinal
254 << " hostname: " << fHostName
255 << " msd: " << msd
256 << " perf index: " << fPerfIndex
257 << " " << stat
258 << std::endl;
259 }
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Setter for fSysInfo
264
266{
267 fSysInfo.fOS = si.fOS; // OS
268 fSysInfo.fModel = si.fModel; // computer model
269 fSysInfo.fCpuType = si.fCpuType; // type of cpu
270 fSysInfo.fCpus = si.fCpus; // number of cpus
271 fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
272 fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
273 fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
274 fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
275}
276
278
279//------------------------------------------------------------------------------
280
281////////////////////////////////////////////////////////////////////////////////
282/// Destructor
283
285{
286 // Just delete the list, the objects are owned by other list
287 if (fWorkers) {
290 }
291}
292////////////////////////////////////////////////////////////////////////////////
293/// Increase number of already merged workers by 1
294
296{
298 Error("SetMergedWorker", "all workers have been already merged before!");
299 else
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Add new worker to the list of workers to be merged by this merger
305
307{
308 if (!fWorkers)
309 fWorkers = new TList();
310 if (fWorkersToMerge == fWorkers->GetSize()) {
311 Error("AddWorker", "all workers have been already assigned to this merger");
312 return;
313 }
314 fWorkers->Add(sl);
315}
316
317////////////////////////////////////////////////////////////////////////////////
318/// Return if merger has already merged all workers, i.e. if it has finished its merging job
319
321{
323}
324
325////////////////////////////////////////////////////////////////////////////////
326/// Return if the determined number of workers has been already assigned to this merger
327
329{
330 if (!fWorkers)
331 return kFALSE;
332
333 return (fWorkers->GetSize() == fWorkersToMerge);
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// This a private API function.
338/// It checks whether the connection string contains a PoD cluster protocol.
339/// If it does, then the connection string will be changed to reflect
340/// a real PROOF connection string for a PROOF cluster managed by PoD.
341/// PoD: http://pod.gsi.de .
342/// Return -1 if the PoD request failed; return 0 otherwise.
343
344static Int_t PoDCheckUrl(TString *_cluster)
345{
346 if ( !_cluster )
347 return 0;
348
349 // trim spaces from both sides of the string
350 *_cluster = _cluster->Strip( TString::kBoth );
351 // PoD protocol string
352 const TString pod_prot("pod");
353
354 // URL test
355 // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
356 TUrl url( _cluster->Data() );
357 if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
358 return 0;
359
360 // PoD cluster is used
361 // call pod-info in a batch mode (-b).
362 // pod-info will find either a local PoD cluster or
363 // a remote one, manged by pod-remote.
364 *_cluster = gSystem->GetFromPipe("pod-info -c -b");
365 if( 0 == _cluster->Length() ) {
366 Error("PoDCheckUrl", "PoD server is not running");
367 return -1;
368 }
369 return 0;
370}
371
372////////////////////////////////////////////////////////////////////////////////
373/// Create a PROOF environment. Starting PROOF involves either connecting
374/// to a master server, which in turn will start a set of slave servers, or
375/// directly starting as master server (if master = ""). Masterurl is of
376/// the form: [proof[s]://]host[:port]. Conffile is the name of the config
377/// file describing the remote PROOF cluster (this argument alows you to
378/// describe different cluster configurations).
379/// The default is proof.conf. Confdir is the directory where the config
380/// file and other PROOF related files are (like motd and noproof files).
381/// Loglevel is the log level (default = 1). User specified custom config
382/// files will be first looked for in $HOME/.conffile.
383
384TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
385 Int_t loglevel, const char *alias, TProofMgr *mgr)
386 : fUrl(masterurl)
387{
388 // Default initializations
389 InitMembers();
390
391 // This may be needed during init
392 fManager = mgr;
393
394 // Default server type
396
397 // Default query mode
399
400 // Parse the main URL, adjusting the missing fields and setting the relevant
401 // bits
404
405 // Protocol and Host
406 if (!masterurl || strlen(masterurl) <= 0) {
407 fUrl.SetProtocol("proof");
408 fUrl.SetHost("__master__");
409 } else if (!(strstr(masterurl, "://"))) {
410 fUrl.SetProtocol("proof");
411 }
412 // Port
413 if (fUrl.GetPort() == TUrl(" ").GetPort())
414 fUrl.SetPort(TUrl("proof:// ").GetPort());
415
416 // Make sure to store the FQDN, so to get a solid reference for subsequent checks
417 if (!strcmp(fUrl.GetHost(), "__master__"))
418 fMaster = fUrl.GetHost();
419 else if (!strlen(fUrl.GetHost()))
421 else
423
424 // Server type
425 if (strlen(fUrl.GetOptions()) > 0) {
426 TString opts(fUrl.GetOptions());
427 if (!(strncmp(fUrl.GetOptions(),"std",3))) {
429 opts.Remove(0,3);
430 fUrl.SetOptions(opts.Data());
431 } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
433 opts.Remove(0,4);
434 fUrl.SetOptions(opts.Data());
435 }
436 }
437
438 // Instance type
442 if (fMaster == "__master__") {
446 } else if (fMaster == "prooflite") {
447 // Client and master are merged
450 }
451 // Flag that we are a client
453 if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
454
455 Init(masterurl, conffile, confdir, loglevel, alias);
456
457 // If the user was not set, get it from the master
458 if (strlen(fUrl.GetUser()) <= 0) {
459 TString usr, emsg;
460 if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
461 TObjString *os = fMacroLog.GetLineWith("const char");
462 if (os) {
463 Ssiz_t fst = os->GetString().First('\"');
464 Ssiz_t lst = os->GetString().Last('\"');
465 usr = os->GetString()(fst+1, lst-fst-1);
466 } else {
467 emsg = "could not find 'const char *' string in macro log";
468 }
469 } else {
470 emsg = "could not retrieve user info";
471 }
472 if (!emsg.IsNull()) {
473 // Get user logon name
475 if (pw) {
476 usr = pw->fUser;
477 delete pw;
478 }
479 Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
480 }
481 // Set the user name in the main URL
482 fUrl.SetUser(usr.Data());
483 }
484
485 // If called by a manager, make sure it stays in last position
486 // for cleaning
487 if (mgr) {
489 gROOT->GetListOfSockets()->Remove(mgr);
490 gROOT->GetListOfSockets()->Add(mgr);
491 }
492
493 // Old-style server type: we add this to the list and set the global pointer
495 if (!gROOT->GetListOfProofs()->FindObject(this))
496 gROOT->GetListOfProofs()->Add(this);
497
498 // Still needed by the packetizers: needs to be changed
499 gProof = this;
500}
501
502////////////////////////////////////////////////////////////////////////////////
503/// Protected constructor to be used by classes deriving from TProof
504/// (they have to call Init themselves and override StartSlaves
505/// appropriately).
506///
507/// This constructor simply closes any previous gProof and sets gProof
508/// to this instance.
509
510TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
511{
512 // Default initializations
513 InitMembers();
514
515 if (!gROOT->GetListOfProofs()->FindObject(this))
516 gROOT->GetListOfProofs()->Add(this);
517
518 gProof = this;
519}
520
521////////////////////////////////////////////////////////////////////////////////
522/// Default initializations
523
525{
526 fValid = kFALSE;
527 fTty = kFALSE;
528 fRecvMessages = 0;
529 fSlaveInfo = 0;
534 fActiveSlaves = 0;
535 fInactiveSlaves = 0;
536 fUniqueSlaves = 0;
539 fActiveMonitor = 0;
540 fUniqueMonitor = 0;
542 fCurrentMonitor = 0;
543 fBytesRead = 0;
544 fRealTime = 0;
545 fCpuTime = 0;
546 fIntHandler = 0;
547 fProgressDialog = 0;
550 fPlayer = 0;
551 fFeedback = 0;
552 fChains = 0;
553 fDSet = 0;
554 fNotIdle = 0;
555 fSync = kTRUE;
559 fLogFileW = 0;
560 fLogFileR = 0;
563 fMacroLog.SetName("ProofLogMacro");
564
565 fWaitingSlaves = 0;
566 fQueries = 0;
567 fOtherQueries = 0;
568 fDrawQueries = 0;
569 fMaxDrawQueries = 1;
570 fSeqNum = 0;
571
572 fSessionID = -1;
574
575 fPackMgr = 0;
577
578 fInputData = 0;
579
580 fPrintProgress = 0;
581
582 fLoadedMacros = 0;
583
584 fProtocol = -1;
585 fSlaves = 0;
587 fBadSlaves = 0;
588 fAllMonitor = 0;
590 fBytesReady = 0;
591 fTotalBytes = 0;
594 fRunningDSets = 0;
595
596 fCollectTimeout = -1;
597
598 fManager = 0;
601
604 fMergers = 0;
605 fMergersCount = -1;
607 fWorkersToMerge = 0;
609
610 fPerfTree = "";
611
613
614 fSelector = 0;
615
616 fPrepTime = 0.;
617
618 // Check if the user defined a list of environment variables to send over:
619 // include them into the dedicated list
620 if (gSystem->Getenv("PROOF_ENVVARS")) {
621 TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
622 Int_t from = 0;
623 while (envs.Tokenize(env, from, ",")) {
624 if (!env.IsNull()) {
625 if (!gSystem->Getenv(env)) {
626 Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
627 } else {
628 if (!envsfound.IsNull()) envsfound += ",";
629 envsfound += env;
631 TProof::AddEnvVar(env, gSystem->Getenv(env));
632 }
633 }
634 }
635 if (envsfound.IsNull()) {
636 Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
637 } else {
638 Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
639 }
640 }
641
642 // Done
643 return;
644}
645
646////////////////////////////////////////////////////////////////////////////////
647/// Clean up PROOF environment.
648
650{
651 if (fChains) {
652 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
653 // remove "chain" from list
654 chain->SetProof(0);
655 RemoveChain(chain);
656 }
657 }
658
659 // remove links to packages enabled on the client
661 // iterate over all packages
663 if (epl) {
664 TIter nxp(epl);
665 while (TObjString *pck = (TObjString *)(nxp())) {
666 FileStat_t stat;
667 if (gSystem->GetPathInfo(pck->String(), stat) == 0) {
668 // check if symlink, if so unlink
669 // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
670 // existing file or to a directory, but if fIsLink is true the symlink exists
671 if (stat.fIsLink)
672 gSystem->Unlink(pck->String());
673 }
674 }
675 epl->Delete();
676 delete epl;
677 }
678 }
679
680 Close();
706 if (fWrksOutputReady) {
708 delete fWrksOutputReady;
709 }
710
711 // remove file with redirected logs
713 if (fLogFileR)
714 fclose(fLogFileR);
715 if (fLogFileW)
716 fclose(fLogFileW);
717 if (fLogFileName.Length() > 0)
719 }
720
721 // Remove for the global list
722 gROOT->GetListOfProofs()->Remove(this);
723 // ... and from the manager list
724 if (fManager && fManager->IsValid())
726
727 if (gProof && gProof == this) {
728 // Set previous as default
729 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
730 while ((gProof = (TProof *)pvp())) {
732 break;
733 }
734 }
735
736 // For those interested in our destruction ...
737 Emit("~TProof()");
738 Emit("CloseWindow()");
739}
740
741////////////////////////////////////////////////////////////////////////////////
742/// Start the PROOF environment. Starting PROOF involves either connecting
743/// to a master server, which in turn will start a set of slave servers, or
744/// directly starting as master server (if master = ""). For a description
745/// of the arguments see the TProof ctor. Returns the number of started
746/// master or slave servers, returns 0 in case of error, in which case
747/// fValid remains false.
748
749Int_t TProof::Init(const char *, const char *conffile,
750 const char *confdir, Int_t loglevel, const char *alias)
751{
753
754 fValid = kFALSE;
755
756 // Connected to terminal?
757 fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
758
759 // If in attach mode, options is filled with additional info
760 Bool_t attach = kFALSE;
761 if (strlen(fUrl.GetOptions()) > 0) {
762 attach = kTRUE;
763 // A flag from the GUI
764 TString opts = fUrl.GetOptions();
765 if (opts.Contains("GUI")) {
767 opts.Remove(opts.Index("GUI"));
768 fUrl.SetOptions(opts);
769 }
770 }
771
773 // Fill default conf file and conf dir
774 if (!conffile || !conffile[0])
776 if (!confdir || !confdir[0])
778 // The group; the client receives it in the kPROOF_SESSIONTAG message
780 } else {
781 fConfDir = confdir;
782 fConfFile = conffile;
783 }
784
785 // Analysise the conffile field
786 if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
788
790 fLogLevel = loglevel;
793 fImage = fMasterServ ? "" : "<local>";
794 fIntHandler = 0;
795 fStatus = 0;
796 fRecvMessages = new TList;
798 fSlaveInfo = 0;
799 fChains = new TList;
802 fRunningDSets = 0;
804 fInputData = 0;
806 fPrintProgress = 0;
807
808 // Timeout for some collect actions
809 fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
810
811 // Should the workers be started dynamically; default: no
812 fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
813
814 // Default entry point for the data pool is the master
816 fDataPoolUrl.Form("root://%s", fMaster.Data());
817 else
818 fDataPoolUrl = "";
819
820 fProgressDialog = 0;
822
823 // Default alias is the master name
824 TString al = (alias) ? alias : fMaster.Data();
825 SetAlias(al);
826
827 // Client logging of messages from the master and slaves
830 fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
831 if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
832 Error("Init", "could not create temporary logfile");
833 if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
834 Error("Init", "could not open temp logfile for reading");
835 }
837
838 // Status of cluster
839 fNotIdle = 0;
840 // Query type
841 fSync = (attach) ? kFALSE : kTRUE;
842 // Not enqueued
844
845 // Counters
846 fBytesRead = 0;
847 fRealTime = 0;
848 fCpuTime = 0;
849
850 // List of queries
851 fQueries = 0;
852 fOtherQueries = 0;
853 fDrawQueries = 0;
854 fMaxDrawQueries = 1;
855 fSeqNum = 0;
856
857 // Remote ID of the session
858 fSessionID = -1;
859
860 // Part of active query
861 fWaitingSlaves = 0;
862
863 // Make remote PROOF player
864 fPlayer = 0;
865 MakePlayer();
866
867 fFeedback = new TList;
869 fFeedback->SetName("FeedbackList");
871
872 // sort slaves by descending performance index
874 fActiveSlaves = new TList;
876 fUniqueSlaves = new TList;
879 fBadSlaves = new TList;
880 fAllMonitor = new TMonitor;
884 fCurrentMonitor = 0;
885
888
889 fLoadedMacros = 0;
890 fPackMgr = 0;
891
892 // Enable optimized sending of streamer infos to use embedded backward/forward
893 // compatibility support between different ROOT versions and different versions of
894 // users classes
895 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
896 if (enableSchemaEvolution) {
898 } else {
899 Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
900 }
901
902 if (IsMaster()) {
903 // to make UploadPackage() method work on the master as well.
905 } else {
906
907 TString sandbox;
908 if (GetSandbox(sandbox, kTRUE) != 0) {
909 Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
910 return 0;
911 }
912
913 // Package Dir
914 TString packdir = gEnv->GetValue("Proof.PackageDir", "");
915 if (packdir.IsNull())
916 packdir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
917 if (AssertPath(packdir, kTRUE) != 0) {
918 Error("Init", "failure asserting directory %s", packdir.Data());
919 return 0;
920 }
921 fPackMgr = new TPackMgr(packdir);
922 if (gDebug > 0)
923 Info("Init", "package directory set to %s", packdir.Data());
924 }
925
926 if (!IsMaster()) {
927 // List of directories where to look for global packages
928 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
930 Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
931 if (gDebug > 0)
932 Info("Init", " %d global package directories registered", nglb);
933 }
934
935 // Master may want dynamic startup
936 if (fDynamicStartup) {
937 if (!IsMaster()) {
938 // If on client - start the master
939 if (!StartSlaves(attach))
940 return 0;
941 }
942 } else {
943
944 // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
945 // result retrieving, ...)
946 Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
947 if (!IsMaster() || !masterOnly) {
948 // Start slaves (the old, static, per-session way)
949 if (!StartSlaves(attach))
950 return 0;
951 // Client: Is Master in dynamic startup mode?
952 if (!IsMaster()) {
953 Int_t dyn = 0;
954 GetRC("Proof.DynamicStartup", dyn);
955 if (dyn != 0) fDynamicStartup = kTRUE;
956 }
957 }
958 }
959 // we are now properly initialized
960 fValid = kTRUE;
961
962 // De-activate monitor (will be activated in Collect)
964
965 // By default go into parallel mode
966 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
967 TNamed *n = 0;
968 if (TProof::GetEnvVars() &&
969 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
970 TString s(n->GetTitle());
971 if (s.IsDigit()) nwrk = s.Atoi();
972 }
973 GoParallel(nwrk, attach);
974
975 // Send relevant initial state to slaves
976 if (!attach)
978 else if (!IsIdle())
979 // redirect log
981
982 // Done at this point, the alias will be communicated to the coordinator, if any
984 SetAlias(al);
985
987
988 if (IsValid()) {
989
990 // Activate input handler
992
994 gROOT->GetListOfSockets()->Add(this);
995 }
996
997 AskParallel();
998
999 return fActiveSlaves->GetSize();
1000}
1001
1002////////////////////////////////////////////////////////////////////////////////
1003/// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1004/// Use the existing setting or the default if nothing is found.
1005/// If 'assert' is kTRUE, make also sure that the path exists.
1006/// Return 0 on success, -1 on failure
1007
1008Int_t TProof::GetSandbox(TString &sb, Bool_t assert, const char *rc)
1009{
1010 // Get it from 'rc', if defined
1011 if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1012 // Or use the default 'rc'
1013 if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1014 // If nothing found , use the default
1015 if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1016 // Expand special settings
1017 if (sb == ".") {
1018 sb = gSystem->pwd();
1019 } else if (sb == "..") {
1020 sb = gSystem->DirName(gSystem->pwd());
1021 }
1023
1024 // Assert the path, if required
1025 if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1026 // Done
1027 return 0;
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// The config file field may contain special instructions which need to be
1032/// parsed at the beginning, e.g. for debug runs with valgrind.
1033/// Several options can be given separated by a ','
1034
1035void TProof::ParseConfigField(const char *config)
1036{
1037 TString sconf(config), opt;
1038 Ssiz_t from = 0;
1039 Bool_t cpuPin = kFALSE;
1040
1041 // Analysise the field
1042 const char *cq = (IsLite()) ? "\"" : "";
1043 while (sconf.Tokenize(opt, from, ",")) {
1044 if (opt.IsNull()) continue;
1045
1046 if (opt.BeginsWith("valgrind")) {
1047 // Any existing valgrind setting? User can give full settings, which we fully respect,
1048 // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1049 // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1050 // will add option "--time-stamp --leak-check=full" to our default options
1051 TString mst, top, sub, wrk, all;
1052 TList *envs = fgProofEnvList;
1053 TNamed *n = 0;
1054 if (envs) {
1055 if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1056 all = n->GetTitle();
1057 if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1058 mst = n->GetTitle();
1059 if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1060 top = n->GetTitle();
1061 if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1062 sub = n->GetTitle();
1063 if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1064 wrk = n->GetTitle();
1065 }
1066 if (all != "" && mst == "") mst = all;
1067 if (all != "" && top == "") top = all;
1068 if (all != "" && sub == "") sub = all;
1069 if (all != "" && wrk == "") wrk = all;
1070 if (all != "" && all.BeginsWith("valgrind_opts:")) {
1071 // The field is used to add an option Reset the setting
1072 Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1073 " must be set again for next run , if any");
1074 TProof::DelEnvVar("PROOF_WRAPPERCMD");
1075 }
1076 TString var, cmd;
1077 cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1078 TString mstlab("NO"), wrklab("NO");
1079 Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1080 !opt.Contains("topmaster") && !opt.Contains("submaster")))
1081 ? kTRUE : kFALSE;
1082 if (doMaster) {
1083 if (!IsLite()) {
1084 // Check if we have to add a var
1085 if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1086 mst.ReplaceAll("valgrind_opts:","");
1087 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1088 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1089 mstlab = "YES";
1090 } else if (mst != "") {
1091 mstlab = "YES";
1092 }
1093 } else {
1094 if (opt.Contains("master")) {
1095 Warning("ParseConfigField",
1096 "master valgrinding does not make sense for PROOF-Lite: ignoring");
1097 opt.ReplaceAll("master", "");
1098 if (!opt.Contains("workers")) return;
1099 }
1100 if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1101 }
1102 }
1103 if (opt.Contains("topmaster")) {
1104 // Check if we have to add a var
1105 if (top == "" || top.BeginsWith("valgrind_opts:")) {
1106 top.ReplaceAll("valgrind_opts:","");
1107 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1108 TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1109 mstlab = "YES";
1110 } else if (top != "") {
1111 mstlab = "YES";
1112 }
1113 }
1114 if (opt.Contains("submaster")) {
1115 // Check if we have to add a var
1116 if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1117 sub.ReplaceAll("valgrind_opts:","");
1118 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1119 TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1120 mstlab = "YES";
1121 } else if (sub != "") {
1122 mstlab = "YES";
1123 }
1124 }
1125 if (opt.Contains("=workers") || opt.Contains("+workers")) {
1126 // Check if we have to add a var
1127 if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1128 wrk.ReplaceAll("valgrind_opts:","");
1129 var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1130 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1131 TString nwrks("2");
1132 Int_t inw = opt.Index('#');
1133 if (inw != kNPOS) {
1134 nwrks = opt(inw+1, opt.Length());
1135 if (!nwrks.IsDigit()) nwrks = "2";
1136 }
1137 // Set the relevant variables
1138 if (!IsLite()) {
1139 TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1140 } else {
1141 gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1142 }
1143 wrklab = nwrks;
1144 // Register the additional worker log in the session file
1145 // (for the master this is done automatically)
1146 TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1147 } else if (wrk != "") {
1148 wrklab = "ALL";
1149 }
1150 }
1151 // Increase the relevant timeouts
1152 if (!IsLite()) {
1153 TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1154 gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1155 } else {
1156 gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1157 }
1158 // Warn for slowness
1159 Printf(" ");
1160 if (!IsLite()) {
1161 Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1162 } else {
1163 Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1164 }
1165 Printf(" ---> Please be patient: startup may be VERY slow ...");
1166 Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1167 Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1168 Printf(" ");
1169
1170 } else if (opt.BeginsWith("igprof-pp")) {
1171
1172 // IgProf profiling on master and worker. PROOF does not set the
1173 // environment for you: proper environment variables (like PATH and
1174 // LD_LIBRARY_PATH) should be set externally
1175
1176 Printf("*** Requested IgProf performance profiling ***");
1177 TString addLogExt = "__igprof.pp__.log";
1178 TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1179 TString tmp;
1180
1181 if (IsLite()) {
1182 addLogFmt.Append("\"");
1183 addLogFmt.Prepend("\"");
1184 }
1185
1186 tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1187 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1188
1189 tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1190 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1191
1192 TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1193
1194 } else if (opt.BeginsWith("cpupin=")) {
1195 // Enable CPU pinning. Takes as argument the list of processor IDs
1196 // that will be used in order. Processor IDs are numbered from 0,
1197 // use likwid to see how they are organized. A possible parameter
1198 // format would be:
1199 //
1200 // cpupin=3+4+0+9+10+22+7
1201 //
1202 // Only the specified processor IDs will be used in a round-robin
1203 // fashion, dealing with the fact that you can request more workers
1204 // than the number of processor IDs you have specified.
1205 //
1206 // To use all available processors in their order:
1207 //
1208 // cpupin=*
1209
1210 opt.Remove(0, 7);
1211
1212 // Remove any char which is neither a number nor a plus '+'
1213 for (Ssiz_t i=0; i<opt.Length(); i++) {
1214 Char_t c = opt[i];
1215 if ((c != '+') && ((c < '0') || (c > '9')))
1216 opt[i] = '_';
1217 }
1218 opt.ReplaceAll("_", "");
1219 TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1220 cpuPin = kTRUE;
1221 } else if (opt.BeginsWith("workers=")) {
1222
1223 // Request for a given number of workers (within the max) or worker
1224 // startup combination:
1225 // workers=5 start max 5 workers (or less, if less are assigned)
1226 // workers=2x start max 2 workers per node (or less, if less are assigned)
1227 opt.ReplaceAll("workers=","");
1228 TProof::AddEnvVar("PROOF_NWORKERS", opt);
1229 }
1230 }
1231
1232 // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1233 #ifdef R__LINUX
1234 if (IsLite() && cpuPin) {
1235 Printf("*** Requested CPU pinning ***");
1236 const TList *ev = GetEnvVars();
1237 const char *pinCmd = "taskset -c <cpupin>";
1238 TString val;
1239 TNamed *p;
1240 if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1241 val = p->GetTitle();
1242 val.Insert(val.Length()-1, " ");
1243 val.Insert(val.Length()-1, pinCmd);
1244 }
1245 else {
1246 val.Form("\"%s\"", pinCmd);
1247 }
1248 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1249 }
1250 #endif
1251}
1252
1253////////////////////////////////////////////////////////////////////////////////
1254/// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1255/// that the path is writable
1256
1257Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1258{
1259 if (!inpath || strlen(inpath) <= 0) {
1260 Error("AssertPath", "undefined input path");
1261 return -1;
1262 }
1263
1264 TString path(inpath);
1265 gSystem->ExpandPathName(path);
1266
1267 if (gSystem->AccessPathName(path, kFileExists)) {
1268 if (gSystem->mkdir(path, kTRUE) != 0) {
1269 Error("AssertPath", "could not create path %s", path.Data());
1270 return -1;
1271 }
1272 }
1273 // It must be writable
1274 if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1275 if (gSystem->Chmod(path, 0666) != 0) {
1276 Error("AssertPath", "could not make path %s writable", path.Data());
1277 return -1;
1278 }
1279 }
1280
1281 // Done
1282 return 0;
1283}
1284
1285////////////////////////////////////////////////////////////////////////////////
1286/// Set manager and schedule its destruction after this for clean
1287/// operations.
1288
1290{
1291 fManager = mgr;
1292
1293 if (mgr) {
1295 gROOT->GetListOfSockets()->Remove(mgr);
1296 gROOT->GetListOfSockets()->Add(mgr);
1297 }
1298}
1299
1300////////////////////////////////////////////////////////////////////////////////
1301/// Works on the master node only.
1302/// It starts workers on the machines in workerList and sets the paths,
1303/// packages and macros as on the master.
1304/// It is a subbstitute for StartSlaves(...)
1305/// The code is mostly the master part of StartSlaves,
1306/// with the parallel startup removed.
1307
1309{
1310 if (!IsMaster()) {
1311 Error("AddWorkers", "AddWorkers can only be called on the master!");
1312 return -1;
1313 }
1314
1315 if (!workerList || !(workerList->GetSize())) {
1316 Error("AddWorkers", "empty list of workers!");
1317 return -2;
1318 }
1319
1320 // Code taken from master part of StartSlaves with the parllel part removed
1321
1323 if (fImage.IsNull())
1325
1326 // Get all workers
1327 UInt_t nSlaves = workerList->GetSize();
1328 UInt_t nSlavesDone = 0;
1329 Int_t ord = 0;
1330
1331 // Loop over all new workers and start them (if we had already workers it means we are
1332 // increasing parallelism or that is not the first time we are called)
1333 Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1334
1335 // A list of TSlave objects for workers that are being added
1336 TList *addedWorkers = new TList();
1337 if (!addedWorkers) {
1338 // This is needed to silence Coverity ...
1339 Error("AddWorkers", "cannot create new list for the workers to be added");
1340 return -2;
1341 }
1342 addedWorkers->SetOwner(kFALSE);
1343 TListIter next(workerList);
1344 TObject *to;
1345 TProofNodeInfo *worker;
1346 TSlaveInfo *dummysi = new TSlaveInfo();
1347 while ((to = next())) {
1348 // Get the next worker from the list
1349 worker = (TProofNodeInfo *)to;
1350
1351 // Read back worker node info
1352 const Char_t *image = worker->GetImage().Data();
1353 const Char_t *workdir = worker->GetWorkDir().Data();
1354 Int_t perfidx = worker->GetPerfIndex();
1355 Int_t sport = worker->GetPort();
1356 if (sport == -1)
1357 sport = fUrl.GetPort();
1358
1359 // Create worker server
1360 TString fullord;
1361 if (worker->GetOrdinal().Length() > 0) {
1362 fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1363 } else {
1364 fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1365 }
1366
1367 // Remove worker from the list of workers terminated gracefully
1368 dummysi->SetOrdinal(fullord);
1370 SafeDelete(rmsi);
1371
1372 // Create worker server
1373 TString wn(worker->GetNodeName());
1374 if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1375 TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1376 // Add group info in the password firdl, if any
1377 if (strlen(gProofServ->GetGroup()) > 0) {
1378 // Set also the user, otherwise the password is not exported
1379 if (strlen(u.GetUser()) <= 0)
1382 }
1383 TSlave *slave = 0;
1384 if (worker->IsWorker()) {
1385 slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1386 } else {
1387 slave = CreateSubmaster(u.GetUrl(), fullord,
1388 image, worker->GetMsd(), worker->GetNWrks());
1389 }
1390
1391 // Add to global list (we will add to the monitor list after
1392 // finalizing the server startup)
1393 Bool_t slaveOk = kTRUE;
1394 fSlaves->Add(slave);
1395 if (slave->IsValid()) {
1396 addedWorkers->Add(slave);
1397 } else {
1398 slaveOk = kFALSE;
1399 fBadSlaves->Add(slave);
1400 Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1401 }
1402
1403 PDB(kGlobal,3)
1404 Info("AddWorkers", "worker on host %s created"
1405 " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1406
1407 // Notify opening of connection
1408 nSlavesDone++;
1410 m << TString("Opening connections to workers") << nSlaves
1411 << nSlavesDone << slaveOk;
1413
1414 ord++;
1415 } //end of the worker loop
1416 SafeDelete(dummysi);
1417
1418 // Cleanup
1419 SafeDelete(workerList);
1420
1421 nSlavesDone = 0;
1422
1423 // Here we finalize the server startup: in this way the bulk
1424 // of remote operations are almost parallelized
1425 TIter nxsl(addedWorkers);
1426 TSlave *sl = 0;
1427 while ((sl = (TSlave *) nxsl())) {
1428
1429 // Finalize setup of the server
1430 if (sl->IsValid())
1431 sl->SetupServ(TSlave::kSlave, 0);
1432
1433 // Monitor good slaves
1434 Bool_t slaveOk = kTRUE;
1435 if (sl->IsValid()) {
1436 fAllMonitor->Add(sl->GetSocket());
1437 PDB(kGlobal,3)
1438 Info("AddWorkers", "worker on host %s finalized"
1439 " and added to list", sl->GetOrdinal());
1440 } else {
1441 slaveOk = kFALSE;
1442 fBadSlaves->Add(sl);
1443 }
1444
1445 // Notify end of startup operations
1446 nSlavesDone++;
1448 m << TString("Setting up worker servers") << nSlaves
1449 << nSlavesDone << slaveOk;
1451 }
1452
1453 // Now set new state on the added workers (on all workers for simplicity)
1454 // use fEnabledPackages, fLoadedMacros,
1455 // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1456 // no need to load packages that are only loaded and not enabled (dyn mode)
1457 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1458 TNamed *n = 0;
1459 if (TProof::GetEnvVars() &&
1460 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1461 TString s(n->GetTitle());
1462 if (s.IsDigit()) nwrk = s.Atoi();
1463 }
1464
1465 if (fDynamicStartup && goMoreParallel) {
1466
1467 PDB(kGlobal, 3)
1468 Info("AddWorkers", "will invoke GoMoreParallel()");
1469 Int_t nw = GoMoreParallel(nwrk);
1470 PDB(kGlobal, 3)
1471 Info("AddWorkers", "GoMoreParallel()=%d", nw);
1472
1473 }
1474 else {
1475 // Not in Dynamic Workers mode
1476 PDB(kGlobal, 3)
1477 Info("AddWorkers", "will invoke GoParallel()");
1478 GoParallel(nwrk, kFALSE, 0);
1479 }
1480
1481 // Set worker processing environment
1482 SetupWorkersEnv(addedWorkers, goMoreParallel);
1483
1484 // Update list of current workers
1485 PDB(kGlobal, 3)
1486 Info("AddWorkers", "will invoke SaveWorkerInfo()");
1488
1489 // Inform the client that the number of workers has changed
1490 if (fDynamicStartup && gProofServ) {
1491 PDB(kGlobal, 3)
1492 Info("AddWorkers", "will invoke SendParallel()");
1494
1495 if (goMoreParallel && fPlayer) {
1496 // In case we are adding workers dynamically to an existing process, we
1497 // should invoke a special player's Process() to set only added workers
1498 // to the proper state
1499 PDB(kGlobal, 3)
1500 Info("AddWorkers", "will send the PROCESS message to selected workers");
1501 fPlayer->JoinProcess(addedWorkers);
1502 // Update merger counters (new workers are not yet active)
1503 fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1504 }
1505 }
1506
1507 // Cleanup
1508 delete addedWorkers;
1509
1510 return 0;
1511}
1512
1513////////////////////////////////////////////////////////////////////////////////
1514/// Set up packages, loaded macros, include and lib paths ...
1515
1516void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1517{
1518 // Packages
1520 if (packs && packs->GetSize() > 0) {
1521 TIter nxp(packs);
1522 TPair *pck = 0;
1523 while ((pck = (TPair *) nxp())) {
1524 // Upload and Enable methods are intelligent and avoid
1525 // re-uploading or re-enabling of a package to a node that has it.
1526 if (fDynamicStartup && increasingWorkers) {
1527 // Upload only on added workers
1528 PDB(kGlobal, 3)
1529 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1530 if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1531 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1532 } else {
1533 PDB(kGlobal, 3)
1534 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1535 if (UploadPackage(pck->GetName()) >= 0)
1536 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1537 }
1538 }
1539 }
1540
1541 // Loaded macros
1542 if (fLoadedMacros) {
1543 TIter nxp(fLoadedMacros);
1544 TObjString *os = 0;
1545 while ((os = (TObjString *) nxp())) {
1546 PDB(kGlobal, 3) {
1547 Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1548 Printf("Loading a macro : %s", os->GetName());
1549 }
1550 Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1551 }
1552 }
1553
1554 // Dynamic path
1556 dyn.ReplaceAll(":", " ");
1557 dyn.ReplaceAll("\"", " ");
1558 PDB(kGlobal, 3)
1559 Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1560 AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1561
1562 // Include path
1564 inc.ReplaceAll("-I", " ");
1565 inc.ReplaceAll("\"", " ");
1566 PDB(kGlobal, 3)
1567 Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1568 AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1569
1570 // Done
1571 return;
1572}
1573
1574////////////////////////////////////////////////////////////////////////////////
1575/// Used for shuting down the workres after a query is finished.
1576/// Sends each of the workers from the workerList, a kPROOF_STOP message.
1577/// If the workerList == 0, shutdown all the workers.
1578
1580{
1581 if (!IsMaster()) {
1582 Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1583 return -1;
1584 }
1585
1586 fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1587
1588 if (!workerList) {
1589 // shutdown all the workers
1590 TIter nxsl(fSlaves);
1591 TSlave *sl = 0;
1592 while ((sl = (TSlave *) nxsl())) {
1593 // Shut down the worker assumig that it is not processing
1594 TerminateWorker(sl);
1595 }
1596
1597 } else {
1598 if (!(workerList->GetSize())) {
1599 Error("RemoveWorkers", "The list of workers should not be empty!");
1600 return -2;
1601 }
1602
1603 // Loop over all the workers and stop them
1604 TListIter next(workerList);
1605 TObject *to;
1606 TProofNodeInfo *worker;
1607 while ((to = next())) {
1608 TSlave *sl = 0;
1609 if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1610 // Get the next worker from the list
1611 worker = (TProofNodeInfo *)to;
1612 TIter nxsl(fSlaves);
1613 while ((sl = (TSlave *) nxsl())) {
1614 // Shut down the worker assumig that it is not processing
1615 if (sl->GetName() == worker->GetNodeName())
1616 break;
1617 }
1618 } else if (to->InheritsFrom(TSlave::Class())) {
1619 sl = (TSlave *) to;
1620 } else {
1621 Warning("RemoveWorkers","unknown object type: %s - it should be"
1622 " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1623 }
1624 // Shut down the worker assumig that it is not processing
1625 if (sl) {
1626 if (gDebug > 0)
1627 Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1628 TerminateWorker(sl);
1629 }
1630 }
1631 }
1632
1633 // Update also the master counter
1634 if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1635
1636 return 0;
1637}
1638
1639////////////////////////////////////////////////////////////////////////////////
1640/// Start up PROOF slaves.
1641
1643{
1644 // If this is a master server, find the config file and start slave
1645 // servers as specified in the config file
1647
1648 Int_t pc = 0;
1649 TList *workerList = new TList;
1650 // Get list of workers
1651 if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1652 TString emsg("no resource currently available for this session: please retry later");
1653 if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1655 return kFALSE;
1656 }
1657 // Setup the workers
1658 if (AddWorkers(workerList) < 0)
1659 return kFALSE;
1660
1661 } else {
1662
1663 // create master server
1664 Printf("Starting master: opening connection ...");
1665 TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1666
1667 if (slave->IsValid()) {
1668
1669 // Notify
1670 fprintf(stderr,"Starting master:"
1671 " connection open: setting up server ... \r");
1672 StartupMessage("Connection to master opened", kTRUE, 1, 1);
1673
1674 if (!attach) {
1675
1676 // Set worker interrupt handler
1677 slave->SetInterruptHandler(kTRUE);
1678
1679 // Finalize setup of the server
1681
1682 if (slave->IsValid()) {
1683
1684 // Notify
1685 Printf("Starting master: OK ");
1686 StartupMessage("Master started", kTRUE, 1, 1);
1687
1688 // check protocol compatibility
1689 // protocol 1 is not supported anymore
1690 if (fProtocol == 1) {
1691 Error("StartSlaves",
1692 "client and remote protocols not compatible (%d and %d)",
1694 slave->Close("S");
1695 delete slave;
1696 return kFALSE;
1697 }
1698
1699 fSlaves->Add(slave);
1700 fAllMonitor->Add(slave->GetSocket());
1701
1702 // Unset worker interrupt handler
1704
1705 // Set interrupt PROOF handler from now on
1707
1708 // Give-up after 5 minutes
1709 Int_t rc = Collect(slave, 300);
1710 Int_t slStatus = slave->GetStatus();
1711 if (slStatus == -99 || slStatus == -98 || rc == 0) {
1712 fSlaves->Remove(slave);
1713 fAllMonitor->Remove(slave->GetSocket());
1714 if (slStatus == -99)
1715 Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1716 else if (slStatus == -98)
1717 Error("StartSlaves", "could not setup output redirection on master");
1718 else
1719 Error("StartSlaves", "setting up master");
1720 slave->Close("S");
1721 delete slave;
1722 return 0;
1723 }
1724
1725 if (!slave->IsValid()) {
1726 fSlaves->Remove(slave);
1727 fAllMonitor->Remove(slave->GetSocket());
1728 slave->Close("S");
1729 delete slave;
1730 Error("StartSlaves",
1731 "failed to setup connection with PROOF master server");
1732 return kFALSE;
1733 }
1734
1735 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1736 if ((fProgressDialog =
1737 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1738 if (fProgressDialog->LoadPlugin() == -1)
1739 fProgressDialog = 0;
1740 }
1741 } else {
1742 // Notify
1743 Printf("Starting master: failure");
1744 }
1745 } else {
1746
1747 // Notify
1748 Printf("Starting master: OK ");
1749 StartupMessage("Master attached", kTRUE, 1, 1);
1750
1751 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1752 if ((fProgressDialog =
1753 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1754 if (fProgressDialog->LoadPlugin() == -1)
1755 fProgressDialog = 0;
1756 }
1757
1758 fSlaves->Add(slave);
1760 }
1761
1762 } else {
1763 delete slave;
1764 // Notify only if verbosity is on: most likely the failure has already been notified
1765 if (gDebug > 0)
1766 Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1767 return kFALSE;
1768 }
1769 }
1770
1771 return kTRUE;
1772}
1773
1774////////////////////////////////////////////////////////////////////////////////
1775/// Close all open slave servers.
1776/// Client can decide to shutdown the remote session by passing option is 'S'
1777/// or 's'. Default for clients is detach, if supported. Masters always
1778/// shutdown the remote counterpart.
1779
1781{
1782 { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1783
1784 fValid = kFALSE;
1785 if (fSlaves) {
1786 if (fIntHandler)
1788
1789 TIter nxs(fSlaves);
1790 TSlave *sl = 0;
1791 while ((sl = (TSlave *)nxs()))
1792 sl->Close(opt);
1793
1794 fActiveSlaves->Clear("nodelete");
1795 fUniqueSlaves->Clear("nodelete");
1796 fAllUniqueSlaves->Clear("nodelete");
1797 fNonUniqueMasters->Clear("nodelete");
1798 fBadSlaves->Clear("nodelete");
1799 fInactiveSlaves->Clear("nodelete");
1800 fSlaves->Delete();
1801 }
1802 }
1803
1805 gROOT->GetListOfSockets()->Remove(this);
1806
1807 if (fChains) {
1808 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1809 // remove "chain" from list
1810 chain->SetProof(0);
1811 RemoveChain(chain);
1812 }
1813 }
1814
1815 if (IsProofd()) {
1816
1817 gROOT->GetListOfProofs()->Remove(this);
1818 if (gProof && gProof == this) {
1819 // Set previous proofd-related as default
1820 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1821 while ((gProof = (TProof *)pvp())) {
1822 if (gProof->IsProofd())
1823 break;
1824 }
1825 }
1826 }
1827 }
1828}
1829
1830////////////////////////////////////////////////////////////////////////////////
1831/// Create a new TSlave of type TSlave::kSlave.
1832/// Note: creation of TSlave is private with TProof as a friend.
1833/// Derived classes must use this function to create slaves.
1834
1835TSlave *TProof::CreateSlave(const char *url, const char *ord,
1836 Int_t perf, const char *image, const char *workdir)
1837{
1838 TSlave* sl = TSlave::Create(url, ord, perf, image,
1839 this, TSlave::kSlave, workdir, 0);
1840
1841 if (sl->IsValid()) {
1842 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1843 // must set fParallel to 1 for slaves since they do not
1844 // report their fParallel with a LOG_DONE message
1845 sl->fParallel = 1;
1846 }
1847
1848 return sl;
1849}
1850
1851
1852////////////////////////////////////////////////////////////////////////////////
1853/// Create a new TSlave of type TSlave::kMaster.
1854/// Note: creation of TSlave is private with TProof as a friend.
1855/// Derived classes must use this function to create slaves.
1856
1857TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1858 const char *image, const char *msd, Int_t nwk)
1859{
1860 TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1861 TSlave::kMaster, 0, msd, nwk);
1862
1863 if (sl->IsValid()) {
1864 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1865 }
1866
1867 return sl;
1868}
1869
1870////////////////////////////////////////////////////////////////////////////////
1871/// Find slave that has TSocket s. Returns 0 in case slave is not found.
1872
1874{
1875 TSlave *sl;
1876 TIter next(fSlaves);
1877
1878 while ((sl = (TSlave *)next())) {
1879 if (sl->IsValid() && sl->GetSocket() == s)
1880 return sl;
1881 }
1882 return 0;
1883}
1884
1885////////////////////////////////////////////////////////////////////////////////
1886/// Add to the fUniqueSlave list the active slaves that have a unique
1887/// (user) file system image. This information is used to transfer files
1888/// only once to nodes that share a file system (an image). Submasters
1889/// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1890/// list. That list is used to trigger the transferring of files to
1891/// the submaster's unique slaves without the need to transfer the file
1892/// to the submaster.
1893
1895{
1901
1902 TIter next(fActiveSlaves);
1903
1904 while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1905 if (fImage == sl->fImage) {
1906 if (sl->GetSlaveType() == TSlave::kMaster) {
1908 fAllUniqueSlaves->Add(sl);
1909 fAllUniqueMonitor->Add(sl->GetSocket());
1910 }
1911 continue;
1912 }
1913
1914 TIter next2(fUniqueSlaves);
1915 TSlave *replace_slave = 0;
1916 Bool_t add = kTRUE;
1917 while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1918 if (sl->fImage == sl2->fImage) {
1919 add = kFALSE;
1920 if (sl->GetSlaveType() == TSlave::kMaster) {
1921 if (sl2->GetSlaveType() == TSlave::kSlave) {
1922 // give preference to master
1923 replace_slave = sl2;
1924 add = kTRUE;
1925 } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1927 fAllUniqueSlaves->Add(sl);
1928 fAllUniqueMonitor->Add(sl->GetSocket());
1929 } else {
1930 Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1931 R__ASSERT(0);
1932 }
1933 }
1934 break;
1935 }
1936 }
1937
1938 if (add) {
1939 fUniqueSlaves->Add(sl);
1940 fAllUniqueSlaves->Add(sl);
1941 fUniqueMonitor->Add(sl->GetSocket());
1942 fAllUniqueMonitor->Add(sl->GetSocket());
1943 if (replace_slave) {
1944 fUniqueSlaves->Remove(replace_slave);
1945 fAllUniqueSlaves->Remove(replace_slave);
1946 fUniqueMonitor->Remove(replace_slave->GetSocket());
1947 fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1948 }
1949 }
1950 }
1951
1952 // will be actiavted in Collect()
1955}
1956
1957////////////////////////////////////////////////////////////////////////////////
1958/// Return number of slaves as described in the config file.
1959
1961{
1962 return fSlaves->GetSize();
1963}
1964
1965////////////////////////////////////////////////////////////////////////////////
1966/// Return number of active slaves, i.e. slaves that are valid and in
1967/// the current computing group.
1968
1970{
1971 return fActiveSlaves->GetSize();
1972}
1973
1974////////////////////////////////////////////////////////////////////////////////
1975/// Return number of inactive slaves, i.e. slaves that are valid but not in
1976/// the current computing group.
1977
1979{
1980 return fInactiveSlaves->GetSize();
1981}
1982
1983////////////////////////////////////////////////////////////////////////////////
1984/// Return number of unique slaves, i.e. active slaves that have each a
1985/// unique different user files system.
1986
1988{
1989 return fUniqueSlaves->GetSize();
1990}
1991
1992////////////////////////////////////////////////////////////////////////////////
1993/// Return number of bad slaves. This are slaves that we in the config
1994/// file, but refused to startup or that died during the PROOF session.
1995
1997{
1998 return fBadSlaves->GetSize();
1999}
2000
2001////////////////////////////////////////////////////////////////////////////////
2002/// Ask the for the statistics of the slaves.
2003
2005{
2006 if (!IsValid()) return;
2007
2010}
2011
2012////////////////////////////////////////////////////////////////////////////////
2013/// Get statistics about CPU time, real time and bytes read.
2014/// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2015/// and GetBytesRead()
2016
2018{
2019 if (fProtocol > 27) {
2020 // This returns the correct result
2021 AskStatistics();
2022 } else {
2023 // AskStatistics is buggy: parse the output of Print()
2026 Print();
2027 gSystem->RedirectOutput(0, 0, &rh);
2028 TMacro *mp = GetLastLog();
2029 if (mp) {
2030 // Look for global directories
2031 TIter nxl(mp->GetListOfLines());
2032 TObjString *os = 0;
2033 while ((os = (TObjString *) nxl())) {
2034 TString s(os->GetName());
2035 if (s.Contains("Total MB's processed:")) {
2036 s.ReplaceAll("Total MB's processed:", "");
2037 if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2038 } else if (s.Contains("Total real time used (s):")) {
2039 s.ReplaceAll("Total real time used (s):", "");
2040 if (s.IsFloat()) fRealTime = s.Atof();
2041 } else if (s.Contains("Total CPU time used (s):")) {
2042 s.ReplaceAll("Total CPU time used (s):", "");
2043 if (s.IsFloat()) fCpuTime = s.Atof();
2044 }
2045 }
2046 delete mp;
2047 }
2048 }
2049
2050 if (verbose) {
2051 Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2052 GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2053 }
2054}
2055
2056////////////////////////////////////////////////////////////////////////////////
2057/// Ask the for the number of parallel slaves.
2058
2060{
2061 if (!IsValid()) return;
2062
2065}
2066
2067////////////////////////////////////////////////////////////////////////////////
2068/// Ask the master for the list of queries.
2069
2071{
2072 if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2073
2074 Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2076 m << all;
2079
2080 // This should have been filled by now
2081 return fQueries;
2082}
2083
2084////////////////////////////////////////////////////////////////////////////////
2085/// Number of queries processed by this session
2086
2088{
2089 if (fQueries)
2090 return fQueries->GetSize() - fOtherQueries;
2091 return 0;
2092}
2093
2094////////////////////////////////////////////////////////////////////////////////
2095/// Set max number of draw queries whose results are saved
2096
2098{
2099 if (max > 0) {
2100 if (fPlayer)
2102 fMaxDrawQueries = max;
2103 }
2104}
2105
2106////////////////////////////////////////////////////////////////////////////////
2107/// Get max number of queries whose full results are kept in the
2108/// remote sandbox
2109
2111{
2113 m << kFALSE;
2116}
2117
2118////////////////////////////////////////////////////////////////////////////////
2119/// Return pointer to the list of query results in the player
2120
2122{
2123 return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2124}
2125
2126////////////////////////////////////////////////////////////////////////////////
2127/// Return pointer to the full TQueryResult instance owned by the player
2128/// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2129
2131{
2132 return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2133}
2134
2135////////////////////////////////////////////////////////////////////////////////
2136/// Ask the master for the list of queries.
2137/// Options:
2138/// "A" show information about all the queries known to the
2139/// server, i.e. even those processed by other sessions
2140/// "L" show only information about queries locally available
2141/// i.e. already retrieved. If "L" is specified, "A" is
2142/// ignored.
2143/// "F" show all details available about queries
2144/// "H" print help menu
2145/// Default ""
2146
2148{
2149 Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2150 if (help) {
2151
2152 // Help
2153
2154 Printf("+++");
2155 Printf("+++ Options: \"A\" show all queries known to server");
2156 Printf("+++ \"L\" show retrieved queries");
2157 Printf("+++ \"F\" full listing of query info");
2158 Printf("+++ \"H\" print this menu");
2159 Printf("+++");
2160 Printf("+++ (case insensitive)");
2161 Printf("+++");
2162 Printf("+++ Use Retrieve(<#>) to retrieve the full"
2163 " query results from the master");
2164 Printf("+++ e.g. Retrieve(8)");
2165
2166 Printf("+++");
2167
2168 return;
2169 }
2170
2171 if (!IsValid()) return;
2172
2173 Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2174
2175 TObject *pq = 0;
2176 if (!local) {
2177 GetListOfQueries(opt);
2178
2179 if (!fQueries) return;
2180
2181 TIter nxq(fQueries);
2182
2183 // Queries processed by other sessions
2184 if (fOtherQueries > 0) {
2185 Printf("+++");
2186 Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2187 Int_t nq = 0;
2188 while (nq++ < fOtherQueries && (pq = nxq()))
2189 pq->Print(opt);
2190 }
2191
2192 // Queries processed by this session
2193 Printf("+++");
2194 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2196 while ((pq = nxq()))
2197 pq->Print(opt);
2198
2199 } else {
2200
2201 // Queries processed by this session
2202 Printf("+++");
2203 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2205
2206 // Queries available locally
2207 TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2208 if (listlocal) {
2209 Printf("+++");
2210 Printf("+++ Queries available locally: %d", listlocal->GetSize());
2211 TIter nxlq(listlocal);
2212 while ((pq = nxlq()))
2213 pq->Print(opt);
2214 }
2215 }
2216 Printf("+++");
2217}
2218
2219////////////////////////////////////////////////////////////////////////////////
2220/// See if the data is ready to be analyzed.
2221
2223{
2224 if (!IsValid()) return kFALSE;
2225
2226 TList submasters;
2227 TIter nextSlave(GetListOfActiveSlaves());
2228 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2229 if (sl->GetSlaveType() == TSlave::kMaster) {
2230 submasters.Add(sl);
2231 }
2232 }
2233
2234 fDataReady = kTRUE; //see if any submasters set it to false
2235 fBytesReady = 0;
2236 fTotalBytes = 0;
2237 //loop over submasters and see if data is ready
2238 if (submasters.GetSize() > 0) {
2239 Broadcast(kPROOF_DATA_READY, &submasters);
2240 Collect(&submasters);
2241 }
2242
2243 bytesready = fBytesReady;
2244 totalbytes = fTotalBytes;
2245
2246 EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2247
2248 PDB(kGlobal,2)
2249 Info("IsDataReady", "%lld / %lld (%s)",
2250 bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2251
2252 return fDataReady;
2253}
2254
2255////////////////////////////////////////////////////////////////////////////////
2256/// Send interrupt to master or slave servers.
2257
2259{
2260 if (!IsValid()) return;
2261
2262 TList *slaves = 0;
2263 if (list == kAll) slaves = fSlaves;
2264 if (list == kActive) slaves = fActiveSlaves;
2265 if (list == kUnique) slaves = fUniqueSlaves;
2266 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2267
2268 if (slaves->GetSize() == 0) return;
2269
2270 TSlave *sl;
2271 TIter next(slaves);
2272
2273 while ((sl = (TSlave *)next())) {
2274 if (sl->IsValid()) {
2275
2276 // Ask slave to progate the interrupt request
2277 sl->Interrupt((Int_t)type);
2278 }
2279 }
2280}
2281
2282////////////////////////////////////////////////////////////////////////////////
2283/// Returns number of slaves active in parallel mode. Returns 0 in case
2284/// there are no active slaves. Returns -1 in case of error.
2285
2287{
2288 if (!IsValid()) return -1;
2289
2290 // iterate over active slaves and return total number of slaves
2291 TIter nextSlave(GetListOfActiveSlaves());
2292 Int_t nparallel = 0;
2293 while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2294 if (sl->GetParallel() >= 0)
2295 nparallel += sl->GetParallel();
2296
2297 return nparallel;
2298}
2299
2300////////////////////////////////////////////////////////////////////////////////
2301/// Returns list of TSlaveInfo's. In case of error return 0.
2302
2304{
2305 if (!IsValid()) return 0;
2306
2307 if (fSlaveInfo == 0) {
2310 } else {
2311 fSlaveInfo->Delete();
2312 }
2313
2314 TList masters;
2315 TIter next(GetListOfSlaves());
2316 TSlave *slave;
2317
2318 while ((slave = (TSlave *) next()) != 0) {
2319 if (slave->GetSlaveType() == TSlave::kSlave) {
2320 const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2321 TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2322 name,
2323 slave->GetPerfIdx());
2324 fSlaveInfo->Add(slaveinfo);
2325
2326 TIter nextactive(GetListOfActiveSlaves());
2327 TSlave *activeslave;
2328 while ((activeslave = (TSlave *) nextactive())) {
2329 if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2330 slaveinfo->SetStatus(TSlaveInfo::kActive);
2331 break;
2332 }
2333 }
2334
2335 TIter nextbad(GetListOfBadSlaves());
2336 TSlave *badslave;
2337 while ((badslave = (TSlave *) nextbad())) {
2338 if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2339 slaveinfo->SetStatus(TSlaveInfo::kBad);
2340 break;
2341 }
2342 }
2343 // Get system info if supported
2344 if (slave->IsValid()) {
2345 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2346 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2347 else
2348 masters.Add(slave);
2349 }
2350
2351 } else if (slave->GetSlaveType() == TSlave::kMaster) {
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 } else {
2359 Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2360 R__ASSERT(0);
2361 }
2362 }
2363 if (masters.GetSize() > 0) Collect(&masters);
2364
2365 return fSlaveInfo;
2366}
2367
2368////////////////////////////////////////////////////////////////////////////////
2369/// Activate slave server list.
2370
2372{
2373 TMonitor *mon = fAllMonitor;
2374 mon->DeActivateAll();
2375
2376 slaves = !slaves ? fActiveSlaves : slaves;
2377
2378 TIter next(slaves);
2379 TSlave *sl;
2380 while ((sl = (TSlave*) next())) {
2381 if (sl->IsValid())
2382 mon->Activate(sl->GetSocket());
2383 }
2384}
2385
2386////////////////////////////////////////////////////////////////////////////////
2387/// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2388/// monitored by 'mon'.
2389
2391{
2392 TMonitor *m = (mon) ? mon : fCurrentMonitor;
2393 if (m) {
2394 if (on)
2395 m->ActivateAll();
2396 else
2397 m->DeActivateAll();
2398 }
2399}
2400
2401////////////////////////////////////////////////////////////////////////////////
2402/// Broadcast the group priority to all workers in the specified list. Returns
2403/// the number of workers the message was successfully sent to.
2404/// Returns -1 in case of error.
2405
2406Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2407{
2408 if (!IsValid()) return -1;
2409
2410 if (workers->GetSize() == 0) return 0;
2411
2412 int nsent = 0;
2413 TIter next(workers);
2414
2415 TSlave *wrk;
2416 while ((wrk = (TSlave *)next())) {
2417 if (wrk->IsValid()) {
2418 if (wrk->SendGroupPriority(grp, priority) == -1)
2419 MarkBad(wrk, "could not send group priority");
2420 else
2421 nsent++;
2422 }
2423 }
2424
2425 return nsent;
2426}
2427
2428////////////////////////////////////////////////////////////////////////////////
2429/// Broadcast the group priority to all workers in the specified list. Returns
2430/// the number of workers the message was successfully sent to.
2431/// Returns -1 in case of error.
2432
2433Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2434{
2435 TList *workers = 0;
2436 if (list == kAll) workers = fSlaves;
2437 if (list == kActive) workers = fActiveSlaves;
2438 if (list == kUnique) workers = fUniqueSlaves;
2439 if (list == kAllUnique) workers = fAllUniqueSlaves;
2440
2441 return BroadcastGroupPriority(grp, priority, workers);
2442}
2443
2444////////////////////////////////////////////////////////////////////////////////
2445/// Reset the merge progress notificator
2446
2448{
2450}
2451
2452////////////////////////////////////////////////////////////////////////////////
2453/// Broadcast a message to all slaves in the specified list. Returns
2454/// the number of slaves the message was successfully sent to.
2455/// Returns -1 in case of error.
2456
2458{
2459 if (!IsValid()) return -1;
2460
2461 if (!slaves || slaves->GetSize() == 0) return 0;
2462
2463 int nsent = 0;
2464 TIter next(slaves);
2465
2466 TSlave *sl;
2467 while ((sl = (TSlave *)next())) {
2468 if (sl->IsValid()) {
2469 if (sl->GetSocket()->Send(mess) == -1)
2470 MarkBad(sl, "could not broadcast request");
2471 else
2472 nsent++;
2473 }
2474 }
2475
2476 return nsent;
2477}
2478
2479////////////////////////////////////////////////////////////////////////////////
2480/// Broadcast a message to all slaves in the specified list (either
2481/// all slaves or only the active slaves). Returns the number of slaves
2482/// the message was successfully sent to. Returns -1 in case of error.
2483
2485{
2486 TList *slaves = 0;
2487 if (list == kAll) slaves = fSlaves;
2488 if (list == kActive) slaves = fActiveSlaves;
2489 if (list == kUnique) slaves = fUniqueSlaves;
2490 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2491
2492 return Broadcast(mess, slaves);
2493}
2494
2495////////////////////////////////////////////////////////////////////////////////
2496/// Broadcast a character string buffer to all slaves in the specified
2497/// list. Use kind to set the TMessage what field. Returns the number of
2498/// slaves the message was sent to. Returns -1 in case of error.
2499
2500Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2501{
2502 TMessage mess(kind);
2503 if (str) mess.WriteString(str);
2504 return Broadcast(mess, slaves);
2505}
2506
2507////////////////////////////////////////////////////////////////////////////////
2508/// Broadcast a character string buffer to all slaves in the specified
2509/// list (either all slaves or only the active slaves). Use kind to
2510/// set the TMessage what field. Returns the number of slaves the message
2511/// was sent to. Returns -1 in case of error.
2512
2513Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2514{
2515 TMessage mess(kind);
2516 if (str) mess.WriteString(str);
2517 return Broadcast(mess, list);
2518}
2519
2520////////////////////////////////////////////////////////////////////////////////
2521/// Broadcast an object to all slaves in the specified list. Use kind to
2522/// set the TMEssage what field. Returns the number of slaves the message
2523/// was sent to. Returns -1 in case of error.
2524
2526{
2527 TMessage mess(kind);
2528 mess.WriteObject(obj);
2529 return Broadcast(mess, slaves);
2530}
2531
2532////////////////////////////////////////////////////////////////////////////////
2533/// Broadcast an object to all slaves in the specified list. Use kind to
2534/// set the TMEssage what field. Returns the number of slaves the message
2535/// was sent to. Returns -1 in case of error.
2536
2538{
2539 TMessage mess(kind);
2540 mess.WriteObject(obj);
2541 return Broadcast(mess, list);
2542}
2543
2544////////////////////////////////////////////////////////////////////////////////
2545/// Broadcast a raw buffer of specified length to all slaves in the
2546/// specified list. Returns the number of slaves the buffer was sent to.
2547/// Returns -1 in case of error.
2548
2549Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2550{
2551 if (!IsValid()) return -1;
2552
2553 if (slaves->GetSize() == 0) return 0;
2554
2555 int nsent = 0;
2556 TIter next(slaves);
2557
2558 TSlave *sl;
2559 while ((sl = (TSlave *)next())) {
2560 if (sl->IsValid()) {
2561 if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2562 MarkBad(sl, "could not send broadcast-raw request");
2563 else
2564 nsent++;
2565 }
2566 }
2567
2568 return nsent;
2569}
2570
2571////////////////////////////////////////////////////////////////////////////////
2572/// Broadcast a raw buffer of specified length to all slaves in the
2573/// specified list. Returns the number of slaves the buffer was sent to.
2574/// Returns -1 in case of error.
2575
2576Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2577{
2578 TList *slaves = 0;
2579 if (list == kAll) slaves = fSlaves;
2580 if (list == kActive) slaves = fActiveSlaves;
2581 if (list == kUnique) slaves = fUniqueSlaves;
2582 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2583
2584 return BroadcastRaw(buffer, length, slaves);
2585}
2586
2587////////////////////////////////////////////////////////////////////////////////
2588/// Broadcast file to all workers in the specified list. Returns the number of workers
2589/// the buffer was sent to.
2590/// Returns -1 in case of error.
2591
2592Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2593{
2594 if (!IsValid()) return -1;
2595
2596 if (wrks->GetSize() == 0) return 0;
2597
2598 int nsent = 0;
2599 TIter next(wrks);
2600
2601 TSlave *wrk;
2602 while ((wrk = (TSlave *)next())) {
2603 if (wrk->IsValid()) {
2604 if (SendFile(file, opt, rfile, wrk) < 0)
2605 Error("BroadcastFile",
2606 "problems sending file to worker %s (%s)",
2607 wrk->GetOrdinal(), wrk->GetName());
2608 else
2609 nsent++;
2610 }
2611 }
2612
2613 return nsent;
2614}
2615
2616////////////////////////////////////////////////////////////////////////////////
2617/// Broadcast file to all workers in the specified list. Returns the number of workers
2618/// the buffer was sent to.
2619/// Returns -1 in case of error.
2620
2621Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2622{
2623 TList *wrks = 0;
2624 if (list == kAll) wrks = fSlaves;
2625 if (list == kActive) wrks = fActiveSlaves;
2626 if (list == kUnique) wrks = fUniqueSlaves;
2627 if (list == kAllUnique) wrks = fAllUniqueSlaves;
2628
2629 return BroadcastFile(file, opt, rfile, wrks);
2630}
2631
2632////////////////////////////////////////////////////////////////////////////////
2633/// Release the used monitor to be used, making sure to delete newly created
2634/// monitors.
2635
2637{
2638 if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2639 && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2640 delete mon;
2641 }
2642}
2643
2644////////////////////////////////////////////////////////////////////////////////
2645/// Collect responses from slave sl. Returns the number of slaves that
2646/// responded (=1).
2647/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2648/// which means wait forever).
2649/// If defined (>= 0) endtype is the message that stops this collection.
2650
2651Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2652{
2653 Int_t rc = 0;
2654
2655 TMonitor *mon = 0;
2656 if (!sl->IsValid()) return 0;
2657
2659 mon = new TMonitor;
2660 } else {
2661 mon = fAllMonitor;
2662 mon->DeActivateAll();
2663 }
2664 mon->Activate(sl->GetSocket());
2665
2666 rc = Collect(mon, timeout, endtype, deactonfail);
2667 ReleaseMonitor(mon);
2668 return rc;
2669}
2670
2671////////////////////////////////////////////////////////////////////////////////
2672/// Collect responses from the slave servers. Returns the number of slaves
2673/// that responded.
2674/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2675/// which means wait forever).
2676/// If defined (>= 0) endtype is the message that stops this collection.
2677
2678Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2679{
2680 Int_t rc = 0;
2681
2682 TMonitor *mon = 0;
2683
2685 mon = new TMonitor;
2686 } else {
2687 mon = fAllMonitor;
2688 mon->DeActivateAll();
2689 }
2690 TIter next(slaves);
2691 TSlave *sl;
2692 while ((sl = (TSlave*) next())) {
2693 if (sl->IsValid())
2694 mon->Activate(sl->GetSocket());
2695 }
2696
2697 rc = Collect(mon, timeout, endtype, deactonfail);
2698 ReleaseMonitor(mon);
2699 return rc;
2700}
2701
2702////////////////////////////////////////////////////////////////////////////////
2703/// Collect responses from the slave servers. Returns the number of slaves
2704/// that responded.
2705/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2706/// which means wait forever).
2707/// If defined (>= 0) endtype is the message that stops this collection.
2708
2709Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2710{
2711 Int_t rc = 0;
2712 TMonitor *mon = 0;
2713
2714 if (list == kAll) mon = fAllMonitor;
2715 if (list == kActive) mon = fActiveMonitor;
2716 if (list == kUnique) mon = fUniqueMonitor;
2717 if (list == kAllUnique) mon = fAllUniqueMonitor;
2718 if (fCurrentMonitor == mon) {
2719 // Get a copy
2720 mon = new TMonitor(*mon);
2721 }
2722 mon->ActivateAll();
2723
2724 rc = Collect(mon, timeout, endtype, deactonfail);
2725 ReleaseMonitor(mon);
2726 return rc;
2727}
2728
2729////////////////////////////////////////////////////////////////////////////////
2730/// Collect responses from the slave servers. Returns the number of messages
2731/// received. Can be 0 if there are no active slaves.
2732/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2733/// which means wait forever).
2734/// If defined (>= 0) endtype is the message that stops this collection.
2735/// Collect also stops its execution from time to time to check for new
2736/// workers in Dynamic Startup mode.
2737
2738Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2739{
2740 Int_t collectId = gRandom->Integer(9999);
2741
2742 PDB(kCollect, 3)
2743 Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2744
2745 // Reset the status flag and clear the messages in the list, if any
2746 fStatus = 0;
2748
2749 Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2750
2751 if (!mon->GetActive(actto)) return 0;
2752
2754
2755 // Used by external code to know what we are monitoring
2756 TMonitor *savedMonitor = 0;
2757 if (fCurrentMonitor) {
2758 savedMonitor = fCurrentMonitor;
2759 fCurrentMonitor = mon;
2760 } else {
2761 fCurrentMonitor = mon;
2762 fBytesRead = 0;
2763 fRealTime = 0.0;
2764 fCpuTime = 0.0;
2765 }
2766
2767 // We want messages on the main window during synchronous collection,
2768 // but we save the present status to restore it at the end
2769 Bool_t saveRedirLog = fRedirLog;
2770 if (!IsIdle() && !IsSync())
2771 fRedirLog = kFALSE;
2772
2773 int cnt = 0, rc = 0;
2774
2775 // Timeout counter
2776 Long_t nto = timeout;
2777 PDB(kCollect, 2)
2778 Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2779
2780 // On clients, handle Ctrl-C during collection
2781 if (fIntHandler)
2782 fIntHandler->Add();
2783
2784 // Sockets w/o activity during the last 'sto' millisecs are deactivated
2785 Int_t nact = 0;
2786 Long_t sto = -1;
2787 Int_t nsto = 60;
2788 Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2789 mon->ResetInterrupt();
2790 while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2791
2792 // Dump last waiting sockets, if in debug mode
2793 PDB(kCollect, 2) {
2794 if (nact < 4) {
2795 TList *al = mon->GetListOfActives();
2796 if (al && al->GetSize() > 0) {
2797 Info("Collect"," %d node(s) still active:", al->GetSize());
2798 TIter nxs(al);
2799 TSocket *xs = 0;
2800 while ((xs = (TSocket *)nxs())) {
2801 TSlave *wrk = FindSlave(xs);
2802 if (wrk)
2803 Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2804 else
2805 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2806 xs->GetInetAddress().GetPort());
2807 }
2808 }
2809 }
2810 }
2811
2812 // Preemptive poll for new workers on the master only in Dynamic Mode and only
2813 // during processing (TODO: should work on Top Master only)
2815 ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2818 fLastPollWorkers_s = time(0);
2820 PDB(kCollect, 1)
2821 Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2822 }
2823
2824 // Wait for a ready socket
2825 PDB(kCollect, 3)
2826 Info("Collect", "Will invoke Select() #%04d", collectId);
2827 TSocket *s = mon->Select(1000);
2828
2829 if (s && s != (TSocket *)(-1)) {
2830 // Get and analyse the info it did receive
2831 rc = CollectInputFrom(s, endtype, deactonfail);
2832 if (rc == 1 || (rc == 2 && !savedMonitor)) {
2833 // Deactivate it if we are done with it
2834 mon->DeActivate(s);
2835 PDB(kCollect, 2)
2836 Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2837 s, mon->GetActive(),
2838 mon->GetListOfActives()->First());
2839 } else if (rc == 2) {
2840 // This end message was for the saved monitor
2841 // Deactivate it if we are done with it
2842 if (savedMonitor) {
2843 savedMonitor->DeActivate(s);
2844 PDB(kCollect, 2)
2845 Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2846 s, savedMonitor->GetActive(),
2847 savedMonitor->GetListOfActives()->First());
2848 }
2849 }
2850
2851 // Update counter (if no error occured)
2852 if (rc >= 0)
2853 cnt++;
2854 } else {
2855 // If not timed-out, exit if not stopped or not aborted
2856 // (player exits status is finished in such a case); otherwise,
2857 // we still need to collect the partial output info
2858 if (!s)
2860 mon->DeActivateAll();
2861 // Decrease the timeout counter if requested
2862 if (s == (TSocket *)(-1) && nto > 0)
2863 nto--;
2864 }
2865
2866 // Check if there are workers with ready output to be sent and ask the first to send it
2868 // Maximum number of concurrent sendings
2869 Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2870 if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2871 mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2872 TIter nxwr(fWrksOutputReady);
2873 TSlave *wrk = 0;
2874 while (mxws && (wrk = (TSlave *) nxwr())) {
2875 if (!wrk->TestBit(TSlave::kOutputRequested)) {
2876 // Ask worker for output
2877 TMessage sendoutput(kPROOF_SENDOUTPUT);
2878 PDB(kCollect, 2)
2879 Info("Collect", "worker %s was asked to send its output to master",
2880 wrk->GetOrdinal());
2881 if (wrk->GetSocket()->Send(sendoutput) != 1) {
2883 mxws--;
2884 }
2885 } else {
2886 // Count
2887 mxws--;
2888 }
2889 }
2890 }
2891
2892 // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2893 sto = -1;
2894 if (--nsto <= 0) {
2895 sto = (Long_t) actto;
2896 nsto = 60;
2897 }
2898
2899 } // end loop over active monitors
2900
2901 // If timed-out, deactivate the remaining sockets
2902 if (nto == 0) {
2903 TList *al = mon->GetListOfActives();
2904 if (al && al->GetSize() > 0) {
2905 // Notify the name of those which did timeout
2906 Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2907 TIter nxs(al);
2908 TSocket *xs = 0;
2909 while ((xs = (TSocket *)nxs())) {
2910 TSlave *wrk = FindSlave(xs);
2911 if (wrk)
2912 Info("Collect"," %s", wrk->GetName());
2913 else
2914 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2915 xs->GetInetAddress().GetPort());
2916 }
2917 }
2918 mon->DeActivateAll();
2919 }
2920
2921 // Deactivate Ctrl-C special handler
2922 if (fIntHandler)
2924
2925 // make sure group view is up to date
2926 SendGroupView();
2927
2928 // Restore redirection setting
2929 fRedirLog = saveRedirLog;
2930
2931 // Restore the monitor
2932 fCurrentMonitor = savedMonitor;
2933
2935
2936 PDB(kCollect, 3)
2937 Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2938
2939 return cnt;
2940}
2941
2942////////////////////////////////////////////////////////////////////////////////
2943/// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2944/// them. Returns the number of new workers found, or <0 on errors.
2945
2947{
2948 // Requests for worker updates
2949 Int_t dummy = 0;
2950 TList *reqWorkers = new TList();
2951 reqWorkers->SetOwner(kFALSE);
2952
2953 if (!TestBit(TProof::kIsMaster)) {
2954 Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2955 return -1;
2956 }
2957 if (!gProofServ) {
2958 Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2959 return -1;
2960 }
2961
2962 gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2963
2964 // List of new workers only (TProofNodeInfo)
2965 TList *newWorkers = new TList();
2966 newWorkers->SetOwner(kTRUE);
2967
2968 TIter next(reqWorkers);
2969 TProofNodeInfo *ni;
2970 TString fullOrd;
2971 while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2972
2973 // Form the full ordinal
2974 fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2975
2976 TIter nextInner(fSlaves);
2977 TSlave *sl;
2978 Bool_t found = kFALSE;
2979 while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
2980 if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
2981 found = kTRUE;
2982 break;
2983 }
2984 }
2985
2986 if (found) delete ni;
2987 else {
2988 newWorkers->Add(ni);
2989 PDB(kGlobal, 1)
2990 Info("PollForNewWorkers", "New worker found: %s:%s",
2991 ni->GetNodeName().Data(), fullOrd.Data());
2992 }
2993 }
2994
2995 delete reqWorkers; // not owner
2996
2997 Int_t nNewWorkers = newWorkers->GetEntries();
2998
2999 // Add the new workers
3000 if (nNewWorkers > 0) {
3001 PDB(kGlobal, 1)
3002 Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
3003 Int_t rv = AddWorkers(newWorkers);
3004 if (rv < 0) {
3005 Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3006 return -1;
3007 }
3008 // Don't delete newWorkers: AddWorkers() will do that
3009 }
3010 else {
3011 PDB(kGlobal, 2)
3012 Info("PollForNewWorkers", "No new worker found");
3013 delete newWorkers;
3014 }
3015
3016 return nNewWorkers;
3017}
3018
3019////////////////////////////////////////////////////////////////////////////////
3020/// Remove links to objects in list 'ol' from gDirectory
3021
3023{
3024 if (ol) {
3025 TIter nxo(ol);
3026 TObject *o = 0;
3027 while ((o = nxo()))
3028 gDirectory->RecursiveRemove(o);
3029 }
3030}
3031
3032////////////////////////////////////////////////////////////////////////////////
3033/// Collect and analyze available input from socket s.
3034/// Returns 0 on success, -1 if any failure occurs.
3035
3037{
3038 TMessage *mess;
3039
3040 Int_t recvrc = 0;
3041 if ((recvrc = s->Recv(mess)) < 0) {
3042 PDB(kCollect,2)
3043 Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3044 Bool_t bad = kTRUE;
3045 if (recvrc == -5) {
3046 // Broken connection: try reconnection
3048 if (s->Reconnect() == 0) {
3050 bad = kFALSE;
3051 }
3052 }
3053 if (bad)
3054 MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3055 // Ignore this wake up
3056 return -1;
3057 }
3058 if (!mess) {
3059 // we get here in case the remote server died
3060 MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3061 return -1;
3062 }
3063 Int_t rc = 0;
3064
3065 Int_t what = mess->What();
3066 TSlave *sl = FindSlave(s);
3067 rc = HandleInputMessage(sl, mess, deactonfail);
3068 if (rc == 1 && (endtype >= 0) && (what != endtype))
3069 // This message was for the base monitor in recursive case
3070 rc = 2;
3071
3072 // We are done successfully
3073 return rc;
3074}
3075
3076////////////////////////////////////////////////////////////////////////////////
3077/// Analyze the received message.
3078/// Returns 0 on success (1 if this the last message from this socket), -1 if
3079/// any failure occurs.
3080
3082{
3083 char str[512];
3084 TObject *obj;
3085 Int_t rc = 0;
3086
3087 if (!mess || !sl) {
3088 Warning("HandleInputMessage", "given an empty message or undefined worker");
3089 return -1;
3090 }
3091 Bool_t delete_mess = kTRUE;
3092 TSocket *s = sl->GetSocket();
3093 if (!s) {
3094 Warning("HandleInputMessage", "worker socket is undefined");
3095 return -1;
3096 }
3097
3098 // The message type
3099 Int_t what = mess->What();
3100
3101 PDB(kCollect,3)
3102 Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3103
3104 switch (what) {
3105
3106 case kMESS_OK:
3107 // Add the message to the list
3108 fRecvMessages->Add(mess);
3109 delete_mess = kFALSE;
3110 break;
3111
3112 case kMESS_OBJECT:
3113 if (fPlayer) fPlayer->HandleRecvHisto(mess);
3114 break;
3115
3116 case kPROOF_FATAL:
3117 { TString msg;
3118 if ((mess->BufferSize() > mess->Length()))
3119 (*mess) >> msg;
3120 if (msg.IsNull()) {
3121 MarkBad(s, "received kPROOF_FATAL");
3122 } else {
3123 MarkBad(s, msg);
3124 }
3125 }
3127 // Finalize the progress dialog
3128 Emit("StopProcess(Bool_t)", kTRUE);
3129 }
3130 break;
3131
3132 case kPROOF_STOP:
3133 // Stop collection from this worker
3134 Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3135 sl->GetOrdinal());
3136 rc = 1;
3137 break;
3138
3140 // Add the message to the list
3141 fRecvMessages->Add(mess);
3142 delete_mess = kFALSE;
3143 rc = 1;
3144 break;
3145
3146 case kPROOF_TOUCH:
3147 // send a request for touching the remote admin file
3148 {
3149 sl->Touch();
3150 }
3151 break;
3152
3153 case kPROOF_GETOBJECT:
3154 // send slave object it asks for
3155 mess->ReadString(str, sizeof(str));
3156 obj = gDirectory->Get(str);
3157 if (obj)
3158 s->SendObject(obj);
3159 else
3160 s->Send(kMESS_NOTOK);
3161 break;
3162
3163 case kPROOF_GETPACKET:
3164 {
3165 PDB(kGlobal,2)
3166 Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3167 TDSetElement *elem = 0;
3168 elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3169
3170 if (elem != (TDSetElement*) -1) {
3172 answ << elem;
3173 s->Send(answ);
3174
3175 while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3176 TPair *p = (TPair*) fWaitingSlaves->First();
3177 s = (TSocket*) p->Key();
3178 TMessage *m = (TMessage*) p->Value();
3179
3180 elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3181 if (elem != (TDSetElement*) -1) {
3183 a << elem;
3184 s->Send(a);
3185 // remove has to happen via Links because TPair does not have
3186 // a Compare() function and therefore RemoveFirst() and
3187 // Remove(TObject*) do not work
3189 delete p;
3190 delete m;
3191 } else {
3192 break;
3193 }
3194 }
3195 } else {
3196 if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3197 fWaitingSlaves->Add(new TPair(s, mess));
3198 delete_mess = kFALSE;
3199 }
3200 }
3201 break;
3202
3203 case kPROOF_LOGFILE:
3204 {
3205 Int_t size;
3206 (*mess) >> size;
3207 PDB(kGlobal,2)
3208 Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3209 RecvLogFile(s, size);
3210 }
3211 break;
3212
3213 case kPROOF_LOGDONE:
3214 (*mess) >> sl->fStatus >> sl->fParallel;
3215 PDB(kCollect,2)
3216 Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3217 sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3218 if (sl->fStatus != 0) {
3219 // Return last nonzero status
3220 fStatus = sl->fStatus;
3221 // Deactivate the worker, if required
3222 if (deactonfail) DeactivateWorker(sl->fOrdinal);
3223 }
3224 // Remove from the workers-ready list
3228 }
3229 rc = 1;
3230 break;
3231
3232 case kPROOF_GETSTATS:
3233 {
3234 (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3235 >> sl->fWorkDir >> sl->fProofWorkDir;
3236 PDB(kCollect,2)
3237 Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3238 TString img;
3239 if ((mess->BufferSize() > mess->Length()))
3240 (*mess) >> img;
3241 // Set image
3242 if (img.IsNull()) {
3243 if (sl->fImage.IsNull())
3244 sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3245 sl->fProofWorkDir.Data());
3246 } else {
3247 sl->fImage = img;
3248 }
3249 PDB(kGlobal,2)
3250 Info("HandleInputMessage",
3251 "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3252
3253 fBytesRead += sl->fBytesRead;
3254 fRealTime += sl->fRealTime;
3255 fCpuTime += sl->fCpuTime;
3256 rc = 1;
3257 }
3258 break;
3259
3260 case kPROOF_GETPARALLEL:
3261 {
3262 Bool_t async = kFALSE;
3263 (*mess) >> sl->fParallel;
3264 if ((mess->BufferSize() > mess->Length()))
3265 (*mess) >> async;
3266 rc = (async) ? 0 : 1;
3267 }
3268 break;
3269
3270 case kPROOF_CHECKFILE:
3271 { // New servers (>= 5.22) send the status
3272 if ((mess->BufferSize() > mess->Length())) {
3273 (*mess) >> fCheckFileStatus;
3274 } else {
3275 // Form old servers this meant success (failure was signaled with the
3276 // dangerous kPROOF_FATAL)
3277 fCheckFileStatus = 1;
3278 }
3279 rc = 1;
3280 }
3281 break;
3282
3283 case kPROOF_SENDFILE:
3284 { // New server: signals ending of sendfile operation
3285 rc = 1;
3286 }
3287 break;
3288
3290 {
3291 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3292 Int_t type = 0;
3293 (*mess) >> type;
3294 switch (type) {
3298 if (fEnabledPackages) {
3300 } else {
3301 Error("HandleInputMessage",
3302 "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3303 }
3304 break;
3308 if (fAvailablePackages) {
3310 } else {
3311 Error("HandleInputMessage",
3312 "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3313 }
3314 break;
3315 default:
3316 Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3317 }
3318 }
3319 break;
3320
3321 case kPROOF_SENDOUTPUT:
3322 {
3323 // We start measuring the merging time
3325
3326 // Worker is ready to send output: make sure the relevant bit is reset
3328 PDB(kGlobal,2)
3329 Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3330 // Create the list if not yet done
3331 if (!fWrksOutputReady) {
3332 fWrksOutputReady = new TList;
3334 }
3335 fWrksOutputReady->Add(sl);
3336 }
3337 break;
3338
3340 {
3341 // We start measuring the merging time
3343
3344 PDB(kGlobal,2)
3345 Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3346 Int_t type = 0;
3347 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3349 Info("HandleInputMessage", "finalization on %s started ...", prefix);
3351 }
3352
3353 while ((mess->BufferSize() > mess->Length())) {
3354 (*mess) >> type;
3355 // If a query result header, add it to the player list
3356 if (fPlayer) {
3357 if (type == 0) {
3358 // Retrieve query result instance (output list not filled)
3359 TQueryResult *pq =
3361 if (pq) {
3362 // Add query to the result list in TProofPlayer
3365 // And clear the output list, as we start merging a new set of results
3366 if (fPlayer->GetOutputList())
3368 // Add the unique query tag as TNamed object to the input list
3369 // so that it is available in TSelectors for monitoring
3370 TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3371 if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3372 fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3373 fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3374 } else {
3375 Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3376 }
3377 } else if (type > 0) {
3378 // Read object
3379 TObject *o = mess->ReadObject(TObject::Class());
3380 // Increment counter on the client side
3382 TString msg;
3383 Bool_t changed = kFALSE;
3384 msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3385 if (gProofServ) {
3387 } else if (IsTty() || changed) {
3388 fprintf(stderr, "%s\r", msg.Data());
3389 }
3390 // Add or merge it
3391 if ((fPlayer->AddOutputObject(o) == 1)) {
3392 // Remove the object if it has been merged
3393 SafeDelete(o);
3394 }
3395 if (type > 1) {
3396 // Update the merger progress info
3398 if (TestBit(TProof::kIsClient) && !IsLite()) {
3399 // In PROOFLite this has to be done once only in TProofLite::Process
3401 if (pq) {
3403 // Add input objects (do not override remote settings, if any)
3404 TObject *xo = 0;
3405 TIter nxin(fPlayer->GetInputList());
3406 // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3407 if (!pq->GetInputList()) pq->SetInputList(new TList());
3408 while ((xo = nxin()))
3409 if (!pq->GetInputList()->FindObject(xo->GetName()))
3410 pq->AddInput(xo->Clone());
3411 // If the last object, notify the GUI that the result arrived
3412 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3413 }
3414 // Processing is over
3415 UpdateDialog();
3416 }
3417 }
3418 }
3419 } else {
3420 Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3421 }
3422 }
3423 }
3424 break;
3425
3426 case kPROOF_OUTPUTLIST:
3427 {
3428 // We start measuring the merging time
3430
3431 PDB(kGlobal,2)
3432 Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3433 TList *out = 0;
3434 if (fPlayer) {
3435 if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3436 out = (TList *) mess->ReadObject(TList::Class());
3437 } else {
3438 TQueryResult *pq =
3440 if (pq) {
3441 // Add query to the result list in TProofPlayer
3444 // To avoid accidental cleanups from anywhere else
3445 // remove objects from gDirectory and clone the list
3446 out = pq->GetOutputList();
3447 CleanGDirectory(out);
3448 out = (TList *) out->Clone();
3449 // Notify the GUI that the result arrived
3450 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3451 } else {
3452 PDB(kGlobal,2)
3453 Info("HandleInputMessage",
3454 "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3455 }
3456 }
3457 if (out) {
3458 out->SetOwner();
3459 fPlayer->AddOutput(out); // Incorporate the list
3460 SafeDelete(out);
3461 } else {
3462 PDB(kGlobal,2)
3463 Info("HandleInputMessage",
3464 "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3465 }
3466 } else {
3467 Warning("HandleInputMessage",
3468 "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3469 }
3470 // On clients at this point processing is over
3471 if (TestBit(TProof::kIsClient) && !IsLite())
3472 UpdateDialog();
3473 }
3474 break;
3475
3476 case kPROOF_QUERYLIST:
3477 {
3478 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3479 (*mess) >> fOtherQueries >> fDrawQueries;
3480 if (fQueries) {
3481 fQueries->Delete();
3482 delete fQueries;
3483 fQueries = 0;
3484 }
3485 fQueries = (TList *) mess->ReadObject(TList::Class());
3486 }
3487 break;
3488
3489 case kPROOF_RETRIEVE:
3490 {
3491 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3492 TQueryResult *pq =
3494 if (pq && fPlayer) {
3496 // Notify the GUI that the result arrived
3497 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3498 } else {
3499 PDB(kGlobal,2)
3500 Info("HandleInputMessage",
3501 "kPROOF_RETRIEVE: query result missing or player undefined");
3502 }
3503 }
3504 break;
3505
3506 case kPROOF_MAXQUERIES:
3507 {
3508 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3509 Int_t max = 0;
3510
3511 (*mess) >> max;
3512 Printf("Number of queries fully kept remotely: %d", max);
3513 }
3514 break;
3515
3517 {
3518 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3519
3520 UInt_t tot = 0, done = 0;
3521 TString action;
3522 Bool_t st = kTRUE;
3523
3524 (*mess) >> action >> tot >> done >> st;
3525
3527 if (tot) {
3528 TString type = (action.Contains("submas")) ? "submasters"
3529 : "workers";
3530 Int_t frac = (Int_t) (done*100.)/tot;
3531 char msg[512] = {0};
3532 if (frac >= 100) {
3533 snprintf(msg, 512, "%s: OK (%d %s) \n",
3534 action.Data(),tot, type.Data());
3535 } else {
3536 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3537 action.Data(), done, tot, frac);
3538 }
3539 if (fSync)
3540 fprintf(stderr,"%s", msg);
3541 else
3542 NotifyLogMsg(msg, 0);
3543 }
3544 // Notify GUIs
3545 StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3546 } else {
3547
3548 // Just send the message one level up
3550 m << action << tot << done << st;
3552 }
3553 }
3554 break;
3555
3557 {
3558 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3559
3560 UInt_t tot = 0, done = 0;
3561 TString action;
3562 Bool_t st = kTRUE;
3563
3564 (*mess) >> action >> tot >> done >> st;
3565
3567 if (tot) {
3568 TString type = "files";
3569 Int_t frac = (Int_t) (done*100.)/tot;
3570 char msg[512] = {0};
3571 if (frac >= 100) {
3572 snprintf(msg, 512, "%s: OK (%d %s) \n",
3573 action.Data(),tot, type.Data());
3574 } else {
3575 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3576 action.Data(), done, tot, frac);
3577 }
3578 if (fSync)
3579 fprintf(stderr,"%s", msg);
3580 else
3581 NotifyLogMsg(msg, 0);
3582 }
3583 // Notify GUIs
3584 DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3585 } else {
3586
3587 // Just send the message one level up
3589 m << action << tot << done << st;
3591 }
3592 }
3593 break;
3594
3596 {
3597 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3598
3599 // For Proof-Lite this variable is the number of workers and is set
3600 // by the player
3601 if (!IsLite()) {
3602 fNotIdle = 1;
3604 }
3605
3606 // Redirect the output, if needed
3608
3609 // The signal is used on masters by XrdProofdProtocol to catch
3610 // the start of processing; on clients it allows to update the
3611 // progress dialog
3612 if (!TestBit(TProof::kIsMaster)) {
3613
3614 // This is the end of preparation
3615 fQuerySTW.Stop();
3617 PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3618
3619 TString selec;
3620 Int_t dsz = -1;
3621 Long64_t first = -1, nent = -1;
3622 (*mess) >> selec >> dsz >> first >> nent;
3623 // Start or reset the progress dialog
3624 if (!gROOT->IsBatch()) {
3625 if (fProgressDialog &&
3628 fProgressDialog->ExecPlugin(5, this,
3629 selec.Data(), dsz, first, nent);
3631 } else {
3632 ResetProgressDialog(selec, dsz, first, nent);
3633 }
3634 }
3636 }
3637 }
3638 }
3639 break;
3640
3641 case kPROOF_ENDINIT:
3642 {
3643 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3644
3646 if (fPlayer)
3648 }
3649 }
3650 break;
3651
3652 case kPROOF_SETIDLE:
3653 {
3654 PDB(kGlobal,2)
3655 Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3656
3657 // The session is idle
3658 if (IsLite()) {
3659 if (fNotIdle > 0) {
3660 fNotIdle--;
3661 PDB(kGlobal,2)
3662 Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3663 } else {
3664 Warning("HandleInputMessage",
3665 "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3666 sl->GetOrdinal());
3667 }
3668 } else {
3669 fNotIdle = 0;
3670 // Check if the query has been enqueued
3671 if ((mess->BufferSize() > mess->Length()))
3672 (*mess) >> fIsWaiting;
3673 }
3674 }
3675 break;
3676
3678 {
3679 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3680
3681 // We have received the sequential number
3682 (*mess) >> fSeqNum;
3683 Bool_t sync = fSync;
3684 if ((mess->BufferSize() > mess->Length()))
3685 (*mess) >> sync;
3686 if (sync != fSync && fSync) {
3687 // The server required to switch to asynchronous mode
3688 Activate();
3689 fSync = kFALSE;
3690 }
3691 DisableGoAsyn();
3692 // Check if the query has been enqueued
3693 fIsWaiting = kTRUE;
3694 // For Proof-Lite this variable is the number of workers and is set by the player
3695 if (!IsLite())
3696 fNotIdle = 1;
3697
3698 rc = 1;
3699 }
3700 break;
3701
3702 case kPROOF_SESSIONTAG:
3703 {
3704 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3705
3706 // We have received the unique tag and save it as name of this object
3707 TString stag;
3708 (*mess) >> stag;
3709 SetName(stag);
3710 // In the TSlave object
3711 sl->SetSessionTag(stag);
3712 // Server may have also sent the group
3713 if ((mess->BufferSize() > mess->Length()))
3714 (*mess) >> fGroup;
3715 // Server may have also sent the user
3716 if ((mess->BufferSize() > mess->Length())) {
3717 TString usr;
3718 (*mess) >> usr;
3719 if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3720 }
3721 }
3722 break;
3723
3724 case kPROOF_FEEDBACK:
3725 {
3726 PDB(kGlobal,2)
3727 Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3728 TList *out = (TList *) mess->ReadObject(TList::Class());
3729 out->SetOwner();
3730 if (fPlayer)
3731 fPlayer->StoreFeedback(sl, out); // Adopts the list
3732 else
3733 // Not yet ready: stop collect asap
3734 rc = 1;
3735 }
3736 break;
3737
3738 case kPROOF_AUTOBIN:
3739 {
3740 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3741
3742 TString name;
3743 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3744
3745 (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3746
3748
3750
3751 answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3752
3753 s->Send(answ);
3754 }
3755 break;
3756
3757 case kPROOF_PROGRESS:
3758 {
3759 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3760
3761 if (GetRemoteProtocol() > 25) {
3762 // New format
3764 (*mess) >> pi;
3765 fPlayer->Progress(sl,pi);
3766 } else if (GetRemoteProtocol() > 11) {
3767 Long64_t total, processed, bytesread;
3768 Float_t initTime, procTime, evtrti, mbrti;
3769 (*mess) >> total >> processed >> bytesread
3770 >> initTime >> procTime
3771 >> evtrti >> mbrti;
3772 if (fPlayer)
3773 fPlayer->Progress(sl, total, processed, bytesread,
3774 initTime, procTime, evtrti, mbrti);
3775
3776 } else {
3777 // Old format
3778 Long64_t total, processed;
3779 (*mess) >> total >> processed;
3780 if (fPlayer)
3781 fPlayer->Progress(sl, total, processed);
3782 }
3783 }
3784 break;
3785
3786 case kPROOF_STOPPROCESS:
3787 {
3788 // This message is sent from a worker that finished processing.
3789 // We determine whether it was asked to finish by the
3790 // packetizer or stopped during processing a packet
3791 // (by TProof::RemoveWorkers() or by an external signal).
3792 // In the later case call packetizer->MarkBad.
3793 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3794
3795 Long64_t events = 0;
3796 Bool_t abort = kFALSE;
3797 TProofProgressStatus *status = 0;
3798
3799 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3800 (*mess) >> status >> abort;
3801 } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3802 (*mess) >> events >> abort;
3803 } else {
3804 (*mess) >> events;
3805 }
3806 if (fPlayer) {
3807 if (fProtocol > 18) {
3808 TList *listOfMissingFiles = 0;
3809 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3810 listOfMissingFiles = new TList();
3811 listOfMissingFiles->SetName("MissingFiles");
3812 if (fPlayer)
3813 fPlayer->AddOutputObject(listOfMissingFiles);
3814 }
3815 if (fPlayer->GetPacketizer()) {
3816 Int_t ret =
3817 fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3818 if (ret > 0)
3819 fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3820 // This object is now owned by the packetizer
3821 status = 0;
3822 }
3823 if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3824 } else {
3825 fPlayer->AddEventsProcessed(events);
3826 }
3827 }
3828 SafeDelete(status);
3830 Emit("StopProcess(Bool_t)", abort);
3831 break;
3832 }
3833
3834 case kPROOF_SUBMERGER:
3835 {
3836 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3837 HandleSubmerger(mess, sl);
3838 }
3839 break;
3840
3842 {
3843 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3844
3845 Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3846 Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3847 TList* tmpinfo = 0;
3848 (*mess) >> tmpinfo;
3849 if (tmpinfo == 0) {
3850 Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3851 } else {
3852 tmpinfo->SetOwner(kFALSE);
3853 Int_t nentries = tmpinfo->GetSize();
3854 for (Int_t i=0; i<nentries; i++) {
3855 TSlaveInfo* slinfo =
3856 dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3857 if (slinfo) {
3858 // If PROOF-Lite
3859 if (IsLite()) slinfo->fHostName = gSystem->HostName();
3860 // Check if we have already a instance for this worker
3861 TIter nxw(fSlaveInfo);
3862 TSlaveInfo *ourwi = 0;
3863 while ((ourwi = (TSlaveInfo *)nxw())) {
3864 if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3865 ourwi->SetSysInfo(slinfo->GetSysInfo());
3866 ourwi->fHostName = slinfo->GetName();
3867 if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3868 ourwi->fDataDir = slinfo->GetDataDir();
3869 break;
3870 }
3871 }
3872 if (!ourwi) {
3873 fSlaveInfo->Add(slinfo);
3874 } else {
3875 slinfo = ourwi;
3876 }
3877 if (slinfo->fStatus != TSlaveInfo::kBad) {
3878 if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3879 if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3880 }
3881 if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3882 slinfo->fMsd = sl->GetMsd();
3883 }
3884 }
3885 delete tmpinfo;
3886 rc = 1;
3887 }
3888 }
3889 break;
3890
3892 {
3893 PDB(kGlobal,2)
3894 Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3895 TDSet* dset = 0;
3896 (*mess) >> dset;
3897 if (!fDSet)
3898 Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3899 else
3900 fDSet->Validate(dset);
3901 delete dset;
3902 }
3903 break;
3904
3905 case kPROOF_DATA_READY:
3906 {
3907 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3908 Bool_t dataready = kFALSE;
3909 Long64_t totalbytes, bytesready;
3910 (*mess) >> dataready >> totalbytes >> bytesready;
3911 fTotalBytes += totalbytes;
3912 fBytesReady += bytesready;
3913 if (dataready == kFALSE) fDataReady = dataready;
3914 }
3915 break;
3916
3917 case kPROOF_PING:
3918 // do nothing (ping is already acknowledged)
3919 break;
3920
3921 case kPROOF_MESSAGE:
3922 {
3923 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3924
3925 // We have received the unique tag and save it as name of this object
3926 TString msg;
3927 (*mess) >> msg;
3928 Bool_t lfeed = kTRUE;
3929 if ((mess->BufferSize() > mess->Length()))
3930 (*mess) >> lfeed;
3931
3933
3934 if (fSync) {
3935 // Notify locally
3936 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3937 } else {
3938 // Notify locally taking care of redirection, windows logs, ...
3939 NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3940 }
3941 } else {
3942
3943 // The message is logged for debugging purposes.
3944 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3945 if (gProofServ) {
3946 // We hide it during normal operations
3948
3949 // And send the message one level up
3950 gProofServ->SendAsynMessage(msg, lfeed);
3951 }
3952 }
3953 }
3954 break;
3955
3957 {
3958 TString vac;
3959 (*mess) >> vac;
3960 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3961 Int_t from = 0;
3962 TString vers, archcomp;
3963 if (vac.Tokenize(vers, from, "|"))
3964 vac.Tokenize(archcomp, from, "|");
3965 sl->SetArchCompiler(archcomp);
3966 vers.ReplaceAll(":","|");
3967 sl->SetROOTVersion(vers);
3968 }
3969 break;
3970
3971 default:
3972 {
3973 Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3974 sl->GetOrdinal(), what);
3975 }
3976 break;
3977 }
3978
3979 // Cleanup
3980 if (delete_mess)
3981 delete mess;
3982
3983 // We are done successfully
3984 return rc;
3985}
3986
3987////////////////////////////////////////////////////////////////////////////////
3988/// Process a message of type kPROOF_SUBMERGER
3989
3991{
3992 // Message sub-type
3993 Int_t type = 0;
3994 (*mess) >> type;
3995 TSocket *s = sl->GetSocket();
3996
3997 switch (type) {
3998 case kOutputSent:
3999 {
4000 if (IsEndMaster()) {
4001 Int_t merger_id = -1;
4002 (*mess) >> merger_id;
4003
4004 PDB(kSubmerger, 2)
4005 Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4006 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4007
4008 if (!fMergers || fMergers->GetSize() <= merger_id) {
4009 Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4010 break;
4011 }
4012 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4013 mi->SetMergedWorker();
4014 if (mi->AreAllWorkersMerged()) {
4015 mi->Deactivate();
4016 if (GetActiveMergersCount() == 0) {
4017 fMergers->Clear();
4018 delete fMergers;
4020 fMergersCount = -1;
4022 PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4023 }
4024 }
4025 } else {
4026 PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4027 }
4028 }
4029 break;
4030
4031 case kMergerDown:
4032 {
4033 Int_t merger_id = -1;
4034 (*mess) >> merger_id;
4035
4036 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4037
4038 if (!fMergers || fMergers->GetSize() <= merger_id) {
4039 Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4040 break;
4041 }
4042
4043 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4044 if (!mi->IsActive()) {
4045 break;
4046 } else {
4047 mi->Deactivate();
4048 }
4049
4050 // Stop the invalid merger in the case it is still listening
4052 stop << Int_t(kStopMerging);
4053 stop << 0;
4054 s->Send(stop);
4055
4056 // Ask for results from merger (only original results from this node as worker are returned)
4057 AskForOutput(mi->GetMerger());
4058
4059 // Ask for results from all workers assigned to this merger
4060 TIter nxo(mi->GetWorkers());
4061 TObject * o = 0;
4062 while ((o = nxo())) {
4063 AskForOutput((TSlave *)o);
4064 }
4065 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4066 }
4067 break;
4068
4069 case kOutputSize:
4070 {
4071 if (IsEndMaster()) {
4072 PDB(kSubmerger, 2)
4073 Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4074
4075 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4076 if (!fFinalizationRunning) {
4077 Info("HandleSubmerger", "finalization on %s started ...", prefix);
4079 }
4080
4081 Int_t output_size = 0;
4082 Int_t merging_port = 0;
4083 (*mess) >> output_size >> merging_port;
4084
4085 PDB(kSubmerger, 2) Info("HandleSubmerger",
4086 "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4087 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4088 TString msg;
4089 if (!fMergersSet) {
4090
4092
4093 // First pass - setting number of mergers according to user or dynamically
4094 fMergersCount = -1; // No mergers used if not set by user
4095 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4096 if (mc) fMergersCount = mc->GetVal(); // Value set by user
4097 TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4098 if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4099
4100 // Mergers count specified by user but not valid
4101 if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4102 msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4103 prefix, fMergersCount, activeWorkers);
4104 if (gProofServ)
4106 else
4107 Printf("%s",msg.Data());
4108 fMergersCount = 0;
4109 }
4110 // Mergers count will be set dynamically
4111 if ((fMergersCount == 0) && (!fMergersByHost)) {
4112 if (activeWorkers > 1) {
4113 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4114 if (activeWorkers / fMergersCount < 2)
4115 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4116 }
4117 if (fMergersCount > 1)
4118 msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4119 prefix, fMergersCount, activeWorkers);
4120 else {
4121 msg.Form("%s: No mergers will be used for %d workers",
4122 prefix, activeWorkers);
4123 fMergersCount = -1;
4124 }
4125 if (gProofServ)
4127 else
4128 Printf("%s",msg.Data());
4129 } else if (fMergersByHost) {
4130 // We force mergers at host level to minimize network traffic
4131 if (activeWorkers > 1) {
4132 fMergersCount = 0;
4133 THashList hosts;
4134 TIter nxwk(fSlaves);
4135 TObject *wrk = 0;
4136 while ((wrk = nxwk())) {
4137 if (!hosts.FindObject(wrk->GetName())) {
4138 hosts.Add(new TObjString(wrk->GetName()));
4139 fMergersCount++;
4140 }
4141 }
4142 }
4143 if (fMergersCount > 1)
4144 msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4145 prefix, fMergersCount, activeWorkers);
4146 else {
4147 msg.Form("%s: No mergers will be used for %d workers",
4148 prefix, activeWorkers);
4149 fMergersCount = -1;
4150 }
4151 if (gProofServ)
4153 else
4154 Printf("%s",msg.Data());
4155 } else {
4156 msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4157 prefix, fMergersCount, activeWorkers);
4158 if (gProofServ)
4160 else
4161 Printf("%s",msg.Data());
4162 }
4163
4164 // We started merging; we call it here because fMergersCount is still the original number
4165 // and can be saved internally
4167
4168 // Update merger counters (new workers are not yet active)
4170
4171 if (fMergersCount > 0) {
4172
4173 fMergers = new TList();
4175 // Total number of workers, which will not act as mergers ('pure workers')
4176 fWorkersToMerge = (activeWorkers - fMergersCount);
4177 // Establish the first merger
4178 if (!CreateMerger(sl, merging_port)) {
4179 // Cannot establish first merger
4180 AskForOutput(sl);
4182 fMergersCount--;
4183 }
4185 } else {
4186 AskForOutput(sl);
4187 }
4189 } else {
4190 // Multiple pass
4191 if (fMergersCount == -1) {
4192 // No mergers. Workers send their outputs directly to master
4193 AskForOutput(sl);
4194 } else {
4195 if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4196 RedirectWorker(s, sl, output_size);
4197 fRedirectNext--;
4198 } else {
4199 Bool_t newMerger = kTRUE;
4200 if (fMergersByHost) {
4201 TIter nxmg(fMergers);
4202 TMergerInfo *mgi = 0;
4203 while ((mgi = (TMergerInfo *) nxmg())) {
4204 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4205 newMerger = kFALSE;
4206 break;
4207 }
4208 }
4209 }
4210 if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4211 // Still not enough mergers established
4212 if (!CreateMerger(sl, merging_port)) {
4213 // Cannot establish a merger
4214 AskForOutput(sl);
4216 fMergersCount--;
4217 }
4218 } else
4219 RedirectWorker(s, sl, output_size);
4220 }
4221 }
4222 }
4223 } else {
4224 Error("HandleSubMerger","kOutputSize received not on endmaster!");
4225 }
4226 }
4227 break;
4228 }
4229}
4230
4231////////////////////////////////////////////////////////////////////////////////
4232/// Redirect output of worker sl to some merger
4233
4235{
4236 Int_t merger_id = -1;
4237
4238 if (fMergersByHost) {
4239 for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4240 TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4241 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4242 merger_id = i;
4243 break;
4244 }
4245 }
4246 } else {
4247 merger_id = FindNextFreeMerger();
4248 }
4249
4250 if (merger_id == -1) {
4251 // No free merger (probably it had crashed before)
4252 AskForOutput(sl);
4253 } else {
4254 TMessage sendoutput(kPROOF_SUBMERGER);
4255 sendoutput << Int_t(kSendOutput);
4256 PDB(kSubmerger, 2)
4257 Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4258
4259 PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4260 if (!fMergers || fMergers->GetSize() <= merger_id) {
4261 Error("RedirectWorker", "#%d not in list ", merger_id);
4262 return;
4263 }
4264 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4265
4266 TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4267 sendoutput << merger_id;
4268 sendoutput << hname;
4269 sendoutput << mi->GetPort();
4270 s->Send(sendoutput);
4271 mi->AddMergedObjects(output_size);
4272 mi->AddWorker(sl);
4273 }
4274}
4275
4276////////////////////////////////////////////////////////////////////////////////
4277/// Return a merger, which is both active and still accepts some workers to be
4278/// assigned to it. It works on the 'round-robin' basis.
4279
4281{
4282 while (fLastAssignedMerger < fMergers->GetSize() &&
4283 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4284 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4286 }
4287
4290 } else {
4291 return fLastAssignedMerger++;
4292 }
4293
4294 while (fLastAssignedMerger < fMergers->GetSize() &&
4295 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4296 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4298 }
4299
4301 return -1;
4302 } else {
4303 return fLastAssignedMerger++;
4304 }
4305}
4306
4307////////////////////////////////////////////////////////////////////////////////
4308/// Master asks for output from worker sl
4309
4311{
4312 TMessage sendoutput(kPROOF_SUBMERGER);
4313 sendoutput << Int_t(kSendOutput);
4314
4315 PDB(kSubmerger, 2) Info("AskForOutput",
4316 "worker %s was asked to send its output to master",
4317 sl->GetOrdinal());
4318
4319 sendoutput << -1;
4320 sendoutput << TString("master");
4321 sendoutput << -1;
4322 sl->GetSocket()->Send(sendoutput);
4324}
4325
4326////////////////////////////////////////////////////////////////////////////////
4327/// Final update of the progress dialog
4328
4330{
4331 if (!fPlayer) return;
4332
4333 // Handle abort ...
4335 if (fSync)
4336 Info("UpdateDialog",
4337 "processing was aborted - %lld events processed",
4339
4340 if (GetRemoteProtocol() > 11) {
4341 // New format
4342 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4343 } else {
4345 }
4346 Emit("StopProcess(Bool_t)", kTRUE);
4347 }
4348
4349 // Handle stop ...
4351 if (fSync)
4352 Info("UpdateDialog",
4353 "processing was stopped - %lld events processed",
4355
4356 if (GetRemoteProtocol() > 25) {
4357 // New format
4358 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4359 } else if (GetRemoteProtocol() > 11) {
4360 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4361 } else {
4363 }
4364 Emit("StopProcess(Bool_t)", kFALSE);
4365 }
4366
4367 // Final update of the dialog box
4368 if (GetRemoteProtocol() > 25) {
4369 // New format
4370 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4371 10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4372 (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4373 } else if (GetRemoteProtocol() > 11) {
4374 // New format
4375 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4376 7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4377 (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4378 } else {
4379 EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4380 }
4381}
4382
4383////////////////////////////////////////////////////////////////////////////////
4384/// Activate the a-sync input handler.
4385
4387{
4388 TIter next(fSlaves);
4389 TSlave *sl;
4390
4391 while ((sl = (TSlave*) next()))
4392 if (sl->GetInputHandler())
4393 sl->GetInputHandler()->Add();
4394}
4395
4396////////////////////////////////////////////////////////////////////////////////
4397/// De-activate a-sync input handler.
4398
4400{
4401 TIter next(fSlaves);
4402 TSlave *sl;
4403
4404 while ((sl = (TSlave*) next()))
4405 if (sl->GetInputHandler())
4406 sl->GetInputHandler()->Remove();
4407}
4408
4409////////////////////////////////////////////////////////////////////////////////
4410/// Get the active mergers count
4411
4413{
4414 if (!fMergers) return 0;
4415
4416 Int_t active_mergers = 0;
4417
4418 TIter mergers(fMergers);
4419 TMergerInfo *mi = 0;
4420 while ((mi = (TMergerInfo *)mergers())) {
4421 if (mi->IsActive()) active_mergers++;
4422 }
4423
4424 return active_mergers;
4425}
4426
4427////////////////////////////////////////////////////////////////////////////////
4428/// Create a new merger
4429
4431{
4432 PDB(kSubmerger, 2)
4433 Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4434
4435 PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4436
4437 if (port <= 0) {
4438 PDB(kSubmerger,2)
4439 Info("CreateMerger", "cannot create merger on port %d - exit", port);
4440 return kFALSE;
4441 }
4442
4443 Int_t workers = -1;
4444 if (!fMergersByHost) {
4445 Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4446 // Number of pure workers, which are not simply divisible by mergers
4447 Int_t rest = fWorkersToMerge % mergersToCreate;
4448 // We add one more worker for each of the first 'rest' mergers being established
4449 if (rest > 0 && fMergers->GetSize() < rest) {
4450 rest = 1;
4451 } else {
4452 rest = 0;
4453 }
4454 workers = (fWorkersToMerge / mergersToCreate) + rest;
4455 } else {
4456 Int_t workersOnHost = 0;
4457 for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4458 if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4459 }
4460 workers = workersOnHost - 1;
4461 }
4462
4463 TString msg;
4464 msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4465
4466 if (gProofServ) {
4468 } else {
4469 Printf("%s",msg.Data());
4470 }
4471 TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4472
4473 TMessage bemerger(kPROOF_SUBMERGER);
4474 bemerger << Int_t(kBeMerger);
4475 bemerger << fMergers->GetSize();
4476 bemerger << workers;
4477 sl->GetSocket()->Send(bemerger);
4478
4479 PDB(kSubmerger,2) Info("CreateMerger",
4480 "merger #%d (port: %d) for %d workers started",
4481 fMergers->GetSize(), port, workers);
4482
4483 fMergers->Add(merger);
4484 fWorkersToMerge = fWorkersToMerge - workers;
4485
4486 fRedirectNext = workers / 2;
4487
4488 PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4489 return kTRUE;
4490}
4491
4492////////////////////////////////////////////////////////////////////////////////
4493/// Add a bad slave server to the bad slave list and remove it from
4494/// the active list and from the two monitor objects. Assume that the work
4495/// done by this worker was lost and ask packerizer to reassign it.
4496
4497void TProof::MarkBad(TSlave *wrk, const char *reason)
4498{
4499 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4500
4501 // We may have been invalidated in the meanwhile: nothing to do in such a case
4502 if (!IsValid()) return;
4503
4504 if (!wrk) {
4505 Error("MarkBad", "worker instance undefined: protocol error? ");
4506 return;
4507 }
4508
4509 // Local URL
4510 static TString thisurl;
4511 if (thisurl.IsNull()) {
4512 if (IsMaster()) {
4513 Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4514 thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4515 if (port > 0) thisurl += TString::Format(":%d", port);
4516 } else {
4517 thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4518 }
4519 }
4520
4521 if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4522 // Message for notification
4523 const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4524 TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4525 TString msg;
4526 msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4527 src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4528 (reason && strlen(reason)) ? reason : "unknown");
4529 Info("MarkBad", "%s", msg.Data());
4530 // Notify one level up, if the case
4531 // Add some hint for diagnostics
4532 if (gProofServ) {
4533 msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4534 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4535 } else {
4536 msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4537 }
4538 msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4539 msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4540 msg += TString::Format(" +++\n");
4541 if (gProofServ) {
4542 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4543 "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4545 } else {
4546 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4547 "Display(\"*\")\n\n", thisurl.Data());
4548 Printf("%s", msg.Data());
4549 }
4550 } else if (reason) {
4551 if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4552 Info("MarkBad", "worker %s at %s:%d asked to terminate",
4553 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4554 }
4555 }
4556
4557 if (IsMaster() && reason) {
4558 if (strcmp(reason, kPROOF_TerminateWorker)) {
4559 // if the reason was not a planned termination
4560 TList *listOfMissingFiles = 0;
4561 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4562 listOfMissingFiles = new TList();
4563 listOfMissingFiles->SetName("MissingFiles");
4564 if (fPlayer)
4565 fPlayer->AddOutputObject(listOfMissingFiles);
4566 }
4567 // If a query is being processed, assume that the work done by
4568 // the worker was lost and needs to be reassigned.
4569 TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4570 if (packetizer) {
4571 // the worker was lost so do resubmit the packets
4572 packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4573 }
4574 } else {
4575 // Tell the coordinator that we are gone
4576 if (gProofServ) {
4577 TString ord(wrk->GetOrdinal());
4578 Int_t id = ord.Last('.');
4579 if (id != kNPOS) ord.Remove(0, id+1);
4581 }
4582 }
4583 } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4584 // We are invalid after this
4585 fValid = kFALSE;
4586 }
4587
4588 fActiveSlaves->Remove(wrk);
4590
4591 fAllMonitor->Remove(wrk->GetSocket());
4593
4595
4596 if (IsMaster()) {
4597 if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4598 // if the reason was a planned termination then delete the worker and
4599 // remove it from all the lists
4600 fSlaves->Remove(wrk);
4601 fBadSlaves->Remove(wrk);
4602 fActiveSlaves->Remove(wrk);
4603 fInactiveSlaves->Remove(wrk);
4604 fUniqueSlaves->Remove(wrk);
4607
4608 // we add it to the list of terminated slave infos instead, so that it
4609 // stays available in the .workers persistent file
4610 TSlaveInfo *si = new TSlaveInfo(
4611 wrk->GetOrdinal(),
4612 Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4613 0, "", wrk->GetWorkDir());
4615 else delete si;
4616
4617 delete wrk;
4618 } else {
4619 fBadSlaves->Add(wrk);
4620 fActiveSlaves->Remove(wrk);
4621 fUniqueSlaves->Remove(wrk);
4625 wrk->Close();
4626 // Update the mergers count, if needed
4627 if (fMergersSet) {
4628 Int_t mergersCount = -1;
4629 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4630 if (mc) mergersCount = mc->GetVal(); // Value set by user
4631 // Mergers count is set dynamically: recalculate it
4632 if (mergersCount == 0) {
4634 if (activeWorkers > 1) {
4635 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4636 if (activeWorkers / fMergersCount < 2)
4637 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4638 }
4639 }
4640 }
4641 }
4642
4643 // Update session workers files
4645 } else {
4646 // On clients the proof session should be removed from the lists
4647 // and deleted, since it is not valid anymore
4648 fSlaves->Remove(wrk);
4649 if (fManager)
4650 fManager->DiscardSession(this);
4651 }
4652}
4653
4654////////////////////////////////////////////////////////////////////////////////
4655/// Add slave with socket s to the bad slave list and remove if from
4656/// the active list and from the two monitor objects.
4657
4658void TProof::MarkBad(TSocket *s, const char *reason)
4659{
4660 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4661
4662 // We may have been invalidated in the meanwhile: nothing to do in such a case
4663 if (!IsValid()) return;
4664
4665 TSlave *wrk = FindSlave(s);
4666 MarkBad(wrk, reason);
4667}
4668
4669////////////////////////////////////////////////////////////////////////////////
4670/// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4671
4673{
4674 if (!wrk) {
4675 Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4676 return;
4677 }
4678
4679 // Send stop message
4680 if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4681 TMessage mess(kPROOF_STOP);
4682 wrk->GetSocket()->Send(mess);
4683 } else {
4684 if (gDebug > 0)
4685 Info("TerminateWorker", "connection to worker is already down: cannot"
4686 " send termination message");
4687 }
4688
4689 // This is a bad worker from now on
4691}
4692
4693////////////////////////////////////////////////////////////////////////////////
4694/// Ask an active worker 'ord' to terminate, i.e. to shutdown
4695
4696void TProof::TerminateWorker(const char *ord)
4697{
4698 if (ord && strlen(ord) > 0) {
4699 Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4700 if (IsMaster()) {
4701 TIter nxw(fSlaves);
4702 TSlave *wrk = 0;
4703 while ((wrk = (TSlave *)nxw())) {
4704 if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4705 TerminateWorker(wrk);
4706 if (!all) break;
4707 }
4708 }
4709 } else {
4710 TMessage mess(kPROOF_STOP);
4711 mess << TString(ord);
4712 Broadcast(mess);
4713 }
4714 }
4715}
4716
4717////////////////////////////////////////////////////////////////////////////////
4718/// Ping PROOF. Returns 1 if master server responded.
4719
4721{
4722 return Ping(kActive);
4723}
4724
4725////////////////////////////////////////////////////////////////////////////////
4726/// Ping PROOF slaves. Returns the number of slaves that responded.
4727
4729{
4730 TList *slaves = 0;
4731 if (list == kAll) slaves = fSlaves;
4732 if (list == kActive) slaves = fActiveSlaves;
4733 if (list == kUnique) slaves = fUniqueSlaves;
4734 if (list == kAllUnique) slaves = fAllUniqueSlaves;
4735
4736 if (slaves->GetSize() == 0) return 0;
4737
4738 int nsent = 0;
4739 TIter next(slaves);
4740
4741 TSlave *sl;
4742 while ((sl = (TSlave *)next())) {
4743 if (sl->IsValid()) {
4744 if (sl->Ping() == -1) {
4745 MarkBad(sl, "ping unsuccessful");
4746 } else {
4747 nsent++;
4748 }
4749 }
4750 }
4751
4752 return nsent;
4753}
4754
4755////////////////////////////////////////////////////////////////////////////////
4756/// Ping PROOF slaves. Returns the number of slaves that responded.
4757
4759{
4760 TList *slaves = fSlaves;
4761
4762 if (slaves->GetSize() == 0) return;
4763
4764 TIter next(slaves);
4765
4766 TSlave *sl;
4767 while ((sl = (TSlave *)next())) {
4768 if (sl->IsValid()) {
4769 sl->Touch();
4770 }
4771 }
4772
4773 return;
4774}
4775
4776////////////////////////////////////////////////////////////////////////////////
4777/// Print status of PROOF cluster.
4778
4779void TProof::Print(Option_t *option) const
4780{
4781 TString secCont;
4782
4784 Printf("Connected to: %s (%s)", GetMaster(),
4785 IsValid() ? "valid" : "invalid");
4786 Printf("Port number: %d", GetPort());
4787 Printf("User: %s", GetUser());
4788 Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4789 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4791 TSlave *sl = (TSlave *)fActiveSlaves->First();
4792 if (sl) {
4793 TString sc;
4794 if (sl->GetSocket()->GetSecContext())
4795 Printf("Security context: %s",
4796 sl->GetSocket()->GetSecContext()->AsString(sc));
4797 Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4798 } else {
4799 Printf("Security context: Error - No connection");
4800 Printf("Proofd protocol version: Error - No connection");
4801 }
4802 Printf("Client protocol version: %d", GetClientProtocol());
4803 Printf("Remote protocol version: %d", GetRemoteProtocol());
4804 Printf("Log level: %d", GetLogLevel());
4805 Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4806 Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4807 if (IsValid())
4808 const_cast<TProof*>(this)->SendPrint(option);
4809 } else {
4810 const_cast<TProof*>(this)->AskStatistics();
4811 if (IsParallel())
4812 Printf("*** Master server %s (parallel mode, %d workers):",
4814 else
4815 Printf("*** Master server %s (sequential mode):",
4817
4818 Printf("Master host name: %s", gSystem->HostName());
4819 Printf("Port number: %d", GetPort());
4820 if (strlen(gProofServ->GetGroup()) > 0) {
4821 Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4822 } else {
4823 Printf("User: %s", GetUser());
4824 }
4825 TString ver;
4826 ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4827 if (gSystem->Getenv("ROOTVERSIONTAG"))
4828 ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4829 Printf("ROOT version|rev|tag: %s", ver.Data());
4830 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4832 Printf("Protocol version: %d", GetClientProtocol());
4833 Printf("Image name: %s", GetImage());
4834 Printf("Working directory: %s", gSystem->WorkingDirectory());
4835 Printf("Config directory: %s", GetConfDir());
4836 Printf("Config file: %s", GetConfFile());
4837 Printf("Log level: %d", GetLogLevel());
4838 Printf("Number of workers: %d", GetNumberOfSlaves());
4839 Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4840 Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4841 Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4842 Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4843 Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4844 Printf("Total real time used (s): %.3f", GetRealTime());
4845 Printf("Total CPU time used (s): %.3f", GetCpuTime());
4846 if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4847 Printf("List of workers:");
4848 TList masters;
4849 TIter nextslave(fSlaves);
4850 while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4851 if (!sl->IsValid()) continue;
4852
4853 if (sl->GetSlaveType() == TSlave::kSlave) {
4854 sl->Print(option);
4855 } else if (sl->GetSlaveType() == TSlave::kMaster) {
4856 TMessage mess(kPROOF_PRINT);
4857 mess.WriteString(option);
4858 if (sl->GetSocket()->Send(mess) == -1)
4859 const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4860 else
4861 masters.Add(sl);
4862 } else {
4863 Error("Print", "TSlave is neither Master nor Worker");
4864 R__ASSERT(0);
4865 }
4866 }
4867 const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4868 }
4869 }
4870}
4871
4872////////////////////////////////////////////////////////////////////////////////
4873/// Extract from opt information about output handling settings.
4874/// The understood keywords are:
4875/// of=<file>, outfile=<file> output file location
4876/// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4877/// mutually exclusive,execution stops
4878/// if both are found)
4879/// sft[=<opt>], savetofile[=<opt>] control saving to file
4880///
4881/// For 'mvf', the <opt> integer has the following meaning:
4882/// <opt> = <how>*10 + <force>
4883/// <force> = 0 save to file if memory threshold is reached
4884/// (the memory threshold is set by the cluster
4885/// admin); in case an output file is defined, the
4886/// files are merged at the end;
4887/// 1 save results to file.
4888/// <how> = 0 save at the end of the query
4889/// 1 save results after each packet (to reduce the
4890/// loss in case of crash).
4891///
4892/// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4893/// to save results after each packet.
4894///
4895/// The separator from the next option is either a ' ' or a ';'
4896///
4897/// All recognized settings are removed from the input string opt.
4898/// If action == 0, set up the output file accordingly, if action == 1 clean related
4899/// output file settings.
4900/// If the final target file is local then 'target' is set to the final local path
4901/// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4902///
4903/// Output file settings are in the form
4904///
4905/// <previous_option>of=name <next_option>
4906/// <previous_option>outfile=name,...;<next_option>
4907///
4908/// The separator from the next option is either a ' ' or a ';'
4909/// Called interanally by TProof::Process.
4910///
4911/// Returns 0 on success, -1 on error.
4912
4914{
4915 TString outfile, dsname, stfopt;
4916 if (action == 0) {
4917 TString tagf, tagd, tags, oo;
4918 Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4919 while (opt.Tokenize(oo, from, "[; ]")) {
4920 if (oo.BeginsWith("of=")) {
4921 tagf = "of=";
4922 iof = opt.Index(tagf);
4923 } else if (oo.BeginsWith("outfile=")) {
4924 tagf = "outfile=";
4925 iof = opt.Index(tagf);
4926 } else if (oo.BeginsWith("ds")) {
4927 tagd = "ds";
4928 iod = opt.Index(tagd);
4929 } else if (oo.BeginsWith("dataset")) {
4930 tagd = "dataset";
4931 iod = opt.Index(tagd);
4932 } else if (oo.BeginsWith("stf")) {
4933 tags = "stf";
4934 ios = opt.Index(tags);
4935 } else if (oo.BeginsWith("savetofile")) {
4936 tags = "savetofile";
4937 ios = opt.Index(tags);
4938 }
4939 }
4940 // Check consistency
4941 if (iof != kNPOS && iod != kNPOS) {
4942 Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4943 return -1;
4944 }
4945
4946 // Check output file first
4947 if (iof != kNPOS) {
4948 from = iof + tagf.Length();
4949 if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4950 Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4951 return -1;
4952 }
4953 // For removal from original options string
4954 tagf += outfile;
4955 }
4956 // Check dataset
4957 if (iod != kNPOS) {
4958 from = iod + tagd.Length();
4959 if (!opt.Tokenize(dsname, from, "[; ]"))
4960 if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4961 // For removal from original options string
4962 tagd += dsname;
4963 // The name may be empty or beginning with a '='
4964 if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4965 if (dsname.Contains("|V")) {
4966 target = "ds|V";
4967 dsname.ReplaceAll("|V", "");
4968 }
4969 if (dsname.IsNull()) dsname = "dataset_<qtag>";
4970 }
4971 // Check stf
4972 if (ios != kNPOS) {
4973 from = ios + tags.Length();
4974 if (!opt.Tokenize(stfopt, from, "[; ]"))
4975 if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
4976 // For removal from original options string
4977 tags += stfopt;
4978 // It must be digit
4979 if (!stfopt.IsNull()) {
4980 if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
4981 if (!stfopt.IsNull()) {
4982 if (!stfopt.IsDigit()) {
4983 Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
4984 return -1;
4985 }
4986 } else {
4987 // Default
4988 stfopt = "1";
4989 }
4990 } else {
4991 // Default
4992 stfopt = "1";
4993 }
4994 }
4995 // Remove from original options string
4996 opt.ReplaceAll(tagf, "");
4997 opt.ReplaceAll(tagd, "");
4998 opt.ReplaceAll(tags, "");
4999 }
5000
5001 // Parse now
5002 if (action == 0) {
5003 // Output file
5004 if (!outfile.IsNull()) {
5005 if (!outfile.BeginsWith("master:")) {
5007 Warning("HandleOutputOptions",
5008 "directory '%s' for the output file does not exists or is not writable:"
5009 " saving to master", gSystem->DirName(outfile.Data()));
5010 outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5011 } else {
5012 if (!IsLite()) {
5013 // The target file is local, so we need to retrieve it
5014 target = outfile;
5015 if (!stfopt.IsNull()) {
5016 outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5017 } else {
5018 outfile = "";
5019 }
5020 }
5021 }
5022 }
5023 if (outfile.BeginsWith("master:")) {
5024 outfile.ReplaceAll("master:", "");
5025 if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5026 // Get the master data dir
5027 TString ddir, emsg;
5028 if (!IsLite()) {
5029 if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5030 TObjString *os = fMacroLog.GetLineWith("const char");
5031 if (os) {
5032 Ssiz_t fst = os->GetString().First('\"');
5033 Ssiz_t lst = os->GetString().Last('\"');
5034 ddir = os->GetString()(fst+1, lst-fst-1);
5035 } else {
5036 emsg = "could not find 'const char *' string in macro log! cannot continue";
5037 }
5038 } else {
5039 emsg = "could not retrieve master data directory info! cannot continue";
5040 }
5041 if (!emsg.IsNull()) {
5042 Error("HandleOutputOptions", "%s", emsg.Data());
5043 return -1;
5044 }
5045 }
5046 if (!ddir.IsNull()) ddir += "/";
5047 if (outfile.IsNull()) {
5048 outfile.Form("%s<file>", ddir.Data());
5049 } else {
5050 outfile.Insert(0, TString::Format("%s", ddir.Data()));
5051 }
5052 }
5053 }
5054 // Set the parameter
5055 if (!outfile.IsNull()) {
5056 if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5057 SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5058 }
5059 }
5060 // Dataset creation
5061 if (!dsname.IsNull()) {
5062 dsname.Insert(0, "ds:");
5063 // Set the parameter
5064 SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5065 // Check the Save-To-File option
5066 if (!stfopt.IsNull()) {
5067 Int_t ostf = (Int_t) stfopt.Atoi();
5068 if (ostf%10 <= 0) {
5069 Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5070 stfopt.Form("%d", ostf+1);
5071 }
5072 } else {
5073 // Minimal setting
5074 stfopt = "1";
5075 }
5076 }
5077 // Save-To-File options
5078 if (!stfopt.IsNull()) {
5079 // Set the parameter
5080 SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5081 }
5082 } else {
5083 // Retrieve the file, if required
5084 if (GetOutputList()) {
5085 if (target == "ds|V") {
5086 // Find the dataset
5087 dsname = "";
5088 TIter nxo(GetOutputList());
5089 TObject *o = 0;
5090 while ((o = nxo())) {
5092 VerifyDataSet(o->GetName());
5093 dsname = o->GetName();
5094 break;
5095 }
5096 }
5097 if (!dsname.IsNull()) {
5098 TFileCollection *fc = GetDataSet(dsname);
5099 if (fc) {
5100 fc->Print();
5101 } else {
5102 Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5103 }
5104 } else {
5105 Warning("HandleOutputOptions", "dataset not found!");
5106 }
5107 } else {
5108 Bool_t targetcopied = kFALSE;
5109 TProofOutputFile *pf = 0;
5110 if (!target.IsNull())
5112 if (pf) {
5113 // Copy the file
5114 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5115 TUrl(target, kTRUE).GetUrl())) {
5116 if (TFile::Cp(pf->GetOutputFileName(), target)) {
5117 Printf(" Output successfully copied to %s", target.Data());
5118 targetcopied = kTRUE;
5119 } else {
5120 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5121 }
5122 }
5123 }
5124 TFile *fout = 0;
5125 TObject *o = 0;
5126 TIter nxo(GetOutputList());
5127 Bool_t swapcopied = kFALSE;
5128 while ((o = nxo())) {
5129 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5130 if (pof) {
5131 if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5132 if (pof == pf && targetcopied) continue;
5133 // Copy the file
5134 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5135 TUrl(target, kTRUE).GetUrl())) {
5136 if (TFile::Cp(pof->GetOutputFileName(), target)) {
5137 Printf(" Output successfully copied to %s", target.Data());
5138 swapcopied = kTRUE;
5139 } else {
5140 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5141 }
5142 }
5143 } else if (pof->IsRetrieve()) {
5144 // Retrieve this file to the local path indicated in the title
5145 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5146 TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5147 if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5148 Printf(" Output successfully copied to %s", pof->GetTitle());
5149 } else {
5150 Warning("HandleOutputOptions",
5151 "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5152 }
5153 }
5154 }
5155 }
5156 }
5157 if (!target.IsNull() && !swapcopied) {
5158 if (!fout && !pf) {
5159 fout = TFile::Open(target, "RECREATE");
5160 if (!fout || (fout && fout->IsZombie())) {
5161 SafeDelete(fout);
5162 Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5163 }
5164 }
5165 if (fout) {
5166 nxo.Reset();
5167 while ((o = nxo())) {
5168 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5169 if (!pof) {
5170 // Write the object to the open output file
5171 o->Write();
5172 }
5173 }
5174 }
5175 }
5176 // Clean-up
5177 if (fout) {
5178 fout->Close();
5179 SafeDelete(fout);
5180 Printf(" Output saved to %s", target.Data());
5181 }
5182 }
5183 }
5184 // Remove the parameter
5185 DeleteParameters("PROOF_DefaultOutputOption");
5186 // Remove the parameter
5187 DeleteParameters("PROOF_SavePartialResults");
5188 }
5189 // Done
5190 return 0;
5191}
5192
5193////////////////////////////////////////////////////////////////////////////////
5194/// Extract from opt in optfb information about wanted feedback settings.
5195/// Feedback are removed from the input string opt.
5196/// If action == 0, set up feedback accordingly, if action == 1 clean related
5197/// feedback settings (using info in optfb, if available, or reparsing opt).
5198///
5199/// Feedback requirements are in the form
5200///
5201/// <previous_option>fb=name1,name2,name3,... <next_option>
5202/// <previous_option>feedback=name1,name2,name3,...;<next_option>
5203///
5204/// The special name 'stats' triggers feedback about events and packets.
5205/// The separator from the next option is either a ' ' or a ';'.
5206/// Called interanally by TProof::Process.
5207
5208void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5209{
5210 Ssiz_t from = 0;
5211 if (action == 0 || (action == 1 && optfb.IsNull())) {
5212 TString tag("fb=");
5213 Ssiz_t ifb = opt.Index(tag);
5214 if (ifb == kNPOS) {
5215 tag = "feedback=";
5216 ifb = opt.Index(tag);
5217 }
5218 if (ifb == kNPOS) return;
5219 from = ifb + tag.Length();
5220
5221 if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5222 Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5223 return;
5224 }
5225 // Remove from original options string
5226 tag += optfb;
5227 opt.ReplaceAll(tag, "");
5228 }
5229
5230 // Parse now
5231 TString nm, startdraw, stopdraw;
5232 from = 0;
5233 while (optfb.Tokenize(nm, from, ",")) {
5234 // Special name first
5235 if (nm == "stats") {
5236 if (action == 0) {
5237 startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5238 gROOT->ProcessLine(startdraw.Data());
5239 SetParameter("PROOF_StatsHist", "");
5240 AddFeedback("PROOF_EventsHist");
5241 AddFeedback("PROOF_PacketsHist");
5242 AddFeedback("PROOF_ProcPcktHist");
5243 } else {
5244 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5245 " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5246 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5247 gROOT->ProcessLine(stopdraw.Data());
5248 DeleteParameters("PROOF_StatsHist");
5249 RemoveFeedback("PROOF_EventsHist");
5250 RemoveFeedback("PROOF_PacketsHist");
5251 RemoveFeedback("PROOF_ProcPcktHist");
5252 }
5253 } else {
5254 if (action == 0) {
5255 // Enable or
5256 AddFeedback(nm);
5257 startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5258 gROOT->ProcessLine(startdraw.Data());
5259 } else {
5260 // ... or disable
5262 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5263 " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5264 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5265 gROOT->ProcessLine(stopdraw.Data());
5266 }
5267 }
5268 }
5269}
5270
5271////////////////////////////////////////////////////////////////////////////////
5272/// Process a data set (TDSet) using the specified selector (.C) file or
5273/// Tselector object
5274/// Entry- or event-lists should be set in the data set object using
5275/// TDSet::SetEntryList.
5276/// The return value is -1 in case of error and TSelector::GetStatus() in
5277/// in case of success.
5278
5279Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5281{
5282 if (!IsValid() || !fPlayer) return -1;
5283
5284 // Set PROOF to running state
5286
5287 TString opt(option), optfb, outfile;
5288 // Enable feedback, if required
5289 if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5290 // Define output file, either from 'opt' or the default one
5291 if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5292
5293 // Resolve query mode
5294 fSync = (GetQueryMode(opt) == kSync);
5295
5296 if (fSync && (!IsIdle() || IsWaiting())) {
5297 // Already queued or processing queries: switch to asynchronous mode
5298 Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5299 fSync = kFALSE;
5300 opt.ReplaceAll("SYNC","");
5301 opt += "ASYN";
5302 }
5303
5304 // Cleanup old temporary datasets
5305 if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5308 }
5309
5310 // deactivate the default application interrupt handler
5311 // ctrl-c's will be forwarded to PROOF to stop the processing
5312 TSignalHandler *sh = 0;
5313 if (fSync) {
5314 if (gApplication)
5316 }
5317
5318 // Make sure we get a fresh result
5320
5321 // Make sure that the workers ready list is empty
5322 if (fWrksOutputReady) {
5325 }
5326
5327 // Make sure the selector path is in the macro path
5328 TProof::AssertMacroPath(selector);
5329
5330 // Reset time measurements
5331 fQuerySTW.Reset();
5332
5333 Long64_t rv = -1;
5334 if (selector && strlen(selector)) {
5335 rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5336 } else if (fSelector) {
5337 rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5338 } else {
5339 Error("Process", "neither a selecrot file nor a selector object have"
5340 " been specified: cannot process!");
5341 }
5342
5343 // This is the end of merging
5344 fQuerySTW.Stop();
5345 Float_t rt = fQuerySTW.RealTime();
5346 // Update the query content
5348 if (qr) {
5349 qr->SetTermTime(rt);
5351 }
5352
5353 // Disable feedback, if required
5354 if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5355 // Finalise output file settings (opt is ignored in here)
5356 if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5357
5358 // Retrieve status from the output list
5359 if (rv >= 0) {
5361 (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5362 if (sst) rv = sst->GetVal();
5363 }
5364
5365 if (fSync) {
5366 // reactivate the default application interrupt handler
5367 if (sh)
5369 // Save the performance info, if required
5370 if (!fPerfTree.IsNull()) {
5371 if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5372 // Must be re-enabled each time
5373 SetPerfTree(0);
5374 }
5375 }
5376
5377 return rv;
5378}
5379
5380////////////////////////////////////////////////////////////////////////////////
5381/// Process a data set (TFileCollection) using the specified selector (.C) file
5382/// or TSelector object.
5383/// The default tree is analyzed (i.e. the first one found). To specify another
5384/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5385/// The return value is -1 in case of error and TSelector::GetStatus() in
5386/// in case of success.
5387
5390{
5391 if (!IsValid() || !fPlayer) return -1;
5392
5393 if (fProtocol < 17) {
5394 Info("Process", "server version < 5.18/00:"
5395 " processing of TFileCollection not supported");
5396 return -1;
5397 }
5398
5399 // We include the TFileCollection to the input list and we create a
5400 // fake TDSet with infor about it
5401 TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5403
5404
5405 Long64_t retval = -1;
5406 if (selector && strlen(selector)) {
5407 retval = Process(dset, selector, option, nentries, first);
5408 } else if (fSelector) {
5409 retval = Process(dset, fSelector, option, nentries, first);
5410 } else {
5411 Error("Process", "neither a selecrot file nor a selector object have"
5412 " been specified: cannot process!");
5413 }
5414 fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5415
5416 // Cleanup
5417 if (IsLite() && !fSync) {
5418 if (!fRunningDSets) fRunningDSets = new TList;
5419 fRunningDSets->Add(dset);
5420 } else {
5421 delete dset;
5422 }
5423
5424 return retval;
5425}
5426
5427////////////////////////////////////////////////////////////////////////////////
5428/// Process a dataset which is stored on the master with name 'dsetname'.
5429/// The syntax for dsetname is name[#[dir/]objname], e.g.
5430/// "mydset" analysis of the first tree in the top dir of the dataset
5431/// named "mydset"
5432/// "mydset#T" analysis tree "T" in the top dir of the dataset
5433/// named "mydset"
5434/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5435/// named "mydset"
5436/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5437/// dataset named "mydset"
5438/// The component 'name' in its more general form contains also the group and
5439/// user name following "/<group>/<user>/<dsname>". Each of these components
5440/// can contain one or more wildcards '*', in which case all the datasets matching
5441/// the expression are added together as a global dataset (wildcard support has
5442/// been added in version 5.27/02).
5443/// The last argument 'elist' specifies an entry- or event-list to be used as
5444/// event selection.
5445/// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5446/// at once in a more flexible way that the one provided by wildcarding. There
5447/// are three possibilities:
5448/// 1) specifying the dataset names separated by the OR operator '|', e.g.
5449/// dsetname = "<dset1>|<dset2>|<dset3>|..."
5450/// in this case the datasets are a seen as a global unique dataset
5451/// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5452/// dsetname = "<dset1>,<dset2> <dset3>,..."
5453/// in this case the datasets are processed one after the other and the
5454/// selector is notified when switching dataset via a bit in the current
5455/// processed element.
5456/// 3) giving the path of a textfile where the dataset names are specified
5457/// on one or multiple lines; the lines found are joined as in 1), unless
5458/// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5459/// with the dataset names listed in 'datasets.txt') in which case they are
5460/// treated as in 2); the file is open in raw mode with TFile::Open and
5461/// therefore it cane be remote, e.g. on a Web server.
5462/// Each <dsetj> has the format specified above for the single dataset processing,
5463/// included wildcarding (the name of the tree and subdirectory must be same for
5464/// all the datasets).
5465/// In the case of multiple datasets, 'elist' is treated a global entry list.
5466/// It is possible to specify per-dataset entry lists using the syntax
5467/// "mydset[#adir/[T]]?enl=entrylist"
5468/// or
5469/// "mydset[#adir/[T]]<<entrylist"
5470/// Here 'entrylist' is a tag identifying, in the order :
5471/// i. a named entry-list in the input list or in the input data list
5472/// ii. a named entry-list in memory (in gDirectory)
5473/// iii. the path of a file containing the entry-list to be used
5474/// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5475/// data list.
5476/// The return value is -1 in case of error and TSelector::GetStatus() in
5477/// in case of success.
5478
5479Long64_t TProof::Process(const char *dsetname, const char *selector,
5480 Option_t *option, Long64_t nentries,
5481 Long64_t first, TObject *elist)
5482{
5483 if (fProtocol < 13) {
5484 Info("Process", "processing 'by name' not supported by the server");
5485 return -1;
5486 }
5487
5488 TString dsname, fname(dsetname);
5489 // If the 'dsetname' corresponds to an existing and readable file we will try to
5490 // interpretate its content as names of datasets to be processed. One line can contain
5491 // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5492 // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5493 // joined with ','.
5494 const char *separator = (fname.EndsWith(",")) ? "," : "|";
5495 if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5496 if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5497 TUrl uf(fname, kTRUE);
5498 uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5499 TFile *f = TFile::Open(uf.GetUrl());
5500 if (f && !(f->IsZombie())) {
5501 const Int_t blen = 8192;
5502 char buf[blen];
5503 Long64_t rest = f->GetSize();
5504 while (rest > 0) {
5505 Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5506 if (f->ReadBuffer(buf, len)) {
5507 Error("Process", "problems reading from file '%s'", fname.Data());
5508 dsname = "";
5509 break;
5510 }
5511 buf[len] = '\0';
5512 dsname += buf;
5513 rest -= len;
5514 }
5515 f->Close();
5516 SafeDelete(f);
5517 // We fail if a failure occured
5518 if (rest > 0) return -1;
5519 } else {
5520 Error("Process", "could not open file '%s'", fname.Data());
5521 return -1;
5522 }
5523 }
5524 if (dsname.IsNull()) {
5525 dsname = dsetname;
5526 } else {
5527 // Remove trailing '\n'
5528 if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5529 // Replace all '\n' with the proper separator
5530 dsname.ReplaceAll("\n", separator);
5531 if (gDebug > 0) {
5532 Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5533 Info("Process", " '%s'", dsname.Data());
5534 }
5535 }
5536
5537 TString names(dsname), name, enl, newname;
5538 // If multi-dataset check if server supports it
5539 if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5540 Info("Process", "multi-dataset processing not supported by the server");
5541 return -1;
5542 }
5543
5544 TEntryList *el = 0;
5545 TString dsobj, dsdir;
5546 Int_t from = 0;
5547 while (names.Tokenize(name, from, "[, |]")) {
5548
5549 newname = name;
5550 // Extract the specific entry-list, if any
5551 enl = "";
5552 Int_t ienl = name.Index("?enl=");
5553 if (ienl == kNPOS) {
5554 ienl = name.Index("<<");
5555 if (ienl != kNPOS) {
5556 newname.Remove(ienl);
5557 ienl += strlen("<<");
5558 }
5559 } else {
5560 newname.Remove(ienl);
5561 ienl += strlen("?enl=");
5562 }
5563
5564 // Check the name syntax first
5565 TString obj, dir("/");
5566 Int_t idxc = newname.Index("#");
5567 if (idxc != kNPOS) {
5568 Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5569 if (idxs != kNPOS) {
5570 obj = newname(idxs+1, newname.Length());
5571 dir = newname(idxc+1, newname.Length());
5572 dir.Remove(dir.Index("/") + 1);
5573 newname.Remove(idxc);
5574 } else {
5575 obj = newname(idxc+1, newname.Length());
5576 newname.Remove(idxc);
5577 }
5578 } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5579 // protection against using ':' instead of '#'
5580 Error("Process", "bad name syntax (%s): please use"
5581 " a '#' after the dataset name", name.Data());
5582 dsname.ReplaceAll(name, "");
5583 continue;
5584 }
5585 if (dsobj.IsNull() && dsdir.IsNull()) {
5586 // The first one specifies obj and dir
5587 dsobj = obj;
5588 dsdir = dir;
5589 } else if (obj != dsobj || dir != dsdir) {
5590 // Inconsistent specification: not supported
5591 Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5592 }
5593 // Process the entry-list name, if any
5594 if (ienl != kNPOS) {
5595 // Get entrylist name or path
5596 enl = name(ienl, name.Length());
5597 el = 0;
5598 TObject *oel = 0;
5599 // If not in the input list ...
5600 TList *inpl = GetInputList();
5601 if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5602 // ... check the heap
5603 if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5604 if ((el = dynamic_cast<TEntryList *>(oel))) {
5605 // Add to the input list (input data not available on master where
5606 // this info will be processed)
5607 if (fProtocol >= 28)
5608 if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5609 }
5610 }
5611 // If not in the heap, check a file, if any
5612 if (!el) {
5613 if (!gSystem->AccessPathName(enl)) {
5614 TFile *f = TFile::Open(enl);
5615 if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5616 TIter nxk(f->GetListOfKeys());
5617 TKey *k = 0;
5618 while ((k = (TKey *) nxk())) {
5619 if (!strcmp(k->GetClassName(), "TEntryList")) {
5620 if (!el) {
5621 if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5622 // Add to the input list (input data not available on master where
5623 // this info will be processed)
5624 if (fProtocol >= 28) {
5625 if (!(inpl->FindObject(el->GetName()))) {
5626 el = (TEntryList *) el->Clone();
5627 AddInput(el);
5628 }
5629 } else {
5630 el = (TEntryList *) el->Clone();
5631 }
5632 }
5633 } else if (strcmp(el->GetName(), k->GetName())) {
5634 Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5635 "if this is not what you want, load first the content in memory"
5636 "and select it by name ", enl.Data());
5637 }
5638 }
5639 }
5640 } else {
5641 Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5642 }
5643 }
5644 }
5645 // Transmit the information
5646 if (fProtocol >= 28) {
5647 newname += "?enl=";
5648 if (el) {
5649 // An entry list object is avalaible in the input list: add its name
5650 newname += el->GetName();
5651 } else {
5652 // The entry list object was not found: send the name, the future entry list manager will
5653 // find it on the server side
5654 newname += enl;
5655 }
5656 }
5657 }
5658 // Adjust the name for this dataset
5659 dsname.ReplaceAll(name, newname);
5660 }
5661
5662 // Create the dataset object
5663 TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5664 // Set entry list
5665 if (el && fProtocol < 28) {
5666 dset->SetEntryList(el);
5667 } else {
5668 dset->SetEntryList(elist);
5669 }
5670 // Run
5671 Long64_t retval = -1;
5672 if (selector && strlen(selector)) {
5673 retval = Process(dset, selector, option, nentries, first);
5674 } else if (fSelector) {
5675 retval = Process(dset, fSelector, option, nentries, first);
5676 } else {
5677 Error("Process", "neither a selector file nor a selector object have"
5678 " been specified: cannot process!");
5679 }
5680 // Cleanup
5681 if (IsLite() && !fSync) {
5682 if (!fRunningDSets) fRunningDSets = new TList;
5683 fRunningDSets->Add(dset);
5684 } else {
5685 delete dset;
5686 }
5687
5688 return retval;
5689}
5690
5691////////////////////////////////////////////////////////////////////////////////
5692/// Generic (non-data based) selector processing: the Process() method of the
5693/// specified selector (.C) or TSelector object is called 'n' times.
5694/// The return value is -1 in case of error and TSelector::GetStatus() in
5695/// in case of success.
5696
5697Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5698{
5699 if (!IsValid()) return -1;
5700
5701 if (fProtocol < 16) {
5702 Info("Process", "server version < 5.17/04: generic processing not supported");
5703 return -1;
5704 }
5705
5706 // Fake data set
5707 TDSet *dset = new TDSet;
5708 dset->SetBit(TDSet::kEmpty);
5709
5710 Long64_t retval = -1;
5711 if (selector && strlen(selector)) {
5712 retval = Process(dset, selector, option, n);
5713 } else if (fSelector) {
5714 retval = Process(dset, fSelector, option, n);
5715 } else {
5716 Error("Process", "neither a selector file nor a selector object have"
5717 " been specified: cannot process!");
5718 }
5719
5720 // Cleanup
5721 if (IsLite() && !fSync) {
5722 if (!fRunningDSets) fRunningDSets = new TList;
5723 fRunningDSets->Add(dset);
5724 } else {
5725 delete dset;
5726 }
5727 return retval;
5728}
5729
5730////////////////////////////////////////////////////////////////////////////////
5731/// Process a data set (TDSet) using the specified selector object.
5732/// Entry- or event-lists should be set in the data set object using
5733/// TDSet::SetEntryList.
5734/// The return value is -1 in case of error and TSelector::GetStatus() in
5735/// in case of success.
5736
5739{
5740 if (fProtocol < 34) {
5741 Error("Process", "server version < 5.33/02:"
5742 "processing by object not supported");
5743 return -1;
5744 }
5745 if (!selector) {
5746 Error("Process", "selector object undefined!");
5747 return -1;
5748 }
5749 fSelector = selector;
5750 Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5751 fSelector = 0;
5752 // Done
5753 return rc;
5754}
5755
5756////////////////////////////////////////////////////////////////////////////////
5757/// Process a data set (TFileCollection) using the specified selector object
5758/// The default tree is analyzed (i.e. the first one found). To specify another
5759/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5760/// The return value is -1 in case of error and TSelector::GetStatus() in
5761/// in case of success.
5762
5765{
5766 if (fProtocol < 34) {
5767 Error("Process", "server version < 5.33/02:"
5768 "processing by object not supported");
5769 return -1;
5770 }
5771 if (!selector) {
5772 Error("Process", "selector object undefined!");
5773 return -1;
5774 }
5775 fSelector = selector;
5776 Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5777 fSelector = 0;
5778 // Done
5779 return rc;
5780}
5781
5782////////////////////////////////////////////////////////////////////////////////
5783/// Process with name of dataset and TSelector object
5784
5785Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5786 Option_t *option, Long64_t nentries,
5787 Long64_t first, TObject *elist)
5788{
5789 if (fProtocol < 34) {
5790 Error("Process", "server version < 5.33/02:"
5791 "processing by object not supported");
5792 return -1;
5793 }
5794 if (!selector) {
5795 Error("Process", "selector object undefined!");
5796 return -1;
5797 }
5798 fSelector = selector;
5799 Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5800 fSelector = 0;
5801 // Done
5802 return rc;
5803}
5804
5805////////////////////////////////////////////////////////////////////////////////
5806/// Generic (non-data based) selector processing: the Process() method of the
5807/// specified selector is called 'n' times.
5808/// The return value is -1 in case of error and TSelector::GetStatus() in
5809/// in case of success.
5810
5812{
5813 if (fProtocol < 34) {
5814 Error("Process", "server version < 5.33/02:"
5815 "processing by object not supported");
5816 return -1;
5817 }
5818 if (!selector) {
5819 Error("Process", "selector object undefined!");
5820 return -1;
5821 }
5822 fSelector = selector;
5823 Long64_t rc = Process((const char*)0, n, option);
5824 fSelector = 0;
5825 // Done
5826 return rc;
5827}
5828
5829////////////////////////////////////////////////////////////////////////////////
5830/// Get reference for the qry-th query in fQueries (as
5831/// displayed by ShowQueries).
5832
5834{
5835 ref = "";
5836 if (qry > 0) {
5837 if (!fQueries)
5839 if (fQueries) {
5840 TIter nxq(fQueries);
5841 TQueryResult *qr = 0;
5842 while ((qr = (TQueryResult *) nxq()))
5843 if (qr->GetSeqNum() == qry) {
5844 ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5845 return 0;
5846 }
5847 }
5848 }
5849 return -1;
5850}
5851
5852////////////////////////////////////////////////////////////////////////////////
5853/// Finalize the qry-th query in fQueries.
5854/// If force, force retrieval if the query is found in the local list
5855/// but has already been finalized (default kFALSE).
5856/// If query < 0, finalize current query.
5857/// Return 0 on success, -1 on error
5858
5860{
5861 if (fPlayer) {
5862 if (qry > 0) {
5863 TString ref;
5864 if (GetQueryReference(qry, ref) == 0) {
5865 return Finalize(ref, force);
5866 } else {
5867 Info("Finalize", "query #%d not found", qry);
5868 }
5869 } else {
5870 // The last query
5871 return Finalize("", force);
5872 }
5873 }
5874 return -1;
5875}
5876
5877////////////////////////////////////////////////////////////////////////////////
5878/// Finalize query with reference ref.
5879/// If force, force retrieval if the query is found in the local list
5880/// but has already been finalized (default kFALSE).
5881/// If ref = 0, finalize current query.
5882/// Return 0 on success, -1 on error
5883
5884Long64_t TProof::Finalize(const char *ref, Bool_t force)
5885{
5886 if (fPlayer) {
5887 // Get the pointer to the query
5888 TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5889 : GetQueryResult();
5891 TString xref(ref);
5892 if (!qr) {
5893 if (!xref.IsNull()) {
5894 retrieve = kTRUE;
5895 }
5896 } else {
5897 if (qr->IsFinalized()) {
5898 if (force) {
5899 retrieve = kTRUE;
5900 } else {
5901 Info("Finalize","query already finalized:"
5902 " use Finalize(<qry>,kTRUE) to force new retrieval");
5903 qr = 0;
5904 }
5905 } else {
5906 retrieve = kTRUE;
5907 xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5908 }
5909 }
5910 if (retrieve) {
5911 Retrieve(xref.Data());
5912 qr = fPlayer->GetQueryResult(xref.Data());
5913 }
5914 if (qr)
5915 return fPlayer->Finalize(qr);
5916 }
5917 return -1;
5918}
5919
5920////////////////////////////////////////////////////////////////////////////////
5921/// Send retrieve request for the qry-th query in fQueries.
5922/// If path is defined save it to path.
5923
5924Int_t TProof::Retrieve(Int_t qry, const char *path)
5925{
5926 if (qry > 0) {
5927 TString ref;
5928 if (GetQueryReference(qry, ref) == 0)
5929 return Retrieve(ref, path);
5930 else
5931 Info("Retrieve", "query #%d not found", qry);
5932 } else {
5933 Info("Retrieve","positive argument required - do nothing");
5934 }
5935 return -1;
5936}
5937
5938////////////////////////////////////////////////////////////////////////////////
5939/// Send retrieve request for the query specified by ref.
5940/// If path is defined save it to path.
5941/// Generic method working for all queries known by the server.
5942
5943Int_t TProof::Retrieve(const char *ref, const char *path)
5944{
5945 if (ref) {
5947 m << TString(ref);
5950
5951 // Archive it locally, if required
5952 if (path) {
5953
5954 // Get pointer to query
5955 TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5956
5957 if (qr) {
5958
5959 TFile *farc = TFile::Open(path,"UPDATE");
5960 if (!farc || (farc && !(farc->IsOpen()))) {
5961 Info("Retrieve", "archive file cannot be open (%s)", path);
5962 return 0;
5963 }
5964 farc->cd();
5965
5966 // Update query status
5967 qr->SetArchived(path);
5968
5969 // Write to file
5970 qr->Write();
5971
5972 farc->Close();
5973 SafeDelete(farc);
5974
5975 } else {
5976 Info("Retrieve", "query not found after retrieve");
5977 return -1;
5978 }
5979 }
5980
5981 return 0;
5982 }
5983 return -1;
5984}
5985
5986////////////////////////////////////////////////////////////////////////////////
5987/// Send remove request for the qry-th query in fQueries.
5988
5990{
5991 if (qry > 0) {
5992 TString ref;
5993 if (GetQueryReference(qry, ref) == 0)
5994 return Remove(ref, all);
5995 else
5996 Info("Remove", "query #%d not found", qry);
5997 } else {
5998 Info("Remove","positive argument required - do nothing");
5999 }
6000 return -1;
6001}
6002
6003////////////////////////////////////////////////////////////////////////////////
6004/// Send remove request for the query specified by ref.
6005/// If all = TRUE remove also local copies of the query, if any.
6006/// Generic method working for all queries known by the server.
6007/// This method can be also used to reset the list of queries
6008/// waiting to be processed: for that purpose use ref == "cleanupqueue".
6009
6010Int_t TProof::Remove(const char *ref, Bool_t all)
6011{
6012 if (all) {
6013 // Remove also local copies, if any
6014 if (fPlayer)
6016 }
6017
6018 if (IsLite()) return 0;
6019
6020 if (ref) {
6022 m << TString(ref);
6025 return 0;
6026 }
6027 return -1;
6028}
6029
6030////////////////////////////////////////////////////////////////////////////////
6031/// Send archive request for the qry-th query in fQueries.
6032
6033Int_t TProof::Archive(Int_t qry, const char *path)
6034{
6035 if (qry > 0) {
6036 TString ref;
6037 if (GetQueryReference(qry, ref) == 0)
6038 return Archive(ref, path);
6039 else
6040 Info("Archive", "query #%d not found", qry);
6041 } else {
6042 Info("Archive","positive argument required - do nothing");
6043 }
6044 return -1;
6045}
6046
6047////////////////////////////////////////////////////////////////////////////////
6048/// Send archive request for the query specified by ref.
6049/// Generic method working for all queries known by the server.
6050/// If ref == "Default", path is understood as a default path for
6051/// archiving.
6052
6053Int_t TProof::Archive(const char *ref, const char *path)
6054{
6055 if (ref) {
6057 m << TString(ref) << TString(path);
6060 return 0;
6061 }
6062 return -1;
6063}
6064
6065////////////////////////////////////////////////////////////////////////////////
6066/// Send cleanup request for the session specified by tag.
6067
6068Int_t TProof::CleanupSession(const char *sessiontag)
6069{
6070 if (sessiontag) {
6072 m << TString(sessiontag);
6075 return 0;
6076 }
6077 return -1;
6078}
6079
6080////////////////////////////////////////////////////////////////////////////////
6081/// Change query running mode to the one specified by 'mode'.
6082
6084{
6085 fQueryMode = mode;
6086
6087 if (gDebug > 0)
6088 Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6089 "Sync" : "Async");
6090}
6091
6092////////////////////////////////////////////////////////////////////////////////
6093/// Find out the query mode based on the current setting and 'mode'.
6094
6096{
6097 EQueryMode qmode = fQueryMode;
6098
6099 if (mode && (strlen(mode) > 0)) {
6100 TString m(mode);
6101 m.ToUpper();
6102 if (m.Contains("ASYN")) {
6103 qmode = kAsync;
6104 } else if (m.Contains("SYNC")) {
6105 qmode = kSync;
6106 }
6107 }
6108
6109 if (gDebug > 0)
6110 Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6111 "Sync" : "Async");
6112
6113 return qmode;
6114}
6115
6116////////////////////////////////////////////////////////////////////////////////
6117/// Execute the specified drawing action on a data set (TDSet).
6118/// Event- or Entry-lists should be set in the data set object using
6119/// TDSet::SetEntryList.
6120/// Returns -1 in case of error or number of selected events otherwise.
6121
6122Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6123 const char *selection, Option_t *option,
6125{
6126 if (!IsValid() || !fPlayer) return -1;
6127
6128 // Make sure that asynchronous processing is not active
6129 if (!IsIdle()) {
6130 Info("DrawSelect","not idle, asynchronous Draw not supported");
6131 return -1;
6132 }
6133 TString opt(option);
6134 Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6135 if (idx != kNPOS)
6136 opt.Replace(idx,4,"");
6137
6138 return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6139}
6140
6141////////////////////////////////////////////////////////////////////////////////
6142/// Execute the specified drawing action on a data set which is stored on the
6143/// master with name 'dsetname'.
6144/// The syntax for dsetname is name[#[dir/]objname], e.g.
6145/// "mydset" analysis of the first tree in the top dir of the dataset
6146/// named "mydset"
6147/// "mydset#T" analysis tree "T" in the top dir of the dataset
6148/// named "mydset"
6149/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6150/// named "mydset"
6151/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6152/// dataset named "mydset"
6153/// The last argument 'enl' specifies an entry- or event-list to be used as
6154/// event selection.
6155/// The return value is -1 in case of error and TSelector::GetStatus() in
6156/// in case of success.
6157
6158Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6159 const char *selection, Option_t *option,
6161{
6162 if (fProtocol < 13) {
6163 Info("Process", "processing 'by name' not supported by the server");
6164 return -1;
6165 }
6166
6167 TString name(dsetname);
6168 TString obj;
6169 TString dir = "/";
6170 Int_t idxc = name.Index("#");
6171 if (idxc != kNPOS) {
6172 Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6173 if (idxs != kNPOS) {
6174 obj = name(idxs+1, name.Length());
6175 dir = name(idxc+1, name.Length());
6176 dir.Remove(dir.Index("/") + 1);
6177 name.Remove(idxc);
6178 } else {
6179 obj = name(idxc+1, name.Length());
6180 name.Remove(idxc);
6181 }
6182 } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6183 // protection against using ':' instead of '#'
6184 Error("DrawSelect", "bad name syntax (%s): please use"
6185 " a '#' after the dataset name", dsetname);
6186 return -1;
6187 }
6188
6189 TDSet *dset = new TDSet(name, obj, dir);
6190 // Set entry-list, if required
6191 dset->SetEntryList(enl);
6192 Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6193 delete dset;
6194 return retval;
6195}
6196
6197////////////////////////////////////////////////////////////////////////////////
6198/// Send STOPPROCESS message to master and workers.
6199
6201{
6202 PDB(kGlobal,2)
6203 Info("StopProcess","enter %d", abort);
6204
6205 if (!IsValid())
6206 return;
6207
6208 // Flag that we have been stopped
6210 SetRunStatus(rst);
6211
6212 if (fPlayer)
6213 fPlayer->StopProcess(abort, timeout);
6214
6215 // Stop any blocking 'Collect' request; on masters we do this only if
6216 // aborting; when stopping, we still need to receive the results
6217 if (TestBit(TProof::kIsClient) || abort)
6219
6220 if (fSlaves->GetSize() == 0)
6221 return;
6222
6223 // Notify the remote counterpart
6224 TSlave *sl;
6225 TIter next(fSlaves);
6226 while ((sl = (TSlave *)next()))
6227 if (sl->IsValid())
6228 // Ask slave to progate the stop/abort request
6229 sl->StopProcess(abort, timeout);
6230}
6231
6232////////////////////////////////////////////////////////////////////////////////
6233/// Signal to disable related switches
6234
6236{
6237 Emit("DisableGoAsyn()");
6238}
6239
6240////////////////////////////////////////////////////////////////////////////////
6241/// Send GOASYNC message to the master.
6242
6244{
6245 if (!IsValid()) return;
6246
6247 if (GetRemoteProtocol() < 22) {
6248 Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6249 return;
6250 }
6251
6252 if (fSync && !IsIdle()) {
6254 Broadcast(m);
6255 } else {
6256 Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6257 }
6258}
6259
6260////////////////////////////////////////////////////////////////////////////////
6261/// Receive the log file of the slave with socket s.
6262
6264{
6265 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6266 char buf[kMAXBUF];
6267
6268 // If macro saving is enabled prepare macro
6272 }
6273
6274 // Append messages to active logging unit
6275 Int_t fdout = -1;
6276 if (!fLogToWindowOnly) {
6277 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6278 if (fdout < 0) {
6279 Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6280 " will not log msgs", fdout);
6281 return;
6282 }
6283 lseek(fdout, (off_t) 0, SEEK_END);
6284 }
6285
6286 Int_t left, rec, r;
6287 Long_t filesize = 0;
6288
6289 while (filesize < size) {
6290 left = Int_t(size - filesize);
6291 if (left >= kMAXBUF)
6292 left = kMAXBUF-1;
6293 rec = s->RecvRaw(&buf, left);
6294 filesize = (rec > 0) ? (filesize + rec) : filesize;
6296 if (rec > 0) {
6297
6298 char *p = buf;
6299 r = rec;
6300 while (r) {
6301 Int_t w;
6302
6303 w = write(fdout, p, r);
6304
6305 if (w < 0) {
6306 SysError("RecvLogFile", "error writing to unit: %d", fdout);
6307 break;
6308 }
6309 r -= w;
6310 p += w;
6311 }
6312 } else if (rec < 0) {
6313 Error("RecvLogFile", "error during receiving log file");
6314 break;
6315 }
6316 }
6317 if (rec > 0) {
6318 buf[rec] = 0;
6319 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6320 // If macro saving is enabled add to TMacro
6322 }
6323 }
6324
6325 // If idle restore logs to main session window
6327 fRedirLog = kFALSE;
6328}
6329
6330////////////////////////////////////////////////////////////////////////////////
6331/// Notify locally 'msg' to the appropriate units (file, stdout, window)
6332/// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6333
6334void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6335{
6336 // Must have somenthing to notify
6337 Int_t len = 0;
6338 if (!msg || (len = strlen(msg)) <= 0)
6339 return;
6340
6341 // Get suffix length if any
6342 Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6343
6344 // Append messages to active logging unit
6345 Int_t fdout = -1;
6346 if (!fLogToWindowOnly) {
6347 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6348 if (fdout < 0) {
6349 Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6350 " will not notify msgs", fdout);
6351 return;
6352 }
6353 lseek(fdout, (off_t) 0, SEEK_END);
6354 }
6355
6356 if (!fLogToWindowOnly) {
6357 // Write to output unit (stdout or a log file)
6358 if (len > 0) {
6359 char *p = (char *)msg;
6360 Int_t r = len;
6361 while (r) {
6362 Int_t w = write(fdout, p, r);
6363 if (w < 0) {
6364 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6365 break;
6366 }
6367 r -= w;
6368 p += w;
6369 }
6370 // Add a suffix, if requested
6371 if (lsfx > 0)
6372 if (write(fdout, sfx, lsfx) != lsfx)
6373 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6374 }
6375 }
6376 if (len > 0) {
6377 // Publish the message to the separate window (if the latter is missing
6378 // the message will just get lost)
6379 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6380 }
6381
6382 // If idle restore logs to main session window
6383 if (fRedirLog && IsIdle())
6384 fRedirLog = kFALSE;
6385}
6386
6387////////////////////////////////////////////////////////////////////////////////
6388/// Log a message into the appropriate window by emitting a signal.
6389
6390void TProof::LogMessage(const char *msg, Bool_t all)
6391{
6392 PDB(kGlobal,1)
6393 Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6394 all ? "true" : "false");
6395
6396 if (gROOT->IsBatch()) {
6397 PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6398 return;
6399 }
6400
6401 if (msg)
6402 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6403
6404 // Re-position at the beginning of the file, if requested.
6405 // This is used by the dialog when it re-opens the log window to
6406 // provide all the session messages
6407 if (all)
6408 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6409
6410 const Int_t kMAXBUF = 32768;
6411 char buf[kMAXBUF];
6412 Int_t len;
6413 do {
6414 while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6415 TSystem::GetErrno() == EINTR)
6417
6418 if (len < 0) {
6419 Error("LogMessage", "error reading log file");
6420 break;
6421 }
6422
6423 if (len > 0) {
6424 buf[len] = 0;
6425 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6426 }
6427
6428 } while (len > 0);
6429}
6430
6431////////////////////////////////////////////////////////////////////////////////
6432/// Send to all active slaves servers the current slave group size
6433/// and their unique id. Returns number of active slaves.
6434/// Returns -1 in case of error.
6435
6437{
6438 if (!IsValid()) return -1;
6439 if (TestBit(TProof::kIsClient)) return 0;
6440 if (!fSendGroupView) return 0;
6442
6443 TIter next(fActiveSlaves);
6444 TSlave *sl;
6445
6446 int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6447 char str[32];
6448
6449 while ((sl = (TSlave *)next())) {
6450 snprintf(str, 32, "%d %d", cnt, size);
6451 if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6452 MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6453 bad++;
6454 } else
6455 cnt++;
6456 }
6457
6458 // Send the group view again in case there was a change in the
6459 // group size due to a bad slave
6460
6461 if (bad) SendGroupView();
6462
6463 return GetNumberOfActiveSlaves();
6464}
6465
6466////////////////////////////////////////////////////////////////////////////////
6467/// Static method to extract the filename (if any) form a CINT command.
6468/// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6469/// appliable.
6470
6472{
6473 TString s = cmd;
6474 s = s.Strip(TString::kBoth);
6475
6476 if (s.Length() > 0 &&
6477 (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6478 TString file = s(2, s.Length());
6479 TString acm, arg, io;
6480 fn = gSystem->SplitAclicMode(file, acm, arg, io);
6481 if (!fn.IsNull())
6482 return kTRUE;
6483 }
6484
6485 // Not found
6486 return kFALSE;
6487}
6488
6489////////////////////////////////////////////////////////////////////////////////
6490/// Send command to be executed on the PROOF master and/or slaves.
6491/// If plusMaster is kTRUE then exeucte on slaves and master too.
6492/// Command can be any legal command line command. Commands like
6493/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6494/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6495/// succes.
6496
6497Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6498{
6499 return Exec(cmd, kActive, plusMaster);
6500}
6501
6502////////////////////////////////////////////////////////////////////////////////
6503/// Send command to be executed on the PROOF master and/or slaves.
6504/// Command can be any legal command line command. Commands like
6505/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6506/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6507/// succes.
6508
6509Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6510{
6511 if (!IsValid()) return -1;
6512
6513 TString s = cmd;
6514 s = s.Strip(TString::kBoth);
6515
6516 if (!s.Length()) return 0;
6517
6518 // check for macro file and make sure the file is available on all slaves
6519 TString filename;
6520 if (TProof::GetFileInCmd(s.Data(), filename)) {
6521 char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6522 if (fn) {
6523 if (GetNumberOfUniqueSlaves() > 0) {
6524 if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6525 Error("Exec", "file %s could not be transfered", fn);
6526 delete [] fn;
6527 return -1;
6528 }
6529 } else {
6530 TString scmd = s(0,3) + fn;
6531 Int_t n = SendCommand(scmd, list);
6532 delete [] fn;
6533 return n;
6534 }
6535 } else {
6536 Error("Exec", "macro %s not found", filename.Data());
6537 return -1;
6538 }
6539 delete [] fn;
6540 }
6541
6542 if (plusMaster) {
6543 if (IsLite()) {
6544 gROOT->ProcessLine(cmd);
6545 } else {
6546 DeactivateWorker("*");
6547 Int_t res = SendCommand(cmd, list);
6548 ActivateWorker("restore");
6549 if (res < 0)
6550 return res;
6551 }
6552 }
6553 return SendCommand(cmd, list);
6554}
6555
6556////////////////////////////////////////////////////////////////////////////////
6557/// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6558/// Command can be any legal command line command. Commands like
6559/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6560/// to the PROOF cluster.
6561/// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6562/// TMacro, accessible via TMacro::GetMacroLog();
6563/// Returns -1 in case of error, >=0 in case of succes.
6564
6565Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6566{
6567 if (!IsValid()) return -1;
6568
6569 TString s = cmd;
6570 s = s.Strip(TString::kBoth);
6571
6572 if (!s.Length()) return 0;
6573
6574 Int_t res = 0;
6575 if (IsLite()) {
6576 gROOT->ProcessLine(cmd);
6577 } else {
6578 Bool_t oldRedirLog = fRedirLog;
6579 fRedirLog = kTRUE;
6580 // Deactivate all workers
6581 DeactivateWorker("*");
6582 fRedirLog = kFALSE;
6583 // Reactivate the target ones, if needed
6584 if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6585 // Honour log-to-macro-saving settings
6586 Bool_t oldSaveLog = fSaveLogToMacro;
6587 fSaveLogToMacro = logtomacro;
6588 res = SendCommand(cmd, kActive);
6589 fSaveLogToMacro = oldSaveLog;
6590 fRedirLog = kTRUE;
6591 ActivateWorker("restore");
6592 fRedirLog = oldRedirLog;
6593 }
6594 // Done
6595 return res;
6596}
6597
6598////////////////////////////////////////////////////////////////////////////////
6599/// Send command to be executed on the PROOF master and/or slaves.
6600/// Command can be any legal command line command, however commands
6601/// like ".x file.C" or ".L file.C" will not cause the file.C to be
6602/// transfered to the PROOF cluster. In that case use TProof::Exec().
6603/// Returns the status send by the remote server as part of the
6604/// kPROOF_LOGDONE message. Typically this is the return code of the
6605/// command on the remote side. Returns -1 in case of error.
6606
6607Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6608{
6609 if (!IsValid()) return -1;
6610
6611 Broadcast(cmd, kMESS_CINT, list);
6612 Collect(list);
6613
6614 return fStatus;
6615}
6616
6617////////////////////////////////////////////////////////////////////////////////
6618/// Get value of environment variable 'env' on node 'ord'
6619
6620TString TProof::Getenv(const char *env, const char *ord)
6621{
6622 // The command to be executed
6623 TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6624 if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6625 // Get the line
6626 TObjString *os = fMacroLog.GetLineWith("const char");
6627 if (os) {
6628 TString info;
6629 Ssiz_t from = 0;
6630 os->GetString().Tokenize(info, from, "\"");
6631 os->GetString().Tokenize(info, from, "\"");
6632 if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6633 return info;
6634 }
6635 return TString("");
6636}
6637
6638////////////////////////////////////////////////////////////////////////////////
6639/// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6640
6641Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6642{
6643 // The command to be executed
6644 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6645 // Exectute the command saving the logs to macro
6646 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6647 // Get the line
6648 TObjString *os = fMacroLog.GetLineWith("const char");
6649 Int_t rc = -1;
6650 if (os) {
6651 Ssiz_t fst = os->GetString().First('\"');
6652 Ssiz_t lst = os->GetString().Last('\"');
6653 TString info = os->GetString()(fst+1, lst-fst-1);
6654 if (info.IsDigit()) {
6655 env = info.Atoi();
6656 rc = 0;
6657 if (gDebug > 0)
6658 Printf("%s: %d", rcenv, env);
6659 }
6660 }
6661 return rc;
6662}
6663
6664////////////////////////////////////////////////////////////////////////////////
6665/// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6666
6667Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6668{
6669 // The command to be executed
6670 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6671 // Exectute the command saving the logs to macro
6672 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6673 // Get the line
6674 TObjString *os = fMacroLog.GetLineWith("const char");
6675 Int_t rc = -1;
6676 if (os) {
6677 Ssiz_t fst = os->GetString().First('\"');
6678 Ssiz_t lst = os->GetString().Last('\"');
6679 TString info = os->GetString()(fst+1, lst-fst-1);
6680 if (info.IsFloat()) {
6681 env = info.Atof();
6682 rc = 0;
6683 if (gDebug > 0)
6684 Printf("%s: %f", rcenv, env);
6685 }
6686 }
6687 return rc;
6688}
6689
6690////////////////////////////////////////////////////////////////////////////////
6691/// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6692
6693Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6694{
6695 // The command to be executed
6696 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6697 // Exectute the command saving the logs to macro
6698 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6699 // Get the line
6700 TObjString *os = fMacroLog.GetLineWith("const char");
6701 Int_t rc = -1;
6702 if (os) {
6703 Ssiz_t fst = os->GetString().First('\"');
6704 Ssiz_t lst = os->GetString().Last('\"');
6705 env = os->GetString()(fst+1, lst-fst-1);
6706 rc = 0;
6707 if (gDebug > 0)
6708 Printf("%s: %s", rcenv, env.Data());
6709 }
6710 return rc;
6711}
6712
6713////////////////////////////////////////////////////////////////////////////////
6714/// Transfer the current state of the master to the active slave servers.
6715/// The current state includes: the current working directory, etc.
6716/// Returns the number of active slaves. Returns -1 in case of error.
6717
6719{
6720 if (!IsValid()) return -1;
6721
6722 // Go to the new directory, reset the interpreter environment and
6723 // tell slave to delete all objects from its new current directory.
6724 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6725
6726 return GetParallel();
6727}
6728
6729////////////////////////////////////////////////////////////////////////////////
6730/// Transfer the current state of the master to the active slave servers.
6731/// The current state includes: the current working directory, etc.
6732/// Returns the number of active slaves. Returns -1 in case of error.
6733
6735{
6736 if (!IsValid()) return -1;
6737
6738 // Go to the new directory, reset the interpreter environment and
6739 // tell slave to delete all objects from its new current directory.
6740 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6741
6742 return GetParallel();
6743}
6744
6745////////////////////////////////////////////////////////////////////////////////
6746/// Transfer the initial (i.e. current) state of the master to all
6747/// slave servers. Currently the initial state includes: log level.
6748/// Returns the number of active slaves. Returns -1 in case of error.
6749
6751{
6752 if (!IsValid()) return -1;
6753
6755
6756 return GetNumberOfActiveSlaves();
6757}
6758
6759////////////////////////////////////////////////////////////////////////////////
6760/// Check if a file needs to be send to the slave. Use the following
6761/// algorithm:
6762/// - check if file appears in file map
6763/// - if yes, get file's modtime and check against time in map,
6764/// if modtime not same get md5 and compare against md5 in map,
6765/// if not same return kTRUE.
6766/// - if no, get file's md5 and modtime and store in file map, ask
6767/// slave if file exists with specific md5, if yes return kFALSE,
6768/// if no return kTRUE.
6769/// The options 'cpopt' define if to copy things from cache to sandbox and what.
6770/// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6771/// must be set in cpopt; the default is copy everything.
6772/// Returns kTRUE in case file needs to be send, returns kFALSE in case
6773/// file is already on remote node.
6774
6775Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6776{
6777 Bool_t sendto = kFALSE;
6778
6779 // create worker based filename
6780 TString sn = slave->GetName();
6781 sn += ":";
6782 sn += slave->GetOrdinal();
6783 sn += ":";
6784 sn += gSystem->BaseName(file);
6785
6786 // check if file is in map
6787 FileMap_t::const_iterator it;
6788 if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6789 // file in map
6790 MD5Mod_t md = (*it).second;
6791 if (md.fModtime != modtime) {
6793 if (md5) {
6794 if ((*md5) != md.fMD5) {
6795 sendto = kTRUE;
6796 md.fMD5 = *md5;
6797 md.fModtime = modtime;
6798 fFileMap[sn] = md;
6799 // When on the master, the master and/or slaves may share
6800 // their file systems and cache. Therefore always make a
6801 // check for the file. If the file already exists with the
6802 // expected md5 the kPROOF_CHECKFILE command will cause the
6803 // file to be copied from cache to slave sandbox.
6805 sendto = kFALSE;
6807 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6808 slave->GetSocket()->Send(mess);
6809
6810 fCheckFileStatus = 0;
6812 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6813 }
6814 }
6815 delete md5;
6816 } else {
6817 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6818 return kFALSE;
6819 }
6820 }
6821 } else {
6822 // file not in map
6824 MD5Mod_t md;
6825 if (md5) {
6826 md.fMD5 = *md5;
6827 md.fModtime = modtime;
6828 fFileMap[sn] = md;
6829 delete md5;
6830 } else {
6831 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6832 return kFALSE;
6833 }
6835 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6836 slave->GetSocket()->Send(mess);
6837
6838 fCheckFileStatus = 0;
6840 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6841 }
6842
6843 return sendto;
6844}
6845
6846////////////////////////////////////////////////////////////////////////////////
6847/// Send a file to master or slave servers. Returns number of slaves
6848/// the file was sent to, maybe 0 in case master and slaves have the same
6849/// file system image, -1 in case of error.
6850/// If defined, send to worker 'wrk' only.
6851/// If defined, the full path of the remote path will be rfile.
6852/// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6853/// (to copy to the cache on a different name use rfile = "cache:newname").
6854/// The mask 'opt' is an or of ESendFileOpt:
6855///
6856/// kAscii (0x0) if set true ascii file transfer is used
6857/// kBinary (0x1) if set true binary file transfer is used
6858/// kForce (0x2) if not set an attempt is done to find out
6859/// whether the file really needs to be downloaded
6860/// (a valid copy may already exist in the cache
6861/// from a previous run); the bit is set by
6862/// UploadPackage, since the check is done elsewhere.
6863/// kForward (0x4) if set, ask server to forward the file to slave
6864/// or submaster (meaningless for slave servers).
6865/// kCpBin (0x8) Retrieve from the cache the binaries associated
6866/// with the file
6867/// kCp (0x10) Retrieve the files from the cache
6868///
6869
6870Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6871{
6872 if (!IsValid()) return -1;
6873
6874 // Use the active slaves list ...
6875 TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6876 // ... or the specified slave, if any
6877 if (wrk) {
6878 slaves = new TList();
6879 slaves->Add(wrk);
6880 }
6881
6882 if (slaves->GetSize() == 0) return 0;
6883
6884#ifndef R__WIN32
6885 Int_t fd = open(file, O_RDONLY);
6886#else
6887 Int_t fd = open(file, O_RDONLY | O_BINARY);
6888#endif
6889 if (fd < 0) {
6890 SysError("SendFile", "cannot open file %s", file);
6891 return -1;
6892 }
6893
6894 // Get info about the file
6895 Long64_t size = -1;
6896 Long_t id, flags, modtime = 0;
6897 if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6898 Error("SendFile", "cannot stat file %s", file);
6899 close(fd);
6900 return -1;
6901 }
6902 if (size == 0) {
6903 Error("SendFile", "empty file %s", file);
6904 close(fd);
6905 return -1;
6906 }
6907
6908 // Decode options
6909 Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6910 Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6911 Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6912
6913 // Copy options
6914 Int_t cpopt = 0;
6915 if ((opt & kCp)) cpopt |= kCp;
6916 if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6917
6918 const Int_t kMAXBUF = 32768; //16384 //65536;
6919 char buf[kMAXBUF];
6920 Int_t nsl = 0;
6921
6922 TIter next(slaves);
6923 TSlave *sl;
6924 TString fnam(rfile);
6925 if (fnam == "cache") {
6926 fnam += TString::Format(":%s", gSystem->BaseName(file));
6927 } else if (fnam.IsNull()) {
6928 fnam = gSystem->BaseName(file);
6929 }
6930 // List on which we will collect the results
6931 fStatus = 0;
6932 while ((sl = (TSlave *)next())) {
6933 if (!sl->IsValid())
6934 continue;
6935
6936 Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6937 // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6938 // is false. Masters might still need to send the file to newly added
6939 // slaves.
6940 PDB(kPackage,2) {
6941 const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6942 Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6943 file, sl->GetName(), sl->GetOrdinal(), sendto);
6944 }
6945 if (sl->fSlaveType == TSlave::kSlave && !sendto)
6946 continue;
6947 // The value of 'size' is used as flag remotely, so we need to
6948 // reset it to 0 if we are not going to send the file
6949 Long64_t siz = sendto ? size : 0;
6950 snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6951 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6952 MarkBad(sl, "could not send kPROOF_SENDFILE request");
6953 continue;
6954 }
6955
6956 if (sendto) {
6957
6958 lseek(fd, 0, SEEK_SET);
6959
6960 Int_t len;
6961 do {
6962 while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6964
6965 if (len < 0) {
6966 SysError("SendFile", "error reading from file %s", file);
6968 close(fd);
6969 return -1;
6970 }
6971
6972 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6973 SysError("SendFile", "error writing to slave %s:%s (now offline)",
6974 sl->GetName(), sl->GetOrdinal());
6975 MarkBad(sl, "sendraw failure");
6976 sl = 0;
6977 break;
6978 }
6979
6980 } while (len > 0);
6981
6982 nsl++;
6983 }
6984 // Wait for the operation to be done
6985 if (sl)
6987 }
6988
6989 close(fd);
6990
6991 // Cleanup temporary list, if any
6992 if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
6993 SafeDelete(slaves);
6994
6995 // We return failure is at least one unique worker failed
6996 return (fStatus != 0) ? -1 : nsl;
6997}
6998
6999////////////////////////////////////////////////////////////////////////////////
7000/// Sends an object to master and workers and expect them to send back a
7001/// message with the output of its TObject::Print(). Returns -1 on error, the
7002/// number of workers that received the objects on success.
7003
7005{
7006 if (!IsValid() || !obj) return -1;
7007 TMessage mess(kPROOF_ECHO);
7008 mess.WriteObject(obj);
7009 return Broadcast(mess);
7010}
7011
7012////////////////////////////////////////////////////////////////////////////////
7013/// Sends a string to master and workers and expect them to echo it back to
7014/// the client via a message. It is a special case of the generic Echo()
7015/// that works with TObjects. Returns -1 on error, the number of workers that
7016/// received the message on success.
7017
7018Int_t TProof::Echo(const char *str)
7019{
7020 TObjString *os = new TObjString(str);
7021 Int_t rv = Echo(os);
7022 delete os;
7023 return rv;
7024}
7025
7026////////////////////////////////////////////////////////////////////////////////
7027/// Send object to master or slave servers. Returns number of slaves object
7028/// was sent to, -1 in case of error.
7029
7031{
7032 if (!IsValid() || !obj) return -1;
7033
7034 TMessage mess(kMESS_OBJECT);
7035
7036 mess.WriteObject(obj);
7037 return Broadcast(mess, list);
7038}
7039
7040////////////////////////////////////////////////////////////////////////////////
7041/// Send print command to master server. Returns number of slaves message
7042/// was sent to. Returns -1 in case of error.
7043
7045{
7046 if (!IsValid()) return -1;
7047
7048 Broadcast(option, kPROOF_PRINT, kActive);
7050}
7051
7052////////////////////////////////////////////////////////////////////////////////
7053/// Set server logging level.
7054
7056{
7057 char str[32];
7058 fLogLevel = level;
7059 gProofDebugLevel = level;
7061 snprintf(str, 32, "%d %u", level, mask);
7063}
7064
7065////////////////////////////////////////////////////////////////////////////////
7066/// Switch ON/OFF the real-time logging facility. When this option is
7067/// ON, log messages from processing are sent back as they come, instead of
7068/// being sent back at the end in one go. This may help debugging or monitoring
7069/// in some cases, but, depending on the amount of log, it may have significant
7070/// consequencies on the load over the network, so it must be used with care.
7071
7073{
7074 if (IsValid()) {
7076 mess << on;
7077 Broadcast(mess);
7078 } else {
7079 Warning("SetRealTimeLog","session is invalid - do nothing");
7080 }
7081}
7082
7083////////////////////////////////////////////////////////////////////////////////
7084/// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7085/// selection is done (if nodes is less than the available nodes).
7086/// Returns the number of parallel slaves. Returns -1 in case of error.
7087
7089{
7090 if (!IsValid()) return -1;
7091
7093 if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7094 return SendCurrentState();
7095 } else {
7096 if (nodes < 0) {
7097 PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7098 } else {
7099 PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7100 nodes == 1 ? "" : "s");
7101 }
7103 mess << nodes << random;
7104 Broadcast(mess);
7106 Int_t n = GetParallel();
7107 PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7108 return n;
7109 }
7110}
7111
7112////////////////////////////////////////////////////////////////////////////////
7113/// Tell PROOF how many slaves to use in parallel. Returns the number of
7114/// parallel slaves. Returns -1 in case of error.
7115
7117{
7118 // If delayed startup reset settings, if required
7119 if (fDynamicStartup && nodes < 0) {
7120 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7121 }
7122
7123 Int_t n = SetParallelSilent(nodes, random);
7125 if (n < 1) {
7126 Printf("PROOF set to sequential mode");
7127 } else {
7128 TString subfix = (n == 1) ? "" : "s";
7129 if (random)
7130 subfix += ", randomly selected";
7131 Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7132 }
7133 } else if (fDynamicStartup && nodes >= 0) {
7134 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7135 gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7136 }
7137 return n;
7138}
7139
7140////////////////////////////////////////////////////////////////////////////////
7141/// Add nWorkersToAdd workers to current list of workers. This function is
7142/// works on the master only, and only when an analysis is ongoing. A message
7143/// is sent back to the client when we go "more" parallel.
7144/// Returns -1 on error, number of total (not added!) workers on success.
7145
7147{
7148 if (!IsValid() || !IsMaster() || IsIdle()) {
7149 Error("GoMoreParallel", "can't invoke here -- should not happen!");
7150 return -1;
7151 }
7152 if (!gProofServ && !IsLite()) {
7153 Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7154 return -1;
7155 }
7156
7157 TSlave *sl = 0x0;
7158 TIter next( fSlaves );
7159 Int_t nAddedWorkers = 0;
7160
7161 while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7162 (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7163
7164 // If worker is of an invalid type, break everything: it should not happen!
7165 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7166 (sl->GetSlaveType() != TSlave::kMaster)) {
7167 Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7168 sl->GetName(), sl->GetOrdinal());
7169 R__ASSERT(0);
7170 }
7171
7172 // Skip current worker if it is not a good candidate
7173 if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7174 (strcmp("IGNORE", sl->GetImage()) == 0)) {
7175 PDB(kGlobal, 2)
7176 Info("GoMoreParallel", "Worker %s:%s won't be considered",
7177 sl->GetName(), sl->GetOrdinal());
7178 continue;
7179 }
7180
7181 // Worker is good but it is already active: skip it
7182 if (fActiveSlaves->FindObject(sl)) {
7183 Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7184 sl->GetName(), sl->GetOrdinal());
7185 continue;
7186 }
7187
7188 //
7189 // From here on: worker is a good candidate
7190 //
7191
7192 if (sl->GetSlaveType() == TSlave::kSlave) {
7194 fActiveSlaves->Add(sl);
7197 nAddedWorkers++;
7198 PDB(kGlobal, 2)
7199 Info("GoMoreParallel", "Worker %s:%s marked as active!",
7200 sl->GetName(), sl->GetOrdinal());
7201 }
7202 else {
7203 // Can't add masters dynamically: this should not happen!
7204 Error("GoMoreParallel", "Dynamic addition of master is not supported");
7205 R__ASSERT(0);
7206 }
7207
7208 } // end loop over all slaves
7209
7210 // Get slave status (will set the slaves fWorkDir correctly)
7211 PDB(kGlobal, 3)
7212 Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7213 AskStatistics();
7214
7215 // Find active slaves with unique image
7216 PDB(kGlobal, 3)
7217 Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7219
7220 // Send new group-view to slaves
7221 PDB(kGlobal, 3)
7222 Info("GoMoreParallel", "Will invoke SendGroupView()");
7223 SendGroupView();
7224
7225 PDB(kGlobal, 3)
7226 Info("GoMoreParallel", "Will invoke GetParallel()");
7227 Int_t nTotalWorkers = GetParallel();
7228
7229 // Notify the client that we've got more workers, and print info on
7230 // Master's log as well
7231 TString s;
7232 s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7233 nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7234 nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7236 Info("GoMoreParallel", "%s", s.Data());
7237
7238 return nTotalWorkers;
7239}
7240
7241////////////////////////////////////////////////////////////////////////////////
7242/// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7243/// list is sorted by slave performace the active list will contain first
7244/// the most performant nodes. Returns the number of active slaves.
7245/// If random is TRUE, and nodes is less than the number of available workers,
7246/// a random selection is done.
7247/// Returns -1 in case of error.
7248
7250{
7251 if (!IsValid()) return -1;
7252
7255
7256 // Prepare the list of candidates first.
7257 // Algorithm depends on random option.
7258 TSlave *sl = 0;
7259 TList *wlst = new TList;
7260 TIter nxt(fSlaves);
7262 while ((sl = (TSlave *)nxt())) {
7263 if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7264 if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7265 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7266 (sl->GetSlaveType() != TSlave::kMaster)) {
7267 Error("GoParallel", "TSlave is neither Master nor Slave");
7268 R__ASSERT(0);
7269 }
7270 // Good candidate
7271 wlst->Add(sl);
7272 // Set it inactive
7273 fInactiveSlaves->Add(sl);
7275 }
7276 }
7277 Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7278 int cnt = 0;
7280 while (cnt < nwrks) {
7281 // Random choice, if requested
7282 if (random) {
7283 Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7284 sl = (TSlave *) wlst->At(iwrk);
7285 } else {
7286 // The first available
7287 sl = (TSlave *) wlst->First();
7288 }
7289 if (!sl) {
7290 Error("GoParallel", "attaching to candidate!");
7291 break;
7292 }
7293 // Remove from the list
7294 wlst->Remove(sl);
7295
7296 Int_t slavenodes = 0;
7297 if (sl->GetSlaveType() == TSlave::kSlave) {
7299 fActiveSlaves->Add(sl);
7302 slavenodes = 1;
7303 } else if (sl->GetSlaveType() == TSlave::kMaster) {
7306 if (!attach) {
7307 Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7308 mess << nn;
7309 } else {
7310 // To get the number of slaves
7311 mess.SetWhat(kPROOF_LOGFILE);
7312 mess << -1 << -1;
7313 }
7314 if (sl->GetSocket()->Send(mess) == -1) {
7315 MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7316 slavenodes = 0;
7317 } else {
7319 if (sl->IsValid()) {
7321 fActiveSlaves->Add(sl);
7324 if (sl->GetParallel() > 0) {
7325 slavenodes = sl->GetParallel();
7326 } else {
7327 // Sequential mode: the master acts as a worker
7328 slavenodes = 1;
7329 }
7330 } else {
7331 MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7332 slavenodes = 0;
7333 }
7334 }
7335 }
7336 // 'slavenodes' may be different than 1 in multimaster setups
7337 cnt += slavenodes;
7338 }
7339
7340 // Cleanup list
7341 wlst->SetOwner(0);
7342 SafeDelete(wlst);
7343
7344 // Get slave status (will set the slaves fWorkDir correctly)
7345 AskStatistics();
7346
7347 // Find active slaves with unique image
7349
7350 // Send new group-view to slaves
7351 if (!attach)
7352 SendGroupView();
7353
7354 Int_t n = GetParallel();
7355
7357 if (n < 1)
7358 printf("PROOF set to sequential mode\n");
7359 else
7360 printf("PROOF set to parallel mode (%d worker%s)\n",
7361 n, n == 1 ? "" : "s");
7362 }
7363
7364 PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7365 return n;
7366}
7367
7368////////////////////////////////////////////////////////////////////////////////
7369/// List contents of the data directory in the sandbox.
7370/// This is the place where files produced by the client queries are kept
7371
7373{
7374 if (!IsValid() || !fManager) return;
7375
7376 // This is run via the manager
7377 fManager->Find("~/data", "-type f", "all");
7378}
7379
7380////////////////////////////////////////////////////////////////////////////////
7381/// Remove files for the data directory.
7382/// The option 'what' can take the values:
7383/// kPurge remove all files and directories under '~/data'
7384/// kUnregistered remove only files not in registered datasets (default)
7385/// kDataset remove files belonging to dataset 'dsname'
7386/// User is prompt for confirmation, unless kForceClear is ORed with the option
7387
7388void TProof::ClearData(UInt_t what, const char *dsname)
7389{
7390 if (!IsValid() || !fManager) return;
7391
7392 // Check whether we need to prompt
7393 TString prompt, a("Y");
7394 Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7395 Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7396
7397 // If all just send the request
7398 if ((what & TProof::kPurge)) {
7399 // Prompt, if requested
7400 if (doask && !Prompt("Do you really want to remove all data files")) return;
7401 if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7402 Warning("ClearData", "problems purging data directory");
7403 return;
7404 } else if ((what & TProof::kDataset)) {
7405 // We must have got a name
7406 if (!dsname || strlen(dsname) <= 0) {
7407 Error("ClearData", "dataset name mandatory when removing a full dataset");
7408 return;
7409 }
7410 // Check if the dataset is registered
7411 if (!ExistsDataSet(dsname)) {
7412 Error("ClearData", "dataset '%s' does not exists", dsname);
7413 return;
7414 }
7415 // Get the file content
7416 TFileCollection *fc = GetDataSet(dsname);
7417 if (!fc) {
7418 Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7419 return;
7420 }
7421 // Prompt, if requested
7422 TString pmpt = TString::Format("Do you really want to remove all data files"
7423 " of dataset '%s'", dsname);
7424 if (doask && !Prompt(pmpt.Data())) return;
7425
7426 // Loop through the files
7427 Bool_t rmds = kTRUE;
7428 TIter nxf(fc->GetList());
7429 TFileInfo *fi = 0;
7430 Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7431 while ((fi = (TFileInfo *) nxf())) {
7432 // Fill the host info
7433 TString host, file;
7434 // Take info from the current url
7435 if (!(fi->GetFirstUrl())) {
7436 Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7437 fi->GetName());
7438 continue;
7439 }
7440 TUrl uf(*(fi->GetFirstUrl()));
7441 file = uf.GetFile();
7442 host = uf.GetHost();
7443 // Now search for any "file:" url
7444 Int_t nurl = fi->GetNUrls();
7445 fi->ResetUrl();
7446 TUrl *up = 0;
7447 while (nurl-- && fi->NextUrl()) {
7448 up = fi->GetCurrentUrl();
7449 if (!strcmp(up->GetProtocol(), "file")) {
7450 TString opt(up->GetOptions());
7451 if (opt.BeginsWith("node=")) {
7452 host=opt;
7453 host.ReplaceAll("node=","");
7454 file = up->GetFile();
7455 break;
7456 }
7457 }
7458 }
7459 // Issue a remove request now
7460 if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7461 Error("ClearData", "problems removing '%s'", file.Data());
7462 // Some files not removed: keep the meta info about this dataset
7463 rmds = kFALSE;
7464 }
7465 rfiles++;
7466 ClearDataProgress(rfiles, nfiles);
7467 }
7468 fprintf(stderr, "\n");
7469 if (rmds) {
7470 // All files were removed successfully: remove also the dataset meta info
7471 RemoveDataSet(dsname);
7472 }
7473 } else if (what & TProof::kUnregistered) {
7474
7475 // Get the existing files
7476 TString outtmp("ProofClearData_");
7477 FILE *ftmp = gSystem->TempFileName(outtmp);
7478 if (!ftmp) {
7479 Error("ClearData", "cannot create temp file for logs");
7480 return;
7481 }
7482 fclose(ftmp);
7484 gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7485 ShowData();
7486 gSystem->RedirectOutput(0, 0, &h);
7487 // Parse the output file now
7488 std::ifstream in;
7489 in.open(outtmp.Data());
7490 if (!in.is_open()) {
7491 Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7492 gSystem->Unlink(outtmp);
7493 return;
7494 }
7495 // Go through
7496 Int_t nfiles = 0;
7497 TMap *afmap = new TMap;
7498 TString line, host, file;
7499 Int_t from = 0;
7500 while (in.good()) {
7501 line.ReadLine(in);
7502 if (line.IsNull()) continue;
7503 while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7504 from = 0;
7505 host = "";
7506 if (!line.Tokenize(host, from, "| ")) continue;
7507 file = "";
7508 if (!line.Tokenize(file, from, "| ")) continue;
7509 if (!host.IsNull() && !file.IsNull()) {
7510 TList *fl = (TList *) afmap->GetValue(host.Data());
7511 if (!fl) {
7512 fl = new TList();
7513 fl->SetName(host);
7514 afmap->Add(new TObjString(host), fl);
7515 }
7516 fl->Add(new TObjString(file));
7517 nfiles++;
7518 PDB(kDataset,2)
7519 Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7520 } else {
7521 Warning("ClearData", "found incomplete line: '%s'", line.Data());
7522 }
7523 }
7524 // Close and remove the file
7525 in.close();
7526 gSystem->Unlink(outtmp);
7527
7528 // Get registered data files
7529 TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7530 TMap *fcmap = GetDataSets(sel);
7531 if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7532 PDB(kDataset,1)
7533 Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7534 SafeDelete(fcmap);
7535 }
7536
7537 // Go thorugh and prepare the lists per node
7538 TString opt;
7539 TObjString *os = 0;
7540 if (fcmap) {
7541 TIter nxfc(fcmap);
7542 while ((os = (TObjString *) nxfc())) {
7543 TFileCollection *fc = 0;
7544 if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7545 TFileInfo *fi = 0;
7546 TIter nxfi(fc->GetList());
7547 while ((fi = (TFileInfo *) nxfi())) {
7548 // Get special "file:" url
7549 fi->ResetUrl();
7550 Int_t nurl = fi->GetNUrls();
7551 TUrl *up = 0;
7552 while (nurl-- && fi->NextUrl()) {
7553 up = fi->GetCurrentUrl();
7554 if (!strcmp(up->GetProtocol(), "file")) {
7555 opt = up->GetOptions();
7556 if (opt.BeginsWith("node=")) {
7557 host=opt;
7558 host.ReplaceAll("node=","");
7559 file = up->GetFile();
7560 PDB(kDataset,2)
7561 Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7562 // Remove this from the full list, if there
7563 TList *fl = (TList *) afmap->GetValue(host.Data());
7564 if (fl) {
7565 TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7566 if (fn) {
7567 fl->Remove(fn);
7568 SafeDelete(fn);
7569 nfiles--;
7570 } else {
7571 Warning("ClearData",
7572 "registered file '%s' not found in the full list!",
7573 file.Data());
7574 }
7575 }
7576 break;
7577 }
7578 }
7579 }
7580 }
7581 }
7582 }
7583 // Clean up the the received map
7584 if (fcmap) fcmap->SetOwner(kTRUE);
7585 SafeDelete(fcmap);
7586 }
7587 // List of the files to be removed
7588 Info("ClearData", "%d unregistered files to be removed:", nfiles);
7589 afmap->Print();
7590 // Prompt, if requested
7591 TString pmpt = TString::Format("Do you really want to remove all %d"
7592 " unregistered data files", nfiles);
7593 if (doask && !Prompt(pmpt.Data())) return;
7594
7595 // Remove one by one; we may implement a bloc remove in the future
7596 Int_t rfiles = 0;
7597 TIter nxls(afmap);
7598 while ((os = (TObjString *) nxls())) {
7599 TList *fl = 0;
7600 if ((fl = (TList *) afmap->GetValue(os))) {
7601 TIter nxf(fl);
7602 TObjString *fn = 0;
7603 while ((fn = (TObjString *) nxf())) {
7604 // Issue a remove request now
7605 if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7606 Error("ClearData", "problems removing '%s' on host '%s'",
7607 fn->GetName(), os->GetName());
7608 }
7609 rfiles++;
7610 ClearDataProgress(rfiles, nfiles);
7611 }
7612 }
7613 }
7614 fprintf(stderr, "\n");
7615 // Final cleanup
7616 afmap->SetOwner(kTRUE);
7617 SafeDelete(afmap);
7618 }
7619}
7620
7621////////////////////////////////////////////////////////////////////////////////
7622/// Prompt the question 'p' requiring an answer y,Y,n,N
7623/// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7624
7626{
7627 TString pp(p);
7628 if (!pp.Contains("?")) pp += "?";
7629 if (!pp.Contains("[y/N]")) pp += " [y/N]";
7630 TString a = Getline(pp.Data());
7631 if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7632 Printf("Please answer y, Y, n or N");
7633 // Unclear answer: assume negative
7634 return kFALSE;
7635 } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7636 // Explicitly Negative answer
7637 return kFALSE;
7638 }
7639 // Explicitly Positive answer
7640 return kTRUE;
7641}
7642
7643////////////////////////////////////////////////////////////////////////////////
7644/// Progress bar for clear data
7645
7647{
7648 fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7649 for (Int_t l = 0; l < 20; l++) {
7650 if (r > 0 && t > 0) {
7651 if (l < 20*r/t)
7652 fprintf(stderr, "=");
7653 else if (l == 20*r/t)
7654 fprintf(stderr, ">");
7655 else if (l > 20*r/t)
7656 fprintf(stderr, ".");
7657 } else
7658 fprintf(stderr, "=");
7659 }
7660 fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7661}
7662
7663////////////////////////////////////////////////////////////////////////////////
7664/// List contents of file cache. If all is true show all caches also on
7665/// slaves. If everything is ok all caches are to be the same.
7666
7668{
7669 if (!IsValid()) return;
7670
7671 TMessage mess(kPROOF_CACHE);
7672 mess << Int_t(kShowCache) << all;
7673 Broadcast(mess, kUnique);
7674
7675 if (all) {
7676 TMessage mess2(kPROOF_CACHE);
7677 mess2 << Int_t(kShowSubCache) << all;
7679
7681 } else {
7683 }
7684}
7685
7686////////////////////////////////////////////////////////////////////////////////
7687/// Remove file from all file caches. If file is 0 or "" or "*", remove all
7688/// the files
7689
7690void TProof::ClearCache(const char *file)
7691{
7692 if (!IsValid()) return;
7693
7694 TMessage mess(kPROOF_CACHE);
7695 mess << Int_t(kClearCache) << TString(file);
7696 Broadcast(mess, kUnique);
7697
7698 TMessage mess2(kPROOF_CACHE);
7699 mess2 << Int_t(kClearSubCache) << TString(file);
7701
7703
7704 // clear file map so files get send again to remote nodes
7705 fFileMap.clear();
7706}
7707
7708////////////////////////////////////////////////////////////////////////////////
7709/// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7710
7711void TProof::SystemCmd(const char *cmd, Int_t fdout)
7712{
7713 if (fdout < 0) {
7714 // Exec directly the command
7715 gSystem->Exec(cmd);
7716 } else {
7717 // Exec via a pipe
7718 FILE *fin = gSystem->OpenPipe(cmd, "r");
7719 if (fin) {
7720 // Now we go
7721 char line[2048];
7722 while (fgets(line, 2048, fin)) {
7723 Int_t r = strlen(line);
7724 if (r > 0) {
7725 if (write(fdout, line, r) < 0) {
7726 ::Warning("TProof::SystemCmd",
7727 "errno %d writing to file descriptor %d",
7728 TSystem::GetErrno(), fdout);
7729 }
7730 } else {
7731 // Done
7732 break;
7733 }
7734 }
7735 gSystem->ClosePipe(fin);
7736 }
7737 }
7738}
7739
7740////////////////////////////////////////////////////////////////////////////////
7741/// List contents of package directory. If all is true show all package
7742/// directories also on slaves. If everything is ok all package directories
7743/// should be the same. If redir is kTRUE the result is redirected to the log
7744/// file (option available for internal actions).
7745
7747{
7748 if (!IsValid()) return;
7749
7750 Bool_t oldredir = fRedirLog;
7751 if (redirlog) fRedirLog = kTRUE;
7752
7753 // Active logging unit
7754 FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7755 if (!fout) {
7756 Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7757 " will not log msgs", fout);
7758 return;
7759 }
7760 lseek(fileno(fout), (off_t) 0, SEEK_END);
7761
7763 fPackMgr->Show();
7764 }
7765
7766 // Nothing more to do if we are a Lite-session
7767 if (IsLite()) {
7768 fRedirLog = oldredir;
7769 return;
7770 }
7771
7772 TMessage mess(kPROOF_CACHE);
7773 mess << Int_t(kShowPackages) << all;
7774 Broadcast(mess, kUnique);
7775
7776 if (all) {
7777 TMessage mess2(kPROOF_CACHE);
7778 mess2 << Int_t(kShowSubPackages) << all;
7780
7782 } else {
7784 }
7785 // Restore logging option
7786 fRedirLog = oldredir;
7787}
7788
7789////////////////////////////////////////////////////////////////////////////////
7790/// List which packages are enabled. If all is true show enabled packages
7791/// for all active slaves. If everything is ok all active slaves should
7792/// have the same packages enabled.
7793
7795{
7796 if (!IsValid()) return;
7797
7799 fPackMgr->ShowEnabled(TString::Format("*** Enabled packages on client on %s\n",
7800 gSystem->HostName()));
7801 }
7802
7803 // Nothing more to do if we are a Lite-session
7804 if (IsLite()) return;
7805
7806 TMessage mess(kPROOF_CACHE);
7807 mess << Int_t(kShowEnabledPackages) << all;
7808 Broadcast(mess);
7810}
7811
7812////////////////////////////////////////////////////////////////////////////////
7813/// Remove all packages.
7814/// Returns 0 in case of success and -1 in case of error.
7815
7817{
7818 if (!IsValid()) return -1;
7819
7820 if (UnloadPackages() == -1)
7821 return -1;
7822
7823 if (DisablePackages() == -1)
7824 return -1;
7825
7826 return fStatus;
7827}
7828
7829////////////////////////////////////////////////////////////////////////////////
7830/// Remove a specific package.
7831/// Returns 0 in case of success and -1 in case of error.
7832
7833Int_t TProof::ClearPackage(const char *package)
7834{
7835 if (!IsValid()) return -1;
7836
7837 if (!package || !package[0]) {
7838 Error("ClearPackage", "need to specify a package name");
7839 return -1;
7840 }
7841
7842 // if name, erroneously, is a par pathname strip off .par and path
7843 TString pac = package;
7844 if (pac.EndsWith(".par"))
7845 pac.Remove(pac.Length()-4);
7846 pac = gSystem->BaseName(pac);
7847
7848 if (UnloadPackage(pac) == -1)
7849 return -1;
7850
7851 if (DisablePackage(pac) == -1)
7852 return -1;
7853
7854 return fStatus;
7855}
7856
7857////////////////////////////////////////////////////////////////////////////////
7858/// Remove a specific package.
7859/// Returns 0 in case of success and -1 in case of error.
7860
7862{
7863 if (!IsValid()) return -1;
7864
7865 if (!pack || strlen(pack) <= 0) {
7866 Error("DisablePackage", "need to specify a package name");
7867 return -1;
7868 }
7869
7870 // if name, erroneously, is a par pathname strip off .par and path
7871 TString pac = pack;
7872 if (pac.EndsWith(".par"))
7873 pac.Remove(pac.Length()-4);
7874 pac = gSystem->BaseName(pac);
7875
7876 if (fPackMgr->Remove(pack) < 0)
7877 Warning("DisablePackage", "problem removing locally package '%s'", pack);
7878
7879 // Nothing more to do if we are a Lite-session
7880 if (IsLite()) return 0;
7881
7882 Int_t st = -1;
7883 Bool_t done = kFALSE;
7884 if (fManager) {
7885 // Try to do it via XROOTD (new way)
7886 TString path;
7887 path.Form("~/packages/%s", pack);
7888 if (fManager->Rm(path, "-rf", "all") != -1) {
7889 path.Append(".par");
7890 if (fManager->Rm(path, "-f", "all") != -1) {
7891 done = kTRUE;
7892 st = 0;
7893 }
7894 }
7895 }
7896 if (!done) {
7897 // Try via TProofServ (old way)
7898 TMessage mess(kPROOF_CACHE);
7899 mess << Int_t(kDisablePackage) << pac;
7900 Broadcast(mess, kUnique);
7901
7902 TMessage mess2(kPROOF_CACHE);
7903 mess2 << Int_t(kDisableSubPackage) << pac;
7905
7907 st = fStatus;
7908 }
7909
7910 // Done
7911 return st;
7912}
7913
7914////////////////////////////////////////////////////////////////////////////////
7915/// Remove all packages.
7916/// Returns 0 in case of success and -1 in case of error.
7917
7919{
7920 if (!IsValid()) return -1;
7921
7922 // remove all packages on client
7923 if (fPackMgr->Remove(nullptr) < 0)
7924 Warning("DisablePackages", "problem removing packages locally");
7925
7926 // Nothing more to do if we are a Lite-session
7927 if (IsLite()) return 0;
7928
7929 Int_t st = -1;
7930 Bool_t done = kFALSE;
7931 if (fManager) {
7932 // Try to do it via XROOTD (new way)
7933 if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
7934 done = kTRUE;
7935 st = 0;
7936 }
7937 }
7938 if (!done) {
7939
7940 TMessage mess(kPROOF_CACHE);
7941 mess << Int_t(kDisablePackages);
7942 Broadcast(mess, kUnique);
7943
7944 TMessage mess2(kPROOF_CACHE);
7945 mess2 << Int_t(kDisableSubPackages);
7947
7949 st = fStatus;
7950 }
7951
7952 // Done
7953 return st;
7954}
7955
7956////////////////////////////////////////////////////////////////////////////////
7957/// Build specified package. Executes the PROOF-INF/BUILD.sh
7958/// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
7959/// then submit build command to slaves, but don't wait
7960/// for results. If opt is kCollectBuildResults then collect result
7961/// from slaves. To be used on the master.
7962/// If opt = kBuildAll (default) then submit and wait for results
7963/// (to be used on the client).
7964/// Returns 0 in case of success and -1 in case of error.
7965
7966Int_t TProof::BuildPackage(const char *package,
7967 EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
7968{
7969 if (!IsValid()) return -1;
7970
7971 if (!package || !package[0]) {
7972 Error("BuildPackage", "need to specify a package name");
7973 return -1;
7974 }
7975
7976 // if name, erroneously, is a par pathname strip off .par and path
7977 TString pac = package;
7978 if (pac.EndsWith(".par"))
7979 pac.Remove(pac.Length()-4);
7980 pac = gSystem->BaseName(pac);
7981
7982 Bool_t buildOnClient = kTRUE;
7983 if (opt == kDontBuildOnClient) {
7984 buildOnClient = kFALSE;
7985 opt = kBuildAll;
7986 }
7987 // Prepare the local package
7988 TString pdir;
7989 Int_t st = 0;
7990
7991 if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
7992 if (workers) {
7993 TMessage mess(kPROOF_CACHE);
7994 mess << Int_t(kBuildPackage) << pac << chkveropt;
7995 Broadcast(mess, workers);
7996
7997 } else {
7998 TMessage mess(kPROOF_CACHE);
7999 mess << Int_t(kBuildPackage) << pac << chkveropt;
8000 Broadcast(mess, kUnique);
8001
8002 TMessage mess2(kPROOF_CACHE);
8003 mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8005 }
8006 }
8007
8008 if (opt >= kBuildAll) {
8009 // by first forwarding the build commands to the master and slaves
8010 // and only then building locally we build in parallel
8011 if (buildOnClient) {
8012 st = fPackMgr->Build(pac, chkveropt);
8013 }
8014
8015
8016 fStatus = 0;
8017 if (!IsLite() || !buildOnClient) {
8018
8019 // On the master, workers that fail are deactivated
8020 // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8021 if (workers) {
8022// Collect(workers, -1, -1, deactivateOnFailure);
8023 Collect(workers);
8024 } else {
8026 }
8027 }
8028
8029 if (fStatus < 0 || st < 0)
8030 return -1;
8031 }
8032
8033 return 0;
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037/// Load specified package. Executes the PROOF-INF/SETUP.C script
8038/// on all active nodes. If notOnClient = true, don't load package
8039/// on the client. The default is to load the package also on the client.
8040/// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8041/// The objects in the list must be streamable; the SETUP macro will be executed
8042/// like this: SETUP.C(loadopts).
8043/// Returns 0 in case of success and -1 in case of error.
8044
8045Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8046 TList *loadopts, TList *workers)
8047{
8048 if (!IsValid()) return -1;
8049
8050 if (!package || !package[0]) {
8051 Error("LoadPackage", "need to specify a package name");
8052 return -1;
8053 }
8054
8055 // if name, erroneously, is a par pathname strip off .par and path
8056 TString pac = package;
8057 if (pac.EndsWith(".par"))
8058 pac.Remove(pac.Length()-4);
8059 pac = gSystem->BaseName(pac);
8060
8061 if (!notOnClient && TestBit(TProof::kIsClient))
8062 if (fPackMgr->Load(package, loadopts) == -1) return -1;
8063
8064 TMessage mess(kPROOF_CACHE);
8065 mess << Int_t(kLoadPackage) << pac;
8066 if (loadopts) mess << loadopts;
8067
8068 // On the master, workers that fail are deactivated
8069 Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8070
8071 Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8072
8073 if (workers) {
8074 PDB(kPackage, 3)
8075 Info("LoadPackage", "Sending load message to selected workers only");
8076 Broadcast(mess, workers);
8077 if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8078 } else {
8079 Broadcast(mess);
8080 Collect(kActive, -1, -1, deactivateOnFailure);
8081 }
8082
8083 return fStatus;
8084}
8085
8086////////////////////////////////////////////////////////////////////////////////
8087/// Unload specified package.
8088/// Returns 0 in case of success and -1 in case of error.
8089
8090Int_t TProof::UnloadPackage(const char *package)
8091{
8092 if (!IsValid()) return -1;
8093
8094 if (!package || !package[0]) {
8095 Error("UnloadPackage", "need to specify a package name");
8096 return -1;
8097 }
8098
8099 // if name, erroneously, is a par pathname strip off .par and path
8100 TString pac = package;
8101 if (pac.EndsWith(".par"))
8102 pac.Remove(pac.Length()-4);
8103 pac = gSystem->BaseName(pac);
8104
8105 if (fPackMgr->Unload(package) < 0)
8106 Warning("UnloadPackage", "unable to remove symlink to %s", package);
8107
8108 // Nothing more to do if we are a Lite-session
8109 if (IsLite()) return 0;
8110
8111 TMessage mess(kPROOF_CACHE);
8112 mess << Int_t(kUnloadPackage) << pac;
8113 Broadcast(mess);
8114 Collect();
8115
8116 return fStatus;
8117}
8118
8119////////////////////////////////////////////////////////////////////////////////
8120/// Unload all packages.
8121/// Returns 0 in case of success and -1 in case of error.
8122
8124{
8125 if (!IsValid()) return -1;
8126
8128 if (fPackMgr->Unload(0) < 0) return -1;
8129 }
8130
8131 // Nothing more to do if we are a Lite-session
8132 if (IsLite()) return 0;
8133
8134 TMessage mess(kPROOF_CACHE);
8135 mess << Int_t(kUnloadPackages);
8136 Broadcast(mess);
8137 Collect();
8138
8139 return fStatus;
8140}
8141
8142////////////////////////////////////////////////////////////////////////////////
8143/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8144/// script if it exists followed by the PROOF-INF/SETUP.C script.
8145/// In case notOnClient = true, don't enable the package on the client.
8146/// The default is to enable packages also on the client.
8147/// If specified, enables packages only on the specified workers.
8148/// Returns 0 in case of success and -1 in case of error.
8149/// Provided for backward compatibility.
8150
8151Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8152 TList *workers)
8153{
8154 return EnablePackage(package, (TList *)0, notOnClient, workers);
8155}
8156
8157////////////////////////////////////////////////////////////////////////////////
8158/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8159/// script if it exists followed by the PROOF-INF/SETUP.C script.
8160/// In case notOnClient = true, don't enable the package on the client.
8161/// The default is to enable packages also on the client.
8162/// It is is possible to specify options for the loading step via 'loadopts';
8163/// the string will be passed passed as argument to SETUP.
8164/// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8165/// plugin version checking during building: possible choices are:
8166/// off no check; failure may occur at loading
8167/// on check ROOT version [default]
8168/// svn check ROOT version and Git commit SHA1.
8169/// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8170/// If specified, enables packages only on the specified workers.
8171/// Returns 0 in case of success and -1 in case of error.
8172
8173Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8174 Bool_t notOnClient, TList *workers)
8175{
8176 TList *optls = 0;
8177 if (loadopts && strlen(loadopts)) {
8178 if (fProtocol > 28) {
8179 TObjString *os = new TObjString(loadopts);
8180 // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8181 os->String().ReplaceAll("checkversion=", "chkv=");
8182 Ssiz_t fcv = kNPOS, lcv = kNPOS;
8183 if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8184 TRegexp re("[; |]");
8185 if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8186 lcv = os->String().Length();
8187 }
8188 TString ocv = os->String()(fcv, lcv - fcv);
8189 Int_t cvopt = -1;
8190 if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8191 cvopt = (Int_t) TPackMgr::kDontCheck;
8192 else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8193 cvopt = (Int_t) TPackMgr::kCheckROOT;
8194 else
8195 Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8196 if (cvopt > -1) {
8197 if (gDebug > 0)
8198 Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8199 optls = new TList;
8200 optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8201 // Remove the special option from; we leave a separator if there were two (one before and one after)
8202 if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8203 if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8204 os->String().ReplaceAll(ocv.Data(), "");
8205 }
8206 }
8207 if (!os->String().IsNull()) {
8208 if (!optls) optls = new TList;
8209 optls->Add(new TObjString(os->String().Data()));
8210 }
8211 if (optls) optls->SetOwner(kTRUE);
8212 } else {
8213 // Notify
8214 Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8215 }
8216 }
8217 // Run
8218 Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8219 // Clean up
8220 SafeDelete(optls);
8221 // Done
8222 return rc;
8223}
8224
8225////////////////////////////////////////////////////////////////////////////////
8226/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8227/// script if it exists followed by the PROOF-INF/SETUP.C script.
8228/// In case notOnClient = true, don't enable the package on the client.
8229/// The default is to enable packages also on the client.
8230/// It is is possible to specify a list of objects to be passed to the SETUP
8231/// functions via 'loadopts'; the objects must be streamable.
8232/// Returns 0 in case of success and -1 in case of error.
8233
8234Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8235 Bool_t notOnClient, TList *workers)
8236{
8237 if (!IsValid()) return -1;
8238
8239 if (!package || !package[0]) {
8240 Error("EnablePackage", "need to specify a package name");
8241 return -1;
8242 }
8243
8244 // if name, erroneously, is a par pathname strip off .par and path
8245 TString pac = package;
8246 if (pac.EndsWith(".par"))
8247 pac.Remove(pac.Length()-4);
8248 pac = gSystem->BaseName(pac);
8249
8251 if (notOnClient)
8252 opt = kDontBuildOnClient;
8253
8254 // Get check version option; user settings have priority
8255 Int_t chkveropt = TPackMgr::kCheckROOT;
8256 TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8257 if (!ocv.IsNull()) {
8258 if (ocv == "off" || ocv == "0")
8259 chkveropt = (Int_t) TPackMgr::kDontCheck;
8260 else if (ocv == "on" || ocv == "1")
8261 chkveropt = (Int_t) TPackMgr::kCheckROOT;
8262 else
8263 Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8264 }
8265 if (loadopts) {
8266 TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8267 if (pcv) {
8268 chkveropt = pcv->GetVal();
8269 loadopts->Remove(pcv);
8270 delete pcv;
8271 }
8272 }
8273 if (gDebug > 0)
8274 Info("EnablePackage", "using check version option: %d", chkveropt);
8275
8276 if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8277 return -1;
8278
8279 TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8280 if (optls && fProtocol <= 28) {
8281 Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8282 optls = 0;
8283 }
8284
8285 if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8286 return -1;
8287
8288 // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8292 }
8294 TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8295 : new TPair(new TObjString(pac), 0);
8297 }
8298
8299 return 0;
8300}
8301
8302////////////////////////////////////////////////////////////////////////////////
8303/// Download a PROOF archive (PAR file) from the master package repository.
8304/// The PAR file is downloaded in the current directory or in the directory
8305/// specified by 'dstdir'. If a package with the same name already exists
8306/// at destination, a check on the MD5 sum is done and the user warned or
8307/// prompted for action, depending is the file is equal or different.
8308/// Returns 0 in case of success and -1 in case of error.
8309
8310Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8311{
8312 if (!fManager || !(fManager->IsValid())) {
8313 Error("DownloadPackage", "the manager is undefined!");
8314 return -1;
8315 }
8316
8317 // Create the default source and destination paths
8318 TString parname(gSystem->BaseName(pack)), src, dst;
8319 if (!parname.EndsWith(".par")) parname += ".par";
8320 src.Form("packages/%s", parname.Data());
8321 if (!dstdir || strlen(dstdir) <= 0) {
8322 dst.Form("./%s", parname.Data());
8323 } else {
8324 // Check the destination directory
8325 FileStat_t st;
8326 if (gSystem->GetPathInfo(dstdir, st) != 0) {
8327 // Directory does not exit: create it
8328 if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8329 Error("DownloadPackage",
8330 "could not create the destination directory '%s' (errno: %d)",
8331 dstdir, TSystem::GetErrno());
8332 return -1;
8333 }
8334 } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8335 Error("DownloadPackage",
8336 "destination path '%s' exist but is not a directory!", dstdir);
8337 return -1;
8338 }
8339 dst.Form("%s/%s", dstdir, parname.Data());
8340 }
8341
8342 // Make sure the source file exists
8343 FileStat_t stsrc;
8345 if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8346 Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8347 Int_t rc = fManager->Stat(src, stsrc);
8348 if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8349 Warning("DownloadPackage", "problems restoring output");
8350 if (rc != 0) {
8351 // Check if there is another possible source
8353 TMacro *mp = GetLastLog();
8354 if (mp) {
8355 // Look for global directories
8356 Bool_t isGlobal = kFALSE;
8357 TIter nxl(mp->GetListOfLines());
8358 TObjString *os = 0;
8359 TString globaldir;
8360 while ((os = (TObjString *) nxl())) {
8361 TString s(os->GetName());
8362 if (s.Contains("*** Global Package cache")) {
8363 // Get the directory
8364 s.Remove(0, s.Last(':') + 1);
8365 s.Remove(s.Last(' '));
8366 globaldir = s;
8367 isGlobal = kTRUE;
8368 } else if (s.Contains("*** Package cache")) {
8369 isGlobal = kFALSE;
8370 globaldir = "";
8371 }
8372 // Check for the package
8373 if (isGlobal && s.Contains(parname)) {
8374 src.Form("%s/%s", globaldir.Data(), parname.Data());
8375 break;
8376 }
8377 }
8378 // Cleanup
8379 delete mp;
8380 }
8381 }
8382
8383 // Do it via the manager
8384 if (fManager->GetFile(src, dst, "silent") != 0) {
8385 Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8386 pack, src.Data(), dst.Data());
8387 return -1;
8388 } else {
8389 Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8390 pack, dst.Data());
8391 }
8392 // Done
8393 return 0;
8394}
8395
8396////////////////////////////////////////////////////////////////////////////////
8397/// Upload a PROOF archive (PAR file). A PAR file is a compressed
8398/// tar file with one special additional directory, PROOF-INF
8399/// (blatantly copied from Java's jar format). It must have the extension
8400/// .par. A PAR file can be directly a binary or a source with a build
8401/// procedure. In the PROOF-INF directory there can be a build script:
8402/// BUILD.sh to be called to build the package, in case of a binary PAR
8403/// file don't specify a build script or make it a no-op. Then there is
8404/// SETUP.C which sets the right environment variables to use the package,
8405/// like LD_LIBRARY_PATH, etc.
8406/// The 'opt' allows to specify whether the .PAR should be just unpacked
8407/// in the existing dir (opt = kUntar, default) or a remove of the existing
8408/// directory should be executed (opt = kRemoveOld), so triggering a full
8409/// re-build. The option if effective only for PROOF protocol > 8 .
8410/// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8411/// an alternative global directory for global usage. This may require special
8412/// privileges.
8413/// If download is kTRUE and the package is not found locally, then it is downloaded
8414/// from the master repository.
8415/// Returns 0 in case of success and -1 in case of error.
8416
8418 TList *workers)
8419{
8420 if (!IsValid()) return -1;
8421
8422 // Remote PAR ?
8424 Bool_t remotepar = (ft == TFile::kWeb || ft == TFile::kNet) ? kTRUE : kFALSE;
8425
8426 TString par(pack), base, name;
8427 if (par.EndsWith(".par")) {
8428 base = gSystem->BaseName(par);
8429 name = base(0, base.Length() - strlen(".par"));
8430 } else {
8431 name = gSystem->BaseName(par);
8432 base.Form("%s.par", name.Data());
8433 par += ".par";
8434 }
8435
8436 // Default location is the local working dir; then the package dir
8437 gSystem->ExpandPathName(par);
8439 Int_t xrc = -1;
8440 if (!remotepar) xrc = TPackMgr::FindParPath(fPackMgr, name, par);
8441 if (xrc == 0) {
8442 // Package is in the global dirs
8443 if (gDebug > 0)
8444 Info("UploadPackage", "global package found (%s): no upload needed",
8445 par.Data());
8446 return 0;
8447 } else if (xrc < 0) {
8448 Error("UploadPackage", "PAR file '%s' not found", par.Data());
8449 return -1;
8450 }
8451 }
8452
8453 // Strategy:
8454 // On the client:
8455 // get md5 of package and check if it is different
8456 // from the one stored in the local package directory. If it is lock
8457 // the package directory and copy the package, unlock the directory.
8458 // On the masters:
8459 // get md5 of package and check if it is different from the
8460 // one stored on the remote node. If it is different lock the remote
8461 // package directory and use TFTP or SendFile to ftp the package to the
8462 // remote node, unlock the directory.
8463
8464
8466 Bool_t rmold = (opt == TProof::kRemoveOld) ? kTRUE : kFALSE;
8467 if (fPackMgr->Install(par, rmold) < 0) {
8468 Error("UploadPackage", "installing '%s' failed", gSystem->BaseName(par));
8469 return -1;
8470 }
8471 }
8472
8473 // Nothing more to do if we are a Lite-session
8474 if (IsLite()) return 0;
8475
8476 TMD5 *md5 = fPackMgr->ReadMD5(name);
8477
8478 TString smsg;
8479 if (remotepar && GetRemoteProtocol() > 36) {
8480 smsg.Form("+%s", par.Data());
8481 } else {
8482 smsg.Form("+%s", base.Data());
8483 }
8484
8486 mess << smsg << (*md5);
8488 smsg.Replace(0, 1, "-");
8489 mess2 << smsg << (*md5);
8491 smsg.Replace(0, 1, "=");
8492 mess3 << smsg << (*md5);
8493
8494 delete md5;
8495
8496 if (fProtocol > 8) {
8497 // Send also the option
8498 mess << (UInt_t) opt;
8499 mess2 << (UInt_t) opt;
8500 mess3 << (UInt_t) opt;
8501 }
8502
8503 // Loop over all slaves with unique fs image, or to a selected
8504 // list of workers, if specified
8505 if (!workers)
8506 workers = fUniqueSlaves;
8507 TIter next(workers);
8508 TSlave *sl = 0;
8509 while ((sl = (TSlave *) next())) {
8510 if (!sl->IsValid())
8511 continue;
8512
8513 sl->GetSocket()->Send(mess);
8514
8515 fCheckFileStatus = 0;
8517 if (fCheckFileStatus == 0) {
8518
8519 if (fProtocol > 5) {
8520 // remote directory is locked, upload file over the open channel
8521 smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
8522 if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
8523 Error("UploadPackage", "%s: problems uploading file %s",
8524 sl->GetOrdinal(), par.Data());
8525 return -1;
8526 }
8527 } else {
8528 // old servers receive it via TFTP
8529 TFTP ftp(TString("root://")+sl->GetName(), 1);
8530 if (!ftp.IsZombie()) {
8531 smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
8532 ftp.cd(smsg.Data());
8533 ftp.put(par, base.Data());
8534 }
8535 }
8536
8537 // install package and unlock dir
8538 sl->GetSocket()->Send(mess2);
8539 fCheckFileStatus = 0;
8541 if (fCheckFileStatus == 0) {
8542 Error("UploadPackage", "%s: unpacking of package %s failed",
8543 sl->GetOrdinal(), base.Data());
8544 return -1;
8545 }
8546 }
8547 }
8548
8549 // loop over all other master nodes
8550 TIter nextmaster(fNonUniqueMasters);
8551 TSlave *ma;
8552 while ((ma = (TSlave *) nextmaster())) {
8553 if (!ma->IsValid())
8554 continue;
8555
8556 ma->GetSocket()->Send(mess3);
8557
8558 fCheckFileStatus = 0;
8560 if (fCheckFileStatus == 0) {
8561 // error -> package should have been found
8562 Error("UploadPackage", "package %s did not exist on submaster %s",
8563 base.Data(), ma->GetOrdinal());
8564 return -1;
8565 }
8566 }
8567
8568 return 0;
8569}
8570
8571
8572////////////////////////////////////////////////////////////////////////////////
8573/// Make sure that the directory path contained by macro is in the macro path
8574
8575void TProof::AssertMacroPath(const char *macro)
8576{
8577 static TString macrop(gROOT->GetMacroPath());
8578 if (macro && strlen(macro) > 0) {
8579 TString dirn(gSystem->DirName(macro));
8580 if (!macrop.Contains(dirn)) {
8581 macrop += TString::Format("%s:", dirn.Data());
8582 gROOT->SetMacroPath(macrop);
8583 }
8584 }
8585}
8586
8587
8588////////////////////////////////////////////////////////////////////////////////
8589/// Load the specified macro on master, workers and, if notOnClient is
8590/// kFALSE, on the client. The macro file is uploaded if new or updated.
8591/// Additional files to be uploaded (or updated, if needed) can be specified
8592/// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
8593/// If existing in the same directory, a header basename(macro).h or .hh, is also
8594/// uploaded.
8595/// The default is to load the macro also on the client; notOnClient can be used
8596/// to avoid loading on the client.
8597/// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
8598/// only, and collection is not done; if uniqueWorkers is kFALSE, collection
8599/// from the previous request is done, and broadcasting + collection from the
8600/// other workers is done.
8601/// The wrks arg can be used on the master to limit the set of workers.
8602/// Returns 0 in case of success and -1 in case of error.
8603
8604Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
8605 TList *wrks)
8606{
8607 if (!IsValid()) return -1;
8608
8609 if (!macro || !macro[0]) {
8610 Error("Load", "need to specify a macro name");
8611 return -1;
8612 }
8613
8614 // Make sure the path is in the macro path
8616
8617 if (TestBit(TProof::kIsClient) && !wrks) {
8618
8619 // Extract the file implementation name first
8620 TString addsname, implname = macro;
8621 Ssiz_t icom = implname.Index(",");
8622 if (icom != kNPOS) {
8623 addsname = implname(icom + 1, implname.Length());
8624 implname.Remove(icom);
8625 }
8626 TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
8627 TString bmsg(basemacro), acmode, args, io;
8628 implname = gSystem->SplitAclicMode(implname, acmode, args, io);
8629
8630 // Macro names must have a standard format
8631 Int_t dot = implname.Last('.');
8632 if (dot == kNPOS) {
8633 Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
8634 return -1;
8635 }
8636
8637 // Is there any associated header file
8638 Bool_t hasHeader = kTRUE;
8639 TString headname = implname;
8640 headname.Remove(dot);
8641 headname += ".h";
8642 if (gSystem->AccessPathName(headname, kReadPermission)) {
8643 TString h = headname;
8644 headname.Remove(dot);
8645 headname += ".hh";
8646 if (gSystem->AccessPathName(headname, kReadPermission)) {
8647 hasHeader = kFALSE;
8648 if (gDebug > 0)
8649 Info("Load", "no associated header file found: tried: %s %s",
8650 h.Data(), headname.Data());
8651 }
8652 }
8653
8654 // Is there any additional file ?
8655 TString addincs;
8656 TList addfiles;
8657 if (!addsname.IsNull()) {
8658 TString fn;
8659 Int_t from = 0;
8660 while (addsname.Tokenize(fn, from, ",")) {
8662 Error("Load", "additional file '%s' not found", fn.Data());
8663 return -1;
8664 }
8665 // Create the additional include statement
8666 if (!notOnClient) {
8667 TString dirn(gSystem->DirName(fn));
8668 if (addincs.IsNull()) {
8669 addincs.Form("-I%s", dirn.Data());
8670 } else if (!addincs.Contains(dirn)) {
8671 addincs += TString::Format(" -I%s", dirn.Data());
8672 }
8673 }
8674 // Remember these files ...
8675 addfiles.Add(new TObjString(fn));
8676 }
8677 }
8678
8679 // Send files now; the md5 check is run here; see SendFile for more
8680 // details.
8681 if (SendFile(implname, kAscii | kForward , "cache") == -1) {
8682 Error("Load", "problems sending implementation file %s", implname.Data());
8683 return -1;
8684 }
8685 if (hasHeader)
8686 if (SendFile(headname, kAscii | kForward , "cache") == -1) {
8687 Error("Load", "problems sending header file %s", headname.Data());
8688 return -1;
8689 }
8690 // Additional files
8691 if (addfiles.GetSize() > 0) {
8692 TIter nxfn(&addfiles);
8693 TObjString *os = 0;
8694 while ((os = (TObjString *) nxfn())) {
8695 // These files need to be available everywhere, cache and sandbox
8696 if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
8697 Error("Load", "problems sending additional file %s", os->GetName());
8698 return -1;
8699 }
8700 // Add the base names to the message broadcasted
8701 bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
8702 }
8703 addfiles.SetOwner(kTRUE);
8704 }
8705
8706 // The files are now on the workers: now we send the loading request
8707 TMessage mess(kPROOF_CACHE);
8708 if (GetRemoteProtocol() < 34) {
8709 mess << Int_t(kLoadMacro) << basemacro;
8710 // This may be needed
8711 AddIncludePath("../../cache");
8712 } else {
8713 mess << Int_t(kLoadMacro) << bmsg;
8714 }
8715 Broadcast(mess, kActive);
8716
8717 // Load locally, if required
8718 if (!notOnClient) {
8719 // Mofify the include path
8720 TString oldincs = gSystem->GetIncludePath();
8721 if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
8722
8723 // By first forwarding the load command to the master and workers
8724 // and only then loading locally we load/build in parallel
8725 gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
8726
8727 // Restore include path
8728 if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
8729
8730 // Update the macro path
8732 TString np(gSystem->DirName(macro));
8733 if (!np.IsNull()) {
8734 np += ":";
8735 if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
8736 Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
8737 mp.Insert(ip, np);
8739 if (gDebug > 0)
8740 Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
8741 }
8742 }
8743 }
8744
8745 // Wait for master and workers to be done
8747
8748 if (IsLite()) {
8749 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8750 if (!fLoadedMacros) {
8751 fLoadedMacros = new TList();
8753 }
8754 // if wrks is specified the macro should already be loaded on the master.
8755 fLoadedMacros->Add(new TObjString(macro));
8756 }
8757
8758 } else {
8759 // On master
8760
8761 // The files are now on the workers: now we send the loading request first
8762 // to the unique workers, so that the eventual compilation occurs only once.
8763 TString basemacro = gSystem->BaseName(macro);
8764 TMessage mess(kPROOF_CACHE);
8765
8766 if (uniqueWorkers) {
8767 mess << Int_t(kLoadMacro) << basemacro;
8768 if (wrks) {
8769 Broadcast(mess, wrks);
8770 Collect(wrks);
8771 } else {
8772 Broadcast(mess, kUnique);
8773 }
8774 } else {
8775 // Wait for the result of the previous sending
8777
8778 // We then send a tuned loading request to the other workers
8779 TList others;
8780 TSlave *wrk = 0;
8781 TIter nxw(fActiveSlaves);
8782 while ((wrk = (TSlave *)nxw())) {
8783 if (!fUniqueSlaves->FindObject(wrk)) {
8784 others.Add(wrk);
8785 }
8786 }
8787
8788 // Do not force compilation, if it was requested
8789 Int_t ld = basemacro.Last('.');
8790 if (ld != kNPOS) {
8791 Int_t lpp = basemacro.Index("++", ld);
8792 if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
8793 }
8794 mess << Int_t(kLoadMacro) << basemacro;
8795 Broadcast(mess, &others);
8796 Collect(&others);
8797 }
8798
8799 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8800 if (!fLoadedMacros) {
8801 fLoadedMacros = new TList();
8803 }
8804 // if wrks is specified the macro should already be loaded on the master.
8805 if (!wrks)
8806 fLoadedMacros->Add(new TObjString(macro));
8807 }
8808
8809 // Done
8810 return 0;
8811}
8812
8813////////////////////////////////////////////////////////////////////////////////
8814/// Add 'libpath' to the lib path search.
8815/// Multiple paths can be specified at once separating them with a comma or
8816/// a blank.
8817/// Return 0 on success, -1 otherwise
8818
8819Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
8820 Bool_t doCollect)
8821{
8822 if ((!libpath || !libpath[0])) {
8823 if (gDebug > 0)
8824 Info("AddDynamicPath", "list is empty - nothing to do");
8825 return 0;
8826 }
8827
8828 // Do it also on clients, if required
8829 if (onClient)
8830 HandleLibIncPath("lib", kTRUE, libpath);
8831
8833 m << TString("lib") << (Bool_t)kTRUE;
8834
8835 // Add paths
8836 if (libpath && strlen(libpath)) {
8837 m << TString(libpath);
8838 } else {
8839 m << TString("-");
8840 }
8841
8842 // Tell the server to send back or not
8843 m << (Int_t)doCollect;
8844
8845 // Forward the request
8846 if (wrks) {
8847 Broadcast(m, wrks);
8848 if (doCollect)
8849 Collect(wrks, fCollectTimeout);
8850 } else {
8851 Broadcast(m);
8853 }
8854
8855 return 0;
8856}
8857
8858////////////////////////////////////////////////////////////////////////////////
8859/// Add 'incpath' to the inc path search.
8860/// Multiple paths can be specified at once separating them with a comma or
8861/// a blank.
8862/// Return 0 on success, -1 otherwise
8863
8864Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
8865 Bool_t doCollect)
8866{
8867 if ((!incpath || !incpath[0])) {
8868 if (gDebug > 0)
8869 Info("AddIncludePath", "list is empty - nothing to do");
8870 return 0;
8871 }
8872
8873 // Do it also on clients, if required
8874 if (onClient)
8875 HandleLibIncPath("inc", kTRUE, incpath);
8876
8878 m << TString("inc") << (Bool_t)kTRUE;
8879
8880 // Add paths
8881 if (incpath && strlen(incpath)) {
8882 m << TString(incpath);
8883 } else {
8884 m << TString("-");
8885 }
8886
8887 // Tell the server to send back or not
8888 m << (Int_t)doCollect;
8889
8890 // Forward the request
8891 if (wrks) {
8892 Broadcast(m, wrks);
8893 if (doCollect)
8894 Collect(wrks, fCollectTimeout);
8895 } else {
8896 Broadcast(m);
8898 }
8899
8900 return 0;
8901}
8902
8903////////////////////////////////////////////////////////////////////////////////
8904/// Remove 'libpath' from the lib path search.
8905/// Multiple paths can be specified at once separating them with a comma or
8906/// a blank.
8907/// Return 0 on success, -1 otherwise
8908
8909Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
8910{
8911 if ((!libpath || !libpath[0])) {
8912 if (gDebug > 0)
8913 Info("RemoveDynamicPath", "list is empty - nothing to do");
8914 return 0;
8915 }
8916
8917 // Do it also on clients, if required
8918 if (onClient)
8919 HandleLibIncPath("lib", kFALSE, libpath);
8920
8922 m << TString("lib") <<(Bool_t)kFALSE;
8923
8924 // Add paths
8925 if (libpath && strlen(libpath))
8926 m << TString(libpath);
8927 else
8928 m << TString("-");
8929
8930 // Forward the request
8931 Broadcast(m);
8933
8934 return 0;
8935}
8936
8937////////////////////////////////////////////////////////////////////////////////
8938/// Remove 'incpath' from the inc path search.
8939/// Multiple paths can be specified at once separating them with a comma or
8940/// a blank.
8941/// Return 0 on success, -1 otherwise
8942
8943Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
8944{
8945 if ((!incpath || !incpath[0])) {
8946 if (gDebug > 0)
8947 Info("RemoveIncludePath", "list is empty - nothing to do");
8948 return 0;
8949 }
8950
8951 // Do it also on clients, if required
8952 if (onClient)
8953 HandleLibIncPath("in", kFALSE, incpath);
8954
8956 m << TString("inc") << (Bool_t)kFALSE;
8957
8958 // Add paths
8959 if (incpath && strlen(incpath))
8960 m << TString(incpath);
8961 else
8962 m << TString("-");
8963
8964 // Forward the request
8965 Broadcast(m);
8967
8968 return 0;
8969}
8970
8971////////////////////////////////////////////////////////////////////////////////
8972/// Handle lib, inc search paths modification request
8973
8974void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
8975{
8976 TString type(what);
8977 TString path(dirs);
8978
8979 // Check type of action
8980 if ((type != "lib") && (type != "inc")) {
8981 Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
8982 return;
8983 }
8984
8985 // Separators can be either commas or blanks
8986 path.ReplaceAll(","," ");
8987
8988 // Decompose lists
8989 TObjArray *op = 0;
8990 if (path.Length() > 0 && path != "-") {
8991 if (!(op = path.Tokenize(" "))) {
8992 Warning("HandleLibIncPath","decomposing path %s", path.Data());
8993 return;
8994 }
8995 }
8996
8997 if (add) {
8998
8999 if (type == "lib") {
9000
9001 // Add libs
9002 TIter nxl(op, kIterBackward);
9003 TObjString *lib = 0;
9004 while ((lib = (TObjString *) nxl())) {
9005 // Expand path
9006 TString xlib = lib->GetName();
9007 gSystem->ExpandPathName(xlib);
9008 // Add to the dynamic lib search path if it exists and can be read
9009 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9010 TString newlibpath = gSystem->GetDynamicPath();
9011 // In the first position after the working dir
9012 Int_t pos = 0;
9013 if (newlibpath.BeginsWith(".:"))
9014 pos = 2;
9015 if (newlibpath.Index(xlib) == kNPOS) {
9016 newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9017 gSystem->SetDynamicPath(newlibpath);
9018 }
9019 } else {
9020 if (gDebug > 0)
9021 Info("HandleLibIncPath",
9022 "libpath %s does not exist or cannot be read - not added", xlib.Data());
9023 }
9024 }
9025
9026 } else {
9027
9028 // Add incs
9029 TIter nxi(op);
9030 TObjString *inc = 0;
9031 while ((inc = (TObjString *) nxi())) {
9032 // Expand path
9033 TString xinc = inc->GetName();
9034 gSystem->ExpandPathName(xinc);
9035 // Add to the dynamic lib search path if it exists and can be read
9036 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9037 TString curincpath = gSystem->GetIncludePath();
9038 if (curincpath.Index(xinc) == kNPOS)
9039 gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9040 } else
9041 if (gDebug > 0)
9042 Info("HandleLibIncPath",
9043 "incpath %s does not exist or cannot be read - not added", xinc.Data());
9044 }
9045 }
9046
9047
9048 } else {
9049
9050 if (type == "lib") {
9051
9052 // Remove libs
9053 TIter nxl(op);
9054 TObjString *lib = 0;
9055 while ((lib = (TObjString *) nxl())) {
9056 // Expand path
9057 TString xlib = lib->GetName();
9058 gSystem->ExpandPathName(xlib);
9059 // Remove from the dynamic lib search path
9060 TString newlibpath = gSystem->GetDynamicPath();
9061 newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9062 gSystem->SetDynamicPath(newlibpath);
9063 }
9064
9065 } else {
9066
9067 // Remove incs
9068 TIter nxi(op);
9069 TObjString *inc = 0;
9070 while ((inc = (TObjString *) nxi())) {
9071 TString newincpath = gSystem->GetIncludePath();
9072 newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9073 // Remove the interpreter path (added anyhow internally)
9074 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9075 gSystem->SetIncludePath(newincpath);
9076 }
9077 }
9078 }
9079}
9080
9081////////////////////////////////////////////////////////////////////////////////
9082/// Get from the master the list of names of the packages available.
9083
9085{
9086 if (!IsValid())
9087 return (TList *)0;
9088
9089 TMessage mess(kPROOF_CACHE);
9090 mess << Int_t(kListPackages);
9091 Broadcast(mess);
9093
9094 return fAvailablePackages;
9095}
9096
9097////////////////////////////////////////////////////////////////////////////////
9098/// Get from the master the list of names of the packages enabled.
9099
9101{
9102 if (!IsValid())
9103 return (TList *)0;
9104
9105 TMessage mess(kPROOF_CACHE);
9106 mess << Int_t(kListEnabledPackages);
9107 Broadcast(mess);
9109
9110 return fEnabledPackages;
9111}
9112
9113////////////////////////////////////////////////////////////////////////////////
9114/// Print a progress bar on stderr. Used in batch mode.
9115
9117 Float_t procTime, Long64_t bytesread)
9118{
9119 if (fPrintProgress) {
9120 Bool_t redirlog = fRedirLog;
9121 fRedirLog = kFALSE;
9122 // Call the external function
9123 (*fPrintProgress)(total, processed, procTime, bytesread);
9124 fRedirLog = redirlog;
9125 return;
9126 }
9127
9128 fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9129
9130 for (int l = 0; l < 20; l++) {
9131 if (total > 0) {
9132 if (l < 20*processed/total)
9133 fprintf(stderr, "=");
9134 else if (l == 20*processed/total)
9135 fprintf(stderr, ">");
9136 else if (l > 20*processed/total)
9137 fprintf(stderr, ".");
9138 } else
9139 fprintf(stderr, "=");
9140 }
9141 Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9142 Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9143 TString sunit("B/s");
9144 if (evtrti > 0.) {
9145 Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9146 if (mbsrti > 0.) {
9147 const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9148 if (mbsrti >= toG) {
9149 mbsrti /= toG;
9150 sunit = "GB/s";
9151 } else if (mbsrti >= toM) {
9152 mbsrti /= toM;
9153 sunit = "MB/s";
9154 } else if (mbsrti >= toK) {
9155 mbsrti /= toK;
9156 sunit = "kB/s";
9157 }
9158 fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9159 (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9160 } else {
9161 fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9162 (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9163 }
9164 } else {
9165 fprintf(stderr, "| %.02f %%\r",
9166 (total ? ((100.0*processed)/total) : 100.0));
9167 }
9168 if (processed >= total) {
9169 fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9170 }
9171}
9172
9173////////////////////////////////////////////////////////////////////////////////
9174/// Get query progress information. Connect a slot to this signal
9175/// to track progress.
9176
9178{
9179 if (fPrintProgress) {
9180 // Call the external function
9181 return (*fPrintProgress)(total, processed, -1., -1);
9182 }
9183
9184 PDB(kGlobal,1)
9185 Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9186
9187 if (gROOT->IsBatch()) {
9188 // Simple progress bar
9189 if (total > 0)
9190 PrintProgress(total, processed);
9191 } else {
9192 EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9193 }
9194}
9195
9196////////////////////////////////////////////////////////////////////////////////
9197/// Get query progress information. Connect a slot to this signal
9198/// to track progress.
9199
9201 Float_t initTime, Float_t procTime,
9202 Float_t evtrti, Float_t mbrti)
9203{
9204 PDB(kGlobal,1)
9205 Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9206 initTime, procTime, evtrti, mbrti);
9207
9208 if (gROOT->IsBatch()) {
9209 // Simple progress bar
9210 if (total > 0)
9211 PrintProgress(total, processed, procTime, bytesread);
9212 } else {
9213 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9214 7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9215 }
9216}
9217
9218////////////////////////////////////////////////////////////////////////////////
9219/// Get query progress information. Connect a slot to this signal
9220/// to track progress.
9221
9223 Float_t initTime, Float_t procTime,
9224 Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9225{
9226 PDB(kGlobal,1)
9227 Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9228 initTime, procTime, evtrti, mbrti, actw, eses);
9229
9230 if (gROOT->IsBatch()) {
9231 // Simple progress bar
9232 if (total > 0)
9233 PrintProgress(total, processed, procTime, bytesread);
9234 } else {
9235 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9236 10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9237 }
9238}
9239
9240////////////////////////////////////////////////////////////////////////////////
9241/// Get list of feedback objects. Connect a slot to this signal
9242/// to monitor the feedback object.
9243
9245{
9246 PDB(kGlobal,1)
9247 Info("Feedback","%d objects", objs->GetSize());
9248 PDB(kFeedback,1) {
9249 Info("Feedback","%d objects", objs->GetSize());
9250 objs->ls();
9251 }
9252
9253 Emit("Feedback(TList *objs)", (Long_t) objs);
9254}
9255
9256////////////////////////////////////////////////////////////////////////////////
9257/// Close progress dialog.
9258
9260{
9261 PDB(kGlobal,1)
9262 Info("CloseProgressDialog",
9263 "called: have progress dialog: %d", fProgressDialogStarted);
9264
9265 // Nothing to do if not there
9267 return;
9268
9269 Emit("CloseProgressDialog()");
9270}
9271
9272////////////////////////////////////////////////////////////////////////////////
9273/// Reset progress dialog.
9274
9275void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9276 Long64_t ent)
9277{
9278 PDB(kGlobal,1)
9279 Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9280
9281 EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9282 4, sel, sz, fst, ent);
9283}
9284
9285////////////////////////////////////////////////////////////////////////////////
9286/// Send startup message.
9287
9288void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9289{
9290 PDB(kGlobal,1)
9291 Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9292
9293 EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9294 4, msg, st, done, total);
9295}
9296
9297////////////////////////////////////////////////////////////////////////////////
9298/// Send dataset preparation status.
9299
9300void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9301{
9302 PDB(kGlobal,1)
9303 Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9304
9305 EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9306 4, msg, st, done, total);
9307}
9308
9309////////////////////////////////////////////////////////////////////////////////
9310/// Send or notify data set status
9311
9312void TProof::SendDataSetStatus(const char *action, UInt_t done,
9313 UInt_t tot, Bool_t st)
9314{
9315 if (IsLite()) {
9316 if (tot) {
9317 TString type = "files";
9318 Int_t frac = (Int_t) (done*100.)/tot;
9319 char msg[512] = {0};
9320 if (frac >= 100) {
9321 snprintf(msg, 512, "%s: OK (%d %s) \n",
9322 action,tot, type.Data());
9323 } else {
9324 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9325 action, done, tot, frac);
9326 }
9327 if (fSync)
9328 fprintf(stderr,"%s", msg);
9329 else
9330 NotifyLogMsg(msg, 0);
9331 }
9332 return;
9333 }
9334
9337 mess << TString(action) << tot << done << st;
9338 gProofServ->GetSocket()->Send(mess);
9339 }
9340}
9341
9342////////////////////////////////////////////////////////////////////////////////
9343/// Notify availability of a query result.
9344
9345void TProof::QueryResultReady(const char *ref)
9346{
9347 PDB(kGlobal,1)
9348 Info("QueryResultReady","ref: %s", ref);
9349
9350 Emit("QueryResultReady(const char*)",ref);
9351}
9352
9353////////////////////////////////////////////////////////////////////////////////
9354/// Validate a TDSet.
9355
9357{
9358 if (dset->ElementsValid()) return;
9359
9360 TList nodes;
9361 nodes.SetOwner();
9362
9363 TList slholder;
9364 slholder.SetOwner();
9365 TList elemholder;
9366 elemholder.SetOwner();
9367
9368 // build nodelist with slaves and elements
9369 TIter nextSlave(GetListOfActiveSlaves());
9370 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9371 TList *sllist = 0;
9372 TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9373 if (!p) {
9374 sllist = new TList;
9375 sllist->SetName(sl->GetName());
9376 slholder.Add(sllist);
9377 TList *elemlist = new TList;
9378 elemlist->SetName(TString(sl->GetName())+"_elem");
9379 elemholder.Add(elemlist);
9380 nodes.Add(new TPair(sllist, elemlist));
9381 } else {
9382 sllist = dynamic_cast<TList*>(p->Key());
9383 }
9384 if (sllist) sllist->Add(sl);
9385 }
9386
9387 // add local elements to nodes
9388 TList nonLocal; // list of nonlocal elements
9389 // make two iterations - first add local elements - then distribute nonlocals
9390 for (Int_t i = 0; i < 2; i++) {
9391 Bool_t local = i>0?kFALSE:kTRUE;
9392 TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9393 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9394 if (elem->GetValid()) continue;
9395 TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9396 if (p) {
9397 TList *eli = dynamic_cast<TList*>(p->Value());
9398 TList *sli = dynamic_cast<TList*>(p->Key());
9399 if (eli && sli) {
9400 eli->Add(elem);
9401
9402 // order list by elements/slave
9403 TPair *p2 = p;
9404 Bool_t stop = kFALSE;
9405 while (!stop) {
9406 TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9407 if (p3) {
9408 TList *p3v = dynamic_cast<TList*>(p3->Value());
9409 TList *p3k = dynamic_cast<TList*>(p3->Key());
9410 if (p3v && p3k) {
9411 Int_t nelem = p3v->GetSize();
9412 Int_t nsl = p3k->GetSize();
9413 if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
9414 else stop = kTRUE;
9415 }
9416 } else {
9417 stop = kTRUE;
9418 }
9419 }
9420
9421 if (p2!=p) {
9422 nodes.Remove(p->Key());
9423 nodes.AddAfter(p2->Key(), p);
9424 }
9425 } else {
9426 Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
9427 continue;
9428 }
9429
9430 } else {
9431 if (local) {
9432 nonLocal.Add(elem);
9433 } else {
9434 Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
9435 }
9436 }
9437 }
9438 }
9439
9440 // send to slaves
9441 TList usedslaves;
9442 TIter nextNode(&nodes);
9443 SetDSet(dset); // set dset to be validated in Collect()
9444 while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
9445 TList *slaves = dynamic_cast<TList*>(node->Key());
9446 TList *setelements = dynamic_cast<TList*>(node->Value());
9447 if (!slaves || !setelements) continue;
9448 // distribute elements over the slaves
9449 Int_t nslaves = slaves->GetSize();
9450 Int_t nelements = setelements->GetSize();
9451 for (Int_t i=0; i<nslaves; i++) {
9452
9453 TDSet copyset(dset->GetType(), dset->GetObjName(),
9454 dset->GetDirectory());
9455 for (Int_t j = (i*nelements)/nslaves;
9456 j < ((i+1)*nelements)/nslaves;
9457 j++) {
9458 TDSetElement *elem =
9459 dynamic_cast<TDSetElement*>(setelements->At(j));
9460 if (elem) {
9461 copyset.Add(elem->GetFileName(), elem->GetObjName(),
9462 elem->GetDirectory(), elem->GetFirst(),
9463 elem->GetNum(), elem->GetMsd());
9464 }
9465 }
9466
9467 if (copyset.GetListOfElements()->GetSize()>0) {
9469 mesg << &copyset;
9470
9471 TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
9472 if (sl) {
9473 PDB(kGlobal,1) Info("ValidateDSet",
9474 "Sending TDSet with %d elements to slave %s"
9475 " to be validated",
9476 copyset.GetListOfElements()->GetSize(),
9477 sl->GetOrdinal());
9478 sl->GetSocket()->Send(mesg);
9479 usedslaves.Add(sl);
9480 }
9481 }
9482 }
9483 }
9484
9485 PDB(kGlobal,1)
9486 Info("ValidateDSet","Calling Collect");
9487 Collect(&usedslaves);
9488 SetDSet(0);
9489}
9490
9491////////////////////////////////////////////////////////////////////////////////
9492/// Add data objects that might be needed during the processing of
9493/// the selector (see Process()). This object can be very large, so they
9494/// are distributed in an optimized way using a dedicated file.
9495/// If push is TRUE the input data are sent over even if no apparent change
9496/// occured to the list.
9497
9499{
9500 if (obj) {
9501 if (!fInputData) fInputData = new TList;
9502 if (!fInputData->FindObject(obj)) {
9503 fInputData->Add(obj);
9505 }
9506 }
9507 if (push) SetBit(TProof::kNewInputData);
9508}
9509
9510////////////////////////////////////////////////////////////////////////////////
9511/// Remove obj form the input data list; if obj is null (default), clear the
9512/// input data info.
9513
9515{
9516 if (!obj) {
9517 if (fInputData) {
9520 }
9522
9523 // Also remove any info about input data in the input list
9524 TObject *o = 0;
9525 TList *in = GetInputList();
9526 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9527 in->Remove(o);
9528 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9529 in->Remove(o);
9530
9531 // ... and reset the file
9532 fInputDataFile = "";
9534
9535 } else if (fInputData) {
9536 Int_t sz = fInputData->GetSize();
9537 while (fInputData->FindObject(obj))
9538 fInputData->Remove(obj);
9539 // Flag for update, if anything changed
9540 if (sz != fInputData->GetSize())
9542 }
9543}
9544
9545////////////////////////////////////////////////////////////////////////////////
9546/// Remove obj 'name' form the input data list;
9547
9549{
9550 TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
9551 if (obj) ClearInputData(obj);
9552}
9553
9554////////////////////////////////////////////////////////////////////////////////
9555/// Set the file to be used to optimally distribute the input data objects.
9556/// If the file exists the object in the file are added to those in the
9557/// fInputData list. If the file path is null, a default file will be created
9558/// at the moment of sending the processing request with the content of
9559/// the fInputData list. See also SendInputDataFile.
9560
9561void TProof::SetInputDataFile(const char *datafile)
9562{
9563 if (datafile && strlen(datafile) > 0) {
9564 if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
9566 fInputDataFile = datafile;
9567 } else {
9568 if (!fInputDataFile.IsNull())
9570 fInputDataFile = "";
9571 }
9572 // Make sure that the chosen file is readable
9575 fInputDataFile = "";
9576 }
9577}
9578
9579////////////////////////////////////////////////////////////////////////////////
9580/// Send the input data objects to the master; the objects are taken from the
9581/// dedicated list and / or the specified file.
9582/// If the fInputData is empty the specified file is sent over.
9583/// If there is no specified file, a file named "inputdata.root" is created locally
9584/// with the content of fInputData and sent over to the master.
9585/// If both fInputData and the specified file are not empty, a copy of the file
9586/// is made locally and augmented with the content of fInputData.
9587
9589{
9590 // Prepare the file
9591 TString dataFile;
9592 PrepareInputDataFile(dataFile);
9593
9594 // Send it, if not empty
9595 if (dataFile.Length() > 0) {
9596
9597 Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
9598 BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
9599
9600 // Set the name in the input list
9601 TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
9602 AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
9603 }
9604}
9605
9606////////////////////////////////////////////////////////////////////////////////
9607/// Prepare the file with the input data objects to be sent the master; the
9608/// objects are taken from the dedicated list and / or the specified file.
9609/// If the fInputData is empty the specified file is sent over.
9610/// If there is no specified file, a file named "inputdata.root" is created locally
9611/// with the content of fInputData and sent over to the master.
9612/// If both fInputData and the specified file are not empty, a copy of the file
9613/// is made locally and augmented with the content of fInputData.
9614
9616{
9617 // Save info about new data for usage in this call;
9619 // Next time we need some change
9621
9622 // Check the list
9623 Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
9624 // Check the file
9625 Bool_t file_ok = kFALSE;
9628 // It must contain something
9630 if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
9631 file_ok = kTRUE;
9632 }
9633
9634 // Remove any info about input data in the input list
9635 TObject *o = 0;
9636 TList *in = GetInputList();
9637 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9638 in->Remove(o);
9639 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9640 in->Remove(o);
9641
9642 // We must have something to send
9643 dataFile = "";
9644 if (!list_ok && !file_ok) return;
9645
9646 // Three cases:
9647 if (file_ok && !list_ok) {
9648 // Just send the file
9649 dataFile = fInputDataFile;
9650 } else if (!file_ok && list_ok) {
9652 // Nothing to do, if no new data
9653 if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
9654 // Create the file first
9655 TFile *f = TFile::Open(fInputDataFile, "RECREATE");
9656 if (f) {
9657 f->cd();
9658 TIter next(fInputData);
9659 TObject *obj;
9660 while ((obj = next())) {
9661 obj->Write(0, TObject::kSingleKey, 0);
9662 }
9663 f->Close();
9664 SafeDelete(f);
9665 } else {
9666 Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
9667 return;
9668 }
9669 dataFile = fInputDataFile;
9670 } else if (file_ok && list_ok) {
9671 dataFile = kPROOF_InputDataFile;
9672 // Create the file if not existing or there are new data
9673 if (newdata || gSystem->AccessPathName(dataFile)) {
9674 // Cleanup previous file if obsolete
9675 if (!gSystem->AccessPathName(dataFile))
9676 gSystem->Unlink(dataFile);
9677 if (dataFile != fInputDataFile) {
9678 // Make a local copy first
9679 if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
9680 Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
9681 return;
9682 }
9683 }
9684 // Add the input data list
9685 TFile *f = TFile::Open(dataFile, "UPDATE");
9686 if (f) {
9687 f->cd();
9688 TIter next(fInputData);
9689 TObject *obj = 0;
9690 while ((obj = next())) {
9691 obj->Write(0, TObject::kSingleKey, 0);
9692 }
9693 f->Close();
9694 SafeDelete(f);
9695 } else {
9696 Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
9697 return;
9698 }
9699 }
9700 }
9701
9702 // Done
9703 return;
9704}
9705
9706////////////////////////////////////////////////////////////////////////////////
9707/// Add objects that might be needed during the processing of
9708/// the selector (see Process()).
9709
9711{
9712 if (fPlayer) fPlayer->AddInput(obj);
9713}
9714
9715////////////////////////////////////////////////////////////////////////////////
9716/// Clear input object list.
9717
9719{
9720 if (fPlayer) fPlayer->ClearInput();
9721
9722 // the system feedback list is always in the input list
9724}
9725
9726////////////////////////////////////////////////////////////////////////////////
9727/// Get input list.
9728
9730{
9731 return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
9732}
9733
9734////////////////////////////////////////////////////////////////////////////////
9735/// Get specified object that has been produced during the processing
9736/// (see Process()).
9737
9739{
9740
9742 // Can be called by MarkBad on the master before the player is initialized
9743 return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
9744
9745 // This checks also associated output files
9746 return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
9747}
9748
9749////////////////////////////////////////////////////////////////////////////////
9750/// Find object 'name' in list 'out' or in the files specified in there
9751
9753{
9754 TObject *o = 0;
9755 if (!name || (name && strlen(name) <= 0) ||
9756 !out || (out && out->GetSize() <= 0)) return o;
9757 if ((o = out->FindObject(name))) return o;
9758
9759 // For the time being we always check for all the files; this may require
9760 // some caching
9761 TProofOutputFile *pf = 0;
9762 TIter nxo(out);
9763 while ((o = nxo())) {
9764 if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
9765 TFile *f = 0;
9766 if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
9767 TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
9768 f = TFile::Open(fn.Data());
9769 if (!f || (f && f->IsZombie())) {
9770 ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
9771 }
9772 }
9773 if (f && (o = f->Get(name))) return o;
9774 }
9775 }
9776
9777 // Done, unsuccessfully
9778 return o;
9779}
9780
9781////////////////////////////////////////////////////////////////////////////////
9782/// Get list with all object created during processing (see Process()).
9783
9785{
9786 if (fOutputList.GetSize() > 0) return &fOutputList;
9787 if (fPlayer) {
9789 return &fOutputList;
9790 }
9791 return (TList *)0;
9792}
9793
9794////////////////////////////////////////////////////////////////////////////////
9795/// Set input list parameter. If the parameter is already
9796/// set it will be set to the new value.
9797
9798void TProof::SetParameter(const char *par, const char *value)
9799{
9800 if (!fPlayer) {
9801 Warning("SetParameter", "player undefined! Ignoring");
9802 return;
9803 }
9804
9805 TList *il = fPlayer->GetInputList();
9806 TObject *item = il->FindObject(par);
9807 if (item) {
9808 il->Remove(item);
9809 delete item;
9810 }
9811 il->Add(new TNamed(par, value));
9812}
9813
9814////////////////////////////////////////////////////////////////////////////////
9815/// Set an input list parameter.
9816
9817void TProof::SetParameter(const char *par, Int_t value)
9818{
9819 if (!fPlayer) {
9820 Warning("SetParameter", "player undefined! Ignoring");
9821 return;
9822 }
9823
9824 TList *il = fPlayer->GetInputList();
9825 TObject *item = il->FindObject(par);
9826 if (item) {
9827 il->Remove(item);
9828 delete item;
9829 }
9830 il->Add(new TParameter<Int_t>(par, value));
9831}
9832
9833////////////////////////////////////////////////////////////////////////////////
9834/// Set an input list parameter.
9835
9836void TProof::SetParameter(const char *par, Long_t value)
9837{
9838 if (!fPlayer) {
9839 Warning("SetParameter", "player undefined! Ignoring");
9840 return;
9841 }
9842
9843 TList *il = fPlayer->GetInputList();
9844 TObject *item = il->FindObject(par);
9845 if (item) {
9846 il->Remove(item);
9847 delete item;
9848 }
9849 il->Add(new TParameter<Long_t>(par, value));
9850}
9851
9852////////////////////////////////////////////////////////////////////////////////
9853/// Set an input list parameter.
9854
9855void TProof::SetParameter(const char *par, Long64_t value)
9856{
9857 if (!fPlayer) {
9858 Warning("SetParameter", "player undefined! Ignoring");
9859 return;
9860 }
9861
9862 TList *il = fPlayer->GetInputList();
9863 TObject *item = il->FindObject(par);
9864 if (item) {
9865 il->Remove(item);
9866 delete item;
9867 }
9868 il->Add(new TParameter<Long64_t>(par, value));
9869}
9870
9871////////////////////////////////////////////////////////////////////////////////
9872/// Set an input list parameter.
9873
9874void TProof::SetParameter(const char *par, Double_t value)
9875{
9876 if (!fPlayer) {
9877 Warning("SetParameter", "player undefined! Ignoring");
9878 return;
9879 }
9880
9881 TList *il = fPlayer->GetInputList();
9882 TObject *item = il->FindObject(par);
9883 if (item) {
9884 il->Remove(item);
9885 delete item;
9886 }
9887 il->Add(new TParameter<Double_t>(par, value));
9888}
9889
9890////////////////////////////////////////////////////////////////////////////////
9891/// Get specified parameter. A parameter set via SetParameter() is either
9892/// a TParameter or a TNamed or 0 in case par is not defined.
9893
9894TObject *TProof::GetParameter(const char *par) const
9895{
9896 if (!fPlayer) {
9897 Warning("GetParameter", "player undefined! Ignoring");
9898 return (TObject *)0;
9899 }
9900
9901 TList *il = fPlayer->GetInputList();
9902 return il->FindObject(par);
9903}
9904
9905////////////////////////////////////////////////////////////////////////////////
9906/// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
9907/// or exact name (e.g. PROOF_MaxSlavesPerNode).
9908
9909void TProof::DeleteParameters(const char *wildcard)
9910{
9911 if (!fPlayer) return;
9912
9913 if (!wildcard) wildcard = "";
9914 TRegexp re(wildcard, kTRUE);
9915 Int_t nch = strlen(wildcard);
9916
9917 TList *il = fPlayer->GetInputList();
9918 if (il) {
9919 TObject *p = 0;
9920 TIter next(il);
9921 while ((p = next())) {
9922 TString s = p->GetName();
9923 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9924 il->Remove(p);
9925 delete p;
9926 }
9927 }
9928}
9929
9930////////////////////////////////////////////////////////////////////////////////
9931/// Show the input list parameters specified by the wildcard.
9932/// Default is the special PROOF control parameters (PROOF_*).
9933
9934void TProof::ShowParameters(const char *wildcard) const
9935{
9936 if (!fPlayer) return;
9937
9938 if (!wildcard) wildcard = "";
9939 TRegexp re(wildcard, kTRUE);
9940 Int_t nch = strlen(wildcard);
9941
9942 TList *il = fPlayer->GetInputList();
9943 TObject *p;
9944 TIter next(il);
9945 while ((p = next())) {
9946 TString s = p->GetName();
9947 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9948 if (p->IsA() == TNamed::Class()) {
9949 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9950 } else if (p->IsA() == TParameter<Long_t>::Class()) {
9951 Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
9952 } else if (p->IsA() == TParameter<Long64_t>::Class()) {
9953 Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
9954 } else if (p->IsA() == TParameter<Double_t>::Class()) {
9955 Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
9956 } else {
9957 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9958 }
9959 }
9960}
9961
9962////////////////////////////////////////////////////////////////////////////////
9963/// Add object to feedback list.
9964
9965void TProof::AddFeedback(const char *name)
9966{
9967 PDB(kFeedback, 3)
9968 Info("AddFeedback", "Adding object \"%s\" to feedback", name);
9969 if (fFeedback->FindObject(name) == 0)
9971}
9972
9973////////////////////////////////////////////////////////////////////////////////
9974/// Remove object from feedback list.
9975
9977{
9979 if (obj != 0) {
9980 fFeedback->Remove(obj);
9981 delete obj;
9982 }
9983}
9984
9985////////////////////////////////////////////////////////////////////////////////
9986/// Clear feedback list.
9987
9989{
9990 fFeedback->Delete();
9991}
9992
9993////////////////////////////////////////////////////////////////////////////////
9994/// Show items in feedback list.
9995
9997{
9998 if (fFeedback->GetSize() == 0) {
9999 Info("","no feedback requested");
10000 return;
10001 }
10002
10003 fFeedback->Print();
10004}
10005
10006////////////////////////////////////////////////////////////////////////////////
10007/// Return feedback list.
10008
10010{
10011 return fFeedback;
10012}
10013
10014////////////////////////////////////////////////////////////////////////////////
10015/// Creates a tree header (a tree with nonexisting files) object for
10016/// the DataSet.
10017
10019{
10021 TSlave *sl = (TSlave*) l->First();
10022 if (sl == 0) {
10023 Error("GetTreeHeader", "No connection");
10024 return 0;
10025 }
10026
10027 TSocket *soc = sl->GetSocket();
10029
10030 msg << dset;
10031
10032 soc->Send(msg);
10033
10034 TMessage *reply;
10035 Int_t d = -1;
10036 if (fProtocol >= 20) {
10038 reply = (TMessage *) fRecvMessages->First();
10039 } else {
10040 d = soc->Recv(reply);
10041 }
10042 if (!reply) {
10043 Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10044 return 0;
10045 }
10046
10047 TString s1;
10048 TTree *t = 0;
10049 (*reply) >> s1;
10050 if (s1 == "Success")
10051 (*reply) >> t;
10052
10053 PDB(kGlobal, 1) {
10054 if (t) {
10055 Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10056 s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10057 } else {
10058 Info("GetTreeHeader", "tree header retrieval failed");
10059 }
10060 }
10061 delete reply;
10062
10063 return t;
10064}
10065
10066////////////////////////////////////////////////////////////////////////////////
10067/// Draw feedback creation proxy. When accessed via TProof avoids
10068/// link dependency on libProofPlayer.
10069
10071{
10072 return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10073}
10074
10075////////////////////////////////////////////////////////////////////////////////
10076/// Set draw feedback option.
10077
10079{
10081}
10082
10083////////////////////////////////////////////////////////////////////////////////
10084/// Delete draw feedback object.
10085
10087{
10089}
10090
10091////////////////////////////////////////////////////////////////////////////////
10092/// FIXME: to be written
10093
10095{
10096 return 0;
10097/*
10098 TMessage msg(kPROOF_GETOUTPUTLIST);
10099 TList* slaves = fActiveSlaves;
10100 Broadcast(msg, slaves);
10101 TMonitor mon;
10102 TList* outputList = new TList();
10103
10104 TIter si(slaves);
10105 TSlave *slave;
10106 while ((slave = (TSlave*)si.Next()) != 0) {
10107 PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10108 slave->GetSocket(), slave->GetName());
10109 mon.Add(slave->GetSocket());
10110 }
10111 mon.ActivateAll();
10112 ((TProof*)gProof)->DeActivateAsyncInput();
10113 ((TProof*)gProof)->fCurrentMonitor = &mon;
10114
10115 while (mon.GetActive() != 0) {
10116 TSocket *sock = mon.Select();
10117 if (!sock) {
10118 Error("GetOutputList","TMonitor::.Select failed!");
10119 break;
10120 }
10121 mon.DeActivate(sock);
10122 TMessage *reply;
10123 if (sock->Recv(reply) <= 0) {
10124 MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10125// Error("GetOutputList","Recv failed! for slave-%d (%s)",
10126// slave->GetOrdinal(), slave->GetName());
10127 continue;
10128 }
10129 if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10130// Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10131// slave->GetOrdinal(), slave->GetName());
10132 MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10133 continue;
10134 }
10135 TList* l;
10136
10137 (*reply) >> l;
10138 TIter next(l);
10139 TNamed *n;
10140 while ( (n = dynamic_cast<TNamed*> (next())) ) {
10141 if (!outputList->FindObject(n->GetName()))
10142 outputList->Add(n);
10143 }
10144 delete reply;
10145 }
10146 ((TProof*)gProof)->fCurrentMonitor = 0;
10147
10148 return outputList;
10149*/
10150}
10151
10152////////////////////////////////////////////////////////////////////////////////
10153/// Build the PROOF's structure in the browser.
10154
10156{
10157 b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10158 b->Add(&fMaster, fMaster.Class(), "fMaster");
10159 b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10160 b->Add(fChains, fChains->Class(), "fChains");
10161
10162 if (fPlayer) {
10163 b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10164 if (fPlayer->GetOutputList())
10165 b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10167 b->Add(fPlayer->GetListOfResults(),
10168 fPlayer->GetListOfResults()->Class(), "ListOfResults");
10169 }
10170}
10171
10172////////////////////////////////////////////////////////////////////////////////
10173/// Set a new PROOF player.
10174
10176{
10177 if (fPlayer)
10178 delete fPlayer;
10179 fPlayer = player;
10180};
10181
10182////////////////////////////////////////////////////////////////////////////////
10183/// Construct a TProofPlayer object. The player string specifies which
10184/// player should be created: remote, slave, sm (supermaster) or base.
10185/// Default is remote. Socket is needed in case a slave player is created.
10186
10188{
10189 if (!player)
10190 player = "remote";
10191
10192 SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10193 return GetPlayer();
10194}
10195
10196////////////////////////////////////////////////////////////////////////////////
10197/// Add chain to data set
10198
10200{
10201 fChains->Add(chain);
10202}
10203
10204////////////////////////////////////////////////////////////////////////////////
10205/// Remove chain from data set
10206
10208{
10209 fChains->Remove(chain);
10210}
10211
10212////////////////////////////////////////////////////////////////////////////////
10213/// Ask for remote logs in the range [start, end]. If start == -1 all the
10214/// messages not yet received are sent back.
10215
10217{
10218 if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10219
10221
10222 msg << start << end;
10223
10224 Broadcast(msg, kActive);
10226}
10227
10228////////////////////////////////////////////////////////////////////////////////
10229/// Fill a TMacro with the log lines since the last reading (fLogFileR)
10230/// Return (TMacro *)0 if no line was logged.
10231/// The returned TMacro must be deleted by the caller.
10232
10234{
10235 TMacro *maclog = 0;
10236
10237 // Save present offset
10238 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10239 if (nowlog < 0) {
10240 SysError("GetLastLog",
10241 "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10242 return maclog;
10243 }
10244
10245 // Get extremes
10246 off_t startlog = nowlog;
10247 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10248 if (endlog < 0) {
10249 SysError("GetLastLog",
10250 "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10251 return maclog;
10252 }
10253
10254 // Perhaps nothing to log
10255 UInt_t tolog = (UInt_t)(endlog - startlog);
10256 if (tolog <= 0) return maclog;
10257
10258 // Set starting point
10259 if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10260 SysError("GetLastLog",
10261 "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10262 return maclog;
10263 }
10264
10265 // Create the output object
10266 maclog = new TMacro;
10267
10268 // Now we go
10269 char line[2048];
10270 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10271 while (fgets(line, wanted, fLogFileR)) {
10272 Int_t r = strlen(line);
10273 if (r > 0) {
10274 if (line[r-1] == '\n') line[r-1] = '\0';
10275 maclog->AddLine(line);
10276 } else {
10277 // Done
10278 break;
10279 }
10280 tolog -= r;
10281 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10282 }
10283
10284 // Restore original pointer
10285 if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10286 Warning("GetLastLog",
10287 "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10288 }
10289
10290 // Done
10291 return maclog;
10292}
10293
10294////////////////////////////////////////////////////////////////////////////////
10295/// Display log of query pq into the log window frame
10296
10298{
10299 if (!pq) return;
10300
10301 TList *lines = pq->GetLogFile()->GetListOfLines();
10302 if (lines) {
10303 TIter nxl(lines);
10304 TObjString *l = 0;
10305 while ((l = (TObjString *)nxl()))
10306 EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10307 }
10308}
10309
10310////////////////////////////////////////////////////////////////////////////////
10311/// Display on screen the content of the temporary log file for query
10312/// in reference
10313
10314void TProof::ShowLog(const char *queryref)
10315{
10316 // Make sure we have all info (GetListOfQueries retrieves the
10317 // head info only)
10318 Retrieve(queryref);
10319
10320 if (fPlayer) {
10321 if (queryref) {
10322 if (fPlayer->GetListOfResults()) {
10324 TQueryResult *qr = 0;
10325 while ((qr = (TQueryResult *) nxq()))
10326 if (strstr(queryref, qr->GetTitle()) &&
10327 strstr(queryref, qr->GetName()))
10328 break;
10329 if (qr) {
10330 PutLog(qr);
10331 return;
10332 }
10333
10334 }
10335 }
10336 }
10337}
10338
10339////////////////////////////////////////////////////////////////////////////////
10340/// Display on screen the content of the temporary log file.
10341/// If qry == -2 show messages from the last (current) query.
10342/// If qry == -1 all the messages not yet displayed are shown (default).
10343/// If qry == 0, all the messages in the file are shown.
10344/// If qry > 0, only the messages related to query 'qry' are shown.
10345/// For qry != -1 the original file offset is restored at the end
10346
10348{
10349 // Save present offset
10350 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10351 if (nowlog < 0) {
10352 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10353 return;
10354 }
10355
10356 // Get extremes
10357 off_t startlog = nowlog;
10358 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10359 if (endlog < 0) {
10360 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10361 return;
10362 }
10363
10364 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10365 if (qry == 0) {
10366 startlog = 0;
10367 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10368 } else if (qry != -1) {
10369
10370 TQueryResult *pq = 0;
10371 if (qry == -2) {
10372 // Pickup the last one
10373 pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10374 if (!pq) {
10376 if (fQueries)
10377 pq = (TQueryResult *)(fQueries->Last());
10378 }
10379 } else if (qry > 0) {
10380 TList *queries = GetQueryResults();
10381 if (queries) {
10382 TIter nxq(queries);
10383 while ((pq = (TQueryResult *)nxq()))
10384 if (qry == pq->GetSeqNum())
10385 break;
10386 }
10387 if (!pq) {
10388 queries = GetListOfQueries();
10389 TIter nxq(queries);
10390 while ((pq = (TQueryResult *)nxq()))
10391 if (qry == pq->GetSeqNum())
10392 break;
10393 }
10394 }
10395 if (pq) {
10396 PutLog(pq);
10397 return;
10398 } else {
10399 if (gDebug > 0)
10400 Info("ShowLog","query %d not found in list", qry);
10401 qry = -1;
10402 }
10403 }
10404
10405 // Number of bytes to log
10406 UInt_t tolog = (UInt_t)(endlog - startlog);
10407
10408 // Perhaps nothing
10409 if (tolog <= 0) {
10410 // Set starting point
10411 lseek(fileno(fLogFileR), startlog, SEEK_SET);
10412 }
10413
10414 // Now we go
10415 Int_t np = 0;
10416 char line[2048];
10417 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10418 while (fgets(line, wanted, fLogFileR)) {
10419
10420 Int_t r = strlen(line);
10421 if (!SendingLogToWindow()) {
10422 if (line[r-1] != '\n') line[r-1] = '\n';
10423 if (r > 0) {
10424 char *p = line;
10425 while (r) {
10426 Int_t w = write(fileno(stdout), p, r);
10427 if (w < 0) {
10428 SysError("ShowLog", "error writing to stdout");
10429 break;
10430 }
10431 r -= w;
10432 p += w;
10433 }
10434 }
10435 tolog -= strlen(line);
10436 np++;
10437
10438 // Ask if more is wanted
10439 if (!(np%10)) {
10440 const char *opt = Getline("More (y/n)? [y]");
10441 if (opt[0] == 'n')
10442 break;
10443 }
10444
10445 // We may be over
10446 if (tolog <= 0)
10447 break;
10448
10449 // Update wanted bytes
10450 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10451 } else {
10452 // Log to window
10453 if (line[r-1] == '\n') line[r-1] = 0;
10455 }
10456 }
10457 if (!SendingLogToWindow()) {
10458 // Avoid screwing up the prompt
10459 if (write(fileno(stdout), "\n", 1) != 1)
10460 SysError("ShowLog", "error writing to stdout");
10461 }
10462
10463 // Restore original pointer
10464 if (qry > -1)
10465 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10466}
10467
10468////////////////////////////////////////////////////////////////////////////////
10469/// Set session with 'id' the default one. If 'id' is not found in the list,
10470/// the current session is set as default
10471
10473{
10474 if (GetManager()) {
10476 if (d) {
10477 if (d->GetProof()) {
10478 gProof = d->GetProof();
10479 return;
10480 }
10481 }
10482
10483 // Id not found or undefined: set as default this session
10484 gProof = this;
10485 }
10486
10487 return;
10488}
10489
10490////////////////////////////////////////////////////////////////////////////////
10491/// Detach this instance to its proofserv.
10492/// If opt is 'S' or 's' the remote server is shutdown
10493
10495{
10496 // Nothing to do if not in contact with proofserv
10497 if (!IsValid()) return;
10498
10499 // Get worker and socket instances
10500 TSlave *sl = (TSlave *) fActiveSlaves->First();
10501 TSocket *s = 0;
10502 if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
10503 Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
10504 return;
10505 }
10506
10507 Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
10508
10509 // If processing, try to stop processing first
10510 if (shutdown && !IsIdle()) {
10511 // Remove pending requests
10512 Remove("cleanupqueue");
10513 // Do not wait for ever, but al least 20 seconds
10514 Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
10515 timeout = (timeout > 20) ? timeout : 20;
10516 // Send stop signal
10517 StopProcess(kFALSE, (Long_t) (timeout / 2));
10518 // Receive results
10519 Collect(kActive, timeout);
10520 }
10521
10522 // Avoid spurious messages: deactivate new inputs ...
10524
10525 // ... and discard existing ones
10526 sl->FlushSocket();
10527
10528 // Close session (we always close the connection)
10529 Close(opt);
10530
10531 // Close the progress dialog, if any
10534
10535 // Update info in the table of our manager, if any
10536 if (GetManager() && GetManager()->QuerySessions("L")) {
10537 TIter nxd(GetManager()->QuerySessions("L"));
10538 TProofDesc *d = 0;
10539 while ((d = (TProofDesc *)nxd())) {
10540 if (d->GetProof() == this) {
10541 d->SetProof(0);
10542 GetManager()->QuerySessions("L")->Remove(d);
10543 break;
10544 }
10545 }
10546 }
10547
10548 // Invalidate this instance
10549 fValid = kFALSE;
10550
10551 return;
10552}
10553
10554////////////////////////////////////////////////////////////////////////////////
10555/// Set an alias for this session. If reconnection is supported, the alias
10556/// will be communicated to the remote coordinator so that it can be recovered
10557/// when reconnecting
10558
10559void TProof::SetAlias(const char *alias)
10560{
10561 // Set it locally
10562 TNamed::SetTitle(alias);
10564 // Set the name at the same value
10565 TNamed::SetName(alias);
10566
10567 // Nothing to do if not in contact with coordinator
10568 if (!IsValid()) return;
10569
10570 if (!IsProofd() && TestBit(TProof::kIsClient)) {
10571 TSlave *sl = (TSlave *) fActiveSlaves->First();
10572 if (sl)
10573 sl->SetAlias(alias);
10574 }
10575
10576 return;
10577}
10578
10579////////////////////////////////////////////////////////////////////////////////
10580/// *** This function is deprecated and will disappear in future versions ***
10581/// *** It is just a wrapper around TFile::Cp.
10582/// *** Please use TProofMgr::UploadFiles.
10583///
10584/// Upload a set of files and save the list of files by name dataSetName.
10585/// The 'files' argument is a list of TFileInfo objects describing the files
10586/// as first url.
10587/// The mask 'opt' is a combination of EUploadOpt:
10588/// kAppend (0x1) if set true files will be appended to
10589/// the dataset existing by given name
10590/// kOverwriteDataSet (0x2) if dataset with given name exited it
10591/// would be overwritten
10592/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10593/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10594/// kOverwriteNoFiles (0x10) overwrite none
10595/// kAskUser (0x0) ask user before overwriteng dataset/files
10596/// The default value is kAskUser.
10597/// The user will be asked to confirm overwriting dataset or files unless
10598/// specified opt provides the answer!
10599/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10600/// skippedFiles argument. The function will add to this list TFileInfo
10601/// objects describing all files that existed on the cluster and were
10602/// not uploaded.
10603///
10604/// Communication Summary
10605/// Client Master
10606/// |------------>DataSetName----------->|
10607/// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
10608/// (*)|-------> call RegisterDataSet ------->|
10609/// (*) - optional
10610
10611Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
10612{
10613 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10614
10615 return -1;
10616}
10617
10618////////////////////////////////////////////////////////////////////////////////
10619/// *** This function is deprecated and will disappear in future versions ***
10620/// *** It is just a wrapper around TFile::Cp.
10621/// *** Please use TProofMgr::UploadFiles.
10622///
10623/// Upload a set of files and save the list of files by name dataSetName.
10624/// The mask 'opt' is a combination of EUploadOpt:
10625/// kAppend (0x1) if set true files will be appended to
10626/// the dataset existing by given name
10627/// kOverwriteDataSet (0x2) if dataset with given name exited it
10628/// would be overwritten
10629/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10630/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10631/// kOverwriteNoFiles (0x10) overwrite none
10632/// kAskUser (0x0) ask user before overwriteng dataset/files
10633/// The default value is kAskUser.
10634/// The user will be asked to confirm overwriting dataset or files unless
10635/// specified opt provides the answer!
10636/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10637/// skippedFiles argument. The function will add to this list TFileInfo
10638/// objects describing all files that existed on the cluster and were
10639/// not uploaded.
10640///
10641
10642Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
10643{
10644 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10645
10646 return -1;
10647}
10648
10649////////////////////////////////////////////////////////////////////////////////
10650/// *** This function is deprecated and will disappear in future versions ***
10651/// *** It is just a wrapper around TFile::Cp.
10652/// *** Please use TProofMgr::UploadFiles.
10653///
10654/// Upload files listed in "file" to PROOF cluster.
10655/// Where file = name of file containing list of files and
10656/// dataset = dataset name and opt is a combination of EUploadOpt bits.
10657/// Each file description (line) can include wildcards.
10658/// Check TFileInfo compatibility
10659
10660Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
10661{
10662 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10663
10664 // Done
10665 return -1;
10666}
10667
10668////////////////////////////////////////////////////////////////////////////////
10669/// Register the 'dataSet' on the cluster under the current
10670/// user, group and the given 'dataSetName'.
10671/// If a dataset with the same name already exists the action fails unless 'opts'
10672/// contains 'O', in which case the old dataset is overwritten, or contains 'U',
10673/// in which case 'newDataSet' is added to the existing dataset (duplications are
10674/// ignored, if any).
10675/// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
10676/// is configured to allow so). By default the dataset is not verified.
10677/// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
10678/// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
10679/// If 'opts' contains 'S' validation would be run serially (meaningful only if
10680/// validation is required).
10681/// Returns kTRUE on success.
10682
10683Bool_t TProof::RegisterDataSet(const char *dataSetName,
10684 TFileCollection *dataSet, const char *optStr)
10685{
10686 // Check TFileInfo compatibility
10687 if (fProtocol < 17) {
10688 Info("RegisterDataSet",
10689 "functionality not available: the server does not have dataset support");
10690 return kFALSE;
10691 }
10692
10693 if (!dataSetName || strlen(dataSetName) <= 0) {
10694 Info("RegisterDataSet", "specifying a dataset name is mandatory");
10695 return kFALSE;
10696 }
10697
10698 Bool_t parallelverify = kFALSE;
10699 TString sopt(optStr);
10700 if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
10701 // We do verification in parallel later on; just register for now
10702 parallelverify = kTRUE;
10703 sopt.ReplaceAll("V", "");
10704 }
10705 // This would screw up things remotely, make sure is not there
10706 sopt.ReplaceAll("S", "");
10707
10709 mess << Int_t(kRegisterDataSet);
10710 mess << TString(dataSetName);
10711 mess << sopt;
10712 mess.WriteObject(dataSet);
10713 Broadcast(mess);
10714
10715 Bool_t result = kTRUE;
10716 Collect();
10717 if (fStatus != 0) {
10718 Error("RegisterDataSet", "dataset was not saved");
10719 result = kFALSE;
10720 return result;
10721 }
10722
10723 // If old server or not verifying in parallel we are done
10724 if (!parallelverify) return result;
10725
10726 // If we are here it means that we will verify in parallel
10727 sopt += "V";
10728 if (VerifyDataSet(dataSetName, sopt) < 0){
10729 Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
10730 return kFALSE;
10731 }
10732
10733 // We are done
10734 return kTRUE;
10735}
10736
10737////////////////////////////////////////////////////////////////////////////////
10738/// Set/Change the name of the default tree. The tree name may contain
10739/// subdir specification in the form "subdir/name".
10740/// Returns 0 on success, -1 otherwise.
10741
10742Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
10743{
10744 // Check TFileInfo compatibility
10745 if (fProtocol < 23) {
10746 Info("SetDataSetTreeName", "functionality not supported by the server");
10747 return -1;
10748 }
10749
10750 if (!dataset || strlen(dataset) <= 0) {
10751 Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
10752 return -1;
10753 }
10754
10755 if (!treename || strlen(treename) <= 0) {
10756 Info("SetDataSetTreeName", "specifying a tree name is mandatory");
10757 return -1;
10758 }
10759
10760 TUri uri(dataset);
10761 TString fragment(treename);
10762 if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
10763 uri.SetFragment(fragment);
10764
10766 mess << Int_t(kSetDefaultTreeName);
10767 mess << uri.GetUri();
10768 Broadcast(mess);
10769
10770 Collect();
10771 if (fStatus != 0) {
10772 Error("SetDataSetTreeName", "some error occured: default tree name not changed");
10773 return -1;
10774 }
10775 return 0;
10776}
10777
10778////////////////////////////////////////////////////////////////////////////////
10779/// Lists all datasets that match given uri.
10780/// The 'optStr' can contain a comma-separated list of servers for which the
10781/// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
10782/// only the global information in the TFileCollection is retrieved; useful to only
10783/// get the list of available datasets.
10784
10785TMap *TProof::GetDataSets(const char *uri, const char *optStr)
10786{
10787 if (fProtocol < 15) {
10788 Info("GetDataSets",
10789 "functionality not available: the server does not have dataset support");
10790 return 0;
10791 }
10792 if (fProtocol < 31 && strstr(optStr, ":lite:"))
10793 Warning("GetDataSets", "'lite' option not supported by the server");
10794
10796 mess << Int_t(kGetDataSets);
10797 mess << TString(uri ? uri : "");
10798 mess << TString(optStr ? optStr : "");
10799 Broadcast(mess);
10801
10802 TMap *dataSetMap = 0;
10803 if (fStatus != 0) {
10804 Error("GetDataSets", "error receiving datasets information");
10805 } else {
10806 // Look in the list
10807 TMessage *retMess = (TMessage *) fRecvMessages->First();
10808 if (retMess && retMess->What() == kMESS_OK) {
10809 if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
10810 Error("GetDataSets", "error receiving datasets");
10811 } else
10812 Error("GetDataSets", "message not found or wrong type (%p)", retMess);
10813 }
10814
10815 return dataSetMap;
10816}
10817
10818////////////////////////////////////////////////////////////////////////////////
10819/// Shows datasets in locations that match the uri.
10820/// By default shows the user's datasets and global ones
10821
10822void TProof::ShowDataSets(const char *uri, const char* optStr)
10823{
10824 if (fProtocol < 15) {
10825 Info("ShowDataSets",
10826 "functionality not available: the server does not have dataset support");
10827 return;
10828 }
10829
10831 mess << Int_t(kShowDataSets);
10832 mess << TString(uri ? uri : "");
10833 mess << TString(optStr ? optStr : "");
10834 Broadcast(mess);
10835
10837 if (fStatus != 0)
10838 Error("ShowDataSets", "error receiving datasets information");
10839}
10840
10841////////////////////////////////////////////////////////////////////////////////
10842/// Returns kTRUE if 'dataset' exists, kFALSE otherwise
10843
10844Bool_t TProof::ExistsDataSet(const char *dataset)
10845{
10846 if (fProtocol < 15) {
10847 Info("ExistsDataSet", "functionality not available: the server has an"
10848 " incompatible version of TFileInfo");
10849 return kFALSE;
10850 }
10851
10852 if (!dataset || strlen(dataset) <= 0) {
10853 Error("ExistsDataSet", "dataset name missing");
10854 return kFALSE;
10855 }
10856
10858 msg << Int_t(kCheckDataSetName) << TString(dataset);
10859 Broadcast(msg);
10861 if (fStatus == -1) {
10862 // The dataset exists
10863 return kTRUE;
10864 }
10865 // The dataset does not exists
10866 return kFALSE;
10867}
10868
10869////////////////////////////////////////////////////////////////////////////////
10870/// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
10871
10872void TProof::ClearDataSetCache(const char *dataset)
10873{
10874 if (fProtocol < 28) {
10875 Info("ClearDataSetCache", "functionality not available on server");
10876 return;
10877 }
10878
10880 msg << Int_t(kCache) << TString(dataset) << TString("clear");
10881 Broadcast(msg);
10883 // Done
10884 return;
10885}
10886
10887////////////////////////////////////////////////////////////////////////////////
10888/// Display the content of the dataset cache, if any (matching 'dataset', if defined).
10889
10890void TProof::ShowDataSetCache(const char *dataset)
10891{
10892 if (fProtocol < 28) {
10893 Info("ShowDataSetCache", "functionality not available on server");
10894 return;
10895 }
10896
10898 msg << Int_t(kCache) << TString(dataset) << TString("show");
10899 Broadcast(msg);
10901 // Done
10902 return;
10903}
10904
10905////////////////////////////////////////////////////////////////////////////////
10906/// Get a list of TFileInfo objects describing the files of the specified
10907/// dataset.
10908/// To get the short version (containing only the global meta information)
10909/// specify optStr = "S:" or optStr = "short:".
10910/// To get the sub-dataset of files located on a given server(s) specify
10911/// the list of servers (comma-separated) in the 'optStr' field.
10912
10913TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10914{
10915 if (fProtocol < 15) {
10916 Info("GetDataSet", "functionality not available: the server has an"
10917 " incompatible version of TFileInfo");
10918 return 0;
10919 }
10920
10921 if (!uri || strlen(uri) <= 0) {
10922 Info("GetDataSet", "specifying a dataset name is mandatory");
10923 return 0;
10924 }
10925
10926 TMessage nameMess(kPROOF_DATASETS);
10927 nameMess << Int_t(kGetDataSet);
10928 nameMess << TString(uri);
10929 nameMess << TString(optStr ? optStr: "");
10930 if (Broadcast(nameMess) < 0)
10931 Error("GetDataSet", "sending request failed");
10932
10934 TFileCollection *fileList = 0;
10935 if (fStatus != 0) {
10936 Error("GetDataSet", "error receiving datasets information");
10937 } else {
10938 // Look in the list
10939 TMessage *retMess = (TMessage *) fRecvMessages->First();
10940 if (retMess && retMess->What() == kMESS_OK) {
10941 if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10942 Error("GetDataSet", "error reading list of files");
10943 } else
10944 Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10945 }
10946
10947 return fileList;
10948}
10949
10950////////////////////////////////////////////////////////////////////////////////
10951/// display meta-info for given dataset usi
10952
10953void TProof::ShowDataSet(const char *uri, const char* opt)
10954{
10955 TFileCollection *fileList = 0;
10956 if ((fileList = GetDataSet(uri))) {
10957 fileList->Print(opt);
10958 delete fileList;
10959 } else
10960 Warning("ShowDataSet","no such dataset: %s", uri);
10961}
10962
10963////////////////////////////////////////////////////////////////////////////////
10964/// Remove the specified dataset from the PROOF cluster.
10965/// Files are not deleted.
10966
10967Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10968{
10969 TMessage nameMess(kPROOF_DATASETS);
10970 nameMess << Int_t(kRemoveDataSet);
10971 nameMess << TString(uri?uri:"");
10972 nameMess << TString(optStr?optStr:"");
10973 if (Broadcast(nameMess) < 0)
10974 Error("RemoveDataSet", "sending request failed");
10976
10977 if (fStatus != 0)
10978 return -1;
10979 else
10980 return 0;
10981}
10982
10983////////////////////////////////////////////////////////////////////////////////
10984/// Find datasets, returns in a TList all found datasets.
10985
10986TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
10987{
10988 Error ("FindDataSets", "not yet implemented");
10989 return (TList *) 0;
10990}
10991
10992////////////////////////////////////////////////////////////////////////////////
10993/// Allows users to request staging of a particular dataset. Requests are
10994/// saved in a special dataset repository and must be honored by the endpoint.
10995
10997{
10998 if (fProtocol < 35) {
10999 Error("RequestStagingDataSet",
11000 "functionality not supported by the server");
11001 return kFALSE;
11002 }
11003
11005 mess << Int_t(kRequestStaging);
11006 mess << TString(dataset);
11007 Broadcast(mess);
11008
11009 Collect();
11010 if (fStatus != 0) {
11011 Error("RequestStagingDataSet", "staging request was unsuccessful");
11012 return kFALSE;
11013 }
11014
11015 return kTRUE;
11016}
11017
11018////////////////////////////////////////////////////////////////////////////////
11019/// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11020/// failure. Dataset not found equals to a failure.
11021
11023{
11024 if (fProtocol < 36) {
11025 Error("CancelStagingDataSet",
11026 "functionality not supported by the server");
11027 return kFALSE;
11028 }
11029
11031 mess << Int_t(kCancelStaging);
11032 mess << TString(dataset);
11033 Broadcast(mess);
11034
11035 Collect();
11036 if (fStatus != 0) {
11037 Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11038 return kFALSE;
11039 }
11040
11041 return kTRUE;
11042}
11043
11044////////////////////////////////////////////////////////////////////////////////
11045/// Obtains a TFileCollection showing the staging status of the specified
11046/// dataset. A valid dataset manager and dataset staging requests repository
11047/// must be present on the endpoint.
11048
11050{
11051 if (fProtocol < 35) {
11052 Error("GetStagingStatusDataSet",
11053 "functionality not supported by the server");
11054 return NULL;
11055 }
11056
11057 TMessage nameMess(kPROOF_DATASETS);
11058 nameMess << Int_t(kStagingStatus);
11059 nameMess << TString(dataset);
11060 if (Broadcast(nameMess) < 0) {
11061 Error("GetStagingStatusDataSet", "sending request failed");
11062 return NULL;
11063 }
11064
11066 TFileCollection *fc = NULL;
11067
11068 if (fStatus < 0) {
11069 Error("GetStagingStatusDataSet", "problem processing the request");
11070 }
11071 else if (fStatus == 0) {
11072 TMessage *retMess = (TMessage *)fRecvMessages->First();
11073 if (retMess && (retMess->What() == kMESS_OK)) {
11074 fc = (TFileCollection *)(
11075 retMess->ReadObject(TFileCollection::Class()) );
11076 if (!fc)
11077 Error("GetStagingStatusDataSet", "error reading list of files");
11078 }
11079 else {
11080 Error("GetStagingStatusDataSet",
11081 "response message not found or wrong type (%p)", retMess);
11082 }
11083 }
11084 //else {}
11085
11086 return fc;
11087}
11088
11089////////////////////////////////////////////////////////////////////////////////
11090/// Like GetStagingStatusDataSet, but displays results immediately.
11091
11092void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11093{
11095 if (fc) {
11096 fc->Print(opt);
11097 delete fc;
11098 }
11099}
11100
11101////////////////////////////////////////////////////////////////////////////////
11102/// Verify if all files in the specified dataset are available.
11103/// Print a list and return the number of missing files.
11104/// Returns -1 in case of error.
11105
11106Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11107{
11108 if (fProtocol < 15) {
11109 Info("VerifyDataSet", "functionality not available: the server has an"
11110 " incompatible version of TFileInfo");
11111 return -1;
11112 }
11113
11114 // Sanity check
11115 if (!uri || (uri && strlen(uri) <= 0)) {
11116 Error("VerifyDataSet", "dataset name is is mandatory");
11117 return -1;
11118 }
11119
11120 Int_t nmissingfiles = 0;
11121
11122 TString sopt(optStr);
11123 if (fProtocol < 34 || sopt.Contains("S")) {
11124 sopt.ReplaceAll("S", "");
11125 Info("VerifyDataSet", "Master-only verification");
11126 TMessage nameMess(kPROOF_DATASETS);
11127 nameMess << Int_t(kVerifyDataSet);
11128 nameMess << TString(uri);
11129 nameMess << sopt;
11130 Broadcast(nameMess);
11131
11133
11134 if (fStatus < 0) {
11135 Info("VerifyDataSet", "no such dataset %s", uri);
11136 return -1;
11137 } else
11138 nmissingfiles = fStatus;
11139 return nmissingfiles;
11140 }
11141
11142 // Request for parallel verification: can only be done if we have workers
11143 if (!IsParallel() && !fDynamicStartup) {
11144 Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11145 Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11146 return -1;
11147 }
11148
11149 // Do parallel verification
11150 return VerifyDataSetParallel(uri, optStr);
11151}
11152
11153////////////////////////////////////////////////////////////////////////////////
11154/// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11155/// TProofLite::VerifyDataSet
11156
11157Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11158{
11159 Int_t nmissingfiles = 0;
11160
11161 // Let PROOF master prepare node-files map
11162 SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11163
11164 // Use TPacketizerFile
11165 TString oldpack;
11166 if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11167 SetParameter("PROOF_Packetizer", "TPacketizerFile");
11168
11169 // Add dataset name
11170 SetParameter("PROOF_VerifyDataSet", uri);
11171 // Add options
11172 SetParameter("PROOF_VerifyDataSetOption", optStr);
11173 SetParameter("PROOF_SavePartialResults", (Int_t)0);
11174 Int_t oldifiip = -1;
11175 if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11176 SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11177
11178 // TO DO : figure out mss and stageoption
11179 const char* mss="";
11180 SetParameter("PROOF_MSS", mss);
11181 const char* stageoption="";
11182 SetParameter("PROOF_StageOption", stageoption);
11183
11184 // Process verification in parallel
11185 Process("TSelVerifyDataSet", (Long64_t) 1);
11186
11187 // Restore packetizer
11188 if (!oldpack.IsNull())
11189 SetParameter("PROOF_Packetizer", oldpack);
11190 else
11191 DeleteParameters("PROOF_Packetizer");
11192
11193 // Delete or restore parameters
11194 DeleteParameters("PROOF_FilesToProcess");
11195 DeleteParameters("PROOF_VerifyDataSet");
11196 DeleteParameters("PROOF_VerifyDataSetOption");
11197 DeleteParameters("PROOF_MSS");
11198 DeleteParameters("PROOF_StageOption");
11199 if (oldifiip > -1) {
11200 SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11201 } else {
11202 DeleteParameters("PROOF_IncludeFileInfoInPacket");
11203 }
11204 DeleteParameters("PROOF_SavePartialResults");
11205
11206 // Merge outputs
11207 Int_t nopened = 0;
11208 Int_t ntouched = 0;
11209 Bool_t changed_ds = kFALSE;
11210
11211 TIter nxtout(GetOutputList());
11212 TObject* obj;
11213 TList *lfiindout = new TList;
11214 while ((obj = nxtout())) {
11215 TList *l = dynamic_cast<TList *>(obj);
11216 if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11217 TIter nxt(l);
11218 TFileInfo *fiindout = 0;
11219 while ((fiindout = (TFileInfo*) nxt())) {
11220 lfiindout->Add(fiindout);
11221 }
11222 }
11223 // Add up number of disppeared files
11224 TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11225 if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11226 nmissingfiles += pdisappeared->GetVal();
11227 }
11228 TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11229 if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11230 nopened += pnopened->GetVal();
11231 }
11232 TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11233 if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11234 ntouched += pntouched->GetVal();
11235 }
11236 TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11237 if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11238 if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11239 }
11240 }
11241
11242 Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11243 " # missing files = %d)",
11244 uri, changed_ds, nopened, ntouched, nmissingfiles);
11245 // Done
11246 return nmissingfiles;
11247}
11248
11249////////////////////////////////////////////////////////////////////////////////
11250/// returns a map of the quotas of all groups
11251
11252TMap *TProof::GetDataSetQuota(const char* optStr)
11253{
11254 if (IsLite()) {
11255 Info("UploadDataSet", "Lite-session: functionality not implemented");
11256 return (TMap *)0;
11257 }
11258
11260 mess << Int_t(kGetQuota);
11261 mess << TString(optStr?optStr:"");
11262 Broadcast(mess);
11263
11265 TMap *groupQuotaMap = 0;
11266 if (fStatus < 0) {
11267 Info("GetDataSetQuota", "could not receive quota");
11268 } else {
11269 // Look in the list
11270 TMessage *retMess = (TMessage *) fRecvMessages->First();
11271 if (retMess && retMess->What() == kMESS_OK) {
11272 if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11273 Error("GetDataSetQuota", "error getting quotas");
11274 } else
11275 Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11276 }
11277
11278 return groupQuotaMap;
11279}
11280
11281////////////////////////////////////////////////////////////////////////////////
11282/// shows the quota and usage of all groups
11283/// if opt contains "U" shows also distribution of usage on user-level
11284
11286{
11287 if (fProtocol < 15) {
11288 Info("ShowDataSetQuota",
11289 "functionality not available: the server does not have dataset support");
11290 return;
11291 }
11292
11293 if (IsLite()) {
11294 Info("UploadDataSet", "Lite-session: functionality not implemented");
11295 return;
11296 }
11297
11299 mess << Int_t(kShowQuota);
11300 mess << TString(opt?opt:"");
11301 Broadcast(mess);
11302
11303 Collect();
11304 if (fStatus != 0)
11305 Error("ShowDataSetQuota", "error receiving quota information");
11306}
11307
11308////////////////////////////////////////////////////////////////////////////////
11309/// If in active in a monitor set ready state
11310
11312{
11313 if (fCurrentMonitor)
11315}
11316
11317////////////////////////////////////////////////////////////////////////////////
11318/// Make sure that the worker identified by the ordinal number 'ord' is
11319/// in the active list. The request will be forwarded to the master
11320/// in direct contact with the worker. If needed, this master will move
11321/// the worker from the inactive to the active list and rebuild the list
11322/// of unique workers.
11323/// Use ord = "*" to activate all inactive workers.
11324/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11325/// status of which will be modified at once.
11326/// Return <0 if something went wrong (-2 if at least one worker was not found)
11327/// or the number of workers with status change (on master; 0 on client).
11328
11330{
11331 return ModifyWorkerLists(ord, kTRUE, save);
11332}
11333
11334////////////////////////////////////////////////////////////////////////////////
11335/// Remove the worker identified by the ordinal number 'ord' from the
11336/// the active list. The request will be forwarded to the master
11337/// in direct contact with the worker. If needed, this master will move
11338/// the worker from the active to the inactive list and rebuild the list
11339/// of unique workers.
11340/// Use ord = "*" to deactivate all active workers.
11341/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11342/// status of which will be modified at once.
11343/// Return <0 if something went wrong (-2 if at least one worker was not found)
11344/// or the number of workers with status change (on master; 0 on client).
11345
11347{
11348 return ModifyWorkerLists(ord, kFALSE, save);
11349}
11350
11351////////////////////////////////////////////////////////////////////////////////
11352/// Modify the worker active/inactive list by making the worker identified by
11353/// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11354/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11355/// status of which will be modified at once.
11356/// If needed, the request will be forwarded to the master in direct contact
11357/// with the worker. The end-master will move the worker from one list to the
11358/// other active and rebuild the list of unique active workers.
11359/// Use ord = "*" to deactivate all active workers.
11360/// If save is TRUE the current active list is saved before any modification is
11361/// done; re-running with ord = "restore" restores the saved list
11362/// Return <0 if something went wrong (-2 if at least one worker was not found)
11363/// or the number of workers with status change (on master; 0 on client).
11364
11366{
11367 // Make sure the input make sense
11368 if (!ord || strlen(ord) <= 0) {
11369 Info("ModifyWorkerLists",
11370 "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11371 return -1;
11372 }
11373 if (gDebug > 0)
11374 Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11375
11376 Int_t nwc = 0;
11377 Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11378 if (IsEndMaster()) {
11379 if (restoring) {
11380 // We are asked to restore the previous settings
11381 nwc = RestoreActiveList();
11382 } else {
11383 if (save) SaveActiveList();
11384 }
11385 }
11386
11387 Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11388
11389 // Check if this is for us
11391 if (!allord &&
11392 strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11393 return 0;
11394 }
11395
11396 Bool_t fw = kTRUE; // Whether to forward one step down
11397 Bool_t rs = kFALSE; // Whether to rescan for unique workers
11398
11399 // Appropriate list pointing
11400 TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11401 TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11402
11403 if (IsEndMaster() && !restoring) {
11404 // Create the hash list of ordinal numbers
11405 THashList *ords = 0;
11406 if (!allord) {
11407 ords = new THashList();
11408 const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
11409 TString oo(ord), o;
11410 Int_t from = 0;
11411 while(oo.Tokenize(o, from, ","))
11412 if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
11413 }
11414 // We do not need to send forward
11415 fw = kFALSE;
11416 // Look for the worker in the initial list
11417 TObject *os = 0;
11418 TSlave *wrk = 0;
11419 if (in->GetSize() > 0) {
11420 TIter nxw(in);
11421 while ((wrk = (TSlave *) nxw())) {
11422 os = 0;
11423 if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
11424 // Add it to the final list
11425 if (!out->FindObject(wrk)) {
11426 out->Add(wrk);
11427 if (add)
11428 fActiveMonitor->Add(wrk->GetSocket());
11429 }
11430 // Remove it from the initial list
11431 in->Remove(wrk);
11432 if (!add) {
11435 } else
11437 // Count
11438 nwc++;
11439 // Nothing to forward (ord is unique)
11440 fw = kFALSE;
11441 // Rescan for unique workers (active list modified)
11442 rs = kTRUE;
11443 // We may be done, if not option 'all'
11444 if (!allord && ords) {
11445 if (os) ords->Remove(os);
11446 if (ords->GetSize() == 0) break;
11447 SafeDelete(os);
11448 }
11449 }
11450 }
11451 }
11452 // If some worker not found, notify it if at the end
11453 if (!fw && ords && ords->GetSize() > 0) {
11454 TString oo;
11455 TIter nxo(ords);
11456 while ((os = nxo())) {
11457 TIter nxw(out);
11458 while ((wrk = (TSlave *) nxw()))
11459 if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
11460 if (!wrk) {
11461 if (!oo.IsNull()) oo += ",";
11462 oo += os->GetName();
11463 }
11464 }
11465 if (!oo.IsNull()) {
11466 Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
11467 nwc = -2;
11468 }
11469 }
11470 // Cleanup hash list
11471 if (ords) {
11472 ords->Delete();
11473 SafeDelete(ords);
11474 }
11475 }
11476
11477 // Rescan for unique workers
11478 if (rs)
11480
11481 // Forward the request one step down, if needed
11482 Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
11483 if (fw) {
11484 if (fProtocol > 32) {
11486 mess << action << TString(ord);
11487 Broadcast(mess);
11489 if (fStatus != 0) {
11490 nwc = (fStatus < nwc) ? fStatus : nwc;
11491 if (fStatus == -2) {
11492 if (gDebug > 0)
11493 Warning("ModifyWorkerLists", "request not completely full filled");
11494 } else {
11495 Error("ModifyWorkerLists", "request failed");
11496 }
11497 }
11498 } else {
11499 TString oo(ord), o;
11500 if (oo.Contains(","))
11501 Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
11502 Int_t from = 0;
11503 while(oo.Tokenize(o, from, ",")) {
11505 mess << action << o;
11506 Broadcast(mess);
11508 }
11509 }
11510 }
11511 // Done
11512 return nwc;
11513}
11514
11515////////////////////////////////////////////////////////////////////////////////
11516/// Save current list of active workers
11517
11519{
11521 if (fInactiveSlaves->GetSize() == 0) {
11522 fActiveSlavesSaved = "*";
11523 } else {
11524 TIter nxw(fActiveSlaves);
11525 TSlave *wk = 0;
11526 while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
11527 }
11528}
11529
11530////////////////////////////////////////////////////////////////////////////////
11531/// Restore saved list of active workers
11532
11534{
11535 // Clear the current active list
11537 // Restore the previous active list
11540
11541 return 0;
11542}
11543
11544////////////////////////////////////////////////////////////////////////////////
11545/// Start a PROOF session on a specific cluster. If cluster is 0 (the
11546/// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
11547/// If cluster is "lite://" we start a PROOF-lite session.
11548/// If cluster is "" (empty string) then we connect to the cluster specified
11549/// by 'Proof.LocalDefault', defaulting to "lite://".
11550/// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
11551/// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
11552/// Via conffile a specific PROOF config file in the confir directory can be specified.
11553/// Use loglevel to set the default loging level for debugging.
11554/// The appropriate instance of TProofMgr is created, if not
11555/// yet existing. The instantiated TProof object is returned.
11556/// Use TProof::cd() to switch between PROOF sessions.
11557/// For more info on PROOF see the TProof ctor.
11558
11559TProof *TProof::Open(const char *cluster, const char *conffile,
11560 const char *confdir, Int_t loglevel)
11561{
11562 const char *pn = "TProof::Open";
11563
11564 // Make sure libProof and dependents are loaded and TProof can be created,
11565 // dependents are loaded via the information in the [system].rootmap file
11566 if (!cluster) {
11567
11568 TPluginManager *pm = gROOT->GetPluginManager();
11569 if (!pm) {
11570 ::Error(pn, "plugin manager not found");
11571 return 0;
11572 }
11573
11574 if (gROOT->IsBatch()) {
11575 ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
11576 return 0;
11577 }
11578 // start PROOF Session Viewer
11579 TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
11580 if (!sv) {
11581 ::Error(pn, "no plugin found for TSessionViewer");
11582 return 0;
11583 }
11584 if (sv->LoadPlugin() == -1) {
11585 ::Error(pn, "plugin for TSessionViewer could not be loaded");
11586 return 0;
11587 }
11588 sv->ExecPlugin(0);
11589 return 0;
11590
11591 } else {
11592
11593 TString clst(cluster);
11594
11595 // Check for PoD cluster
11596 if (PoDCheckUrl( &clst ) < 0) return 0;
11597
11598 if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
11599 if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
11600
11601 // Parse input URL
11602 TUrl u(clst);
11603
11604 // *** GG, 060711: this does not seem to work any more (at XrdClient level)
11605 // *** to be investigated (it is not really needed; static tunnels work).
11606 // Dynamic tunnel:
11607 // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
11608 TString opts(u.GetOptions());
11609 if (!opts.IsNull()) {
11610 Int_t it = opts.Index("tunnel=");
11611 if (it != kNPOS) {
11612 TString sport = opts(it + strlen("tunnel="), opts.Length());
11613 TString host("127.0.0.1");
11614 Int_t port = -1;
11615 Int_t ic = sport.Index(":");
11616 if (ic != kNPOS) {
11617 // Isolate the host
11618 host = sport(0, ic);
11619 sport.Remove(0, ic + 1);
11620 }
11621 if (!sport.IsDigit()) {
11622 // Remove the non digit part
11623 TRegexp re("[^0-9]");
11624 Int_t ind = sport.Index(re);
11625 if (ind != kNPOS)
11626 sport.Remove(ind);
11627 }
11628 // Set the port
11629 if (sport.IsDigit())
11630 port = sport.Atoi();
11631 if (port > 0) {
11632 // Set the relevant variables
11633 ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
11634 gEnv->SetValue("XNet.SOCKS4Host", host);
11635 gEnv->SetValue("XNet.SOCKS4Port", port);
11636 } else {
11637 // Warn parsing problems
11638 ::Warning("TProof::Open",
11639 "problems parsing tunnelling info from options: %s", opts.Data());
11640 }
11641 }
11642 }
11643
11644 // Find out if we are required to attach to a specific session
11645 Int_t locid = -1;
11646 Bool_t create = kFALSE;
11647 if (opts.Length() > 0) {
11648 if (opts.BeginsWith("N",TString::kIgnoreCase)) {
11649 create = kTRUE;
11650 opts.Remove(0,1);
11651 u.SetOptions(opts);
11652 } else if (opts.IsDigit()) {
11653 locid = opts.Atoi();
11654 }
11655 }
11656
11657 // Attach-to or create the appropriate manager
11659
11660 TProof *proof = 0;
11661 if (mgr && mgr->IsValid()) {
11662
11663 // If XProofd we always attempt an attach first (unless
11664 // explicitly not requested).
11665 Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
11666 if (attach) {
11667 TProofDesc *d = 0;
11668 if (locid < 0)
11669 // Get the list of sessions
11670 d = (TProofDesc *) mgr->QuerySessions("")->First();
11671 else
11672 d = (TProofDesc *) mgr->GetProofDesc(locid);
11673 if (d) {
11674 proof = (TProof*) mgr->AttachSession(d);
11675 if (!proof || !proof->IsValid()) {
11676 if (locid)
11677 ::Error(pn, "new session could not be attached");
11678 SafeDelete(proof);
11679 }
11680 }
11681 }
11682
11683 // start the PROOF session
11684 if (!proof) {
11685 proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
11686 if (!proof || !proof->IsValid()) {
11687 ::Error(pn, "new session could not be created");
11688 SafeDelete(proof);
11689 }
11690 }
11691 }
11692 return proof;
11693 }
11694}
11695
11696////////////////////////////////////////////////////////////////////////////////
11697/// Get instance of the effective manager for 'url'
11698/// Return 0 on failure.
11699
11700TProofMgr *TProof::Mgr(const char *url)
11701{
11702 if (!url)
11703 return (TProofMgr *)0;
11704
11705 // Attach or create the relevant instance
11706 return TProofMgr::Create(url);
11707}
11708
11709////////////////////////////////////////////////////////////////////////////////
11710/// Wrapper around TProofMgr::Reset(...).
11711
11712void TProof::Reset(const char *url, Bool_t hard)
11713{
11714 if (url) {
11715 TProofMgr *mgr = TProof::Mgr(url);
11716 if (mgr && mgr->IsValid())
11717 mgr->Reset(hard);
11718 else
11719 ::Error("TProof::Reset",
11720 "unable to initialize a valid manager instance");
11721 }
11722}
11723
11724////////////////////////////////////////////////////////////////////////////////
11725/// Get environemnt variables.
11726
11728{
11729 return fgProofEnvList;
11730}
11731
11732////////////////////////////////////////////////////////////////////////////////
11733/// Add an variable to the list of environment variables passed to proofserv
11734/// on the master and slaves
11735
11736void TProof::AddEnvVar(const char *name, const char *value)
11737{
11738 if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
11739
11740 if (fgProofEnvList == 0) {
11741 // initialize the list if needed
11742 fgProofEnvList = new TList;
11744 } else {
11745 // replace old entries with the same name
11747 if (o != 0) {
11749 }
11750 }
11751 fgProofEnvList->Add(new TNamed(name, value));
11752}
11753
11754////////////////////////////////////////////////////////////////////////////////
11755/// Remove an variable from the list of environment variables passed to proofserv
11756/// on the master and slaves
11757
11758void TProof::DelEnvVar(const char *name)
11759{
11760 if (fgProofEnvList == 0) return;
11761
11763 if (o != 0) {
11765 }
11766}
11767
11768////////////////////////////////////////////////////////////////////////////////
11769/// Clear the list of environment variables passed to proofserv
11770/// on the master and slaves
11771
11773{
11774 if (fgProofEnvList == 0) return;
11775
11777}
11778
11779////////////////////////////////////////////////////////////////////////////////
11780/// Save information about the worker set in the file .workers in the working
11781/// dir. Called each time there is a change in the worker setup, e.g. by
11782/// TProof::MarkBad().
11783
11785{
11786 // We must be masters
11788 return;
11789
11790 // We must have a server defined
11791 if (!gProofServ) {
11792 Error("SaveWorkerInfo","gProofServ undefined");
11793 return;
11794 }
11795
11796 // The relevant lists must be defined
11797 if (!fSlaves && !fBadSlaves) {
11798 Warning("SaveWorkerInfo","all relevant worker lists is undefined");
11799 return;
11800 }
11801
11802 // Create or truncate the file first
11803 TString fnwrk = TString::Format("%s/.workers",
11805 FILE *fwrk = fopen(fnwrk.Data(),"w");
11806 if (!fwrk) {
11807 Error("SaveWorkerInfo",
11808 "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
11809 return;
11810 }
11811
11812 // Do we need to register an additional line for another log?
11813 TString addlogext;
11814 TString addLogTag;
11815 if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
11816 addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
11817 TPMERegexp reLogTag("^__(.*)__\\.log"); // $
11818 if (reLogTag.Match(addlogext) == 2) {
11819 addLogTag = reLogTag[1];
11820 }
11821 else {
11822 addLogTag = "+++";
11823 }
11824 if (gDebug > 0)
11825 Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
11826 }
11827
11828 // Used to eliminate datetime and PID from workdir to obtain log file name
11829 TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
11830
11831 // Loop over the list of workers (active is any worker not flagged as bad)
11832 TIter nxa(fSlaves);
11833 TSlave *wrk = 0;
11834 TString logfile;
11835 while ((wrk = (TSlave *) nxa())) {
11836 Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
11837 logfile = wrk->GetWorkDir();
11838 if (re.Match(logfile) == 2) logfile = re[1];
11839 else continue; // invalid (should not happen)
11840 // Write out record for this worker
11841 fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
11842 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11843 wrk->GetOrdinal(), logfile.Data());
11844 // Additional line, if required
11845 if (addlogext.Length() > 0) {
11846 fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
11847 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11848 wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
11849 }
11850
11851 }
11852
11853 // Loop also over the list of bad workers (if they failed to startup they are not in
11854 // the overall list
11855 TIter nxb(fBadSlaves);
11856 while ((wrk = (TSlave *) nxb())) {
11857 logfile = wrk->GetWorkDir();
11858 if (re.Match(logfile) == 2) logfile = re[1];
11859 else continue; // invalid (should not happen)
11860 if (!fSlaves->FindObject(wrk)) {
11861 // Write out record for this worker
11862 fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
11863 wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
11864 wrk->GetOrdinal(), logfile.Data());
11865 }
11866 }
11867
11868 // Eventually loop over the list of gracefully terminated workers: we'll get
11869 // logfiles from those workers as well. They'll be shown with a special
11870 // status of "2"
11872 TSlaveInfo *sli;
11873 while (( sli = (TSlaveInfo *)nxt() )) {
11874 logfile = sli->GetDataDir();
11875 if (re.Match(logfile) == 2) logfile = re[1];
11876 else continue; // invalid (should not happen)
11877 fprintf(fwrk, "%s 2 %s %s.log\n",
11878 sli->GetName(), sli->GetOrdinal(), logfile.Data());
11879 // Additional line, if required
11880 if (addlogext.Length() > 0) {
11881 fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
11882 sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
11883 logfile.Data(), addlogext.Data());
11884 }
11885 }
11886
11887 // Close file
11888 fclose(fwrk);
11889
11890 // We are done
11891 return;
11892}
11893
11894////////////////////////////////////////////////////////////////////////////////
11895/// Get the value from the specified parameter from the specified collection.
11896/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11897/// or value type does not match), 0 otherwise.
11898
11900{
11901 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11902 if (obj) {
11903 TNamed *p = dynamic_cast<TNamed*>(obj);
11904 if (p) {
11905 value = p->GetTitle();
11906 return 0;
11907 }
11908 }
11909 return -1;
11910
11911}
11912
11913////////////////////////////////////////////////////////////////////////////////
11914/// Get the value from the specified parameter from the specified collection.
11915/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11916/// or value type does not match), 0 otherwise.
11917
11919{
11920 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11921 if (obj) {
11922 TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
11923 if (p) {
11924 value = p->GetVal();
11925 return 0;
11926 }
11927 }
11928 return -1;
11929}
11930
11931////////////////////////////////////////////////////////////////////////////////
11932/// Get the value from the specified parameter from the specified collection.
11933/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11934/// or value type does not match), 0 otherwise.
11935
11937{
11938 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11939 if (obj) {
11940 TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
11941 if (p) {
11942 value = p->GetVal();
11943 return 0;
11944 }
11945 }
11946 return -1;
11947}
11948
11949////////////////////////////////////////////////////////////////////////////////
11950/// Get the value from the specified parameter from the specified collection.
11951/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11952/// or value type does not match), 0 otherwise.
11953
11955{
11956 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11957 if (obj) {
11958 TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
11959 if (p) {
11960 value = p->GetVal();
11961 return 0;
11962 }
11963 }
11964 return -1;
11965}
11966
11967////////////////////////////////////////////////////////////////////////////////
11968/// Get the value from the specified parameter from the specified collection.
11969/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11970/// or value type does not match), 0 otherwise.
11971
11973{
11974 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11975 if (obj) {
11976 TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
11977 if (p) {
11978 value = p->GetVal();
11979 return 0;
11980 }
11981 }
11982 return -1;
11983}
11984
11985////////////////////////////////////////////////////////////////////////////////
11986/// Make sure that dataset is in the form to be processed. This may mean
11987/// retrieving the relevant info from the dataset manager or from the
11988/// attached input list.
11989/// Returns 0 on success, -1 on error
11990
11992 TDataSetManager *mgr, TString &emsg)
11993{
11994 emsg = "";
11995
11996 // We must have something to process
11997 if (!dset || !input || !mgr) {
11998 emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
11999 return -1;
12000 }
12001
12002 TList *datasets = new TList;
12003 TFileCollection *dataset = 0;
12004 TString lookupopt;
12005 TString dsname(dset->GetName());
12006
12007 // First extract the "entry list" part on the global name, if any
12008 TString dsns(dsname), enlname;
12009 Ssiz_t eli = dsns.Index("?enl=");
12010 if (eli != kNPOS) {
12011 enlname = dsns(eli + strlen("?enl="), dsns.Length());
12012 dsns.Remove(eli, dsns.Length()-eli);
12013 }
12014
12015 // The dataset maybe in the form of a TFileCollection in the input list
12016 if (dsname.BeginsWith("TFileCollection:")) {
12017 // Isolate the real name
12018 dsname.ReplaceAll("TFileCollection:", "");
12019 // Get the object
12020 dataset = (TFileCollection *) input->FindObject(dsname);
12021 if (!dataset) {
12022 emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12023 return -1;
12024 }
12025 // Remove from everywhere
12026 input->RecursiveRemove(dataset);
12027 // Add it to the local list
12028 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12029 // Make sure we lookup everything (unless the client or the administrator
12030 // required something else)
12031 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12032 lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12033 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12034 }
12035 }
12036
12037 // This is the name we parse for additional specifications, such directory
12038 // and object name; for multiple datasets we assume that the directory and
12039 // and object name are the same for all datasets
12040 TString dsnparse;
12041 // The received message included an empty dataset, with only the name
12042 // defined: assume that a dataset, stored on the PROOF master by that
12043 // name, should be processed.
12044 if (!dataset) {
12045
12046 TFileCollection *fc = nullptr;
12047
12048 // Check if the entry list and dataset name are valid. If they have spaces,
12049 // commas, or pipes, they are not considered as valid and we revert to the
12050 // "multiple datasets" case
12051 TRegexp rg("[, |]");
12052 Bool_t validEnl = (enlname.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12053 Bool_t validSdsn = (dsns.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12054
12055 if (validEnl && validSdsn && (( fc = mgr->GetDataSet(dsns) ))) {
12056
12057 //
12058 // String corresponds to ONE dataset only
12059 //
12060
12061 TIter nxfi(fc->GetList());
12062 TFileInfo *fi;
12063 while (( fi = (TFileInfo *)nxfi() ))
12064 fi->SetTitle(dsns.Data());
12065 dataset = fc;
12066 dsnparse = dsns; // without entry list
12067
12068 // Adds the entry list (or empty string if not specified)
12069 datasets->Add( new TPair(dataset, new TObjString( enlname.Data() )) );
12070
12071 } else {
12072
12073 //
12074 // String does NOT correspond to one dataset: check if many datasets
12075 // were specified instead
12076 //
12077
12078 dsns = dsname.Data();
12079 TString dsn1;
12080 Int_t from1 = 0;
12081 while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12082 TString dsn2;
12083 Int_t from2 = 0;
12084 while (dsn1.Tokenize(dsn2, from2, "|")) {
12085 enlname = "";
12086 Int_t ienl = dsn2.Index("?enl=");
12087 if (ienl != kNPOS) {
12088 enlname = dsn2(ienl + 5, dsn2.Length());
12089 dsn2.Remove(ienl);
12090 }
12091 if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12092 // Save dataset name in TFileInfo's title to use it in TDset
12093 TIter nxfi(fc->GetList());
12094 TFileInfo *fi;
12095 while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12096 dsnparse = dsn2;
12097 if (!dataset) {
12098 // This is our dataset
12099 dataset = fc;
12100 } else {
12101 // Add it to the dataset
12102 dataset->Add(fc);
12103 SafeDelete(fc);
12104 }
12105 }
12106 }
12107 // The dataset name(s) in the first element
12108 if (dataset) {
12109 if (dataset->GetList()->First())
12110 ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12111 // Add it to the local list
12112 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12113 }
12114 // Reset the pointer
12115 dataset = 0;
12116 }
12117
12118 }
12119
12120 //
12121 // At this point the dataset(s) to be processed, if any, are found in the
12122 // "datasets" variable
12123 //
12124
12125 if (!datasets || datasets->GetSize() <= 0) {
12126 emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12127 return -1;
12128 } else {
12129 // Make 'dataset' to point to the first one in the list
12130 if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12131 emsg.Form("dataset pointer is null: corruption? - aborting");
12132 return -1;
12133 }
12134 }
12135 // Apply the lookup option requested by the client or the administartor
12136 // (by default we trust the information in the dataset)
12137 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12138 lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12139 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12140 }
12141 } else {
12142 // We were given a named, single, TFileCollection
12143 dsnparse = dsname;
12144 }
12145
12146 // Logic for the subdir/obj names: try first to see if the dataset name contains
12147 // some info; if not check the settings in the TDSet object itself; if still empty
12148 // check the default tree name / path in the TFileCollection object; if still empty
12149 // use the default as the flow will determine
12150 TString dsTree;
12151 // Get the [subdir/]tree, if any
12152 mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12153 if (dsTree.IsNull()) {
12154 // Use what we have in the original dataset; we need this to locate the
12155 // meta data information
12156 dsTree += dset->GetDirectory();
12157 dsTree += dset->GetObjName();
12158 }
12159 if (!dsTree.IsNull() && dsTree != "/") {
12160 TString tree(dsTree);
12161 Int_t idx = tree.Index("/");
12162 if (idx != kNPOS) {
12163 TString dir = tree(0, idx+1);
12164 tree.Remove(0, idx);
12165 dset->SetDirectory(dir);
12166 }
12167 dset->SetObjName(tree);
12168 } else {
12169 // Use the default obj name from the TFileCollection
12170 dsTree = dataset->GetDefaultTreeName();
12171 }
12172
12173 // Pass dataset server mapping instructions, if any
12175 TList *srvmapslist = srvmapsref;
12176 TString srvmaps;
12177 if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12178 srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12179 if (gProofServ) {
12180 TString msg;
12181 if (srvmapsref && !srvmapslist) {
12182 msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12183 } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12184 msg.Form("+++ Info: dataset server mapping(s) modified by user");
12185 } else if (!srvmapsref && srvmapslist) {
12186 msg.Form("+++ Info: dataset server mapping(s) added by user");
12187 }
12189 }
12190 }
12191
12192 // Flag multi-datasets
12193 if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12194 // Loop over the list of datasets
12195 TList *listOfMissingFiles = new TList;
12196 TEntryList *entrylist = 0;
12197 TPair *pair = 0;
12198 TIter nxds(datasets);
12199 while ((pair = (TPair *) nxds())) {
12200 // File Collection
12201 dataset = (TFileCollection *) pair->Key();
12202 // Entry list, if any
12203 TEntryList *enl = 0;
12204 TObjString *os = (TObjString *) pair->Value();
12205 if (strlen(os->GetName())) {
12206 if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12207 if (gProofServ)
12209 " entry list %s not found", os->GetName()));
12210 }
12211 if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12212 if (gProofServ)
12214 " no sub-lists in entry-list!"));
12215 }
12216 }
12217 TList *missingFiles = new TList;
12218 TSeqCollection* files = dataset->GetList();
12219 if (gDebug > 0) files->Print();
12220 Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12221 if (dset->TestBit(TDSet::kMultiDSet)) {
12222 TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12223 ds->SetSrvMaps(srvmapslist);
12224 if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12225 emsg.Form("error integrating dataset %s", dataset->GetName());
12226 continue;
12227 }
12228 // Add the TDSet object to the multi-dataset
12229 dset->Add(ds);
12230 // Add entry list if any
12231 if (enl) ds->SetEntryList(enl);
12232 } else {
12233 dset->SetSrvMaps(srvmapslist);
12234 if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12235 emsg.Form("error integrating dataset %s", dataset->GetName());
12236 continue;
12237 }
12238 if (enl) entrylist = enl;
12239 }
12240 if (missingFiles) {
12241 // The missing files objects have to be removed from the dataset
12242 // before delete.
12243 TIter next(missingFiles);
12244 TObject *file;
12245 while ((file = next())) {
12246 dataset->GetList()->Remove(file);
12247 listOfMissingFiles->Add(file);
12248 }
12249 missingFiles->SetOwner(kFALSE);
12250 missingFiles->Clear();
12251 }
12252 SafeDelete(missingFiles);
12253 }
12254 // Cleanup; we need to do this because pairs do no delete their content
12255 nxds.Reset();
12256 while ((pair = (TPair *) nxds())) {
12257 if (pair->Key()) delete pair->Key();
12258 if (pair->Value()) delete pair->Value();
12259 }
12260 datasets->SetOwner(kTRUE);
12261 SafeDelete(datasets);
12262
12263 // Cleanup the server mapping list, if created by the user
12264 if (srvmapslist && srvmapslist != srvmapsref) {
12265 srvmapslist->SetOwner(kTRUE);
12266 SafeDelete(srvmapslist);
12267 }
12268
12269 // Set the global entrylist, if required
12270 if (entrylist) dset->SetEntryList(entrylist);
12271
12272 // Make sure it will be sent back merged with other similar lists created
12273 // during processing; this list will be transferred by the player to the
12274 // output list, once the latter has been created (see TProofPlayerRemote::Process)
12275 if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12276 listOfMissingFiles->SetName("MissingFiles");
12277 input->Add(listOfMissingFiles);
12278 }
12279
12280 // Done
12281 return 0;
12282}
12283
12284////////////////////////////////////////////////////////////////////////////////
12285/// Save input data file from 'cachedir' into the sandbox or create a the file
12286/// with input data objects
12287
12288Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12289{
12290 TList *input = 0;
12291
12292 // We must have got something to process
12293 if (!qr || !(input = qr->GetInputList()) ||
12294 !cachedir || strlen(cachedir) <= 0) return 0;
12295
12296 // There must be some input data or input data file
12297 TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12298 TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12299 if (!data && !inputdata) return 0;
12300 // Default dstination filename
12301 if (!data)
12302 input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12303
12304 TString dstname(data->GetTitle()), srcname;
12305 Bool_t fromcache = kFALSE;
12306 if (dstname.BeginsWith("cache:")) {
12307 fromcache = kTRUE;
12308 dstname.ReplaceAll("cache:", "");
12309 srcname.Form("%s/%s", cachedir, dstname.Data());
12310 if (gSystem->AccessPathName(srcname)) {
12311 emsg.Form("input data file not found in cache (%s)", srcname.Data());
12312 return -1;
12313 }
12314 }
12315
12316 // If from cache, just move the cache file
12317 if (fromcache) {
12318 if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12319 emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12320 return -1;
12321 }
12322 } else {
12323 // Create the file
12324 if (inputdata && inputdata->GetSize() > 0) {
12325 TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12326 if (f) {
12327 f->cd();
12328 inputdata->Write();
12329 f->Close();
12330 delete f;
12331 } else {
12332 emsg.Form("could not create %s", dstname.Data());
12333 return -1;
12334 }
12335 } else {
12336 emsg.Form("no input data!");
12337 return -1;
12338 }
12339 }
12340 ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12341
12342 // Save the file name and clean up the data list
12343 data->SetTitle(dstname);
12344 if (inputdata) {
12345 input->Remove(inputdata);
12346 inputdata->SetOwner();
12347 delete inputdata;
12348 }
12349
12350 // Done
12351 return 0;
12352}
12353
12354////////////////////////////////////////////////////////////////////////////////
12355/// Send the input data file to the workers
12356
12358{
12359 TList *input = 0;
12360
12361 // We must have got something to process
12362 if (!qr || !(input = qr->GetInputList())) return 0;
12363
12364 // There must be some input data or input data file
12365 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12366 if (!inputdata) return 0;
12367
12368 TString fname(inputdata->GetTitle());
12369 if (gSystem->AccessPathName(fname)) {
12370 emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12371 return -1;
12372 }
12373
12374 // PROOF session must available
12375 if (!p || !p->IsValid()) {
12376 emsg.Form("TProof object undefined or invalid: protocol error!");
12377 return -1;
12378 }
12379
12380 // Send to unique workers and submasters
12381 p->BroadcastFile(fname, TProof::kBinary, "cache");
12382
12383 // Done
12384 return 0;
12385}
12386
12387////////////////////////////////////////////////////////////////////////////////
12388/// Get the input data from the file defined in the input list
12389
12390Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12391{
12392 // We must have got something to process
12393 if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12394
12395 // There must be some input data or input data file
12396 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12397 if (!inputdata) return 0;
12398
12399 TString fname;
12400 fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12401 if (gSystem->AccessPathName(fname)) {
12402 emsg.Form("input data file not found in cache (%s)", fname.Data());
12403 return -1;
12404 }
12405
12406 // List of added objects (for proper cleaning ...)
12407 TList *added = new TList;
12408 added->SetName("PROOF_InputObjsFromFile");
12409 // Read the input data into the input list
12410 TFile *f = TFile::Open(fname.Data());
12411 if (f) {
12412 TList *keys = (TList *) f->GetListOfKeys();
12413 if (!keys) {
12414 emsg.Form("could not get list of object keys from file");
12415 return -1;
12416 }
12417 TIter nxk(keys);
12418 TKey *k = 0;
12419 while ((k = (TKey *)nxk())) {
12420 TObject *o = f->Get(k->GetName());
12421 if (o) {
12422 input->Add(o);
12423 added->Add(o);
12424 }
12425 }
12426 // Add the file as last one
12427 if (added->GetSize() > 0) {
12428 added->Add(f);
12429 input->Add(added);
12430 } else {
12431 // Cleanup the file now
12432 f->Close();
12433 delete f;
12434 }
12435 } else {
12436 emsg.Form("could not open %s", fname.Data());
12437 return -1;
12438 }
12439
12440 // Done
12441 return 0;
12442}
12443
12444////////////////////////////////////////////////////////////////////////////////
12445/// Start the log viewer window usign the plugin manager
12446
12447void TProof::LogViewer(const char *url, Int_t idx)
12448{
12449 if (!gROOT->IsBatch()) {
12450 // Get the handler, if not yet done
12451 if (!fgLogViewer) {
12452 if ((fgLogViewer =
12453 gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
12454 if (fgLogViewer->LoadPlugin() == -1) {
12455 fgLogViewer = 0;
12456 ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
12457 return;
12458 }
12459 }
12460 }
12461 if (fgLogViewer) {
12462 // Execute the plug-in
12463 TString u = (url && strlen(url) <= 0) ? "lite" : url;
12464 fgLogViewer->ExecPlugin(2, u.Data(), idx);
12465 }
12466 } else {
12467 if (url && strlen(url) > 0) {
12468 ::Info("TProof::LogViewer",
12469 "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
12470 } else if (url && strlen(url) <= 0) {
12471 ::Info("TProof::LogViewer",
12472 "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
12473 } else {
12474 ::Info("TProof::LogViewer",
12475 "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
12476 }
12477 }
12478 // Done
12479 return;
12480}
12481
12482////////////////////////////////////////////////////////////////////////////////
12483/// Enable/Disable the graphic progress dialog.
12484/// By default the dialog is enabled
12485
12487{
12488 if (on)
12490 else
12492}
12493
12494////////////////////////////////////////////////////////////////////////////////
12495/// Show information about missing files during query described by 'qr' or the
12496/// last query if qr is null (default).
12497/// A short summary is printed in the end.
12498
12500{
12501 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12502 if (!xqr) {
12503 Warning("ShowMissingFiles", "no (last) query found: do nothing");
12504 return;
12505 }
12506
12507 // Get the list, if any
12508 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12509 if (!missing) {
12510 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12511 return;
12512 }
12513
12514 Int_t nmf = 0, ncf = 0;
12515 Long64_t msz = 0, mszzip = 0, mev = 0;
12516 // Scan the list
12517 TFileInfo *fi = 0;
12518 TIter nxf(missing);
12519 while ((fi = (TFileInfo *) nxf())) {
12520 char status = 'M';
12521 if (fi->TestBit(TFileInfo::kCorrupted)) {
12522 ncf++;
12523 status = 'C';
12524 } else {
12525 nmf++;
12526 }
12527 TFileInfoMeta *im = fi->GetMetaData();
12528 if (im) {
12529 if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
12530 if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
12531 mev += im->GetEntries();
12532 Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
12533 } else {
12534 Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
12535 }
12536 }
12537
12538 // Final notification
12539 if (msz <= 0) msz = -1;
12540 if (mszzip <= 0) mszzip = -1;
12541 Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
12542 if (msz > 0. || mszzip > 0.) {
12543 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12544 " about %.2f%% of the total (%lld bytes, %lld zipped)",
12545 nmf, ncf, mev, xf * 100., msz, mszzip);
12546 } else {
12547 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12548 " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
12549 }
12550}
12551
12552////////////////////////////////////////////////////////////////////////////////
12553/// Get a TFileCollection with the files missing in the query described by 'qr'
12554/// or the last query if qr is null (default).
12555/// Return a null pointer if none were found, for whatever reason.
12556/// The caller is responsible for the returned object.
12557
12559{
12560 TFileCollection *fc = 0;
12561
12562 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12563 if (!xqr) {
12564 Warning("GetMissingFiles", "no (last) query found: do nothing");
12565 return fc;
12566 }
12567
12568 // Get the list, if any
12569 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12570 if (!missing) {
12571 if (gDebug > 0)
12572 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12573 return fc;
12574 }
12575
12576 // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
12577 TString fcname("unknown");
12578 TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
12579 if (ds) {
12580 fcname.Form("%s.m0", ds->GetName());
12581 Int_t j = 1;
12582 while (gDirectory->FindObject(fcname) && j < 1000)
12583 fcname.Form("%s.m%d", ds->GetName(), j++);
12584 }
12585 fc = new TFileCollection(fcname, "Missing Files");
12586 if (ds) fc->SetDefaultTreeName(ds->GetObjName());
12587 // Scan the list
12588 TFileInfo *fi = 0;
12589 TIter nxf(missing);
12590 while ((fi = (TFileInfo *) nxf())) {
12591 fc->Add((TFileInfo *) fi->Clone());
12592 }
12593 fc->Update();
12594 // Done
12595 return fc;
12596}
12597
12598////////////////////////////////////////////////////////////////////////////////
12599/// Enable/Disable saving of the performance tree
12600
12601void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
12602{
12603 if (pf && strlen(pf) > 0) {
12604 fPerfTree = pf;
12605 SetParameter("PROOF_StatsHist", "");
12606 SetParameter("PROOF_StatsTrace", "");
12607 if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
12608 Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
12609 } else {
12610 fPerfTree = "";
12611 DeleteParameters("PROOF_StatsHist");
12612 DeleteParameters("PROOF_StatsTrace");
12613 DeleteParameters("PROOF_SlaveStatsTrace");
12614 Info("SetPerfTree", "saving of the performance tree disabled");
12615 }
12616}
12617
12618////////////////////////////////////////////////////////////////////////////////
12619/// Save performance information from TPerfStats to file 'pf'.
12620/// If 'ref' is defined, do it for query 'ref'.
12621/// Return 0 on sucecss, -1 in case of any error
12622
12623Int_t TProof::SavePerfTree(const char *pf, const char *ref)
12624{
12625 if (!IsValid()) {
12626 Error("SafePerfTree", "this TProof instance is invalid!");
12627 return -1;
12628 }
12629
12630 TList *outls = GetOutputList();
12631 TString sref;
12632 if (ref && strlen(ref) > 0) {
12633 if (!fPlayer) {
12634 Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
12635 return -1;
12636 }
12638 if (!qr) {
12639 Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
12640 return -1;
12641 }
12642 outls = qr->GetOutputList();
12643 sref.Form(" for requested query '%s'", ref);
12644 }
12645 if (!outls || (outls && outls->GetSize() <= 0)) {
12646 Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
12647 return -1;
12648 }
12649
12650 TString fn = fPerfTree;
12651 if (pf && strlen(pf)) fn = pf;
12652 if (fn.IsNull()) fn = "perftree.root";
12653
12654 TFile f(fn, "RECREATE");
12655 if (f.IsZombie()) {
12656 Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
12657 } else {
12658 f.cd();
12659 TIter nxo(outls);
12660 TObject* obj = 0;
12661 while ((obj = nxo())) {
12662 TString objname(obj->GetName());
12663 if (objname.BeginsWith("PROOF_")) {
12664 // Must list the objects since other PROOF_ objects exist
12665 // besides timing objects
12666 if (objname == "PROOF_PerfStats" ||
12667 objname == "PROOF_PacketsHist" ||
12668 objname == "PROOF_EventsHist" ||
12669 objname == "PROOF_NodeHist" ||
12670 objname == "PROOF_LatencyHist" ||
12671 objname == "PROOF_ProcTimeHist" ||
12672 objname == "PROOF_CpuTimeHist")
12673 obj->Write();
12674 }
12675 }
12676 f.Close();
12677 }
12678 Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
12679
12680 // Done
12681 return 0;
12682}
void Class()
Definition: Class.C:29
@ kPROOF_VALIDATE_DSET
Definition: MessageTypes.h:70
@ kPROOF_PING
Definition: MessageTypes.h:48
@ kMESS_OK
Definition: MessageTypes.h:32
@ kPROOF_DATA_READY
Definition: MessageTypes.h:71
@ kPROOF_GETSTATS
Definition: MessageTypes.h:68
@ kPROOF_GETTREEHEADER
Definition: MessageTypes.h:66
@ kPROOF_PROGRESS
Definition: MessageTypes.h:61
@ kPROOF_QUERYLIST
Definition: MessageTypes.h:72
@ kPROOF_CHECKFILE
Definition: MessageTypes.h:53
@ kPROOF_GOASYNC
Definition: MessageTypes.h:96
@ kPROOF_PARALLEL
Definition: MessageTypes.h:55
@ kPROOF_LOGLEVEL
Definition: MessageTypes.h:44
@ kMESS_NOTOK
Definition: MessageTypes.h:33
@ kPROOF_SENDOUTPUT
Definition: MessageTypes.h:99
@ kPROOF_SESSIONTAG
Definition: MessageTypes.h:79
@ kPROOF_RETRIEVE
Definition: MessageTypes.h:73
@ kPROOF_AUTOBIN
Definition: MessageTypes.h:58
@ kPROOF_TOUCH
Definition: MessageTypes.h:94
@ kPROOF_GETOBJECT
Definition: MessageTypes.h:51
@ kMESS_OBJECT
Definition: MessageTypes.h:35
@ kPROOF_STOPPROCESS
Definition: MessageTypes.h:63
@ kPROOF_VERSARCHCOMP
Definition: MessageTypes.h:92
@ kPROOF_LOGFILE
Definition: MessageTypes.h:45
@ kPROOF_REMOVE
Definition: MessageTypes.h:75
@ kPROOF_FATAL
Definition: MessageTypes.h:43
@ kPROOF_OUTPUTOBJECT
Definition: MessageTypes.h:89
@ kPROOF_REALTIMELOG
Definition: MessageTypes.h:91
@ kPROOF_SUBMERGER
Definition: MessageTypes.h:97
@ kPROOF_QUERYSUBMITTED
Definition: MessageTypes.h:78
@ kPROOF_ARCHIVE
Definition: MessageTypes.h:74
@ kPROOF_SENDFILE
Definition: MessageTypes.h:54
@ kPROOF_ECHO
Definition: MessageTypes.h:98
@ kPROOF_GETPACKET
Definition: MessageTypes.h:52
@ kPROOF_WORKERLISTS
Definition: MessageTypes.h:87
@ kPROOF_OUTPUTLIST
Definition: MessageTypes.h:57
@ kPROOF_RESET
Definition: MessageTypes.h:50
@ kPROOF_GETPARALLEL
Definition: MessageTypes.h:69
@ kPROOF_PRINT
Definition: MessageTypes.h:49
@ kPROOF_FEEDBACK
Definition: MessageTypes.h:62
@ kPROOF_SERVERSTARTED
Definition: MessageTypes.h:82
@ kPROOF_DATASET_STATUS
Definition: MessageTypes.h:88
@ kPROOF_LIB_INC_PATH
Definition: MessageTypes.h:86
@ kPROOF_CACHE
Definition: MessageTypes.h:59
@ kPROOF_MESSAGE
Definition: MessageTypes.h:85
@ kPROOF_LOGDONE
Definition: MessageTypes.h:46
@ kPROOF_DATASETS
Definition: MessageTypes.h:83
@ kMESS_CINT
Definition: MessageTypes.h:36
@ kPROOF_ENDINIT
Definition: MessageTypes.h:93
@ kPROOF_PACKAGE_LIST
Definition: MessageTypes.h:84
@ kPROOF_SETIDLE
Definition: MessageTypes.h:77
@ kPROOF_STARTPROCESS
Definition: MessageTypes.h:76
@ kPROOF_GETSLAVEINFO
Definition: MessageTypes.h:65
@ kPROOF_MAXQUERIES
Definition: MessageTypes.h:80
@ kPROOF_CLEANUPSESSION
Definition: MessageTypes.h:81
@ kPROOF_STOP
Definition: MessageTypes.h:42
@ kPROOF_GROUPVIEW
Definition: MessageTypes.h:41
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:543
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define s1(x)
Definition: RSha256.hxx:91
#define h(i)
Definition: RSha256.hxx:106
static void retrieve(const gsl_integration_workspace *workspace, double *a, double *b, double *r, double *e)
static RooMathCoreReg dummy
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
R__EXTERN TApplication * gApplication
Definition: TApplication.h:165
const Bool_t kIterBackward
Definition: TCollection.h:41
#define gDirectory
Definition: TDirectory.h:218
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
#define R__ASSERT(e)
Definition: TError.h:96
void Error(const char *location, const char *msgfmt,...)
static unsigned int total
XFontStruct * id
Definition: TGX11.cxx:108
char name[80]
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:120
float xmin
Definition: THbookFile.cxx:93
int nentries
Definition: THbookFile.cxx:89
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
#define gInterpreter
Definition: TInterpreter.h:553
const Bool_t kSortDescending
Definition: TList.h:38
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:53
#define PDB(mask, level)
Definition: TProofDebug.h:56
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:54
R__EXTERN TProofServ * gProofServ
Definition: TProofServ.h:347
static Int_t PoDCheckUrl(TString *_cluster)
This a private API function.
Definition: TProof.cxx:344
TProof * gProof
Definition: TProof.cxx:105
const char *const kPROOF_WorkerIdleTO
Definition: TProof.h:135
const char *const kPROOF_PackDir
Definition: TProof.h:126
const char *const kPROOF_ConfFile
Definition: TProof.h:122
const char *const kPROOF_WorkDir
Definition: TProof.h:124
const Long64_t kPROOF_DynWrkPollInt_s
Definition: TProof.h:138
const char *const kPROOF_InputDataFile
Definition: TProof.h:136
const char *const kPROOF_ConfDir
Definition: TProof.h:123
const Int_t kPROOF_Protocol
Definition: TProof.h:120
const char *const kPROOF_TerminateWorker
Definition: TProof.h:134
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:59
#define gROOT
Definition: TROOT.h:414
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
@ kFileExists
Definition: TSystem.h:45
@ kReadPermission
Definition: TSystem.h:48
@ kWritePermission
Definition: TSystem.h:47
Bool_t R_ISLNK(Int_t mode)
Definition: TSystem.h:120
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:116
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
#define R__LOCKGUARD(mutex)
#define O_BINARY
Definition: civetweb.c:799
#define snprintf
Definition: civetweb.c:1540
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3728
TSignalHandler * GetSignalHandler() const
Definition: TApplication.h:106
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
virtual void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE)
Write object to I/O buffer.
Definition: TBufferIO.cxx:530
Int_t BufferSize() const
Definition: TBuffer.h:97
Int_t Length() const
Definition: TBuffer.h:99
A chain is a collection of files containing TTree objects.
Definition: TChain.h:34
Collection abstract base class.
Definition: TCollection.h:63
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void SetName(const char *name)
Definition: TCollection.h:204
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
Bool_t Contains(const char *name) const
Definition: TCollection.h:169
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
Manages an element of a TDSet.
Definition: TDSet.h:66
const char * GetObjName() const
Definition: TDSet.h:120
Long64_t GetNum() const
Definition: TDSet.h:114
const char * GetDirectory() const
Return directory where to look for object.
Definition: TDSet.cxx:253
const char * GetMsd() const
Definition: TDSet.h:117
const char * GetFileName() const
Definition: TDSet.h:111
Long64_t GetFirst() const
Definition: TDSet.h:112
This class implements a data set to be used for PROOF processing.
Definition: TDSet.h:153
virtual void SetEntryList(TObject *aList)
Set entry (or event) list for this data set.
Definition: TDSet.cxx:1894
virtual Bool_t Add(const char *file, const char *objname=0, const char *dir=0, Long64_t first=0, Long64_t num=-1, const char *msd=0)
Add file to list of files to be analyzed.
Definition: TDSet.cxx:1052
Bool_t ElementsValid()
Check if all elements are valid.
Definition: TDSet.cxx:1556
void SetSrvMaps(TList *srvmaps=0)
Set (or unset) the list for mapping servers coordinate for files.
Definition: TDSet.cxx:1172
void Validate()
Validate the TDSet by opening files.
Definition: TDSet.cxx:1590
const char * GetType() const
Definition: TDSet.h:228
TList * GetListOfElements() const
Definition: TDSet.h:231
void SetDirectory(const char *dir)
Set/change directory.
Definition: TDSet.cxx:1041
void SetObjName(const char *objname)
Set/change object name.
Definition: TDSet.cxx:1026
const char * GetDirectory() const
Definition: TDSet.h:230
const char * GetObjName() const
Definition: TDSet.h:229
@ kEmpty
Definition: TDSet.h:159
@ kMultiDSet
Definition: TDSet.h:162
virtual TFileCollection * GetDataSet(const char *uri, const char *server=0)
Utility function used in various methods for user dataset upload.
static TList * GetDataSetSrvMaps()
Static getter for server mapping list.
static TList * ParseDataSetSrvMaps(const TString &srvmaps)
Create a server mapping list from the content of 'srvmaps' Return the list (owned by the caller) or 0...
Bool_t ParseUri(const char *uri, TString *dsGroup=0, TString *dsUser=0, TString *dsName=0, TString *dsTree=0, Bool_t onlyCurrent=kFALSE, Bool_t wildcards=kFALSE)
Parses a (relative) URI that describes a DataSet on the cluster.
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Utility class to draw objects in the feedback list during queries.
Definition: TDrawFeedback.h:35
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:26
virtual TList * GetLists() const
Definition: TEntryList.h:73
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:736
Definition: TFTP.h:34
void cd(const char *dir) const
Definition: TFTP.h:113
void put(const char *file, const char *remoteName=0)
Definition: TFTP.h:111
Class that contains a list of TFileInfo's and accumulated meta data information about its entries.
THashList * GetList()
void Print(Option_t *option="") const
Prints the contents of the TFileCollection.
const char * GetDefaultTreeName() const
Returns the tree set with SetDefaultTreeName if set Returns the name of the first tree in the meta da...
Int_t Add(TFileInfo *info)
Add TFileInfo to the collection.
virtual void Remove()
Remove file event handler from system file handler list.
virtual void Add()
Add file event handler to system file handler list.
Long64_t GetZipBytes() const
Definition: TFileInfo.h:144
Long64_t GetTotBytes() const
Definition: TFileInfo.h:143
Long64_t GetEntries() const
Definition: TFileInfo.h:139
Class describing a generic file including meta information.
Definition: TFileInfo.h:38
@ kCorrupted
Definition: TFileInfo.h:58
TUrl * NextUrl()
Iterator function, start iteration by calling ResetUrl().
Definition: TFileInfo.cxx:260
TUrl * GetFirstUrl() const
Definition: TFileInfo.h:71
Int_t GetNUrls() const
Definition: TFileInfo.h:74
void ResetUrl()
Definition: TFileInfo.h:68
TUrl * GetCurrentUrl() const
Return the current url.
Definition: TFileInfo.cxx:248
TFileInfoMeta * GetMetaData(const char *meta=0) const
Get meta data object with specified name.
Definition: TFileInfo.cxx:424
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:914
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=0)
Resolve the file type as a function of the protocol field in 'name'.
Definition: TFile.cxx:4693
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1420
EFileType
File type.
Definition: TFile.h:187
@ kWeb
Definition: TFile.h:187
@ kNet
Definition: TFile.h:187
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition: TFile.cxx:4876
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3980
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:262
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:378
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:207
Int_t GetPort() const
Definition: TInetAddress.h:73
const char * GetHostName() const
Definition: TInetAddress.h:71
void Reset()
Definition: TCollection.h:252
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual const char * GetClassName() const
Definition: TKey.h:71
Iterator of linked list.
Definition: TList.h:200
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:327
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:690
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:247
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:761
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:656
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:474
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:31
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition: TMacro.cxx:139
TList * GetListOfLines() const
Definition: TMacro.h:51
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:301
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection).
Definition: TMap.cxx:53
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
Bool_t AreAllWorkersAssigned()
Return if the determined number of workers has been already assigned to this merger.
Definition: TProof.cxx:328
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job.
Definition: TProof.cxx:320
TSlave * GetMerger()
Definition: TProof.h:274
virtual ~TMergerInfo()
Destructor.
Definition: TProof.cxx:284
Int_t fWorkersToMerge
Definition: TProof.h:254
Bool_t IsActive()
Definition: TProof.h:288
TList * fWorkers
Definition: TProof.h:259
void SetMergedWorker()
Increase number of already merged workers by 1.
Definition: TProof.cxx:295
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition: TProof.cxx:306
void Deactivate()
Definition: TProof.h:287
Int_t fMergedWorkers
Definition: TProof.h:256
TList * GetWorkers()
Definition: TProof.h:272
Int_t GetPort()
Definition: TProof.h:275
void AddMergedObjects(Int_t objects)
Definition: TProof.h:282
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
UInt_t What() const
Definition: TMessage.h:75
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriory.
Definition: TMessage.cxx:221
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition: TMonitor.cxx:241
virtual void ActivateAll()
Activate all de-activated sockets.
Definition: TMonitor.cxx:268
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition: TMonitor.cxx:250
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition: TMonitor.cxx:168
void ResetInterrupt()
Definition: TMonitor.h:72
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition: TMonitor.cxx:284
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition: TMonitor.cxx:498
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
void Interrupt()
Definition: TMonitor.h:71
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TNamed()
Definition: TNamed.h:36
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Collectable string class.
Definition: TObjString.h:28
const char * GetName() const
Returns name of object.
Definition: TObjString.h: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:785
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:144
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:894
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:321
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
@ kSingleKey
write collection with single key
Definition: TObject.h:87
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:97
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition: TPRegexp.cxx:708
The PROOF package manager contains tools to manage packages.
Definition: TPackMgr.h:37
@ kDontCheck
Definition: TPackMgr.h:39
@ kCheckROOT
Definition: TPackMgr.h:39
void Show(const char *title=0)
Show available packages.
Definition: TPackMgr.cxx:548
Int_t Build(const char *pack, Int_t opt=TPackMgr::kCheckROOT)
Method to build a package.
Definition: TPackMgr.cxx:87
Int_t Install(const char *par, Bool_t rmold=kFALSE)
Install package from par (unpack the file in the directory); par can be an URL for remote retrieval.
Definition: TPackMgr.cxx:766
void ShowEnabled(const char *title=0)
Show enabled packages.
Definition: TPackMgr.cxx:662
static Int_t FindParPath(TPackMgr *packmgr, const char *pack, TString &par)
Get the full path to PAR, looking also in the global dirs.
Definition: TPackMgr.cxx:933
static Int_t RegisterGlobalPath(const char *paths)
Parse one or more paths as possible sources of packages Returns number of paths added; or -1 in case ...
Definition: TPackMgr.cxx:871
Int_t Load(const char *pack, TList *optls=0)
Method to load a package taking an option list Return -1 on error, 0 otherwise.
Definition: TPackMgr.cxx:220
Int_t Unload(const char *pack)
Method to unload a package.
Definition: TPackMgr.cxx:411
TList * GetListOfEnabled() const
Get list of enabled packages Returns a pointer to a TList object, transferring ownership to the calle...
Definition: TPackMgr.cxx:644
Int_t Remove(const char *pack=0, Bool_t dolock=kTRUE)
Remove package 'pack' If 'pack' is null or empty all packages are cleared.
Definition: TPackMgr.cxx:593
TMD5 * ReadMD5(const char *pack)
Read MD5 checksum of the PAR file from the PROOF-INF/md5.txt file.
Definition: TPackMgr.cxx:708
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
TObject * Value() const
Definition: TMap.h:121
const char * GetName() const
Returns name of object.
Definition: TMap.h:116
TObject * Key() const
Definition: TMap.h:120
Named parameter, streamable and storable.
Definition: TParameter.h:37
const AParamType & GetVal() const
Definition: TParameter.h:69
const char * GetName() const
Returns name of object.
Definition: TParameter.h:68
Long_t ExecPlugin(int nargs, const T &... params)
Int_t LoadPlugin()
Load the plugin library for this handler.
This class implements a plugin library manager.
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
TProofInputHandler(const TProofInputHandler &)
TProof * fProof
Definition: TProof.h:201
Bool_t Notify()
Handle input.
Definition: TProof.cxx:166
TSocket * fSocket
Definition: TProof.h:200
Bool_t Notify()
TProof interrupt handler.
Definition: TProof.cxx:119
void IncreaseIdx()
Definition: TProof.h:311
void DecreaseNWrks()
Definition: TProof.h:309
void Reset(Int_t n=-1)
Definition: TProof.h:312
const char * Export(Bool_t &changed)
Definition: TProof.h:304
static char fgCr[4]
Definition: TProof.h:300
void IncreaseNWrks()
Definition: TProof.h:310
void SetNWrks(Int_t n)
Definition: TProof.h:313
The PROOF manager interacts with the PROOF server coordinator to create or destroy a PROOF session,...
Definition: TProofMgr.h:43
virtual Int_t Reset(Bool_t hard=kFALSE, const char *usr=0)
Send a cleanup request for the sessions associated with the current user.
Definition: TProofMgr.cxx:306
virtual TList * QuerySessions(Option_t *opt="S")
Get list of sessions accessible to this manager.
Definition: TProofMgr.cxx:228
static TProofMgr * Create(const char *url, Int_t loglevel=-1, const char *alias=0, Bool_t xpd=kTRUE)
Static method returning the appropriate TProofMgr object using the plugin manager.
Definition: TProofMgr.cxx:498
virtual Int_t Rm(const char *, const char *=0, const char *=0)
Run 'rm' on 'what'. Locally it is just a call to TSystem::Unlink .
Definition: TProofMgr.cxx:1065
virtual void Find(const char *="~/", const char *=0, const char *=0)
Definition: TProofMgr.h:113
virtual TProof * CreateSession(const char *=0, const char *=0, Int_t=-1)
Create a new remote session (master and associated workers).
Definition: TProofMgr.cxx:386
virtual Bool_t IsValid() const
Definition: TProofMgr.h:77
@ kProofLite
Definition: TProofMgr.h:46
@ kXProofd
Definition: TProofMgr.h:46
virtual Int_t GetFile(const char *, const char *, const char *=0)
Definition: TProofMgr.h:122
virtual TProof * AttachSession(Int_t, Bool_t=kFALSE)
Dummy version provided for completeness.
Definition: TProofMgr.cxx:123
virtual Bool_t IsProofd() const
Definition: TProofMgr.h:76
virtual TProofDesc * GetProofDesc(Int_t id)
Get TProofDesc instance corresponding to 'id'.
Definition: TProofMgr.cxx:324
virtual Int_t Stat(const char *, FileStat_t &, const char *=0)
Definition: TProofMgr.h:120
virtual Bool_t IsLite() const
Definition: TProofMgr.h:75
virtual void DiscardSession(TProof *p)
Discard TProofDesc of session 'p' from the internal list.
Definition: TProofMgr.cxx:366
The purpose of this class is to provide a complete node description for masters, submasters and worke...
const TString & GetMsd() const
Int_t GetNWrks() const
const TString & GetImage() const
Bool_t IsWorker() const
const TString & GetOrdinal() const
const TString & GetWorkDir() const
Int_t GetPerfIndex() const
const TString & GetNodeName() const
Int_t GetPort() const
const char * GetName() const
Returns name of object.
Class to steer the merging of files produced on the workers.
const char * GetDir(Bool_t raw=kFALSE) const
const char * GetOutputFileName() const
const char * GetFileName() const
Bool_t IsRetrieve() const
void AttachList(TList *alist)
Attach to list 'alist'.
Container class for processing statistics.
Long64_t GetEntries() const
const char * GetOrdinal() const
Definition: TProofServ.h:253
const char * GetImage() const
Definition: TProofServ.h:244
TList * GetEnabledPackages() const
Definition: TProofServ.h:267
virtual EQueryAction GetWorkers(TList *workers, Int_t &prioritychange, Bool_t resume=kFALSE)
Get list of workers to be used from now on.
virtual void ReleaseWorker(const char *)
Definition: TProofServ.h:305
const char * GetUser() const
Definition: TProofServ.h:241
void FlushLogFile()
Reposition the read pointer in the log file to the very end.
TSocket * GetSocket() const
Definition: TProofServ.h:257
const char * GetGroup() const
Definition: TProofServ.h:242
void SendAsynMessage(const char *msg, Bool_t lf=kTRUE)
Send an asychronous message to the master / client .
static void ResolveKeywords(TString &fname, const char *path=0)
Replace <ord>, <user>, , <group>, <stag>, <qnum>, <file>, <rver> and <build> placeholders in fname.
TPackMgr * GetPackMgr() const
Definition: TProofServ.h:249
void SendParallel(Bool_t async=kFALSE)
Send number of parallel nodes to master or client.
const char * GetSessionDir() const
Definition: TProofServ.h:247
const char * GetWorkDir() const
Definition: TProofServ.h:243
const char * GetPrefix() const
Definition: TProofServ.h:276
Bool_t IsTopMaster() const
Definition: TProofServ.h:295
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition: TProof.h:316
void HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
Handle lib, inc search paths modification request.
Definition: TProof.cxx:8974
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:6509
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition: TProof.cxx:1978
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7746
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition: TProof.cxx:7372
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:7044
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition: TProof.cxx:11700
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition: TProof.cxx:4430
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:2433
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:2087
TProofMgr * fManager
Definition: TProof.h:587
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition: TProof.cxx:4386
TList * GetOutputNames()
FIXME: to be written.
Definition: TProof.cxx:10094
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:6235
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition: TProof.cxx:10297
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:6334
void Activate(TList *slaves=0)
Activate slave server list.
Definition: TProof.cxx:2371
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8417
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:5208
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6734
void Close(Option_t *option="")
Close all open slave servers.
Definition: TProof.cxx:1780
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:7088
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:7918
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:8310
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:11252
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:12288
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:2147
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:7966
Bool_t IsTty() const
Definition: TProof.h:938
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4779
Int_t GetClientProtocol() const
Definition: TProof.h:914
Int_t fCollectTimeout
Definition: TProof.h:583
virtual ~TProof()
Clean up PROOF environment.
Definition: TProof.cxx:649
EQueryMode fQueryMode
Definition: TProof.h:588
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition: TProof.cxx:10207
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition: TProof.cxx:1516
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:12390
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:7030
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition: TProof.cxx:4913
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:9965
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:12447
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:716
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition: TProof.cxx:3022
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition: TProof.cxx:4399
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:2549
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:11772
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:9498
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2059
FileMap_t fFileMap
Definition: TProof.h:502
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7690
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:10872
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:11329
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition: TProof.cxx:6068
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition: TProof.cxx:11022
TList * fChains
Definition: TProof.h:496
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:9894
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:6033
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition: TProof.cxx:4310
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition: TProof.cxx:9084
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'.
Definition: TProof.cxx:2130
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition: TProof.cxx:1960
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition: TProof.cxx:9288
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:8575
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:8864
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition: TProof.cxx:10785
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:7667
void ClearFeedback()
Clear feedback list.
Definition: TProof.cxx:9988
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:11559
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition: TProof.cxx:10155
Int_t GetPort() const
Definition: TProof.h:912
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition: TProof.cxx:11311
void ResetMergePrg()
Reset the merge progress notificator.
Definition: TProof.cxx:2447
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition: TProof.cxx:12601
void ClearData(UInt_t what=kUnregistered, const char *dsname=0)
Remove files for the data directory.
Definition: TProof.cxx:7388
Bool_t IsValid() const
Definition: TProof.h:937
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4758
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:1257
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition: TProof.cxx:11092
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition: TProof.cxx:11157
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:11365
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7116
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition: TProof.cxx:7146
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:10890
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:4280
@ 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:6641
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:11736
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:6471
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition: TProof.cxx:10822
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:2651
Float_t GetCpuTime() const
Definition: TProof.h:931
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition: TProof.cxx:7646
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition: TProof.cxx:12357
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10175
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7833
Int_t SendInitialState()
Transfer the initial (i.e.
Definition: TProof.cxx:6750
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1308
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition: TProof.cxx:2017
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:10683
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition: TProof.cxx:2457
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:9909
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:9615
void InitMembers()
Default initializations.
Definition: TProof.cxx:524
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition: TProof.cxx:4234
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition: TProof.cxx:3990
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:9561
Int_t fStatus
Definition: TProof.h:470
TList * fRunningDSets
Definition: TProof.h:581
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7816
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:9798
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition: TProof.cxx:1642
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition: TProof.cxx:4720
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:1857
void SaveActiveList()
Save current list of active workers.
Definition: TProof.cxx:11518
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:10742
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:12499
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:8943
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'.
Definition: TProof.cxx:2390
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2286
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:8090
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition: TProof.cxx:9976
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition: TProof.cxx:5989
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:4329
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2004
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition: TProof.cxx:10559
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:10494
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:9116
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:749
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:6122
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:11346
@ 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:7072
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition: TProof.cxx:10472
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:12558
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning,...
Definition: TProof.cxx:1035
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition: TProof.cxx:1996
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition: TProof.cxx:5924
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:2592
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:9934
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:9312
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:10967
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition: TProof.cxx:6390
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition: TProof.cxx:11712
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition: TProof.cxx:2946
Int_t fLastAssignedMerger
Definition: TProof.h:552
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition: TProof.cxx:2121
void ShowFeedback() const
Show items in feedback list.
Definition: TProof.cxx:9996
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:7249
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition: TProof.cxx:6083
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8123
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10187
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:10986
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition: TProof.cxx:12623
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:8604
@ 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:8819
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition: TProof.cxx:510
Bool_t fDynamicStartup
Definition: TProof.h:589
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1579
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition: TProof.cxx:9177
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition: TProof.cxx:5859
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:8909
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:11285
Bool_t fIsPollingWorkers
Definition: TProof.h:475
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition: TProof.cxx:10086
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:11049
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:6775
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:7625
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition: TProof.cxx:12486
TString fLogFileName
Definition: TProof.h:511
void GoAsynchronous()
Send GOASYNC message to the master.
Definition: TProof.cxx:6243
Int_t fCheckFileStatus
Definition: TProof.h:471
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:9784
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:1289
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition: TProof.cxx:6620
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:6200
TList * GetEnabledPackages() const
Definition: TProof.h:735
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition: TProof.cxx:1969
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:1835
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition: TProof.cxx:2110
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:6870
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:11991
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:2258
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:10611
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:4497
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition: TProof.cxx:6436
Bool_t IsProofd() const
Definition: TProof.h:934
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition: TProof.cxx:11533
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:7004
void ShowLog(Int_t qry=-1)
Display on screen the content of the temporary log file.
Definition: TProof.cxx:10347
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:9514
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6607
void Feedback(TList *objs)
Get list of feedback objects.
Definition: TProof.cxx:9244
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition: TProof.cxx:10996
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:9738
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2303
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition: TProof.cxx:10018
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9356
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:10660
@ 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:1894
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:4672
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition: TProof.cxx:7711
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition: TProof.cxx:6095
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:8045
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:9275
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition: TProof.cxx:10078
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:10913
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:10070
void AddChain(TChain *chain)
Add chain to data set.
Definition: TProof.cxx:10199
static const TList * GetEnvVars()
Get environemnt variables.
Definition: TProof.cxx:11727
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition: TProof.cxx:1873
TString fGroup
Definition: TProof.h:468
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition: TProof.cxx:9100
TList * GetFeedbackList() const
Return feedback list.
Definition: TProof.cxx:10009
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:9588
TList * fEnabledPackages
Definition: TProof.h:580
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2070
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:11758
Int_t BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
Broadcast an object to all slaves in the specified list.
Definition: TProof.cxx:2525
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7055
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:5279
void ClearInput()
Clear input object list.
Definition: TProof.cxx:9718
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:1008
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7861
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition: TProof.cxx:5833
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition: TProof.cxx:1987
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition: TProof.cxx:10844
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition: TProof.cxx:10953
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition: TProof.cxx:3081
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:9710
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:6263
Bool_t IsMaster() const
Definition: TProof.h:936
void CloseProgressDialog()
Close progress dialog.
Definition: TProof.cxx:9259
TProofOutputList fOutputList
Definition: TProof.h:538
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition: TProof.cxx:4412
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition: TProof.cxx:9300
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition: TProof.cxx:10233
TList * GetInputList()
Get input list.
Definition: TProof.cxx:9729
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:2636
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7794
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition: TProof.cxx:2097
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition: TProof.cxx:10216
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition: TProof.cxx:3036
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:9345
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition: TProof.cxx:11784
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition: TProof.cxx:8151
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:2222
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:11106
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.
Definition: TQueryResult.h:36
virtual void SetOutputList(TList *out, Bool_t adopt=kTRUE)
Set / change the output list.
Long64_t GetEntries() const
Definition: TQueryResult.h:122
Int_t GetSeqNum() const
Definition: TQueryResult.h:115
void SetTermTime(Float_t termtime)
Definition: TQueryResult.h:100
void SetArchived(const char *archfile)
Set (or update) query in archived state.
TList * GetOutputList()
Definition: TQueryResult.h:131
void SetPrepTime(Float_t preptime)
Definition: TQueryResult.h:97
virtual void SetInputList(TList *in, Bool_t adopt=kTRUE)
Set / change the input list.
TObject * GetInputObject(const char *classname) const
Return first instance of class 'classname' in the input list.
void AddInput(TObject *obj)
Add obj to the input list.
TList * GetInputList()
Definition: TQueryResult.h:120
TMacro * GetLogFile() const
Definition: TQueryResult.h:126
Bool_t IsFinalized() const
Definition: TQueryResult.h:145
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2767
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition: TROOT.cxx:2793
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:541
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition: TRandom.cxx:349
Regular expression class.
Definition: TRegexp.h:31
virtual const char * AsString(TString &out)
Returns short string with relevant information about this security context.
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:33
Sequenceable collection abstract base class.
virtual void Add()
Add signal handler to system signal handler list.
virtual void Remove()
Remove signal handler from system signal handler list.
ESlaveStatus fStatus
Definition: TProof.h:222
Int_t Compare(const TObject *obj) const
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:180
TString fMsd
Definition: TProof.h:218
SysInfo_t GetSysInfo() const
Definition: TProof.h:233
TString fDataDir
Definition: TProof.h:219
Int_t fPerfIndex
Definition: TProof.h:220
void SetStatus(ESlaveStatus stat)
Definition: TProof.h:234
@ kActive
Definition: TProof.h:214
@ kNotActive
Definition: TProof.h:214
TString fOrdinal
Definition: TProof.h:216
const char * GetOrdinal() const
Definition: TProof.h:232
TString fHostName
Definition: TProof.h:217
void SetSysInfo(SysInfo_t si)
Setter for fSysInfo.
Definition: TProof.cxx:265
void SetOrdinal(const char *ord)
Definition: TProof.h:236
SysInfo_t fSysInfo
Definition: TProof.h:221
const char * GetName() const
Returns name of object.
Definition: TProof.h:231
Bool_t IsEqual(const TObject *obj) const
Used to compare slaveinfos by ordinal.
Definition: TProof.cxx:208
const char * GetDataDir() const
Definition: TProof.h:229
void Print(Option_t *option="") const
Print slave info.
Definition: TProof.cxx:222
Class describing a PROOF worker server.
Definition: TSlave.h:46
Int_t fStatus
Definition: TSlave.h:96
Int_t fParallel
Definition: TSlave.h:97
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition: TSlave.cxx:656
TString fImage
Definition: TSlave.h:80
Float_t fRealTime
Definition: TSlave.h:93
const char * GetWorkDir() const
Definition: TSlave.h:127
ESlaveType fSlaveType
Definition: TSlave.h:95
Int_t GetSlaveType() const
Definition: TSlave.h:139
Int_t GetParallel() const
Definition: TSlave.h:141
Float_t fCpuTime
Definition: TSlave.h:94
const char * GetImage() const
Definition: TSlave.h:125
void SetArchCompiler(const char *ac)
Definition: TSlave.h:158
Int_t GetPort() const
Definition: TSlave.h:130
@ kSlave
Definition: TSlave.h:55
@ kMaster
Definition: TSlave.h:55
TSocket * GetSocket() const
Definition: TSlave.h:134
@ kOutputRequested
Definition: TSlave.h:58
virtual void SetStatus(Int_t st)
Definition: TSlave.h:113
virtual void StopProcess(Bool_t abort, Int_t timeout)
Sent stop/abort request to PROOF server.
Definition: TSlave.cxx:630
virtual void FlushSocket()
Definition: TSlave.h:105
const char * GetUser() const
Definition: TSlave.h:128
TFileHandler * GetInputHandler() const
Definition: TSlave.h:144
TString fWorkDir
Definition: TSlave.h:82
const char * GetMsd() const
Definition: TSlave.h:142
@ kActive
Definition: TSlave.h:56
@ kInactive
Definition: TSlave.h:56
TString fOrdinal
Definition: TSlave.h:86
Long64_t fBytesRead
Definition: TSlave.h:92
static TSlave * Create(const char *url, const char *ord, Int_t perf, const char *image, TProof *proof, Int_t stype, const char *workdir, const char *msd, Int_t nwk=1)
Static method returning the appropriate TSlave object for the remote server.
Definition: TSlave.cxx:442
virtual void Touch()
Definition: TSlave.h:165
TString fProofWorkDir
Definition: TSlave.h:81
void SetInputHandler(TFileHandler *ih)
Adopt and register input handler for this slave.
Definition: TSlave.cxx:394
virtual void Interrupt(Int_t type)
Send interrupt OOB byte to master or slave servers.
Definition: TSlave.cxx:511
Int_t GetStatus() const
Definition: TSlave.h:140
virtual void SetInterruptHandler(Bool_t)
Definition: TSlave.h:156
virtual Int_t SetupServ(Int_t stype, const char *conffile)
Init a PROOF slave object.
Definition: TSlave.cxx:179
virtual Int_t Ping()
Ping the remote master or slave servers.
Definition: TSlave.cxx:494
virtual Int_t SendGroupPriority(const char *, Int_t)
Definition: TSlave.h:110
const char * GetName() const
Returns name of object.
Definition: TSlave.h:124
TString fName
Definition: TSlave.h:79
virtual Bool_t IsValid() const
Definition: TSlave.h:150
void SetSessionTag(const char *st)
Definition: TSlave.h:161
const char * GetOrdinal() const
Definition: TSlave.h:131
const char * GetProofWorkDir() const
Definition: TSlave.h:126
void SetROOTVersion(const char *rv)
Definition: TSlave.h:159
virtual void Close(Option_t *opt="")
Close slave socket.
Definition: TSlave.cxx:277
Int_t GetPerfIdx() const
Definition: TSlave.h:132
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:816
Int_t GetRemoteProtocol() const
Definition: TSocket.h:126
TInetAddress GetInetAddress() const
Definition: TSocket.h:113
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:619
virtual Bool_t IsValid() const
Definition: TSocket.h:132
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:521
A sorted doubly linked list.
Definition: TSortedList.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:110
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:77
void Reset()
Definition: TStopwatch.h:52
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:418
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:644
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1106
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:1987
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1791
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:499
const char * Data() const
Definition: TString.h:364
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1763
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
@ kTrailing
Definition: TString.h:262
@ kBoth
Definition: TString.h:262
@ kIgnoreCase
Definition: TString.h:263
@ kExact
Definition: TString.h:263
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:892
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Prepend(const char *cs)
Definition: TString.h:656
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3820
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:285
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1264
const char * pwd()
Definition: TSystem.h:425
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:269
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:4064
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition: TSystem.cxx:1496
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1013
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:716
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1331
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1652
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3894
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4163
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:913
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:662
virtual void SetIncludePath(const char *includePath)
IncludePath should contain the list of compiler flags to indicate where to find user defined header f...
Definition: TSystem.cxx:4099
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:671
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1388
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1286
virtual FILE * TempFileName(TString &base, const char *dir=0)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition: TSystem.cxx:1487
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:680
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:941
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:541
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1782
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:689
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:312
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1644
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:958
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1793
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:878
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1536
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2334
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:551
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1636
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3804
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1371
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1588
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1702
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1472
A TTree represents a columnar dataset.
Definition: TTree.h:71
virtual Long64_t GetMaxEntryLoop() const
Definition: TTree.h:436
This class represents a RFC 3986 compatible URI.
Definition: TUri.h:35
Bool_t SetFragment(const TString &fragment)
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:35
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
const char * GetFile() const
Definition: TUrl.h:72
void SetUser(const char *user)
Definition: TUrl.h:85
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition: TUrl.cxx:518
const char * GetUser() const
Definition: TUrl.h:68
const char * GetHost() const
Definition: TUrl.h:70
void SetOptions(const char *opt)
Definition: TUrl.h:90
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
const char * GetOptions() const
Definition: TUrl.h:74
void SetHost(const char *host)
Definition: TUrl.h:87
const char * GetProtocol() const
Definition: TUrl.h:67
void SetPort(Int_t port)
Definition: TUrl.h:91
Int_t GetPort() const
Definition: TUrl.h:81
void SetPasswd(const char *pw)
Definition: TUrl.h:86
The packetizer is a load balancing object created for each query.
virtual Int_t AddProcessed(TSlave *, TProofProgressStatus *, Double_t, TList **)
virtual void MarkBad(TSlave *, TProofProgressStatus *, TList **)
Abstract interface for the PROOF player.
virtual TDSetElement * GetNextPacket(TSlave *slave, TMessage *r)=0
virtual void AddEventsProcessed(Long64_t ev)=0
virtual void AddInput(TObject *inp)=0
virtual TQueryResult * GetCurrentQuery() const =0
virtual void AddOutput(TList *out)=0
virtual TList * GetInputList() const =0
virtual TObject * GetOutput(const char *name) const =0
virtual void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)=0
virtual void SetMaxDrawQueries(Int_t max)=0
virtual Long64_t GetEventsProcessed() const =0
virtual Long64_t DrawSelect(TDSet *set, const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual TQueryResult * GetQueryResult(const char *ref)=0
virtual void SetMerging(Bool_t on=kTRUE)=0
virtual EExitStatus GetExitStatus() const =0
virtual void Progress(Long64_t total, Long64_t processed)=0
virtual void AddQueryResult(TQueryResult *q)=0
static TVirtualProofPlayer * Create(const char *player, TProof *p, TSocket *s=0)
Create a PROOF player.
virtual void UpdateAutoBin(const char *name, Double_t &xmin, Double_t &xmax, Double_t &ymin, Double_t &ymax, Double_t &zmin, Double_t &zmax)=0
virtual Int_t AddOutputObject(TObject *obj)=0
virtual Bool_t JoinProcess(TList *workers)=0
virtual TList * GetListOfResults() const =0
virtual void ClearInput()=0
virtual void HandleRecvHisto(TMessage *mess)=0
virtual void RemoveQueryResult(const char *ref)=0
virtual void StopProcess(Bool_t abort, Int_t timeout=-1)=0
virtual Long64_t Finalize(Bool_t force=kFALSE, Bool_t sync=kFALSE)=0
virtual Long64_t Process(TDSet *set, const char *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)=0
virtual void StoreFeedback(TObject *slave, TList *out)=0
virtual TDrawFeedback * CreateDrawFeedback(TProof *p)=0
virtual TVirtualPacketizer * GetPacketizer() const
virtual void DeleteDrawFeedback(TDrawFeedback *f)=0
virtual TList * GetOutputList() const =0
virtual void SetInitTime()=0
virtual void SetCurrentQuery(TQueryResult *q)=0
TLine * line
const Int_t n
Definition: legend1.C:16
static constexpr double nm
static constexpr double s
static constexpr double pi
static constexpr double pc
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:701
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
Definition: file.py:1
Definition: first.py:1
Definition: tree.py:1
const char * cnt
Definition: TXMLSetup.cxx:74
Int_t fMode
Definition: TSystem.h:128
Bool_t fIsLink
Definition: TSystem.h:133
Int_t fCpuSpeed
Definition: TSystem.h:156
Int_t fL2Cache
Definition: TSystem.h:158
Int_t fBusSpeed
Definition: TSystem.h:157
TString fCpuType
Definition: TSystem.h:154
Int_t fCpus
Definition: TSystem.h:155
Int_t fPhysRam
Definition: TSystem.h:159
TString fOS
Definition: TSystem.h:152
TString fModel
Definition: TSystem.h:153
Long_t fModtime
Definition: TProof.h:499
TString fUser
Definition: TSystem.h:142
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12