Logo ROOT  
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 "TFTP.h"
65#include "THashList.h"
66#include "TInterpreter.h"
67#include "TKey.h"
68#include "TMap.h"
69#include "TMath.h"
70#include "TMessage.h"
71#include "TMonitor.h"
72#include "TObjArray.h"
73#include "TObjString.h"
74#include "TParameter.h"
75#include "TProof.h"
76#include "TProofNodeInfo.h"
77#include "TProofOutputFile.h"
78#include "TVirtualProofPlayer.h"
79#include "TVirtualPacketizer.h"
80#include "TProofServ.h"
81#include "TPluginManager.h"
82#include "TQueryResult.h"
83#include "TRandom.h"
84#include "TRegexp.h"
85#include "TROOT.h"
86#include "TSlave.h"
87#include "TSocket.h"
88#include "TSortedList.h"
89#include "TSystem.h"
90#include "TTree.h"
91#include "TUrl.h"
92#include "TFileCollection.h"
93#include "TDataSetManager.h"
94#include "TDataSetManagerFile.h"
95#include "TMacro.h"
96#include "TSelector.h"
97#include "TPRegexp.h"
98#include "TPackMgr.h"
99
100#include <mutex>
101
103
104// Rotating indicator
105char TProofMergePrg::fgCr[4] = {'-', '\\', '|', '/'};
106
107TList *TProof::fgProofEnvList = 0; // List of env vars for proofserv
108TPluginHandler *TProof::fgLogViewer = 0; // Log viewer handler
109
111
112//----- PROOF Interrupt signal handler -----------------------------------------
113////////////////////////////////////////////////////////////////////////////////
114/// TProof interrupt handler.
115
117{
118 if (!fProof->IsTty() || fProof->GetRemoteProtocol() < 22) {
119
120 // Cannot ask the user : abort any remote processing
122
123 } else {
124 // Real stop or request to switch to asynchronous?
125 const char *a = 0;
126 if (fProof->GetRemoteProtocol() < 22) {
127 a = Getline("\nSwitch to asynchronous mode not supported remotely:"
128 "\nEnter S/s to stop, Q/q to quit, any other key to continue: ");
129 } else {
130 a = Getline("\nEnter A/a to switch asynchronous, S/s to stop, Q/q to quit,"
131 " any other key to continue: ");
132 }
133 if (a[0] == 'Q' || a[0] == 'S' || a[0] == 'q' || a[0] == 's') {
134
135 Info("Notify","Processing interrupt signal ... %c", a[0]);
136
137 // Stop or abort any remote processing
138 Bool_t abort = (a[0] == 'Q' || a[0] == 'q') ? kTRUE : kFALSE;
139 fProof->StopProcess(abort);
140
141 } else if ((a[0] == 'A' || a[0] == 'a') && fProof->GetRemoteProtocol() >= 22) {
142 // Stop any remote processing
144 }
145 }
146
147 return kTRUE;
148}
149
150//----- Input handler for messages from TProofServ -----------------------------
151////////////////////////////////////////////////////////////////////////////////
152/// Constructor
153
155 : TFileHandler(s->GetDescriptor(),1),
156 fSocket(s), fProof(p)
157{
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Handle input
162
164{
166 return kTRUE;
167}
168
169
170//------------------------------------------------------------------------------
171
173
174////////////////////////////////////////////////////////////////////////////////
175/// Used to sort slaveinfos by ordinal.
176
178{
179 if (!obj) return 1;
180
181 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
182
183 if (!si) return fOrdinal.CompareTo(obj->GetName());
184
185 const char *myord = GetOrdinal();
186 const char *otherord = si->GetOrdinal();
187 while (myord && otherord) {
188 Int_t myval = atoi(myord);
189 Int_t otherval = atoi(otherord);
190 if (myval < otherval) return 1;
191 if (myval > otherval) return -1;
192 myord = strchr(myord, '.');
193 if (myord) myord++;
194 otherord = strchr(otherord, '.');
195 if (otherord) otherord++;
196 }
197 if (myord) return -1;
198 if (otherord) return 1;
199 return 0;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Used to compare slaveinfos by ordinal.
204
206{
207 if (!obj) return kFALSE;
208 const TSlaveInfo *si = dynamic_cast<const TSlaveInfo*>(obj);
209 if (!si) return kFALSE;
210 return (strcmp(GetOrdinal(), si->GetOrdinal()) == 0);
211}
212
213////////////////////////////////////////////////////////////////////////////////
214/// Print slave info. If opt = "active" print only the active
215/// slaves, if opt="notactive" print only the not active slaves,
216/// if opt = "bad" print only the bad slaves, else
217/// print all slaves.
218
220{
221 TString stat = fStatus == kActive ? "active" :
222 fStatus == kBad ? "bad" :
223 "not active";
224
225 Bool_t newfmt = kFALSE;
226 TString oo(opt);
227 if (oo.Contains("N")) {
228 newfmt = kTRUE;
229 oo.ReplaceAll("N","");
230 }
231 if (oo == "active" && fStatus != kActive) return;
232 if (oo == "notactive" && fStatus != kNotActive) return;
233 if (oo == "bad" && fStatus != kBad) return;
234
235 if (newfmt) {
236 TString msd, si, datadir;
237 if (!(fMsd.IsNull())) msd.Form("| msd: %s ", fMsd.Data());
238 if (!(fDataDir.IsNull())) datadir.Form("| datadir: %s ", fDataDir.Data());
239 if (fSysInfo.fCpus > 0) {
240 si.Form("| %s, %d cores, %d MB ram", fHostName.Data(),
242 } else {
243 si.Form("| %s", fHostName.Data());
244 }
245 Printf("Worker: %9s %s %s%s| %s", fOrdinal.Data(), si.Data(), msd.Data(), datadir.Data(), stat.Data());
246
247 } else {
248 TString msd = fMsd.IsNull() ? "<null>" : fMsd.Data();
249
250 std::cout << "Slave: " << fOrdinal
251 << " hostname: " << fHostName
252 << " msd: " << msd
253 << " perf index: " << fPerfIndex
254 << " " << stat
255 << std::endl;
256 }
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// Setter for fSysInfo
261
263{
264 fSysInfo.fOS = si.fOS; // OS
265 fSysInfo.fModel = si.fModel; // computer model
266 fSysInfo.fCpuType = si.fCpuType; // type of cpu
267 fSysInfo.fCpus = si.fCpus; // number of cpus
268 fSysInfo.fCpuSpeed = si.fCpuSpeed; // cpu speed in MHz
269 fSysInfo.fBusSpeed = si.fBusSpeed; // bus speed in MHz
270 fSysInfo.fL2Cache = si.fL2Cache; // level 2 cache size in KB
271 fSysInfo.fPhysRam = si.fPhysRam; // Physical RAM
272}
273
275
276//------------------------------------------------------------------------------
277
278////////////////////////////////////////////////////////////////////////////////
279/// Destructor
280
282{
283 // Just delete the list, the objects are owned by other list
284 if (fWorkers) {
287 }
288}
289////////////////////////////////////////////////////////////////////////////////
290/// Increase number of already merged workers by 1
291
293{
295 Error("SetMergedWorker", "all workers have been already merged before!");
296 else
298}
299
300////////////////////////////////////////////////////////////////////////////////
301/// Add new worker to the list of workers to be merged by this merger
302
304{
305 if (!fWorkers)
306 fWorkers = new TList();
307 if (fWorkersToMerge == fWorkers->GetSize()) {
308 Error("AddWorker", "all workers have been already assigned to this merger");
309 return;
310 }
311 fWorkers->Add(sl);
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Return if merger has already merged all workers, i.e. if it has finished its merging job
316
318{
320}
321
322////////////////////////////////////////////////////////////////////////////////
323/// Return if the determined number of workers has been already assigned to this merger
324
326{
327 if (!fWorkers)
328 return kFALSE;
329
330 return (fWorkers->GetSize() == fWorkersToMerge);
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// This a private API function.
335/// It checks whether the connection string contains a PoD cluster protocol.
336/// If it does, then the connection string will be changed to reflect
337/// a real PROOF connection string for a PROOF cluster managed by PoD.
338/// PoD: http://pod.gsi.de .
339/// Return -1 if the PoD request failed; return 0 otherwise.
340
341static Int_t PoDCheckUrl(TString *_cluster)
342{
343 if ( !_cluster )
344 return 0;
345
346 // trim spaces from both sides of the string
347 *_cluster = _cluster->Strip( TString::kBoth );
348 // PoD protocol string
349 const TString pod_prot("pod");
350
351 // URL test
352 // TODO: The URL test is to support remote PoD servers (not managed by pod-remote)
353 TUrl url( _cluster->Data() );
354 if( pod_prot.CompareTo(url.GetProtocol(), TString::kIgnoreCase) )
355 return 0;
356
357 // PoD cluster is used
358 // call pod-info in a batch mode (-b).
359 // pod-info will find either a local PoD cluster or
360 // a remote one, manged by pod-remote.
361 *_cluster = gSystem->GetFromPipe("pod-info -c -b");
362 if( 0 == _cluster->Length() ) {
363 Error("PoDCheckUrl", "PoD server is not running");
364 return -1;
365 }
366 return 0;
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Create a PROOF environment. Starting PROOF involves either connecting
371/// to a master server, which in turn will start a set of slave servers, or
372/// directly starting as master server (if master = ""). Masterurl is of
373/// the form: [proof[s]://]host[:port]. Conffile is the name of the config
374/// file describing the remote PROOF cluster (this argument alows you to
375/// describe different cluster configurations).
376/// The default is proof.conf. Confdir is the directory where the config
377/// file and other PROOF related files are (like motd and noproof files).
378/// Loglevel is the log level (default = 1). User specified custom config
379/// files will be first looked for in $HOME/.conffile.
380
381TProof::TProof(const char *masterurl, const char *conffile, const char *confdir,
382 Int_t loglevel, const char *alias, TProofMgr *mgr)
383 : fUrl(masterurl)
384{
385 // Default initializations
386 InitMembers();
387
388 // This may be needed during init
389 fManager = mgr;
390
391 // Default server type
393
394 // Default query mode
396
397 // Parse the main URL, adjusting the missing fields and setting the relevant
398 // bits
401
402 // Protocol and Host
403 if (!masterurl || strlen(masterurl) <= 0) {
404 fUrl.SetProtocol("proof");
405 fUrl.SetHost("__master__");
406 } else if (!(strstr(masterurl, "://"))) {
407 fUrl.SetProtocol("proof");
408 }
409 // Port
410 if (fUrl.GetPort() == TUrl(" ").GetPort())
411 fUrl.SetPort(TUrl("proof:// ").GetPort());
412
413 // Make sure to store the FQDN, so to get a solid reference for subsequent checks
414 if (!strcmp(fUrl.GetHost(), "__master__"))
415 fMaster = fUrl.GetHost();
416 else if (!strlen(fUrl.GetHost()))
418 else
420
421 // Server type
422 if (strlen(fUrl.GetOptions()) > 0) {
423 TString opts(fUrl.GetOptions());
424 if (!(strncmp(fUrl.GetOptions(),"std",3))) {
426 opts.Remove(0,3);
427 fUrl.SetOptions(opts.Data());
428 } else if (!(strncmp(fUrl.GetOptions(),"lite",4))) {
430 opts.Remove(0,4);
431 fUrl.SetOptions(opts.Data());
432 }
433 }
434
435 // Instance type
439 if (fMaster == "__master__") {
443 } else if (fMaster == "prooflite") {
444 // Client and master are merged
447 }
448 // Flag that we are a client
450 if (!gSystem->Getenv("ROOTPROOFCLIENT")) gSystem->Setenv("ROOTPROOFCLIENT","");
451
452 Init(masterurl, conffile, confdir, loglevel, alias);
453
454 // If the user was not set, get it from the master
455 if (strlen(fUrl.GetUser()) <= 0) {
456 TString usr, emsg;
457 if (Exec("gProofServ->GetUser()", "0", kTRUE) == 0) {
458 TObjString *os = fMacroLog.GetLineWith("const char");
459 if (os) {
460 Ssiz_t fst = os->GetString().First('\"');
461 Ssiz_t lst = os->GetString().Last('\"');
462 usr = os->GetString()(fst+1, lst-fst-1);
463 } else {
464 emsg = "could not find 'const char *' string in macro log";
465 }
466 } else {
467 emsg = "could not retrieve user info";
468 }
469 if (!emsg.IsNull()) {
470 // Get user logon name
472 if (pw) {
473 usr = pw->fUser;
474 delete pw;
475 }
476 Warning("TProof", "%s: using local default %s", emsg.Data(), usr.Data());
477 }
478 // Set the user name in the main URL
479 fUrl.SetUser(usr.Data());
480 }
481
482 // If called by a manager, make sure it stays in last position
483 // for cleaning
484 if (mgr) {
486 gROOT->GetListOfSockets()->Remove(mgr);
487 gROOT->GetListOfSockets()->Add(mgr);
488 }
489
490 // Old-style server type: we add this to the list and set the global pointer
492 if (!gROOT->GetListOfProofs()->FindObject(this))
493 gROOT->GetListOfProofs()->Add(this);
494
495 // Still needed by the packetizers: needs to be changed
496 gProof = this;
497}
498
499////////////////////////////////////////////////////////////////////////////////
500/// Protected constructor to be used by classes deriving from TProof
501/// (they have to call Init themselves and override StartSlaves
502/// appropriately).
503///
504/// This constructor simply closes any previous gProof and sets gProof
505/// to this instance.
506
507TProof::TProof() : fUrl(""), fServType(TProofMgr::kXProofd)
508{
509 // Default initializations
510 InitMembers();
511
512 if (!gROOT->GetListOfProofs()->FindObject(this))
513 gROOT->GetListOfProofs()->Add(this);
514
515 gProof = this;
516}
517
518////////////////////////////////////////////////////////////////////////////////
519/// Default initializations
520
522{
523 fValid = kFALSE;
524 fTty = kFALSE;
525 fRecvMessages = 0;
526 fSlaveInfo = 0;
531 fActiveSlaves = 0;
532 fInactiveSlaves = 0;
533 fUniqueSlaves = 0;
536 fActiveMonitor = 0;
537 fUniqueMonitor = 0;
539 fCurrentMonitor = 0;
540 fBytesRead = 0;
541 fRealTime = 0;
542 fCpuTime = 0;
543 fIntHandler = 0;
544 fProgressDialog = 0;
547 fPlayer = 0;
548 fFeedback = 0;
549 fChains = 0;
550 fDSet = 0;
551 fNotIdle = 0;
552 fSync = kTRUE;
556 fLogFileW = 0;
557 fLogFileR = 0;
560 fMacroLog.SetName("ProofLogMacro");
561
562 fWaitingSlaves = 0;
563 fQueries = 0;
564 fOtherQueries = 0;
565 fDrawQueries = 0;
566 fMaxDrawQueries = 1;
567 fSeqNum = 0;
568
569 fSessionID = -1;
571
572 fPackMgr = 0;
574
575 fInputData = 0;
576
577 fPrintProgress = 0;
578
579 fLoadedMacros = 0;
580
581 fProtocol = -1;
582 fSlaves = 0;
584 fBadSlaves = 0;
585 fAllMonitor = 0;
587 fBytesReady = 0;
588 fTotalBytes = 0;
591 fRunningDSets = 0;
592
593 fCollectTimeout = -1;
594
595 fManager = 0;
598
601 fMergers = 0;
602 fMergersCount = -1;
604 fWorkersToMerge = 0;
606
607 fPerfTree = "";
608
610
611 fSelector = 0;
612
613 fPrepTime = 0.;
614
615 // Check if the user defined a list of environment variables to send over:
616 // include them into the dedicated list
617 if (gSystem->Getenv("PROOF_ENVVARS")) {
618 TString envs(gSystem->Getenv("PROOF_ENVVARS")), env, envsfound;
619 Int_t from = 0;
620 while (envs.Tokenize(env, from, ",")) {
621 if (!env.IsNull()) {
622 if (!gSystem->Getenv(env)) {
623 Warning("Init", "request for sending over undefined environemnt variable '%s' - ignoring", env.Data());
624 } else {
625 if (!envsfound.IsNull()) envsfound += ",";
626 envsfound += env;
628 TProof::AddEnvVar(env, gSystem->Getenv(env));
629 }
630 }
631 }
632 if (envsfound.IsNull()) {
633 Warning("Init", "none of the requested env variables were found: '%s'", envs.Data());
634 } else {
635 Info("Init", "the following environment variables have been added to the list to be sent to the nodes: '%s'", envsfound.Data());
636 }
637 }
638
639 // Done
640 return;
641}
642
643////////////////////////////////////////////////////////////////////////////////
644/// Clean up PROOF environment.
645
647{
648 if (fChains) {
649 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
650 // remove "chain" from list
651 chain->SetProof(0);
652 RemoveChain(chain);
653 }
654 }
655
656 // remove links to packages enabled on the client
658 // iterate over all packages
660 if (epl) {
661 TIter nxp(epl);
662 while (TObjString *pck = (TObjString *)(nxp())) {
663 FileStat_t stat;
664 if (gSystem->GetPathInfo(pck->String(), stat) == 0) {
665 // check if symlink, if so unlink
666 // NOTE: GetPathInfo() returns 1 in case of symlink that does not point to
667 // existing file or to a directory, but if fIsLink is true the symlink exists
668 if (stat.fIsLink)
669 gSystem->Unlink(pck->String());
670 }
671 }
672 epl->Delete();
673 delete epl;
674 }
675 }
676
677 Close();
703 if (fWrksOutputReady) {
705 delete fWrksOutputReady;
706 }
707
708 // remove file with redirected logs
710 if (fLogFileR)
711 fclose(fLogFileR);
712 if (fLogFileW)
713 fclose(fLogFileW);
714 if (fLogFileName.Length() > 0)
716 }
717
718 // Remove for the global list
719 gROOT->GetListOfProofs()->Remove(this);
720 // ... and from the manager list
721 if (fManager && fManager->IsValid())
723
724 if (gProof && gProof == this) {
725 // Set previous as default
726 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
727 while ((gProof = (TProof *)pvp())) {
729 break;
730 }
731 }
732
733 // For those interested in our destruction ...
734 Emit("~TProof()");
735 Emit("CloseWindow()");
736}
737
738////////////////////////////////////////////////////////////////////////////////
739/// Start the PROOF environment. Starting PROOF involves either connecting
740/// to a master server, which in turn will start a set of slave servers, or
741/// directly starting as master server (if master = ""). For a description
742/// of the arguments see the TProof ctor. Returns the number of started
743/// master or slave servers, returns 0 in case of error, in which case
744/// fValid remains false.
745
746Int_t TProof::Init(const char *, const char *conffile,
747 const char *confdir, Int_t loglevel, const char *alias)
748{
750
751 fValid = kFALSE;
752
753 // Connected to terminal?
754 fTty = (isatty(0) == 0 || isatty(1) == 0) ? kFALSE : kTRUE;
755
756 // If in attach mode, options is filled with additional info
757 Bool_t attach = kFALSE;
758 if (strlen(fUrl.GetOptions()) > 0) {
759 attach = kTRUE;
760 // A flag from the GUI
761 TString opts = fUrl.GetOptions();
762 if (opts.Contains("GUI")) {
764 opts.Remove(opts.Index("GUI"));
765 fUrl.SetOptions(opts);
766 }
767 }
768
770 // Fill default conf file and conf dir
771 if (!conffile || !conffile[0])
773 if (!confdir || !confdir[0])
775 // The group; the client receives it in the kPROOF_SESSIONTAG message
777 } else {
778 fConfDir = confdir;
779 fConfFile = conffile;
780 }
781
782 // Analysise the conffile field
783 if (fConfFile.Contains("workers=0")) fConfFile.ReplaceAll("workers=0", "masteronly");
785
787 fLogLevel = loglevel;
790 fImage = fMasterServ ? "" : "<local>";
791 fIntHandler = 0;
792 fStatus = 0;
793 fRecvMessages = new TList;
795 fSlaveInfo = 0;
796 fChains = new TList;
799 fRunningDSets = 0;
801 fInputData = 0;
803 fPrintProgress = 0;
804
805 // Timeout for some collect actions
806 fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
807
808 // Should the workers be started dynamically; default: no
809 fDynamicStartup = gEnv->GetValue("Proof.DynamicStartup", kFALSE);
810
811 // Default entry point for the data pool is the master
813 fDataPoolUrl.Form("root://%s", fMaster.Data());
814 else
815 fDataPoolUrl = "";
816
817 fProgressDialog = 0;
819
820 // Default alias is the master name
821 TString al = (alias) ? alias : fMaster.Data();
822 SetAlias(al);
823
824 // Client logging of messages from the master and slaves
827 fLogFileName.Form("%s/ProofLog_%d", gSystem->TempDirectory(), gSystem->GetPid());
828 if ((fLogFileW = fopen(fLogFileName, "w")) == 0)
829 Error("Init", "could not create temporary logfile");
830 if ((fLogFileR = fopen(fLogFileName, "r")) == 0)
831 Error("Init", "could not open temp logfile for reading");
832 }
834
835 // Status of cluster
836 fNotIdle = 0;
837 // Query type
838 fSync = (attach) ? kFALSE : kTRUE;
839 // Not enqueued
841
842 // Counters
843 fBytesRead = 0;
844 fRealTime = 0;
845 fCpuTime = 0;
846
847 // List of queries
848 fQueries = 0;
849 fOtherQueries = 0;
850 fDrawQueries = 0;
851 fMaxDrawQueries = 1;
852 fSeqNum = 0;
853
854 // Remote ID of the session
855 fSessionID = -1;
856
857 // Part of active query
858 fWaitingSlaves = 0;
859
860 // Make remote PROOF player
861 fPlayer = 0;
862 MakePlayer();
863
864 fFeedback = new TList;
866 fFeedback->SetName("FeedbackList");
868
869 // sort slaves by descending performance index
871 fActiveSlaves = new TList;
873 fUniqueSlaves = new TList;
876 fBadSlaves = new TList;
877 fAllMonitor = new TMonitor;
881 fCurrentMonitor = 0;
882
885
886 fLoadedMacros = 0;
887 fPackMgr = 0;
888
889 // Enable optimized sending of streamer infos to use embedded backward/forward
890 // compatibility support between different ROOT versions and different versions of
891 // users classes
892 Bool_t enableSchemaEvolution = gEnv->GetValue("Proof.SchemaEvolution",1);
893 if (enableSchemaEvolution) {
895 } else {
896 Info("TProof", "automatic schema evolution in TMessage explicitly disabled");
897 }
898
899 if (IsMaster()) {
900 // to make UploadPackage() method work on the master as well.
902 } else {
903
904 TString sandbox;
905 if (GetSandbox(sandbox, kTRUE) != 0) {
906 Error("Init", "failure asserting sandbox directory %s", sandbox.Data());
907 return 0;
908 }
909
910 // Package Dir
911 TString packdir = gEnv->GetValue("Proof.PackageDir", "");
912 if (packdir.IsNull())
913 packdir.Form("%s/%s", sandbox.Data(), kPROOF_PackDir);
914 if (AssertPath(packdir, kTRUE) != 0) {
915 Error("Init", "failure asserting directory %s", packdir.Data());
916 return 0;
917 }
918 fPackMgr = new TPackMgr(packdir);
919 if (gDebug > 0)
920 Info("Init", "package directory set to %s", packdir.Data());
921 }
922
923 if (!IsMaster()) {
924 // List of directories where to look for global packages
925 TString globpack = gEnv->GetValue("Proof.GlobalPackageDirs","");
927 Int_t nglb = TPackMgr::RegisterGlobalPath(globpack);
928 if (gDebug > 0)
929 Info("Init", " %d global package directories registered", nglb);
930 }
931
932 // Master may want dynamic startup
933 if (fDynamicStartup) {
934 if (!IsMaster()) {
935 // If on client - start the master
936 if (!StartSlaves(attach))
937 return 0;
938 }
939 } else {
940
941 // Master Only mode (for operations requiring only the master, e.g. dataset browsing,
942 // result retrieving, ...)
943 Bool_t masterOnly = gEnv->GetValue("Proof.MasterOnly", kFALSE);
944 if (!IsMaster() || !masterOnly) {
945 // Start slaves (the old, static, per-session way)
946 if (!StartSlaves(attach))
947 return 0;
948 // Client: Is Master in dynamic startup mode?
949 if (!IsMaster()) {
950 Int_t dyn = 0;
951 GetRC("Proof.DynamicStartup", dyn);
952 if (dyn != 0) fDynamicStartup = kTRUE;
953 }
954 }
955 }
956 // we are now properly initialized
957 fValid = kTRUE;
958
959 // De-activate monitor (will be activated in Collect)
961
962 // By default go into parallel mode
963 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
964 TNamed *n = 0;
965 if (TProof::GetEnvVars() &&
966 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
967 TString s(n->GetTitle());
968 if (s.IsDigit()) nwrk = s.Atoi();
969 }
970 GoParallel(nwrk, attach);
971
972 // Send relevant initial state to slaves
973 if (!attach)
975 else if (!IsIdle())
976 // redirect log
978
979 // Done at this point, the alias will be communicated to the coordinator, if any
981 SetAlias(al);
982
984
985 if (IsValid()) {
986
987 // Activate input handler
989
991 gROOT->GetListOfSockets()->Add(this);
992 }
993
994 AskParallel();
995
996 return fActiveSlaves->GetSize();
997}
998
999////////////////////////////////////////////////////////////////////////////////
1000/// Set the sandbox path from ' Proof.Sandbox' or the alternative var 'rc'.
1001/// Use the existing setting or the default if nothing is found.
1002/// If 'assert' is kTRUE, make also sure that the path exists.
1003/// Return 0 on success, -1 on failure
1004
1005Int_t TProof::GetSandbox(TString &sb, Bool_t assert, const char *rc)
1006{
1007 // Get it from 'rc', if defined
1008 if (rc && strlen(rc)) sb = gEnv->GetValue(rc, sb);
1009 // Or use the default 'rc'
1010 if (sb.IsNull()) sb = gEnv->GetValue("Proof.Sandbox", "");
1011 // If nothing found , use the default
1012 if (sb.IsNull()) sb.Form("~/%s", kPROOF_WorkDir);
1013 // Expand special settings
1014 if (sb == ".") {
1015 sb = gSystem->pwd();
1016 } else if (sb == "..") {
1017 sb = gSystem->DirName(gSystem->pwd());
1018 }
1020
1021 // Assert the path, if required
1022 if (assert && AssertPath(sb, kTRUE) != 0) return -1;
1023 // Done
1024 return 0;
1025}
1026
1027////////////////////////////////////////////////////////////////////////////////
1028/// The config file field may contain special instructions which need to be
1029/// parsed at the beginning, e.g. for debug runs with valgrind.
1030/// Several options can be given separated by a ','
1031
1032void TProof::ParseConfigField(const char *config)
1033{
1034 TString sconf(config), opt;
1035 Ssiz_t from = 0;
1036 Bool_t cpuPin = kFALSE;
1037
1038 // Analysise the field
1039 const char *cq = (IsLite()) ? "\"" : "";
1040 while (sconf.Tokenize(opt, from, ",")) {
1041 if (opt.IsNull()) continue;
1042
1043 if (opt.BeginsWith("valgrind")) {
1044 // Any existing valgrind setting? User can give full settings, which we fully respect,
1045 // or pass additional options for valgrind by prefixing 'valgrind_opts:'. For example,
1046 // TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", "valgrind_opts:--time-stamp --leak-check=full"
1047 // will add option "--time-stamp --leak-check=full" to our default options
1048 TString mst, top, sub, wrk, all;
1049 TList *envs = fgProofEnvList;
1050 TNamed *n = 0;
1051 if (envs) {
1052 if ((n = (TNamed *) envs->FindObject("PROOF_WRAPPERCMD")))
1053 all = n->GetTitle();
1054 if ((n = (TNamed *) envs->FindObject("PROOF_MASTER_WRAPPERCMD")))
1055 mst = n->GetTitle();
1056 if ((n = (TNamed *) envs->FindObject("PROOF_TOPMASTER_WRAPPERCMD")))
1057 top = n->GetTitle();
1058 if ((n = (TNamed *) envs->FindObject("PROOF_SUBMASTER_WRAPPERCMD")))
1059 sub = n->GetTitle();
1060 if ((n = (TNamed *) envs->FindObject("PROOF_SLAVE_WRAPPERCMD")))
1061 wrk = n->GetTitle();
1062 }
1063 if (all != "" && mst == "") mst = all;
1064 if (all != "" && top == "") top = all;
1065 if (all != "" && sub == "") sub = all;
1066 if (all != "" && wrk == "") wrk = all;
1067 if (all != "" && all.BeginsWith("valgrind_opts:")) {
1068 // The field is used to add an option Reset the setting
1069 Info("ParseConfigField","valgrind run: resetting 'PROOF_WRAPPERCMD':"
1070 " must be set again for next run , if any");
1071 TProof::DelEnvVar("PROOF_WRAPPERCMD");
1072 }
1073 TString var, cmd;
1074 cmd.Form("%svalgrind -v --suppressions=<rootsys>/etc/valgrind-root.supp", cq);
1075 TString mstlab("NO"), wrklab("NO");
1076 Bool_t doMaster = (opt == "valgrind" || (opt.Contains("master") &&
1077 !opt.Contains("topmaster") && !opt.Contains("submaster")))
1078 ? kTRUE : kFALSE;
1079 if (doMaster) {
1080 if (!IsLite()) {
1081 // Check if we have to add a var
1082 if (mst == "" || mst.BeginsWith("valgrind_opts:")) {
1083 mst.ReplaceAll("valgrind_opts:","");
1084 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), mst.Data());
1085 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", var);
1086 mstlab = "YES";
1087 } else if (mst != "") {
1088 mstlab = "YES";
1089 }
1090 } else {
1091 if (opt.Contains("master")) {
1092 Warning("ParseConfigField",
1093 "master valgrinding does not make sense for PROOF-Lite: ignoring");
1094 opt.ReplaceAll("master", "");
1095 if (!opt.Contains("workers")) return;
1096 }
1097 if (opt == "valgrind" || opt == "valgrind=") opt = "valgrind=workers";
1098 }
1099 }
1100 if (opt.Contains("topmaster")) {
1101 // Check if we have to add a var
1102 if (top == "" || top.BeginsWith("valgrind_opts:")) {
1103 top.ReplaceAll("valgrind_opts:","");
1104 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), top.Data());
1105 TProof::AddEnvVar("PROOF_TOPMASTER_WRAPPERCMD", var);
1106 mstlab = "YES";
1107 } else if (top != "") {
1108 mstlab = "YES";
1109 }
1110 }
1111 if (opt.Contains("submaster")) {
1112 // Check if we have to add a var
1113 if (sub == "" || sub.BeginsWith("valgrind_opts:")) {
1114 sub.ReplaceAll("valgrind_opts:","");
1115 var.Form("%s --log-file=<logfilemst>.valgrind.log %s", cmd.Data(), sub.Data());
1116 TProof::AddEnvVar("PROOF_SUBMASTER_WRAPPERCMD", var);
1117 mstlab = "YES";
1118 } else if (sub != "") {
1119 mstlab = "YES";
1120 }
1121 }
1122 if (opt.Contains("=workers") || opt.Contains("+workers")) {
1123 // Check if we have to add a var
1124 if (wrk == "" || wrk.BeginsWith("valgrind_opts:")) {
1125 wrk.ReplaceAll("valgrind_opts:","");
1126 var.Form("%s --log-file=<logfilewrk>.__valgrind__.log %s%s", cmd.Data(), wrk.Data(), cq);
1127 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", var);
1128 TString nwrks("2");
1129 Int_t inw = opt.Index('#');
1130 if (inw != kNPOS) {
1131 nwrks = opt(inw+1, opt.Length());
1132 if (!nwrks.IsDigit()) nwrks = "2";
1133 }
1134 // Set the relevant variables
1135 if (!IsLite()) {
1136 TProof::AddEnvVar("PROOF_NWORKERS", nwrks);
1137 } else {
1138 gEnv->SetValue("ProofLite.Workers", nwrks.Atoi());
1139 }
1140 wrklab = nwrks;
1141 // Register the additional worker log in the session file
1142 // (for the master this is done automatically)
1143 TProof::AddEnvVar("PROOF_ADDITIONALLOG", "__valgrind__.log*");
1144 } else if (wrk != "") {
1145 wrklab = "ALL";
1146 }
1147 }
1148 // Increase the relevant timeouts
1149 if (!IsLite()) {
1150 TProof::AddEnvVar("PROOF_INTWAIT", "5000");
1151 gEnv->SetValue("Proof.SocketActivityTimeout", 6000);
1152 } else {
1153 gEnv->SetValue("ProofLite.StartupTimeOut", 5000);
1154 }
1155 // Warn for slowness
1156 Printf(" ");
1157 if (!IsLite()) {
1158 Printf(" ---> Starting a debug run with valgrind (master:%s, workers:%s)", mstlab.Data(), wrklab.Data());
1159 } else {
1160 Printf(" ---> Starting a debug run with valgrind (workers:%s)", wrklab.Data());
1161 }
1162 Printf(" ---> Please be patient: startup may be VERY slow ...");
1163 Printf(" ---> Logs will be available as special tags in the log window (from the progress dialog or TProof::LogViewer()) ");
1164 Printf(" ---> (Reminder: this debug run makes sense only if you are running a debug version of ROOT)");
1165 Printf(" ");
1166
1167 } else if (opt.BeginsWith("igprof-pp")) {
1168
1169 // IgProf profiling on master and worker. PROOF does not set the
1170 // environment for you: proper environment variables (like PATH and
1171 // LD_LIBRARY_PATH) should be set externally
1172
1173 Printf("*** Requested IgProf performance profiling ***");
1174 TString addLogExt = "__igprof.pp__.log";
1175 TString addLogFmt = "igprof -pk -pp -t proofserv.exe -o %s.%s";
1176 TString tmp;
1177
1178 if (IsLite()) {
1179 addLogFmt.Append("\"");
1180 addLogFmt.Prepend("\"");
1181 }
1182
1183 tmp.Form(addLogFmt.Data(), "<logfilemst>", addLogExt.Data());
1184 TProof::AddEnvVar("PROOF_MASTER_WRAPPERCMD", tmp.Data());
1185
1186 tmp.Form(addLogFmt.Data(), "<logfilewrk>", addLogExt.Data());
1187 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", tmp.Data() );
1188
1189 TProof::AddEnvVar("PROOF_ADDITIONALLOG", addLogExt.Data());
1190
1191 } else if (opt.BeginsWith("cpupin=")) {
1192 // Enable CPU pinning. Takes as argument the list of processor IDs
1193 // that will be used in order. Processor IDs are numbered from 0,
1194 // use likwid to see how they are organized. A possible parameter
1195 // format would be:
1196 //
1197 // cpupin=3+4+0+9+10+22+7
1198 //
1199 // Only the specified processor IDs will be used in a round-robin
1200 // fashion, dealing with the fact that you can request more workers
1201 // than the number of processor IDs you have specified.
1202 //
1203 // To use all available processors in their order:
1204 //
1205 // cpupin=*
1206
1207 opt.Remove(0, 7);
1208
1209 // Remove any char which is neither a number nor a plus '+'
1210 for (Ssiz_t i=0; i<opt.Length(); i++) {
1211 Char_t c = opt[i];
1212 if ((c != '+') && ((c < '0') || (c > '9')))
1213 opt[i] = '_';
1214 }
1215 opt.ReplaceAll("_", "");
1216 TProof::AddEnvVar("PROOF_SLAVE_CPUPIN_ORDER", opt);
1217 cpuPin = kTRUE;
1218 } else if (opt.BeginsWith("workers=")) {
1219
1220 // Request for a given number of workers (within the max) or worker
1221 // startup combination:
1222 // workers=5 start max 5 workers (or less, if less are assigned)
1223 // workers=2x start max 2 workers per node (or less, if less are assigned)
1224 opt.ReplaceAll("workers=","");
1225 TProof::AddEnvVar("PROOF_NWORKERS", opt);
1226 }
1227 }
1228
1229 // In case of PROOF-Lite, enable CPU pinning when requested (Linux only)
1230 #ifdef R__LINUX
1231 if (IsLite() && cpuPin) {
1232 Printf("*** Requested CPU pinning ***");
1233 const TList *ev = GetEnvVars();
1234 const char *pinCmd = "taskset -c <cpupin>";
1235 TString val;
1236 TNamed *p;
1237 if (ev && (p = dynamic_cast<TNamed *>(ev->FindObject("PROOF_SLAVE_WRAPPERCMD")))) {
1238 val = p->GetTitle();
1239 val.Insert(val.Length()-1, " ");
1240 val.Insert(val.Length()-1, pinCmd);
1241 }
1242 else {
1243 val.Form("\"%s\"", pinCmd);
1244 }
1245 TProof::AddEnvVar("PROOF_SLAVE_WRAPPERCMD", val.Data());
1246 }
1247 #endif
1248}
1249
1250////////////////////////////////////////////////////////////////////////////////
1251/// Make sure that 'path' exists; if 'writable' is kTRUE, make also sure
1252/// that the path is writable
1253
1254Int_t TProof::AssertPath(const char *inpath, Bool_t writable)
1255{
1256 if (!inpath || strlen(inpath) <= 0) {
1257 Error("AssertPath", "undefined input path");
1258 return -1;
1259 }
1260
1261 TString path(inpath);
1262 gSystem->ExpandPathName(path);
1263
1264 if (gSystem->AccessPathName(path, kFileExists)) {
1265 if (gSystem->mkdir(path, kTRUE) != 0) {
1266 Error("AssertPath", "could not create path %s", path.Data());
1267 return -1;
1268 }
1269 }
1270 // It must be writable
1271 if (gSystem->AccessPathName(path, kWritePermission) && writable) {
1272 if (gSystem->Chmod(path, 0666) != 0) {
1273 Error("AssertPath", "could not make path %s writable", path.Data());
1274 return -1;
1275 }
1276 }
1277
1278 // Done
1279 return 0;
1280}
1281
1282////////////////////////////////////////////////////////////////////////////////
1283/// Set manager and schedule its destruction after this for clean
1284/// operations.
1285
1287{
1288 fManager = mgr;
1289
1290 if (mgr) {
1292 gROOT->GetListOfSockets()->Remove(mgr);
1293 gROOT->GetListOfSockets()->Add(mgr);
1294 }
1295}
1296
1297////////////////////////////////////////////////////////////////////////////////
1298/// Works on the master node only.
1299/// It starts workers on the machines in workerList and sets the paths,
1300/// packages and macros as on the master.
1301/// It is a subbstitute for StartSlaves(...)
1302/// The code is mostly the master part of StartSlaves,
1303/// with the parallel startup removed.
1304
1306{
1307 if (!IsMaster()) {
1308 Error("AddWorkers", "AddWorkers can only be called on the master!");
1309 return -1;
1310 }
1311
1312 if (!workerList || !(workerList->GetSize())) {
1313 Error("AddWorkers", "empty list of workers!");
1314 return -2;
1315 }
1316
1317 // Code taken from master part of StartSlaves with the parllel part removed
1318
1320 if (fImage.IsNull())
1322
1323 // Get all workers
1324 UInt_t nSlaves = workerList->GetSize();
1325 UInt_t nSlavesDone = 0;
1326 Int_t ord = 0;
1327
1328 // Loop over all new workers and start them (if we had already workers it means we are
1329 // increasing parallelism or that is not the first time we are called)
1330 Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
1331
1332 // A list of TSlave objects for workers that are being added
1333 TList *addedWorkers = new TList();
1334 if (!addedWorkers) {
1335 // This is needed to silence Coverity ...
1336 Error("AddWorkers", "cannot create new list for the workers to be added");
1337 return -2;
1338 }
1339 addedWorkers->SetOwner(kFALSE);
1340 TListIter next(workerList);
1341 TObject *to;
1342 TProofNodeInfo *worker;
1343 TSlaveInfo *dummysi = new TSlaveInfo();
1344 while ((to = next())) {
1345 // Get the next worker from the list
1346 worker = (TProofNodeInfo *)to;
1347
1348 // Read back worker node info
1349 const Char_t *image = worker->GetImage().Data();
1350 const Char_t *workdir = worker->GetWorkDir().Data();
1351 Int_t perfidx = worker->GetPerfIndex();
1352 Int_t sport = worker->GetPort();
1353 if (sport == -1)
1354 sport = fUrl.GetPort();
1355
1356 // Create worker server
1357 TString fullord;
1358 if (worker->GetOrdinal().Length() > 0) {
1359 fullord.Form("%s.%s", gProofServ->GetOrdinal(), worker->GetOrdinal().Data());
1360 } else {
1361 fullord.Form("%s.%d", gProofServ->GetOrdinal(), ord);
1362 }
1363
1364 // Remove worker from the list of workers terminated gracefully
1365 dummysi->SetOrdinal(fullord);
1367 SafeDelete(rmsi);
1368
1369 // Create worker server
1370 TString wn(worker->GetNodeName());
1371 if (wn == "localhost" || wn.BeginsWith("localhost.")) wn = gSystem->HostName();
1372 TUrl u(TString::Format("%s:%d", wn.Data(), sport));
1373 // Add group info in the password firdl, if any
1374 if (strlen(gProofServ->GetGroup()) > 0) {
1375 // Set also the user, otherwise the password is not exported
1376 if (strlen(u.GetUser()) <= 0)
1379 }
1380 TSlave *slave = 0;
1381 if (worker->IsWorker()) {
1382 slave = CreateSlave(u.GetUrl(), fullord, perfidx, image, workdir);
1383 } else {
1384 slave = CreateSubmaster(u.GetUrl(), fullord,
1385 image, worker->GetMsd(), worker->GetNWrks());
1386 }
1387
1388 // Add to global list (we will add to the monitor list after
1389 // finalizing the server startup)
1390 Bool_t slaveOk = kTRUE;
1391 fSlaves->Add(slave);
1392 if (slave->IsValid()) {
1393 addedWorkers->Add(slave);
1394 } else {
1395 slaveOk = kFALSE;
1396 fBadSlaves->Add(slave);
1397 Warning("AddWorkers", "worker '%s' is invalid", slave->GetOrdinal());
1398 }
1399
1400 PDB(kGlobal,3)
1401 Info("AddWorkers", "worker on host %s created"
1402 " and added to list (ord: %s)", worker->GetName(), slave->GetOrdinal());
1403
1404 // Notify opening of connection
1405 nSlavesDone++;
1407 m << TString("Opening connections to workers") << nSlaves
1408 << nSlavesDone << slaveOk;
1410
1411 ord++;
1412 } //end of the worker loop
1413 SafeDelete(dummysi);
1414
1415 // Cleanup
1416 SafeDelete(workerList);
1417
1418 nSlavesDone = 0;
1419
1420 // Here we finalize the server startup: in this way the bulk
1421 // of remote operations are almost parallelized
1422 TIter nxsl(addedWorkers);
1423 TSlave *sl = 0;
1424 while ((sl = (TSlave *) nxsl())) {
1425
1426 // Finalize setup of the server
1427 if (sl->IsValid())
1428 sl->SetupServ(TSlave::kSlave, 0);
1429
1430 // Monitor good slaves
1431 Bool_t slaveOk = kTRUE;
1432 if (sl->IsValid()) {
1433 fAllMonitor->Add(sl->GetSocket());
1434 PDB(kGlobal,3)
1435 Info("AddWorkers", "worker on host %s finalized"
1436 " and added to list", sl->GetOrdinal());
1437 } else {
1438 slaveOk = kFALSE;
1439 fBadSlaves->Add(sl);
1440 }
1441
1442 // Notify end of startup operations
1443 nSlavesDone++;
1445 m << TString("Setting up worker servers") << nSlaves
1446 << nSlavesDone << slaveOk;
1448 }
1449
1450 // Now set new state on the added workers (on all workers for simplicity)
1451 // use fEnabledPackages, fLoadedMacros,
1452 // gSystem->GetDynamicPath() and gSystem->GetIncludePath()
1453 // no need to load packages that are only loaded and not enabled (dyn mode)
1454 Int_t nwrk = GetRemoteProtocol() > 35 ? -1 : 9999;
1455 TNamed *n = 0;
1456 if (TProof::GetEnvVars() &&
1457 (n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS"))) {
1458 TString s(n->GetTitle());
1459 if (s.IsDigit()) nwrk = s.Atoi();
1460 }
1461
1462 if (fDynamicStartup && goMoreParallel) {
1463
1464 PDB(kGlobal, 3)
1465 Info("AddWorkers", "will invoke GoMoreParallel()");
1466 Int_t nw = GoMoreParallel(nwrk);
1467 PDB(kGlobal, 3)
1468 Info("AddWorkers", "GoMoreParallel()=%d", nw);
1469
1470 }
1471 else {
1472 // Not in Dynamic Workers mode
1473 PDB(kGlobal, 3)
1474 Info("AddWorkers", "will invoke GoParallel()");
1475 GoParallel(nwrk, kFALSE, 0);
1476 }
1477
1478 // Set worker processing environment
1479 SetupWorkersEnv(addedWorkers, goMoreParallel);
1480
1481 // Update list of current workers
1482 PDB(kGlobal, 3)
1483 Info("AddWorkers", "will invoke SaveWorkerInfo()");
1485
1486 // Inform the client that the number of workers has changed
1487 if (fDynamicStartup && gProofServ) {
1488 PDB(kGlobal, 3)
1489 Info("AddWorkers", "will invoke SendParallel()");
1491
1492 if (goMoreParallel && fPlayer) {
1493 // In case we are adding workers dynamically to an existing process, we
1494 // should invoke a special player's Process() to set only added workers
1495 // to the proper state
1496 PDB(kGlobal, 3)
1497 Info("AddWorkers", "will send the PROCESS message to selected workers");
1498 fPlayer->JoinProcess(addedWorkers);
1499 // Update merger counters (new workers are not yet active)
1500 fMergePrg.SetNWrks(fActiveSlaves->GetSize() + addedWorkers->GetSize());
1501 }
1502 }
1503
1504 // Cleanup
1505 delete addedWorkers;
1506
1507 return 0;
1508}
1509
1510////////////////////////////////////////////////////////////////////////////////
1511/// Set up packages, loaded macros, include and lib paths ...
1512
1513void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
1514{
1515 // Packages
1517 if (packs && packs->GetSize() > 0) {
1518 TIter nxp(packs);
1519 TPair *pck = 0;
1520 while ((pck = (TPair *) nxp())) {
1521 // Upload and Enable methods are intelligent and avoid
1522 // re-uploading or re-enabling of a package to a node that has it.
1523 if (fDynamicStartup && increasingWorkers) {
1524 // Upload only on added workers
1525 PDB(kGlobal, 3)
1526 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
1527 if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
1528 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
1529 } else {
1530 PDB(kGlobal, 3)
1531 Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
1532 if (UploadPackage(pck->GetName()) >= 0)
1533 EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
1534 }
1535 }
1536 }
1537
1538 // Loaded macros
1539 if (fLoadedMacros) {
1540 TIter nxp(fLoadedMacros);
1541 TObjString *os = 0;
1542 while ((os = (TObjString *) nxp())) {
1543 PDB(kGlobal, 3) {
1544 Info("SetupWorkersEnv", "will invoke Load() on selected workers");
1545 Printf("Loading a macro : %s", os->GetName());
1546 }
1547 Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
1548 }
1549 }
1550
1551 // Dynamic path
1553 dyn.ReplaceAll(":", " ");
1554 dyn.ReplaceAll("\"", " ");
1555 PDB(kGlobal, 3)
1556 Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
1557 AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
1558
1559 // Include path
1561 inc.ReplaceAll("-I", " ");
1562 inc.ReplaceAll("\"", " ");
1563 PDB(kGlobal, 3)
1564 Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
1565 AddIncludePath(inc, kFALSE, addedWorkers, kFALSE); // Do not Collect
1566
1567 // Done
1568 return;
1569}
1570
1571////////////////////////////////////////////////////////////////////////////////
1572/// Used for shuting down the workres after a query is finished.
1573/// Sends each of the workers from the workerList, a kPROOF_STOP message.
1574/// If the workerList == 0, shutdown all the workers.
1575
1577{
1578 if (!IsMaster()) {
1579 Error("RemoveWorkers", "RemoveWorkers can only be called on the master!");
1580 return -1;
1581 }
1582
1583 fFileMap.clear(); // This could be avoided if CopyFromCache was used in SendFile
1584
1585 if (!workerList) {
1586 // shutdown all the workers
1587 TIter nxsl(fSlaves);
1588 TSlave *sl = 0;
1589 while ((sl = (TSlave *) nxsl())) {
1590 // Shut down the worker assumig that it is not processing
1591 TerminateWorker(sl);
1592 }
1593
1594 } else {
1595 if (!(workerList->GetSize())) {
1596 Error("RemoveWorkers", "The list of workers should not be empty!");
1597 return -2;
1598 }
1599
1600 // Loop over all the workers and stop them
1601 TListIter next(workerList);
1602 TObject *to;
1603 TProofNodeInfo *worker;
1604 while ((to = next())) {
1605 TSlave *sl = 0;
1606 if (!strcmp(to->ClassName(), "TProofNodeInfo")) {
1607 // Get the next worker from the list
1608 worker = (TProofNodeInfo *)to;
1609 TIter nxsl(fSlaves);
1610 while ((sl = (TSlave *) nxsl())) {
1611 // Shut down the worker assumig that it is not processing
1612 if (sl->GetName() == worker->GetNodeName())
1613 break;
1614 }
1615 } else if (to->InheritsFrom(TSlave::Class())) {
1616 sl = (TSlave *) to;
1617 } else {
1618 Warning("RemoveWorkers","unknown object type: %s - it should be"
1619 " TProofNodeInfo or inheriting from TSlave", to->ClassName());
1620 }
1621 // Shut down the worker assumig that it is not processing
1622 if (sl) {
1623 if (gDebug > 0)
1624 Info("RemoveWorkers","terminating worker %s", sl->GetOrdinal());
1625 TerminateWorker(sl);
1626 }
1627 }
1628 }
1629
1630 // Update also the master counter
1631 if (gProofServ && fSlaves->GetSize() <= 0) gProofServ->ReleaseWorker("master");
1632
1633 return 0;
1634}
1635
1636////////////////////////////////////////////////////////////////////////////////
1637/// Start up PROOF slaves.
1638
1640{
1641 // If this is a master server, find the config file and start slave
1642 // servers as specified in the config file
1644
1645 Int_t pc = 0;
1646 TList *workerList = new TList;
1647 // Get list of workers
1648 if (gProofServ->GetWorkers(workerList, pc) == TProofServ::kQueryStop) {
1649 TString emsg("no resource currently available for this session: please retry later");
1650 if (gDebug > 0) Info("StartSlaves", "%s", emsg.Data());
1652 return kFALSE;
1653 }
1654 // Setup the workers
1655 if (AddWorkers(workerList) < 0)
1656 return kFALSE;
1657
1658 } else {
1659
1660 // create master server
1661 Printf("Starting master: opening connection ...");
1662 TSlave *slave = CreateSubmaster(fUrl.GetUrl(), "0", "master", 0);
1663
1664 if (slave->IsValid()) {
1665
1666 // Notify
1667 fprintf(stderr,"Starting master:"
1668 " connection open: setting up server ... \r");
1669 StartupMessage("Connection to master opened", kTRUE, 1, 1);
1670
1671 if (!attach) {
1672
1673 // Set worker interrupt handler
1674 slave->SetInterruptHandler(kTRUE);
1675
1676 // Finalize setup of the server
1678
1679 if (slave->IsValid()) {
1680
1681 // Notify
1682 Printf("Starting master: OK ");
1683 StartupMessage("Master started", kTRUE, 1, 1);
1684
1685 // check protocol compatibility
1686 // protocol 1 is not supported anymore
1687 if (fProtocol == 1) {
1688 Error("StartSlaves",
1689 "client and remote protocols not compatible (%d and %d)",
1691 slave->Close("S");
1692 delete slave;
1693 return kFALSE;
1694 }
1695
1696 fSlaves->Add(slave);
1697 fAllMonitor->Add(slave->GetSocket());
1698
1699 // Unset worker interrupt handler
1701
1702 // Set interrupt PROOF handler from now on
1704
1705 // Give-up after 5 minutes
1706 Int_t rc = Collect(slave, 300);
1707 Int_t slStatus = slave->GetStatus();
1708 if (slStatus == -99 || slStatus == -98 || rc == 0) {
1709 fSlaves->Remove(slave);
1710 fAllMonitor->Remove(slave->GetSocket());
1711 if (slStatus == -99)
1712 Error("StartSlaves", "no resources available or problems setting up workers (check logs)");
1713 else if (slStatus == -98)
1714 Error("StartSlaves", "could not setup output redirection on master");
1715 else
1716 Error("StartSlaves", "setting up master");
1717 slave->Close("S");
1718 delete slave;
1719 return 0;
1720 }
1721
1722 if (!slave->IsValid()) {
1723 fSlaves->Remove(slave);
1724 fAllMonitor->Remove(slave->GetSocket());
1725 slave->Close("S");
1726 delete slave;
1727 Error("StartSlaves",
1728 "failed to setup connection with PROOF master server");
1729 return kFALSE;
1730 }
1731
1732 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1733 if ((fProgressDialog =
1734 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1735 if (fProgressDialog->LoadPlugin() == -1)
1736 fProgressDialog = 0;
1737 }
1738 } else {
1739 // Notify
1740 Printf("Starting master: failure");
1741 }
1742 } else {
1743
1744 // Notify
1745 Printf("Starting master: OK ");
1746 StartupMessage("Master attached", kTRUE, 1, 1);
1747
1748 if (!gROOT->IsBatch() && TestBit(kUseProgressDialog)) {
1749 if ((fProgressDialog =
1750 gROOT->GetPluginManager()->FindHandler("TProofProgressDialog")))
1751 if (fProgressDialog->LoadPlugin() == -1)
1752 fProgressDialog = 0;
1753 }
1754
1755 fSlaves->Add(slave);
1757 }
1758
1759 } else {
1760 delete slave;
1761 // Notify only if verbosity is on: most likely the failure has already been notified
1762 if (gDebug > 0)
1763 Error("StartSlaves", "failed to create (or connect to) the PROOF master server");
1764 return kFALSE;
1765 }
1766 }
1767
1768 return kTRUE;
1769}
1770
1771////////////////////////////////////////////////////////////////////////////////
1772/// Close all open slave servers.
1773/// Client can decide to shutdown the remote session by passing option is 'S'
1774/// or 's'. Default for clients is detach, if supported. Masters always
1775/// shutdown the remote counterpart.
1776
1778{
1779 { std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
1780
1781 fValid = kFALSE;
1782 if (fSlaves) {
1783 if (fIntHandler)
1785
1786 TIter nxs(fSlaves);
1787 TSlave *sl = 0;
1788 while ((sl = (TSlave *)nxs()))
1789 sl->Close(opt);
1790
1791 fActiveSlaves->Clear("nodelete");
1792 fUniqueSlaves->Clear("nodelete");
1793 fAllUniqueSlaves->Clear("nodelete");
1794 fNonUniqueMasters->Clear("nodelete");
1795 fBadSlaves->Clear("nodelete");
1796 fInactiveSlaves->Clear("nodelete");
1797 fSlaves->Delete();
1798 }
1799 }
1800
1802 gROOT->GetListOfSockets()->Remove(this);
1803
1804 if (fChains) {
1805 while (TChain *chain = dynamic_cast<TChain*> (fChains->First()) ) {
1806 // remove "chain" from list
1807 chain->SetProof(0);
1808 RemoveChain(chain);
1809 }
1810 }
1811
1812 if (IsProofd()) {
1813
1814 gROOT->GetListOfProofs()->Remove(this);
1815 if (gProof && gProof == this) {
1816 // Set previous proofd-related as default
1817 TIter pvp(gROOT->GetListOfProofs(), kIterBackward);
1818 while ((gProof = (TProof *)pvp())) {
1819 if (gProof->IsProofd())
1820 break;
1821 }
1822 }
1823 }
1824 }
1825}
1826
1827////////////////////////////////////////////////////////////////////////////////
1828/// Create a new TSlave of type TSlave::kSlave.
1829/// Note: creation of TSlave is private with TProof as a friend.
1830/// Derived classes must use this function to create slaves.
1831
1832TSlave *TProof::CreateSlave(const char *url, const char *ord,
1833 Int_t perf, const char *image, const char *workdir)
1834{
1835 TSlave* sl = TSlave::Create(url, ord, perf, image,
1836 this, TSlave::kSlave, workdir, 0);
1837
1838 if (sl->IsValid()) {
1839 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1840 // must set fParallel to 1 for slaves since they do not
1841 // report their fParallel with a LOG_DONE message
1842 sl->fParallel = 1;
1843 }
1844
1845 return sl;
1846}
1847
1848
1849////////////////////////////////////////////////////////////////////////////////
1850/// Create a new TSlave of type TSlave::kMaster.
1851/// Note: creation of TSlave is private with TProof as a friend.
1852/// Derived classes must use this function to create slaves.
1853
1854TSlave *TProof::CreateSubmaster(const char *url, const char *ord,
1855 const char *image, const char *msd, Int_t nwk)
1856{
1857 TSlave *sl = TSlave::Create(url, ord, 100, image, this,
1858 TSlave::kMaster, 0, msd, nwk);
1859
1860 if (sl->IsValid()) {
1861 sl->SetInputHandler(new TProofInputHandler(this, sl->GetSocket()));
1862 }
1863
1864 return sl;
1865}
1866
1867////////////////////////////////////////////////////////////////////////////////
1868/// Find slave that has TSocket s. Returns 0 in case slave is not found.
1869
1871{
1872 TSlave *sl;
1873 TIter next(fSlaves);
1874
1875 while ((sl = (TSlave *)next())) {
1876 if (sl->IsValid() && sl->GetSocket() == s)
1877 return sl;
1878 }
1879 return 0;
1880}
1881
1882////////////////////////////////////////////////////////////////////////////////
1883/// Add to the fUniqueSlave list the active slaves that have a unique
1884/// (user) file system image. This information is used to transfer files
1885/// only once to nodes that share a file system (an image). Submasters
1886/// which are not in fUniqueSlaves are put in the fNonUniqueMasters
1887/// list. That list is used to trigger the transferring of files to
1888/// the submaster's unique slaves without the need to transfer the file
1889/// to the submaster.
1890
1892{
1898
1899 TIter next(fActiveSlaves);
1900
1901 while (TSlave *sl = dynamic_cast<TSlave*>(next())) {
1902 if (fImage == sl->fImage) {
1903 if (sl->GetSlaveType() == TSlave::kMaster) {
1905 fAllUniqueSlaves->Add(sl);
1906 fAllUniqueMonitor->Add(sl->GetSocket());
1907 }
1908 continue;
1909 }
1910
1911 TIter next2(fUniqueSlaves);
1912 TSlave *replace_slave = 0;
1913 Bool_t add = kTRUE;
1914 while (TSlave *sl2 = dynamic_cast<TSlave*>(next2())) {
1915 if (sl->fImage == sl2->fImage) {
1916 add = kFALSE;
1917 if (sl->GetSlaveType() == TSlave::kMaster) {
1918 if (sl2->GetSlaveType() == TSlave::kSlave) {
1919 // give preference to master
1920 replace_slave = sl2;
1921 add = kTRUE;
1922 } else if (sl2->GetSlaveType() == TSlave::kMaster) {
1924 fAllUniqueSlaves->Add(sl);
1925 fAllUniqueMonitor->Add(sl->GetSocket());
1926 } else {
1927 Error("FindUniqueSlaves", "TSlave is neither Master nor Slave");
1928 R__ASSERT(0);
1929 }
1930 }
1931 break;
1932 }
1933 }
1934
1935 if (add) {
1936 fUniqueSlaves->Add(sl);
1937 fAllUniqueSlaves->Add(sl);
1938 fUniqueMonitor->Add(sl->GetSocket());
1939 fAllUniqueMonitor->Add(sl->GetSocket());
1940 if (replace_slave) {
1941 fUniqueSlaves->Remove(replace_slave);
1942 fAllUniqueSlaves->Remove(replace_slave);
1943 fUniqueMonitor->Remove(replace_slave->GetSocket());
1944 fAllUniqueMonitor->Remove(replace_slave->GetSocket());
1945 }
1946 }
1947 }
1948
1949 // will be actiavted in Collect()
1952}
1953
1954////////////////////////////////////////////////////////////////////////////////
1955/// Return number of slaves as described in the config file.
1956
1958{
1959 return fSlaves->GetSize();
1960}
1961
1962////////////////////////////////////////////////////////////////////////////////
1963/// Return number of active slaves, i.e. slaves that are valid and in
1964/// the current computing group.
1965
1967{
1968 return fActiveSlaves->GetSize();
1969}
1970
1971////////////////////////////////////////////////////////////////////////////////
1972/// Return number of inactive slaves, i.e. slaves that are valid but not in
1973/// the current computing group.
1974
1976{
1977 return fInactiveSlaves->GetSize();
1978}
1979
1980////////////////////////////////////////////////////////////////////////////////
1981/// Return number of unique slaves, i.e. active slaves that have each a
1982/// unique different user files system.
1983
1985{
1986 return fUniqueSlaves->GetSize();
1987}
1988
1989////////////////////////////////////////////////////////////////////////////////
1990/// Return number of bad slaves. This are slaves that we in the config
1991/// file, but refused to startup or that died during the PROOF session.
1992
1994{
1995 return fBadSlaves->GetSize();
1996}
1997
1998////////////////////////////////////////////////////////////////////////////////
1999/// Ask the for the statistics of the slaves.
2000
2002{
2003 if (!IsValid()) return;
2004
2007}
2008
2009////////////////////////////////////////////////////////////////////////////////
2010/// Get statistics about CPU time, real time and bytes read.
2011/// If verbose, print the resuls (always available via GetCpuTime(), GetRealTime()
2012/// and GetBytesRead()
2013
2015{
2016 if (fProtocol > 27) {
2017 // This returns the correct result
2018 AskStatistics();
2019 } else {
2020 // AskStatistics is buggy: parse the output of Print()
2023 Print();
2024 gSystem->RedirectOutput(0, 0, &rh);
2025 TMacro *mp = GetLastLog();
2026 if (mp) {
2027 // Look for global directories
2028 TIter nxl(mp->GetListOfLines());
2029 TObjString *os = 0;
2030 while ((os = (TObjString *) nxl())) {
2031 TString s(os->GetName());
2032 if (s.Contains("Total MB's processed:")) {
2033 s.ReplaceAll("Total MB's processed:", "");
2034 if (s.IsFloat()) fBytesRead = (Long64_t) s.Atof() * (1024*1024);
2035 } else if (s.Contains("Total real time used (s):")) {
2036 s.ReplaceAll("Total real time used (s):", "");
2037 if (s.IsFloat()) fRealTime = s.Atof();
2038 } else if (s.Contains("Total CPU time used (s):")) {
2039 s.ReplaceAll("Total CPU time used (s):", "");
2040 if (s.IsFloat()) fCpuTime = s.Atof();
2041 }
2042 }
2043 delete mp;
2044 }
2045 }
2046
2047 if (verbose) {
2048 Printf(" Real/CPU time (s): %.3f / %.3f; workers: %d; processed: %.2f MBs",
2049 GetRealTime(), GetCpuTime(), GetParallel(), float(GetBytesRead())/(1024*1024));
2050 }
2051}
2052
2053////////////////////////////////////////////////////////////////////////////////
2054/// Ask the for the number of parallel slaves.
2055
2057{
2058 if (!IsValid()) return;
2059
2062}
2063
2064////////////////////////////////////////////////////////////////////////////////
2065/// Ask the master for the list of queries.
2066
2068{
2069 if (!IsValid() || TestBit(TProof::kIsMaster)) return (TList *)0;
2070
2071 Bool_t all = ((strchr(opt,'A') || strchr(opt,'a'))) ? kTRUE : kFALSE;
2073 m << all;
2076
2077 // This should have been filled by now
2078 return fQueries;
2079}
2080
2081////////////////////////////////////////////////////////////////////////////////
2082/// Number of queries processed by this session
2083
2085{
2086 if (fQueries)
2087 return fQueries->GetSize() - fOtherQueries;
2088 return 0;
2089}
2090
2091////////////////////////////////////////////////////////////////////////////////
2092/// Set max number of draw queries whose results are saved
2093
2095{
2096 if (max > 0) {
2097 if (fPlayer)
2099 fMaxDrawQueries = max;
2100 }
2101}
2102
2103////////////////////////////////////////////////////////////////////////////////
2104/// Get max number of queries whose full results are kept in the
2105/// remote sandbox
2106
2108{
2110 m << kFALSE;
2113}
2114
2115////////////////////////////////////////////////////////////////////////////////
2116/// Return pointer to the list of query results in the player
2117
2119{
2120 return (fPlayer ? fPlayer->GetListOfResults() : (TList *)0);
2121}
2122
2123////////////////////////////////////////////////////////////////////////////////
2124/// Return pointer to the full TQueryResult instance owned by the player
2125/// and referenced by 'ref'. If ref = 0 or "", return the last query result.
2126
2128{
2129 return (fPlayer ? fPlayer->GetQueryResult(ref) : (TQueryResult *)0);
2130}
2131
2132////////////////////////////////////////////////////////////////////////////////
2133/// Ask the master for the list of queries.
2134/// Options:
2135/// "A" show information about all the queries known to the
2136/// server, i.e. even those processed by other sessions
2137/// "L" show only information about queries locally available
2138/// i.e. already retrieved. If "L" is specified, "A" is
2139/// ignored.
2140/// "F" show all details available about queries
2141/// "H" print help menu
2142/// Default ""
2143
2145{
2146 Bool_t help = ((strchr(opt,'H') || strchr(opt,'h'))) ? kTRUE : kFALSE;
2147 if (help) {
2148
2149 // Help
2150
2151 Printf("+++");
2152 Printf("+++ Options: \"A\" show all queries known to server");
2153 Printf("+++ \"L\" show retrieved queries");
2154 Printf("+++ \"F\" full listing of query info");
2155 Printf("+++ \"H\" print this menu");
2156 Printf("+++");
2157 Printf("+++ (case insensitive)");
2158 Printf("+++");
2159 Printf("+++ Use Retrieve(<#>) to retrieve the full"
2160 " query results from the master");
2161 Printf("+++ e.g. Retrieve(8)");
2162
2163 Printf("+++");
2164
2165 return;
2166 }
2167
2168 if (!IsValid()) return;
2169
2170 Bool_t local = ((strchr(opt,'L') || strchr(opt,'l'))) ? kTRUE : kFALSE;
2171
2172 TObject *pq = 0;
2173 if (!local) {
2174 GetListOfQueries(opt);
2175
2176 if (!fQueries) return;
2177
2178 TIter nxq(fQueries);
2179
2180 // Queries processed by other sessions
2181 if (fOtherQueries > 0) {
2182 Printf("+++");
2183 Printf("+++ Queries processed during other sessions: %d", fOtherQueries);
2184 Int_t nq = 0;
2185 while (nq++ < fOtherQueries && (pq = nxq()))
2186 pq->Print(opt);
2187 }
2188
2189 // Queries processed by this session
2190 Printf("+++");
2191 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2193 while ((pq = nxq()))
2194 pq->Print(opt);
2195
2196 } else {
2197
2198 // Queries processed by this session
2199 Printf("+++");
2200 Printf("+++ Queries processed during this session: selector: %d, draw: %d",
2202
2203 // Queries available locally
2204 TList *listlocal = fPlayer ? fPlayer->GetListOfResults() : (TList *)0;
2205 if (listlocal) {
2206 Printf("+++");
2207 Printf("+++ Queries available locally: %d", listlocal->GetSize());
2208 TIter nxlq(listlocal);
2209 while ((pq = nxlq()))
2210 pq->Print(opt);
2211 }
2212 }
2213 Printf("+++");
2214}
2215
2216////////////////////////////////////////////////////////////////////////////////
2217/// See if the data is ready to be analyzed.
2218
2220{
2221 if (!IsValid()) return kFALSE;
2222
2223 TList submasters;
2224 TIter nextSlave(GetListOfActiveSlaves());
2225 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
2226 if (sl->GetSlaveType() == TSlave::kMaster) {
2227 submasters.Add(sl);
2228 }
2229 }
2230
2231 fDataReady = kTRUE; //see if any submasters set it to false
2232 fBytesReady = 0;
2233 fTotalBytes = 0;
2234 //loop over submasters and see if data is ready
2235 if (submasters.GetSize() > 0) {
2236 Broadcast(kPROOF_DATA_READY, &submasters);
2237 Collect(&submasters);
2238 }
2239
2240 bytesready = fBytesReady;
2241 totalbytes = fTotalBytes;
2242
2243 EmitVA("IsDataReady(Long64_t,Long64_t)", 2, totalbytes, bytesready);
2244
2245 PDB(kGlobal,2)
2246 Info("IsDataReady", "%lld / %lld (%s)",
2247 bytesready, totalbytes, fDataReady?"READY":"NOT READY");
2248
2249 return fDataReady;
2250}
2251
2252////////////////////////////////////////////////////////////////////////////////
2253/// Send interrupt to master or slave servers.
2254
2256{
2257 if (!IsValid()) return;
2258
2259 TList *slaves = 0;
2260 if (list == kAll) slaves = fSlaves;
2261 if (list == kActive) slaves = fActiveSlaves;
2262 if (list == kUnique) slaves = fUniqueSlaves;
2263 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2264
2265 if (slaves->GetSize() == 0) return;
2266
2267 TSlave *sl;
2268 TIter next(slaves);
2269
2270 while ((sl = (TSlave *)next())) {
2271 if (sl->IsValid()) {
2272
2273 // Ask slave to progate the interrupt request
2274 sl->Interrupt((Int_t)type);
2275 }
2276 }
2277}
2278
2279////////////////////////////////////////////////////////////////////////////////
2280/// Returns number of slaves active in parallel mode. Returns 0 in case
2281/// there are no active slaves. Returns -1 in case of error.
2282
2284{
2285 if (!IsValid()) return -1;
2286
2287 // iterate over active slaves and return total number of slaves
2288 TIter nextSlave(GetListOfActiveSlaves());
2289 Int_t nparallel = 0;
2290 while (TSlave* sl = dynamic_cast<TSlave*>(nextSlave()))
2291 if (sl->GetParallel() >= 0)
2292 nparallel += sl->GetParallel();
2293
2294 return nparallel;
2295}
2296
2297////////////////////////////////////////////////////////////////////////////////
2298/// Returns list of TSlaveInfo's. In case of error return 0.
2299
2301{
2302 if (!IsValid()) return 0;
2303
2304 if (fSlaveInfo == 0) {
2307 } else {
2308 fSlaveInfo->Delete();
2309 }
2310
2311 TList masters;
2312 TIter next(GetListOfSlaves());
2313 TSlave *slave;
2314
2315 while ((slave = (TSlave *) next()) != 0) {
2316 if (slave->GetSlaveType() == TSlave::kSlave) {
2317 const char *name = IsLite() ? gSystem->HostName() : slave->GetName();
2318 TSlaveInfo *slaveinfo = new TSlaveInfo(slave->GetOrdinal(),
2319 name,
2320 slave->GetPerfIdx());
2321 fSlaveInfo->Add(slaveinfo);
2322
2323 TIter nextactive(GetListOfActiveSlaves());
2324 TSlave *activeslave;
2325 while ((activeslave = (TSlave *) nextactive())) {
2326 if (TString(slaveinfo->GetOrdinal()) == activeslave->GetOrdinal()) {
2327 slaveinfo->SetStatus(TSlaveInfo::kActive);
2328 break;
2329 }
2330 }
2331
2332 TIter nextbad(GetListOfBadSlaves());
2333 TSlave *badslave;
2334 while ((badslave = (TSlave *) nextbad())) {
2335 if (TString(slaveinfo->GetOrdinal()) == badslave->GetOrdinal()) {
2336 slaveinfo->SetStatus(TSlaveInfo::kBad);
2337 break;
2338 }
2339 }
2340 // Get system info if supported
2341 if (slave->IsValid()) {
2342 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2343 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2344 else
2345 masters.Add(slave);
2346 }
2347
2348 } else if (slave->GetSlaveType() == TSlave::kMaster) {
2349 if (slave->IsValid()) {
2350 if (slave->GetSocket()->Send(kPROOF_GETSLAVEINFO) == -1)
2351 MarkBad(slave, "could not send kPROOF_GETSLAVEINFO message");
2352 else
2353 masters.Add(slave);
2354 }
2355 } else {
2356 Error("GetSlaveInfo", "TSlave is neither Master nor Slave");
2357 R__ASSERT(0);
2358 }
2359 }
2360 if (masters.GetSize() > 0) Collect(&masters);
2361
2362 return fSlaveInfo;
2363}
2364
2365////////////////////////////////////////////////////////////////////////////////
2366/// Activate slave server list.
2367
2369{
2370 TMonitor *mon = fAllMonitor;
2371 mon->DeActivateAll();
2372
2373 slaves = !slaves ? fActiveSlaves : slaves;
2374
2375 TIter next(slaves);
2376 TSlave *sl;
2377 while ((sl = (TSlave*) next())) {
2378 if (sl->IsValid())
2379 mon->Activate(sl->GetSocket());
2380 }
2381}
2382
2383////////////////////////////////////////////////////////////////////////////////
2384/// Activate (on == TRUE) or deactivate (on == FALSE) all sockets
2385/// monitored by 'mon'.
2386
2388{
2389 TMonitor *m = (mon) ? mon : fCurrentMonitor;
2390 if (m) {
2391 if (on)
2392 m->ActivateAll();
2393 else
2394 m->DeActivateAll();
2395 }
2396}
2397
2398////////////////////////////////////////////////////////////////////////////////
2399/// Broadcast the group priority to all workers in the specified list. Returns
2400/// the number of workers the message was successfully sent to.
2401/// Returns -1 in case of error.
2402
2403Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, TList *workers)
2404{
2405 if (!IsValid()) return -1;
2406
2407 if (workers->GetSize() == 0) return 0;
2408
2409 int nsent = 0;
2410 TIter next(workers);
2411
2412 TSlave *wrk;
2413 while ((wrk = (TSlave *)next())) {
2414 if (wrk->IsValid()) {
2415 if (wrk->SendGroupPriority(grp, priority) == -1)
2416 MarkBad(wrk, "could not send group priority");
2417 else
2418 nsent++;
2419 }
2420 }
2421
2422 return nsent;
2423}
2424
2425////////////////////////////////////////////////////////////////////////////////
2426/// Broadcast the group priority to all workers in the specified list. Returns
2427/// the number of workers the message was successfully sent to.
2428/// Returns -1 in case of error.
2429
2430Int_t TProof::BroadcastGroupPriority(const char *grp, Int_t priority, ESlaves list)
2431{
2432 TList *workers = 0;
2433 if (list == kAll) workers = fSlaves;
2434 if (list == kActive) workers = fActiveSlaves;
2435 if (list == kUnique) workers = fUniqueSlaves;
2436 if (list == kAllUnique) workers = fAllUniqueSlaves;
2437
2438 return BroadcastGroupPriority(grp, priority, workers);
2439}
2440
2441////////////////////////////////////////////////////////////////////////////////
2442/// Reset the merge progress notificator
2443
2445{
2447}
2448
2449////////////////////////////////////////////////////////////////////////////////
2450/// Broadcast a message to all slaves in the specified list. Returns
2451/// the number of slaves the message was successfully sent to.
2452/// Returns -1 in case of error.
2453
2455{
2456 if (!IsValid()) return -1;
2457
2458 if (!slaves || slaves->GetSize() == 0) return 0;
2459
2460 int nsent = 0;
2461 TIter next(slaves);
2462
2463 TSlave *sl;
2464 while ((sl = (TSlave *)next())) {
2465 if (sl->IsValid()) {
2466 if (sl->GetSocket()->Send(mess) == -1)
2467 MarkBad(sl, "could not broadcast request");
2468 else
2469 nsent++;
2470 }
2471 }
2472
2473 return nsent;
2474}
2475
2476////////////////////////////////////////////////////////////////////////////////
2477/// Broadcast a message to all slaves in the specified list (either
2478/// all slaves or only the active slaves). Returns the number of slaves
2479/// the message was successfully sent to. Returns -1 in case of error.
2480
2482{
2483 TList *slaves = 0;
2484 if (list == kAll) slaves = fSlaves;
2485 if (list == kActive) slaves = fActiveSlaves;
2486 if (list == kUnique) slaves = fUniqueSlaves;
2487 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2488
2489 return Broadcast(mess, slaves);
2490}
2491
2492////////////////////////////////////////////////////////////////////////////////
2493/// Broadcast a character string buffer to all slaves in the specified
2494/// list. Use kind to set the TMessage what field. Returns the number of
2495/// slaves the message was sent to. Returns -1 in case of error.
2496
2497Int_t TProof::Broadcast(const char *str, Int_t kind, TList *slaves)
2498{
2499 TMessage mess(kind);
2500 if (str) mess.WriteString(str);
2501 return Broadcast(mess, slaves);
2502}
2503
2504////////////////////////////////////////////////////////////////////////////////
2505/// Broadcast a character string buffer to all slaves in the specified
2506/// list (either all slaves or only the active slaves). Use kind to
2507/// set the TMessage what field. Returns the number of slaves the message
2508/// was sent to. Returns -1 in case of error.
2509
2510Int_t TProof::Broadcast(const char *str, Int_t kind, ESlaves list)
2511{
2512 TMessage mess(kind);
2513 if (str) mess.WriteString(str);
2514 return Broadcast(mess, list);
2515}
2516
2517////////////////////////////////////////////////////////////////////////////////
2518/// Broadcast an object to all slaves in the specified list. Use kind to
2519/// set the TMEssage what field. Returns the number of slaves the message
2520/// was sent to. Returns -1 in case of error.
2521
2523{
2524 TMessage mess(kind);
2525 mess.WriteObject(obj);
2526 return Broadcast(mess, slaves);
2527}
2528
2529////////////////////////////////////////////////////////////////////////////////
2530/// Broadcast an object to all slaves in the specified list. Use kind to
2531/// set the TMEssage what field. Returns the number of slaves the message
2532/// was sent to. Returns -1 in case of error.
2533
2535{
2536 TMessage mess(kind);
2537 mess.WriteObject(obj);
2538 return Broadcast(mess, list);
2539}
2540
2541////////////////////////////////////////////////////////////////////////////////
2542/// Broadcast a raw buffer of specified length to all slaves in the
2543/// specified list. Returns the number of slaves the buffer was sent to.
2544/// Returns -1 in case of error.
2545
2546Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, TList *slaves)
2547{
2548 if (!IsValid()) return -1;
2549
2550 if (slaves->GetSize() == 0) return 0;
2551
2552 int nsent = 0;
2553 TIter next(slaves);
2554
2555 TSlave *sl;
2556 while ((sl = (TSlave *)next())) {
2557 if (sl->IsValid()) {
2558 if (sl->GetSocket()->SendRaw(buffer, length) == -1)
2559 MarkBad(sl, "could not send broadcast-raw request");
2560 else
2561 nsent++;
2562 }
2563 }
2564
2565 return nsent;
2566}
2567
2568////////////////////////////////////////////////////////////////////////////////
2569/// Broadcast a raw buffer of specified length to all slaves in the
2570/// specified list. Returns the number of slaves the buffer was sent to.
2571/// Returns -1 in case of error.
2572
2573Int_t TProof::BroadcastRaw(const void *buffer, Int_t length, ESlaves list)
2574{
2575 TList *slaves = 0;
2576 if (list == kAll) slaves = fSlaves;
2577 if (list == kActive) slaves = fActiveSlaves;
2578 if (list == kUnique) slaves = fUniqueSlaves;
2579 if (list == kAllUnique) slaves = fAllUniqueSlaves;
2580
2581 return BroadcastRaw(buffer, length, slaves);
2582}
2583
2584////////////////////////////////////////////////////////////////////////////////
2585/// Broadcast file to all workers in the specified list. Returns the number of workers
2586/// the buffer was sent to.
2587/// Returns -1 in case of error.
2588
2589Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, TList *wrks)
2590{
2591 if (!IsValid()) return -1;
2592
2593 if (wrks->GetSize() == 0) return 0;
2594
2595 int nsent = 0;
2596 TIter next(wrks);
2597
2598 TSlave *wrk;
2599 while ((wrk = (TSlave *)next())) {
2600 if (wrk->IsValid()) {
2601 if (SendFile(file, opt, rfile, wrk) < 0)
2602 Error("BroadcastFile",
2603 "problems sending file to worker %s (%s)",
2604 wrk->GetOrdinal(), wrk->GetName());
2605 else
2606 nsent++;
2607 }
2608 }
2609
2610 return nsent;
2611}
2612
2613////////////////////////////////////////////////////////////////////////////////
2614/// Broadcast file to all workers in the specified list. Returns the number of workers
2615/// the buffer was sent to.
2616/// Returns -1 in case of error.
2617
2618Int_t TProof::BroadcastFile(const char *file, Int_t opt, const char *rfile, ESlaves list)
2619{
2620 TList *wrks = 0;
2621 if (list == kAll) wrks = fSlaves;
2622 if (list == kActive) wrks = fActiveSlaves;
2623 if (list == kUnique) wrks = fUniqueSlaves;
2624 if (list == kAllUnique) wrks = fAllUniqueSlaves;
2625
2626 return BroadcastFile(file, opt, rfile, wrks);
2627}
2628
2629////////////////////////////////////////////////////////////////////////////////
2630/// Release the used monitor to be used, making sure to delete newly created
2631/// monitors.
2632
2634{
2635 if (mon && (mon != fAllMonitor) && (mon != fActiveMonitor)
2636 && (mon != fUniqueMonitor) && (mon != fAllUniqueMonitor)) {
2637 delete mon;
2638 }
2639}
2640
2641////////////////////////////////////////////////////////////////////////////////
2642/// Collect responses from slave sl. Returns the number of slaves that
2643/// responded (=1).
2644/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2645/// which means wait forever).
2646/// If defined (>= 0) endtype is the message that stops this collection.
2647
2648Int_t TProof::Collect(const TSlave *sl, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2649{
2650 Int_t rc = 0;
2651
2652 TMonitor *mon = 0;
2653 if (!sl->IsValid()) return 0;
2654
2656 mon = new TMonitor;
2657 } else {
2658 mon = fAllMonitor;
2659 mon->DeActivateAll();
2660 }
2661 mon->Activate(sl->GetSocket());
2662
2663 rc = Collect(mon, timeout, endtype, deactonfail);
2664 ReleaseMonitor(mon);
2665 return rc;
2666}
2667
2668////////////////////////////////////////////////////////////////////////////////
2669/// Collect responses from the slave servers. Returns the number of slaves
2670/// that responded.
2671/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2672/// which means wait forever).
2673/// If defined (>= 0) endtype is the message that stops this collection.
2674
2675Int_t TProof::Collect(TList *slaves, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2676{
2677 Int_t rc = 0;
2678
2679 TMonitor *mon = 0;
2680
2682 mon = new TMonitor;
2683 } else {
2684 mon = fAllMonitor;
2685 mon->DeActivateAll();
2686 }
2687 TIter next(slaves);
2688 TSlave *sl;
2689 while ((sl = (TSlave*) next())) {
2690 if (sl->IsValid())
2691 mon->Activate(sl->GetSocket());
2692 }
2693
2694 rc = Collect(mon, timeout, endtype, deactonfail);
2695 ReleaseMonitor(mon);
2696 return rc;
2697}
2698
2699////////////////////////////////////////////////////////////////////////////////
2700/// Collect responses from the slave servers. Returns the number of slaves
2701/// that responded.
2702/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2703/// which means wait forever).
2704/// If defined (>= 0) endtype is the message that stops this collection.
2705
2706Int_t TProof::Collect(ESlaves list, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2707{
2708 Int_t rc = 0;
2709 TMonitor *mon = 0;
2710
2711 if (list == kAll) mon = fAllMonitor;
2712 if (list == kActive) mon = fActiveMonitor;
2713 if (list == kUnique) mon = fUniqueMonitor;
2714 if (list == kAllUnique) mon = fAllUniqueMonitor;
2715 if (fCurrentMonitor == mon) {
2716 // Get a copy
2717 mon = new TMonitor(*mon);
2718 }
2719 mon->ActivateAll();
2720
2721 rc = Collect(mon, timeout, endtype, deactonfail);
2722 ReleaseMonitor(mon);
2723 return rc;
2724}
2725
2726////////////////////////////////////////////////////////////////////////////////
2727/// Collect responses from the slave servers. Returns the number of messages
2728/// received. Can be 0 if there are no active slaves.
2729/// If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
2730/// which means wait forever).
2731/// If defined (>= 0) endtype is the message that stops this collection.
2732/// Collect also stops its execution from time to time to check for new
2733/// workers in Dynamic Startup mode.
2734
2735Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deactonfail)
2736{
2737 Int_t collectId = gRandom->Integer(9999);
2738
2739 PDB(kCollect, 3)
2740 Info("Collect", ">>>>>> Entering collect responses #%04d", collectId);
2741
2742 // Reset the status flag and clear the messages in the list, if any
2743 fStatus = 0;
2745
2746 Long_t actto = (Long_t)(gEnv->GetValue("Proof.SocketActivityTimeout", -1) * 1000);
2747
2748 if (!mon->GetActive(actto)) return 0;
2749
2751
2752 // Used by external code to know what we are monitoring
2753 TMonitor *savedMonitor = 0;
2754 if (fCurrentMonitor) {
2755 savedMonitor = fCurrentMonitor;
2756 fCurrentMonitor = mon;
2757 } else {
2758 fCurrentMonitor = mon;
2759 fBytesRead = 0;
2760 fRealTime = 0.0;
2761 fCpuTime = 0.0;
2762 }
2763
2764 // We want messages on the main window during synchronous collection,
2765 // but we save the present status to restore it at the end
2766 Bool_t saveRedirLog = fRedirLog;
2767 if (!IsIdle() && !IsSync())
2768 fRedirLog = kFALSE;
2769
2770 int cnt = 0, rc = 0;
2771
2772 // Timeout counter
2773 Long_t nto = timeout;
2774 PDB(kCollect, 2)
2775 Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
2776
2777 // On clients, handle Ctrl-C during collection
2778 if (fIntHandler)
2779 fIntHandler->Add();
2780
2781 // Sockets w/o activity during the last 'sto' millisecs are deactivated
2782 Int_t nact = 0;
2783 Long_t sto = -1;
2784 Int_t nsto = 60;
2785 Int_t pollint = gEnv->GetValue("Proof.DynamicStartupPollInt", (Int_t) kPROOF_DynWrkPollInt_s);
2786 mon->ResetInterrupt();
2787 while ((nact = mon->GetActive(sto)) && (nto < 0 || nto > 0)) {
2788
2789 // Dump last waiting sockets, if in debug mode
2790 PDB(kCollect, 2) {
2791 if (nact < 4) {
2792 TList *al = mon->GetListOfActives();
2793 if (al && al->GetSize() > 0) {
2794 Info("Collect"," %d node(s) still active:", al->GetSize());
2795 TIter nxs(al);
2796 TSocket *xs = 0;
2797 while ((xs = (TSocket *)nxs())) {
2798 TSlave *wrk = FindSlave(xs);
2799 if (wrk)
2800 Info("Collect"," %s (%s)", wrk->GetName(), wrk->GetOrdinal());
2801 else
2802 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2803 xs->GetInetAddress().GetPort());
2804 }
2805 }
2806 }
2807 }
2808
2809 // Preemptive poll for new workers on the master only in Dynamic Mode and only
2810 // during processing (TODO: should work on Top Master only)
2812 ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= pollint))) {
2815 fLastPollWorkers_s = time(0);
2817 PDB(kCollect, 1)
2818 Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
2819 }
2820
2821 // Wait for a ready socket
2822 PDB(kCollect, 3)
2823 Info("Collect", "Will invoke Select() #%04d", collectId);
2824 TSocket *s = mon->Select(1000);
2825
2826 if (s && s != (TSocket *)(-1)) {
2827 // Get and analyse the info it did receive
2828 rc = CollectInputFrom(s, endtype, deactonfail);
2829 if (rc == 1 || (rc == 2 && !savedMonitor)) {
2830 // Deactivate it if we are done with it
2831 mon->DeActivate(s);
2832 PDB(kCollect, 2)
2833 Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
2834 s, mon->GetActive(),
2835 mon->GetListOfActives()->First());
2836 } else if (rc == 2) {
2837 // This end message was for the saved monitor
2838 // Deactivate it if we are done with it
2839 if (savedMonitor) {
2840 savedMonitor->DeActivate(s);
2841 PDB(kCollect, 2)
2842 Info("Collect","save monitor: deactivating %p (active: %d, %p)",
2843 s, savedMonitor->GetActive(),
2844 savedMonitor->GetListOfActives()->First());
2845 }
2846 }
2847
2848 // Update counter (if no error occured)
2849 if (rc >= 0)
2850 cnt++;
2851 } else {
2852 // If not timed-out, exit if not stopped or not aborted
2853 // (player exits status is finished in such a case); otherwise,
2854 // we still need to collect the partial output info
2855 if (!s)
2857 mon->DeActivateAll();
2858 // Decrease the timeout counter if requested
2859 if (s == (TSocket *)(-1) && nto > 0)
2860 nto--;
2861 }
2862
2863 // Check if there are workers with ready output to be sent and ask the first to send it
2865 // Maximum number of concurrent sendings
2866 Int_t mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2867 if (TProof::GetParameter(fPlayer->GetInputList(), "PROOF_ControlSendOutput", mxws) != 0)
2868 mxws = gEnv->GetValue("Proof.ControlSendOutput", 1);
2869 TIter nxwr(fWrksOutputReady);
2870 TSlave *wrk = 0;
2871 while (mxws && (wrk = (TSlave *) nxwr())) {
2872 if (!wrk->TestBit(TSlave::kOutputRequested)) {
2873 // Ask worker for output
2874 TMessage sendoutput(kPROOF_SENDOUTPUT);
2875 PDB(kCollect, 2)
2876 Info("Collect", "worker %s was asked to send its output to master",
2877 wrk->GetOrdinal());
2878 if (wrk->GetSocket()->Send(sendoutput) != 1) {
2880 mxws--;
2881 }
2882 } else {
2883 // Count
2884 mxws--;
2885 }
2886 }
2887 }
2888
2889 // Check if we need to check the socket activity (we do it every 10 cycles ~ 10 sec)
2890 sto = -1;
2891 if (--nsto <= 0) {
2892 sto = (Long_t) actto;
2893 nsto = 60;
2894 }
2895
2896 } // end loop over active monitors
2897
2898 // If timed-out, deactivate the remaining sockets
2899 if (nto == 0) {
2900 TList *al = mon->GetListOfActives();
2901 if (al && al->GetSize() > 0) {
2902 // Notify the name of those which did timeout
2903 Info("Collect"," %d node(s) went in timeout:", al->GetSize());
2904 TIter nxs(al);
2905 TSocket *xs = 0;
2906 while ((xs = (TSocket *)nxs())) {
2907 TSlave *wrk = FindSlave(xs);
2908 if (wrk)
2909 Info("Collect"," %s", wrk->GetName());
2910 else
2911 Info("Collect"," %p: %s:%d", xs, xs->GetInetAddress().GetHostName(),
2912 xs->GetInetAddress().GetPort());
2913 }
2914 }
2915 mon->DeActivateAll();
2916 }
2917
2918 // Deactivate Ctrl-C special handler
2919 if (fIntHandler)
2921
2922 // make sure group view is up to date
2923 SendGroupView();
2924
2925 // Restore redirection setting
2926 fRedirLog = saveRedirLog;
2927
2928 // Restore the monitor
2929 fCurrentMonitor = savedMonitor;
2930
2932
2933 PDB(kCollect, 3)
2934 Info("Collect", "<<<<<< Exiting collect responses #%04d", collectId);
2935
2936 return cnt;
2937}
2938
2939////////////////////////////////////////////////////////////////////////////////
2940/// Asks the PROOF Serv for new workers in Dynamic Startup mode and activates
2941/// them. Returns the number of new workers found, or <0 on errors.
2942
2944{
2945 // Requests for worker updates
2946 Int_t dummy = 0;
2947 TList *reqWorkers = new TList();
2948 reqWorkers->SetOwner(kFALSE);
2949
2950 if (!TestBit(TProof::kIsMaster)) {
2951 Error("PollForNewWorkers", "Can't invoke: not on a master -- should not happen!");
2952 return -1;
2953 }
2954 if (!gProofServ) {
2955 Error("PollForNewWorkers", "No ProofServ available -- should not happen!");
2956 return -1;
2957 }
2958
2959 gProofServ->GetWorkers(reqWorkers, dummy, kTRUE); // last 2 are dummy
2960
2961 // List of new workers only (TProofNodeInfo)
2962 TList *newWorkers = new TList();
2963 newWorkers->SetOwner(kTRUE);
2964
2965 TIter next(reqWorkers);
2966 TProofNodeInfo *ni;
2967 TString fullOrd;
2968 while (( ni = dynamic_cast<TProofNodeInfo *>(next()) )) {
2969
2970 // Form the full ordinal
2971 fullOrd.Form("%s.%s", gProofServ->GetOrdinal(), ni->GetOrdinal().Data());
2972
2973 TIter nextInner(fSlaves);
2974 TSlave *sl;
2975 Bool_t found = kFALSE;
2976 while (( sl = dynamic_cast<TSlave *>(nextInner()) )) {
2977 if ( strcmp(sl->GetOrdinal(), fullOrd.Data()) == 0 ) {
2978 found = kTRUE;
2979 break;
2980 }
2981 }
2982
2983 if (found) delete ni;
2984 else {
2985 newWorkers->Add(ni);
2986 PDB(kGlobal, 1)
2987 Info("PollForNewWorkers", "New worker found: %s:%s",
2988 ni->GetNodeName().Data(), fullOrd.Data());
2989 }
2990 }
2991
2992 delete reqWorkers; // not owner
2993
2994 Int_t nNewWorkers = newWorkers->GetEntries();
2995
2996 // Add the new workers
2997 if (nNewWorkers > 0) {
2998 PDB(kGlobal, 1)
2999 Info("PollForNewWorkers", "Requesting to add %d new worker(s)", newWorkers->GetEntries());
3000 Int_t rv = AddWorkers(newWorkers);
3001 if (rv < 0) {
3002 Error("PollForNewWorkers", "Call to AddWorkers() failed (got %d < 0)", rv);
3003 return -1;
3004 }
3005 // Don't delete newWorkers: AddWorkers() will do that
3006 }
3007 else {
3008 PDB(kGlobal, 2)
3009 Info("PollForNewWorkers", "No new worker found");
3010 delete newWorkers;
3011 }
3012
3013 return nNewWorkers;
3014}
3015
3016////////////////////////////////////////////////////////////////////////////////
3017/// Remove links to objects in list 'ol' from gDirectory
3018
3020{
3021 if (ol) {
3022 TIter nxo(ol);
3023 TObject *o = 0;
3024 while ((o = nxo()))
3025 gDirectory->RecursiveRemove(o);
3026 }
3027}
3028
3029////////////////////////////////////////////////////////////////////////////////
3030/// Collect and analyze available input from socket s.
3031/// Returns 0 on success, -1 if any failure occurs.
3032
3034{
3035 TMessage *mess;
3036
3037 Int_t recvrc = 0;
3038 if ((recvrc = s->Recv(mess)) < 0) {
3039 PDB(kCollect,2)
3040 Info("CollectInputFrom","%p: got %d from Recv()", s, recvrc);
3041 Bool_t bad = kTRUE;
3042 if (recvrc == -5) {
3043 // Broken connection: try reconnection
3045 if (s->Reconnect() == 0) {
3047 bad = kFALSE;
3048 }
3049 }
3050 if (bad)
3051 MarkBad(s, "problems receiving a message in TProof::CollectInputFrom(...)");
3052 // Ignore this wake up
3053 return -1;
3054 }
3055 if (!mess) {
3056 // we get here in case the remote server died
3057 MarkBad(s, "undefined message in TProof::CollectInputFrom(...)");
3058 return -1;
3059 }
3060 Int_t rc = 0;
3061
3062 Int_t what = mess->What();
3063 TSlave *sl = FindSlave(s);
3064 rc = HandleInputMessage(sl, mess, deactonfail);
3065 if (rc == 1 && (endtype >= 0) && (what != endtype))
3066 // This message was for the base monitor in recursive case
3067 rc = 2;
3068
3069 // We are done successfully
3070 return rc;
3071}
3072
3073////////////////////////////////////////////////////////////////////////////////
3074/// Analyze the received message.
3075/// Returns 0 on success (1 if this the last message from this socket), -1 if
3076/// any failure occurs.
3077
3079{
3080 char str[512];
3081 TObject *obj;
3082 Int_t rc = 0;
3083
3084 if (!mess || !sl) {
3085 Warning("HandleInputMessage", "given an empty message or undefined worker");
3086 return -1;
3087 }
3088 Bool_t delete_mess = kTRUE;
3089 TSocket *s = sl->GetSocket();
3090 if (!s) {
3091 Warning("HandleInputMessage", "worker socket is undefined");
3092 return -1;
3093 }
3094
3095 // The message type
3096 Int_t what = mess->What();
3097
3098 PDB(kCollect,3)
3099 Info("HandleInputMessage", "got type %d from '%s'", what, sl->GetOrdinal());
3100
3101 switch (what) {
3102
3103 case kMESS_OK:
3104 // Add the message to the list
3105 fRecvMessages->Add(mess);
3106 delete_mess = kFALSE;
3107 break;
3108
3109 case kMESS_OBJECT:
3110 if (fPlayer) fPlayer->HandleRecvHisto(mess);
3111 break;
3112
3113 case kPROOF_FATAL:
3114 { TString msg;
3115 if ((mess->BufferSize() > mess->Length()))
3116 (*mess) >> msg;
3117 if (msg.IsNull()) {
3118 MarkBad(s, "received kPROOF_FATAL");
3119 } else {
3120 MarkBad(s, msg);
3121 }
3122 }
3124 // Finalize the progress dialog
3125 Emit("StopProcess(Bool_t)", kTRUE);
3126 }
3127 break;
3128
3129 case kPROOF_STOP:
3130 // Stop collection from this worker
3131 Info("HandleInputMessage", "received kPROOF_STOP from %s: disabling any further collection this worker",
3132 sl->GetOrdinal());
3133 rc = 1;
3134 break;
3135
3137 // Add the message to the list
3138 fRecvMessages->Add(mess);
3139 delete_mess = kFALSE;
3140 rc = 1;
3141 break;
3142
3143 case kPROOF_TOUCH:
3144 // send a request for touching the remote admin file
3145 {
3146 sl->Touch();
3147 }
3148 break;
3149
3150 case kPROOF_GETOBJECT:
3151 // send slave object it asks for
3152 mess->ReadString(str, sizeof(str));
3153 obj = gDirectory->Get(str);
3154 if (obj)
3155 s->SendObject(obj);
3156 else
3157 s->Send(kMESS_NOTOK);
3158 break;
3159
3160 case kPROOF_GETPACKET:
3161 {
3162 PDB(kGlobal,2)
3163 Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
3164 TDSetElement *elem = 0;
3165 elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
3166
3167 if (elem != (TDSetElement*) -1) {
3169 answ << elem;
3170 s->Send(answ);
3171
3172 while (fWaitingSlaves != 0 && fWaitingSlaves->GetSize()) {
3173 TPair *p = (TPair*) fWaitingSlaves->First();
3174 s = (TSocket*) p->Key();
3175 TMessage *m = (TMessage*) p->Value();
3176
3177 elem = fPlayer ? fPlayer->GetNextPacket(sl, m) : 0;
3178 if (elem != (TDSetElement*) -1) {
3180 a << elem;
3181 s->Send(a);
3182 // remove has to happen via Links because TPair does not have
3183 // a Compare() function and therefore RemoveFirst() and
3184 // Remove(TObject*) do not work
3186 delete p;
3187 delete m;
3188 } else {
3189 break;
3190 }
3191 }
3192 } else {
3193 if (fWaitingSlaves == 0) fWaitingSlaves = new TList;
3194 fWaitingSlaves->Add(new TPair(s, mess));
3195 delete_mess = kFALSE;
3196 }
3197 }
3198 break;
3199
3200 case kPROOF_LOGFILE:
3201 {
3202 Int_t size;
3203 (*mess) >> size;
3204 PDB(kGlobal,2)
3205 Info("HandleInputMessage","%s: kPROOF_LOGFILE: size: %d", sl->GetOrdinal(), size);
3206 RecvLogFile(s, size);
3207 }
3208 break;
3209
3210 case kPROOF_LOGDONE:
3211 (*mess) >> sl->fStatus >> sl->fParallel;
3212 PDB(kCollect,2)
3213 Info("HandleInputMessage","%s: kPROOF_LOGDONE: status %d parallel %d",
3214 sl->GetOrdinal(), sl->fStatus, sl->fParallel);
3215 if (sl->fStatus != 0) {
3216 // Return last nonzero status
3217 fStatus = sl->fStatus;
3218 // Deactivate the worker, if required
3219 if (deactonfail) DeactivateWorker(sl->fOrdinal);
3220 }
3221 // Remove from the workers-ready list
3225 }
3226 rc = 1;
3227 break;
3228
3229 case kPROOF_GETSTATS:
3230 {
3231 (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
3232 >> sl->fWorkDir >> sl->fProofWorkDir;
3233 PDB(kCollect,2)
3234 Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
3235 TString img;
3236 if ((mess->BufferSize() > mess->Length()))
3237 (*mess) >> img;
3238 // Set image
3239 if (img.IsNull()) {
3240 if (sl->fImage.IsNull())
3241 sl->fImage.Form("%s:%s", TUrl(sl->fName).GetHostFQDN(),
3242 sl->fProofWorkDir.Data());
3243 } else {
3244 sl->fImage = img;
3245 }
3246 PDB(kGlobal,2)
3247 Info("HandleInputMessage",
3248 "kPROOF_GETSTATS:%s image: %s", sl->GetOrdinal(), sl->GetImage());
3249
3250 fBytesRead += sl->fBytesRead;
3251 fRealTime += sl->fRealTime;
3252 fCpuTime += sl->fCpuTime;
3253 rc = 1;
3254 }
3255 break;
3256
3257 case kPROOF_GETPARALLEL:
3258 {
3259 Bool_t async = kFALSE;
3260 (*mess) >> sl->fParallel;
3261 if ((mess->BufferSize() > mess->Length()))
3262 (*mess) >> async;
3263 rc = (async) ? 0 : 1;
3264 }
3265 break;
3266
3267 case kPROOF_CHECKFILE:
3268 { // New servers (>= 5.22) send the status
3269 if ((mess->BufferSize() > mess->Length())) {
3270 (*mess) >> fCheckFileStatus;
3271 } else {
3272 // Form old servers this meant success (failure was signaled with the
3273 // dangerous kPROOF_FATAL)
3274 fCheckFileStatus = 1;
3275 }
3276 rc = 1;
3277 }
3278 break;
3279
3280 case kPROOF_SENDFILE:
3281 { // New server: signals ending of sendfile operation
3282 rc = 1;
3283 }
3284 break;
3285
3287 {
3288 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PACKAGE_LIST: enter");
3289 Int_t type = 0;
3290 (*mess) >> type;
3291 switch (type) {
3295 if (fEnabledPackages) {
3297 } else {
3298 Error("HandleInputMessage",
3299 "kPROOF_PACKAGE_LIST: kListEnabledPackages: TList not found in message!");
3300 }
3301 break;
3305 if (fAvailablePackages) {
3307 } else {
3308 Error("HandleInputMessage",
3309 "kPROOF_PACKAGE_LIST: kListPackages: TList not found in message!");
3310 }
3311 break;
3312 default:
3313 Error("HandleInputMessage", "kPROOF_PACKAGE_LIST: unknown type: %d", type);
3314 }
3315 }
3316 break;
3317
3318 case kPROOF_SENDOUTPUT:
3319 {
3320 // We start measuring the merging time
3322
3323 // Worker is ready to send output: make sure the relevant bit is reset
3325 PDB(kGlobal,2)
3326 Info("HandleInputMessage","kPROOF_SENDOUTPUT: enter (%s)", sl->GetOrdinal());
3327 // Create the list if not yet done
3328 if (!fWrksOutputReady) {
3329 fWrksOutputReady = new TList;
3331 }
3332 fWrksOutputReady->Add(sl);
3333 }
3334 break;
3335
3337 {
3338 // We start measuring the merging time
3340
3341 PDB(kGlobal,2)
3342 Info("HandleInputMessage","kPROOF_OUTPUTOBJECT: enter");
3343 Int_t type = 0;
3344 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
3346 Info("HandleInputMessage", "finalization on %s started ...", prefix);
3348 }
3349
3350 while ((mess->BufferSize() > mess->Length())) {
3351 (*mess) >> type;
3352 // If a query result header, add it to the player list
3353 if (fPlayer) {
3354 if (type == 0) {
3355 // Retrieve query result instance (output list not filled)
3356 TQueryResult *pq =
3358 if (pq) {
3359 // Add query to the result list in TProofPlayer
3362 // And clear the output list, as we start merging a new set of results
3363 if (fPlayer->GetOutputList())
3365 // Add the unique query tag as TNamed object to the input list
3366 // so that it is available in TSelectors for monitoring
3367 TString qid = TString::Format("%s:%s",pq->GetTitle(),pq->GetName());
3368 if (fPlayer->GetInputList()->FindObject("PROOF_QueryTag"))
3369 fPlayer->GetInputList()->Remove(fPlayer->GetInputList()->FindObject("PROOF_QueryTag"));
3370 fPlayer->AddInput(new TNamed("PROOF_QueryTag", qid.Data()));
3371 } else {
3372 Warning("HandleInputMessage","kPROOF_OUTPUTOBJECT: query result missing");
3373 }
3374 } else if (type > 0) {
3375 // Read object
3376 TObject *o = mess->ReadObject(TObject::Class());
3377 // Increment counter on the client side
3379 TString msg;
3380 Bool_t changed = kFALSE;
3381 msg.Form("%s: merging output objects ... %s", prefix, fMergePrg.Export(changed));
3382 if (gProofServ) {
3384 } else if (IsTty() || changed) {
3385 fprintf(stderr, "%s\r", msg.Data());
3386 }
3387 // Add or merge it
3388 if ((fPlayer->AddOutputObject(o) == 1)) {
3389 // Remove the object if it has been merged
3390 SafeDelete(o);
3391 }
3392 if (type > 1) {
3393 // Update the merger progress info
3395 if (TestBit(TProof::kIsClient) && !IsLite()) {
3396 // In PROOFLite this has to be done once only in TProofLite::Process
3398 if (pq) {
3400 // Add input objects (do not override remote settings, if any)
3401 TObject *xo = 0;
3402 TIter nxin(fPlayer->GetInputList());
3403 // Servers prior to 5.28/00 do not create the input list in the TQueryResult
3404 if (!pq->GetInputList()) pq->SetInputList(new TList());
3405 while ((xo = nxin()))
3406 if (!pq->GetInputList()->FindObject(xo->GetName()))
3407 pq->AddInput(xo->Clone());
3408 // If the last object, notify the GUI that the result arrived
3409 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3410 }
3411 // Processing is over
3412 UpdateDialog();
3413 }
3414 }
3415 }
3416 } else {
3417 Warning("HandleInputMessage", "kPROOF_OUTPUTOBJECT: player undefined!");
3418 }
3419 }
3420 }
3421 break;
3422
3423 case kPROOF_OUTPUTLIST:
3424 {
3425 // We start measuring the merging time
3426
3427 PDB(kGlobal,2)
3428 Info("HandleInputMessage","%s: kPROOF_OUTPUTLIST: enter", sl->GetOrdinal());
3429 TList *out = 0;
3430 if (fPlayer) {
3432 if (TestBit(TProof::kIsMaster) || fProtocol < 7) {
3433 out = (TList *) mess->ReadObject(TList::Class());
3434 } else {
3435 TQueryResult *pq =
3437 if (pq) {
3438 // Add query to the result list in TProofPlayer
3441 // To avoid accidental cleanups from anywhere else
3442 // remove objects from gDirectory and clone the list
3443 out = pq->GetOutputList();
3444 CleanGDirectory(out);
3445 out = (TList *) out->Clone();
3446 // Notify the GUI that the result arrived
3447 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3448 } else {
3449 PDB(kGlobal,2)
3450 Info("HandleInputMessage",
3451 "%s: kPROOF_OUTPUTLIST: query result missing", sl->GetOrdinal());
3452 }
3453 }
3454 if (out) {
3455 out->SetOwner();
3456 fPlayer->AddOutput(out); // Incorporate the list
3457 SafeDelete(out);
3458 } else {
3459 PDB(kGlobal,2)
3460 Info("HandleInputMessage",
3461 "%s: kPROOF_OUTPUTLIST: outputlist is empty", sl->GetOrdinal());
3462 }
3463 } else {
3464 Warning("HandleInputMessage",
3465 "%s: kPROOF_OUTPUTLIST: player undefined!", sl->GetOrdinal());
3466 }
3467 // On clients at this point processing is over
3468 if (TestBit(TProof::kIsClient) && !IsLite())
3469 UpdateDialog();
3470 }
3471 break;
3472
3473 case kPROOF_QUERYLIST:
3474 {
3475 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYLIST: enter");
3476 (*mess) >> fOtherQueries >> fDrawQueries;
3477 if (fQueries) {
3478 fQueries->Delete();
3479 delete fQueries;
3480 fQueries = 0;
3481 }
3482 fQueries = (TList *) mess->ReadObject(TList::Class());
3483 }
3484 break;
3485
3486 case kPROOF_RETRIEVE:
3487 {
3488 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_RETRIEVE: enter");
3489 TQueryResult *pq =
3491 if (pq && fPlayer) {
3493 // Notify the GUI that the result arrived
3494 QueryResultReady(TString::Format("%s:%s", pq->GetTitle(), pq->GetName()));
3495 } else {
3496 PDB(kGlobal,2)
3497 Info("HandleInputMessage",
3498 "kPROOF_RETRIEVE: query result missing or player undefined");
3499 }
3500 }
3501 break;
3502
3503 case kPROOF_MAXQUERIES:
3504 {
3505 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MAXQUERIES: enter");
3506 Int_t max = 0;
3507
3508 (*mess) >> max;
3509 Printf("Number of queries fully kept remotely: %d", max);
3510 }
3511 break;
3512
3514 {
3515 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SERVERSTARTED: enter");
3516
3517 UInt_t tot = 0, done = 0;
3518 TString action;
3519 Bool_t st = kTRUE;
3520
3521 (*mess) >> action >> tot >> done >> st;
3522
3524 if (tot) {
3525 TString type = (action.Contains("submas")) ? "submasters"
3526 : "workers";
3527 Int_t frac = (Int_t) (done*100.)/tot;
3528 char msg[512] = {0};
3529 if (frac >= 100) {
3530 snprintf(msg, 512, "%s: OK (%d %s) \n",
3531 action.Data(),tot, type.Data());
3532 } else {
3533 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3534 action.Data(), done, tot, frac);
3535 }
3536 if (fSync)
3537 fprintf(stderr,"%s", msg);
3538 else
3539 NotifyLogMsg(msg, 0);
3540 }
3541 // Notify GUIs
3542 StartupMessage(action.Data(), st, (Int_t)done, (Int_t)tot);
3543 } else {
3544
3545 // Just send the message one level up
3547 m << action << tot << done << st;
3549 }
3550 }
3551 break;
3552
3554 {
3555 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_DATASET_STATUS: enter");
3556
3557 UInt_t tot = 0, done = 0;
3558 TString action;
3559 Bool_t st = kTRUE;
3560
3561 (*mess) >> action >> tot >> done >> st;
3562
3564 if (tot) {
3565 TString type = "files";
3566 Int_t frac = (Int_t) (done*100.)/tot;
3567 char msg[512] = {0};
3568 if (frac >= 100) {
3569 snprintf(msg, 512, "%s: OK (%d %s) \n",
3570 action.Data(),tot, type.Data());
3571 } else {
3572 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
3573 action.Data(), done, tot, frac);
3574 }
3575 if (fSync)
3576 fprintf(stderr,"%s", msg);
3577 else
3578 NotifyLogMsg(msg, 0);
3579 }
3580 // Notify GUIs
3581 DataSetStatus(action.Data(), st, (Int_t)done, (Int_t)tot);
3582 } else {
3583
3584 // Just send the message one level up
3586 m << action << tot << done << st;
3588 }
3589 }
3590 break;
3591
3593 {
3594 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STARTPROCESS: enter");
3595
3596 // For Proof-Lite this variable is the number of workers and is set
3597 // by the player
3598 if (!IsLite()) {
3599 fNotIdle = 1;
3601 }
3602
3603 // Redirect the output, if needed
3605
3606 // The signal is used on masters by XrdProofdProtocol to catch
3607 // the start of processing; on clients it allows to update the
3608 // progress dialog
3609 if (!TestBit(TProof::kIsMaster)) {
3610
3611 // This is the end of preparation
3612 fQuerySTW.Stop();
3614 PDB(kGlobal,2) Info("HandleInputMessage","Preparation time: %f s", fPrepTime);
3615
3616 TString selec;
3617 Int_t dsz = -1;
3618 Long64_t first = -1, nent = -1;
3619 (*mess) >> selec >> dsz >> first >> nent;
3620 // Start or reset the progress dialog
3621 if (!gROOT->IsBatch()) {
3622 if (fProgressDialog &&
3625 fProgressDialog->ExecPlugin(5, this,
3626 selec.Data(), dsz, first, nent);
3628 } else {
3629 ResetProgressDialog(selec, dsz, first, nent);
3630 }
3631 }
3633 }
3634 }
3635 }
3636 break;
3637
3638 case kPROOF_ENDINIT:
3639 {
3640 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_ENDINIT: enter");
3641
3643 if (fPlayer)
3645 }
3646 }
3647 break;
3648
3649 case kPROOF_SETIDLE:
3650 {
3651 PDB(kGlobal,2)
3652 Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
3653
3654 // The session is idle
3655 if (IsLite()) {
3656 if (fNotIdle > 0) {
3657 fNotIdle--;
3658 PDB(kGlobal,2)
3659 Info("HandleInputMessage", "%s: got kPROOF_SETIDLE", sl->GetOrdinal());
3660 } else {
3661 Warning("HandleInputMessage",
3662 "%s: got kPROOF_SETIDLE but no running workers ! protocol error?",
3663 sl->GetOrdinal());
3664 }
3665 } else {
3666 fNotIdle = 0;
3667 // Check if the query has been enqueued
3668 if ((mess->BufferSize() > mess->Length()))
3669 (*mess) >> fIsWaiting;
3670 }
3671 }
3672 break;
3673
3675 {
3676 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_QUERYSUBMITTED: enter");
3677
3678 // We have received the sequential number
3679 (*mess) >> fSeqNum;
3680 Bool_t sync = fSync;
3681 if ((mess->BufferSize() > mess->Length()))
3682 (*mess) >> sync;
3683 if (sync != fSync && fSync) {
3684 // The server required to switch to asynchronous mode
3685 Activate();
3686 fSync = kFALSE;
3687 }
3688 DisableGoAsyn();
3689 // Check if the query has been enqueued
3690 fIsWaiting = kTRUE;
3691 // For Proof-Lite this variable is the number of workers and is set by the player
3692 if (!IsLite())
3693 fNotIdle = 1;
3694
3695 rc = 1;
3696 }
3697 break;
3698
3699 case kPROOF_SESSIONTAG:
3700 {
3701 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_SESSIONTAG: enter");
3702
3703 // We have received the unique tag and save it as name of this object
3704 TString stag;
3705 (*mess) >> stag;
3706 SetName(stag);
3707 // In the TSlave object
3708 sl->SetSessionTag(stag);
3709 // Server may have also sent the group
3710 if ((mess->BufferSize() > mess->Length()))
3711 (*mess) >> fGroup;
3712 // Server may have also sent the user
3713 if ((mess->BufferSize() > mess->Length())) {
3714 TString usr;
3715 (*mess) >> usr;
3716 if (!usr.IsNull()) fUrl.SetUser(usr.Data());
3717 }
3718 }
3719 break;
3720
3721 case kPROOF_FEEDBACK:
3722 {
3723 PDB(kGlobal,2)
3724 Info("HandleInputMessage","kPROOF_FEEDBACK: enter");
3725 TList *out = (TList *) mess->ReadObject(TList::Class());
3726 out->SetOwner();
3727 if (fPlayer)
3728 fPlayer->StoreFeedback(sl, out); // Adopts the list
3729 else
3730 // Not yet ready: stop collect asap
3731 rc = 1;
3732 }
3733 break;
3734
3735 case kPROOF_AUTOBIN:
3736 {
3737 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_AUTOBIN: enter");
3738
3739 TString name;
3740 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
3741
3742 (*mess) >> name >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
3743
3745
3747
3748 answ << name << xmin << xmax << ymin << ymax << zmin << zmax;
3749
3750 s->Send(answ);
3751 }
3752 break;
3753
3754 case kPROOF_PROGRESS:
3755 {
3756 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_PROGRESS: enter");
3757
3758 if (GetRemoteProtocol() > 25) {
3759 // New format
3761 (*mess) >> pi;
3762 fPlayer->Progress(sl,pi);
3763 } else if (GetRemoteProtocol() > 11) {
3764 Long64_t total, processed, bytesread;
3765 Float_t initTime, procTime, evtrti, mbrti;
3766 (*mess) >> total >> processed >> bytesread
3767 >> initTime >> procTime
3768 >> evtrti >> mbrti;
3769 if (fPlayer)
3770 fPlayer->Progress(sl, total, processed, bytesread,
3771 initTime, procTime, evtrti, mbrti);
3772
3773 } else {
3774 // Old format
3775 Long64_t total, processed;
3776 (*mess) >> total >> processed;
3777 if (fPlayer)
3778 fPlayer->Progress(sl, total, processed);
3779 }
3780 }
3781 break;
3782
3783 case kPROOF_STOPPROCESS:
3784 {
3785 // This message is sent from a worker that finished processing.
3786 // We determine whether it was asked to finish by the
3787 // packetizer or stopped during processing a packet
3788 // (by TProof::RemoveWorkers() or by an external signal).
3789 // In the later case call packetizer->MarkBad.
3790 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_STOPPROCESS: enter");
3791
3792 Long64_t events = 0;
3793 Bool_t abort = kFALSE;
3794 TProofProgressStatus *status = 0;
3795
3796 if ((mess->BufferSize() > mess->Length()) && (fProtocol > 18)) {
3797 (*mess) >> status >> abort;
3798 } else if ((mess->BufferSize() > mess->Length()) && (fProtocol > 8)) {
3799 (*mess) >> events >> abort;
3800 } else {
3801 (*mess) >> events;
3802 }
3803 if (fPlayer) {
3804 if (fProtocol > 18) {
3805 TList *listOfMissingFiles = 0;
3806 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
3807 listOfMissingFiles = new TList();
3808 listOfMissingFiles->SetName("MissingFiles");
3809 if (fPlayer)
3810 fPlayer->AddOutputObject(listOfMissingFiles);
3811 }
3812 if (fPlayer->GetPacketizer()) {
3813 Int_t ret =
3814 fPlayer->GetPacketizer()->AddProcessed(sl, status, 0, &listOfMissingFiles);
3815 if (ret > 0)
3816 fPlayer->GetPacketizer()->MarkBad(sl, status, &listOfMissingFiles);
3817 // This object is now owned by the packetizer
3818 status = 0;
3819 }
3820 if (status) fPlayer->AddEventsProcessed(status->GetEntries());
3821 } else {
3822 fPlayer->AddEventsProcessed(events);
3823 }
3824 }
3825 SafeDelete(status);
3827 Emit("StopProcess(Bool_t)", abort);
3828 break;
3829 }
3830
3831 case kPROOF_SUBMERGER:
3832 {
3833 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_SUBMERGER: enter");
3834 HandleSubmerger(mess, sl);
3835 }
3836 break;
3837
3839 {
3840 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_GETSLAVEINFO: enter");
3841
3842 Bool_t active = (GetListOfActiveSlaves()->FindObject(sl) != 0);
3843 Bool_t bad = (GetListOfBadSlaves()->FindObject(sl) != 0);
3844 TList* tmpinfo = 0;
3845 (*mess) >> tmpinfo;
3846 if (tmpinfo == 0) {
3847 Error("HandleInputMessage", "kPROOF_GETSLAVEINFO: no list received!");
3848 } else {
3849 tmpinfo->SetOwner(kFALSE);
3850 Int_t nentries = tmpinfo->GetSize();
3851 for (Int_t i=0; i<nentries; i++) {
3852 TSlaveInfo* slinfo =
3853 dynamic_cast<TSlaveInfo*>(tmpinfo->At(i));
3854 if (slinfo) {
3855 // If PROOF-Lite
3856 if (IsLite()) slinfo->fHostName = gSystem->HostName();
3857 // Check if we have already a instance for this worker
3858 TIter nxw(fSlaveInfo);
3859 TSlaveInfo *ourwi = 0;
3860 while ((ourwi = (TSlaveInfo *)nxw())) {
3861 if (!strcmp(ourwi->GetOrdinal(), slinfo->GetOrdinal())) {
3862 ourwi->SetSysInfo(slinfo->GetSysInfo());
3863 ourwi->fHostName = slinfo->GetName();
3864 if (slinfo->GetDataDir() && (strlen(slinfo->GetDataDir()) > 0))
3865 ourwi->fDataDir = slinfo->GetDataDir();
3866 break;
3867 }
3868 }
3869 if (!ourwi) {
3870 fSlaveInfo->Add(slinfo);
3871 } else {
3872 slinfo = ourwi;
3873 }
3874 if (slinfo->fStatus != TSlaveInfo::kBad) {
3875 if (!active) slinfo->SetStatus(TSlaveInfo::kNotActive);
3876 if (bad) slinfo->SetStatus(TSlaveInfo::kBad);
3877 }
3878 if (sl->GetMsd() && (strlen(sl->GetMsd()) > 0))
3879 slinfo->fMsd = sl->GetMsd();
3880 }
3881 }
3882 delete tmpinfo;
3883 rc = 1;
3884 }
3885 }
3886 break;
3887
3889 {
3890 PDB(kGlobal,2)
3891 Info("HandleInputMessage", "kPROOF_VALIDATE_DSET: enter");
3892 TDSet* dset = 0;
3893 (*mess) >> dset;
3894 if (!fDSet)
3895 Error("HandleInputMessage", "kPROOF_VALIDATE_DSET: fDSet not set");
3896 else
3897 fDSet->Validate(dset);
3898 delete dset;
3899 }
3900 break;
3901
3902 case kPROOF_DATA_READY:
3903 {
3904 PDB(kGlobal,2) Info("HandleInputMessage", "kPROOF_DATA_READY: enter");
3905 Bool_t dataready = kFALSE;
3906 Long64_t totalbytes, bytesready;
3907 (*mess) >> dataready >> totalbytes >> bytesready;
3908 fTotalBytes += totalbytes;
3909 fBytesReady += bytesready;
3910 if (dataready == kFALSE) fDataReady = dataready;
3911 }
3912 break;
3913
3914 case kPROOF_PING:
3915 // do nothing (ping is already acknowledged)
3916 break;
3917
3918 case kPROOF_MESSAGE:
3919 {
3920 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_MESSAGE: enter");
3921
3922 // We have received the unique tag and save it as name of this object
3923 TString msg;
3924 (*mess) >> msg;
3925 Bool_t lfeed = kTRUE;
3926 if ((mess->BufferSize() > mess->Length()))
3927 (*mess) >> lfeed;
3928
3930
3931 if (fSync) {
3932 // Notify locally
3933 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3934 } else {
3935 // Notify locally taking care of redirection, windows logs, ...
3936 NotifyLogMsg(msg, (lfeed ? "\n" : "\r"));
3937 }
3938 } else {
3939
3940 // The message is logged for debugging purposes.
3941 fprintf(stderr,"%s%c", msg.Data(), (lfeed ? '\n' : '\r'));
3942 if (gProofServ) {
3943 // We hide it during normal operations
3945
3946 // And send the message one level up
3947 gProofServ->SendAsynMessage(msg, lfeed);
3948 }
3949 }
3950 }
3951 break;
3952
3954 {
3955 TString vac;
3956 (*mess) >> vac;
3957 PDB(kGlobal,2) Info("HandleInputMessage","kPROOF_VERSARCHCOMP: %s", vac.Data());
3958 Int_t from = 0;
3959 TString vers, archcomp;
3960 if (vac.Tokenize(vers, from, "|"))
3961 vac.Tokenize(archcomp, from, "|");
3962 sl->SetArchCompiler(archcomp);
3963 vers.ReplaceAll(":","|");
3964 sl->SetROOTVersion(vers);
3965 }
3966 break;
3967
3968 default:
3969 {
3970 Error("HandleInputMessage", "unknown command received from '%s' (what = %d)",
3971 sl->GetOrdinal(), what);
3972 }
3973 break;
3974 }
3975
3976 // Cleanup
3977 if (delete_mess)
3978 delete mess;
3979
3980 // We are done successfully
3981 return rc;
3982}
3983
3984////////////////////////////////////////////////////////////////////////////////
3985/// Process a message of type kPROOF_SUBMERGER
3986
3988{
3989 // Message sub-type
3990 Int_t type = 0;
3991 (*mess) >> type;
3992 TSocket *s = sl->GetSocket();
3993
3994 switch (type) {
3995 case kOutputSent:
3996 {
3997 if (IsEndMaster()) {
3998 Int_t merger_id = -1;
3999 (*mess) >> merger_id;
4000
4001 PDB(kSubmerger, 2)
4002 Info("HandleSubmerger", "kOutputSent: Worker %s:%d:%s had sent its output to merger #%d",
4003 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), merger_id);
4004
4005 if (!fMergers || fMergers->GetSize() <= merger_id) {
4006 Error("HandleSubmerger", "kOutputSize: #%d not in list ", merger_id);
4007 break;
4008 }
4009 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4010 mi->SetMergedWorker();
4011 if (mi->AreAllWorkersMerged()) {
4012 mi->Deactivate();
4013 if (GetActiveMergersCount() == 0) {
4014 fMergers->Clear();
4015 delete fMergers;
4017 fMergersCount = -1;
4019 PDB(kSubmerger, 2) Info("HandleSubmerger", "all mergers removed ... ");
4020 }
4021 }
4022 } else {
4023 PDB(kSubmerger, 2) Error("HandleSubmerger","kOutputSent: received not on endmaster!");
4024 }
4025 }
4026 break;
4027
4028 case kMergerDown:
4029 {
4030 Int_t merger_id = -1;
4031 (*mess) >> merger_id;
4032
4033 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown: #%d ", merger_id);
4034
4035 if (!fMergers || fMergers->GetSize() <= merger_id) {
4036 Error("HandleSubmerger", "kMergerDown: #%d not in list ", merger_id);
4037 break;
4038 }
4039
4040 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4041 if (!mi->IsActive()) {
4042 break;
4043 } else {
4044 mi->Deactivate();
4045 }
4046
4047 // Stop the invalid merger in the case it is still listening
4049 stop << Int_t(kStopMerging);
4050 stop << 0;
4051 s->Send(stop);
4052
4053 // Ask for results from merger (only original results from this node as worker are returned)
4054 AskForOutput(mi->GetMerger());
4055
4056 // Ask for results from all workers assigned to this merger
4057 TIter nxo(mi->GetWorkers());
4058 TObject * o = 0;
4059 while ((o = nxo())) {
4060 AskForOutput((TSlave *)o);
4061 }
4062 PDB(kSubmerger, 2) Info("HandleSubmerger", "kMergerDown:%d: exit", merger_id);
4063 }
4064 break;
4065
4066 case kOutputSize:
4067 {
4068 if (IsEndMaster()) {
4069 PDB(kSubmerger, 2)
4070 Info("HandleSubmerger", "worker %s reported as finished ", sl->GetOrdinal());
4071
4072 const char *prefix = gProofServ ? gProofServ->GetPrefix() : "Lite-0";
4073 if (!fFinalizationRunning) {
4074 Info("HandleSubmerger", "finalization on %s started ...", prefix);
4076 }
4077
4078 Int_t output_size = 0;
4079 Int_t merging_port = 0;
4080 (*mess) >> output_size >> merging_port;
4081
4082 PDB(kSubmerger, 2) Info("HandleSubmerger",
4083 "kOutputSize: Worker %s:%d:%s reports %d output objects (+ available port %d)",
4084 sl->GetName(), sl->GetPort(), sl->GetOrdinal(), output_size, merging_port);
4085 TString msg;
4086 if (!fMergersSet) {
4087
4089
4090 // First pass - setting number of mergers according to user or dynamically
4091 fMergersCount = -1; // No mergers used if not set by user
4092 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4093 if (mc) fMergersCount = mc->GetVal(); // Value set by user
4094 TParameter<Int_t> *mh = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_MergersByHost"));
4095 if (mh) fMergersByHost = (mh->GetVal() != 0) ? kTRUE : kFALSE; // Assign submergers by hostname
4096
4097 // Mergers count specified by user but not valid
4098 if (fMergersCount < 0 || (fMergersCount > (activeWorkers/2) )) {
4099 msg.Form("%s: Invalid request: cannot start %d mergers for %d workers",
4100 prefix, fMergersCount, activeWorkers);
4101 if (gProofServ)
4103 else
4104 Printf("%s",msg.Data());
4105 fMergersCount = 0;
4106 }
4107 // Mergers count will be set dynamically
4108 if ((fMergersCount == 0) && (!fMergersByHost)) {
4109 if (activeWorkers > 1) {
4110 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4111 if (activeWorkers / fMergersCount < 2)
4112 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4113 }
4114 if (fMergersCount > 1)
4115 msg.Form("%s: Number of mergers set dynamically to %d (for %d workers)",
4116 prefix, fMergersCount, activeWorkers);
4117 else {
4118 msg.Form("%s: No mergers will be used for %d workers",
4119 prefix, activeWorkers);
4120 fMergersCount = -1;
4121 }
4122 if (gProofServ)
4124 else
4125 Printf("%s",msg.Data());
4126 } else if (fMergersByHost) {
4127 // We force mergers at host level to minimize network traffic
4128 if (activeWorkers > 1) {
4129 fMergersCount = 0;
4130 THashList hosts;
4131 TIter nxwk(fSlaves);
4132 TObject *wrk = 0;
4133 while ((wrk = nxwk())) {
4134 if (!hosts.FindObject(wrk->GetName())) {
4135 hosts.Add(new TObjString(wrk->GetName()));
4136 fMergersCount++;
4137 }
4138 }
4139 }
4140 if (fMergersCount > 1)
4141 msg.Form("%s: Number of mergers set to %d (for %d workers), one for each slave host",
4142 prefix, fMergersCount, activeWorkers);
4143 else {
4144 msg.Form("%s: No mergers will be used for %d workers",
4145 prefix, activeWorkers);
4146 fMergersCount = -1;
4147 }
4148 if (gProofServ)
4150 else
4151 Printf("%s",msg.Data());
4152 } else {
4153 msg.Form("%s: Number of mergers set by user to %d (for %d workers)",
4154 prefix, fMergersCount, activeWorkers);
4155 if (gProofServ)
4157 else
4158 Printf("%s",msg.Data());
4159 }
4160
4161 // We started merging; we call it here because fMergersCount is still the original number
4162 // and can be saved internally
4164
4165 // Update merger counters (new workers are not yet active)
4167
4168 if (fMergersCount > 0) {
4169
4170 fMergers = new TList();
4172 // Total number of workers, which will not act as mergers ('pure workers')
4173 fWorkersToMerge = (activeWorkers - fMergersCount);
4174 // Establish the first merger
4175 if (!CreateMerger(sl, merging_port)) {
4176 // Cannot establish first merger
4177 AskForOutput(sl);
4179 fMergersCount--;
4180 }
4182 } else {
4183 AskForOutput(sl);
4184 }
4186 } else {
4187 // Multiple pass
4188 if (fMergersCount == -1) {
4189 // No mergers. Workers send their outputs directly to master
4190 AskForOutput(sl);
4191 } else {
4192 if ((fRedirectNext > 0 ) && (!fMergersByHost)) {
4193 RedirectWorker(s, sl, output_size);
4194 fRedirectNext--;
4195 } else {
4196 Bool_t newMerger = kTRUE;
4197 if (fMergersByHost) {
4198 TIter nxmg(fMergers);
4199 TMergerInfo *mgi = 0;
4200 while ((mgi = (TMergerInfo *) nxmg())) {
4201 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4202 newMerger = kFALSE;
4203 break;
4204 }
4205 }
4206 }
4207 if ((fMergersCount > fMergers->GetSize()) && newMerger) {
4208 // Still not enough mergers established
4209 if (!CreateMerger(sl, merging_port)) {
4210 // Cannot establish a merger
4211 AskForOutput(sl);
4213 fMergersCount--;
4214 }
4215 } else
4216 RedirectWorker(s, sl, output_size);
4217 }
4218 }
4219 }
4220 } else {
4221 Error("HandleSubMerger","kOutputSize received not on endmaster!");
4222 }
4223 }
4224 break;
4225 }
4226}
4227
4228////////////////////////////////////////////////////////////////////////////////
4229/// Redirect output of worker sl to some merger
4230
4232{
4233 Int_t merger_id = -1;
4234
4235 if (fMergersByHost) {
4236 for (Int_t i = 0; i < fMergers->GetSize(); i++) {
4237 TMergerInfo *mgi = (TMergerInfo *)fMergers->At(i);
4238 if (!strcmp(sl->GetName(), mgi->GetMerger()->GetName())) {
4239 merger_id = i;
4240 break;
4241 }
4242 }
4243 } else {
4244 merger_id = FindNextFreeMerger();
4245 }
4246
4247 if (merger_id == -1) {
4248 // No free merger (probably it had crashed before)
4249 AskForOutput(sl);
4250 } else {
4251 TMessage sendoutput(kPROOF_SUBMERGER);
4252 sendoutput << Int_t(kSendOutput);
4253 PDB(kSubmerger, 2)
4254 Info("RedirectWorker", "redirecting worker %s to merger %d", sl->GetOrdinal(), merger_id);
4255
4256 PDB(kSubmerger, 2) Info("RedirectWorker", "redirecting output to merger #%d", merger_id);
4257 if (!fMergers || fMergers->GetSize() <= merger_id) {
4258 Error("RedirectWorker", "#%d not in list ", merger_id);
4259 return;
4260 }
4261 TMergerInfo * mi = (TMergerInfo *) fMergers->At(merger_id);
4262
4263 TString hname = (IsLite()) ? "localhost" : mi->GetMerger()->GetName();
4264 sendoutput << merger_id;
4265 sendoutput << hname;
4266 sendoutput << mi->GetPort();
4267 s->Send(sendoutput);
4268 mi->AddMergedObjects(output_size);
4269 mi->AddWorker(sl);
4270 }
4271}
4272
4273////////////////////////////////////////////////////////////////////////////////
4274/// Return a merger, which is both active and still accepts some workers to be
4275/// assigned to it. It works on the 'round-robin' basis.
4276
4278{
4279 while (fLastAssignedMerger < fMergers->GetSize() &&
4280 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4281 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4283 }
4284
4287 } else {
4288 return fLastAssignedMerger++;
4289 }
4290
4291 while (fLastAssignedMerger < fMergers->GetSize() &&
4292 (!((TMergerInfo*)fMergers->At(fLastAssignedMerger))->IsActive() ||
4293 ((TMergerInfo*)fMergers->At(fLastAssignedMerger))->AreAllWorkersAssigned())) {
4295 }
4296
4298 return -1;
4299 } else {
4300 return fLastAssignedMerger++;
4301 }
4302}
4303
4304////////////////////////////////////////////////////////////////////////////////
4305/// Master asks for output from worker sl
4306
4308{
4309 TMessage sendoutput(kPROOF_SUBMERGER);
4310 sendoutput << Int_t(kSendOutput);
4311
4312 PDB(kSubmerger, 2) Info("AskForOutput",
4313 "worker %s was asked to send its output to master",
4314 sl->GetOrdinal());
4315
4316 sendoutput << -1;
4317 sendoutput << TString("master");
4318 sendoutput << -1;
4319 sl->GetSocket()->Send(sendoutput);
4321}
4322
4323////////////////////////////////////////////////////////////////////////////////
4324/// Final update of the progress dialog
4325
4327{
4328 if (!fPlayer) return;
4329
4330 // Handle abort ...
4332 if (fSync)
4333 Info("UpdateDialog",
4334 "processing was aborted - %lld events processed",
4336
4337 if (GetRemoteProtocol() > 11) {
4338 // New format
4339 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4340 } else {
4342 }
4343 Emit("StopProcess(Bool_t)", kTRUE);
4344 }
4345
4346 // Handle stop ...
4348 if (fSync)
4349 Info("UpdateDialog",
4350 "processing was stopped - %lld events processed",
4352
4353 if (GetRemoteProtocol() > 25) {
4354 // New format
4355 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1., -1, -1, -1.);
4356 } else if (GetRemoteProtocol() > 11) {
4357 Progress(-1, fPlayer->GetEventsProcessed(), -1, -1., -1., -1., -1.);
4358 } else {
4360 }
4361 Emit("StopProcess(Bool_t)", kFALSE);
4362 }
4363
4364 // Final update of the dialog box
4365 if (GetRemoteProtocol() > 25) {
4366 // New format
4367 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
4368 10, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),(Float_t)(-1.),(Float_t)(-1.),
4369 (Float_t)(-1.),(Float_t)(-1.),(Int_t)(-1),(Int_t)(-1),(Float_t)(-1.));
4370 } else if (GetRemoteProtocol() > 11) {
4371 // New format
4372 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
4373 7, (Long64_t)(-1), (Long64_t)(-1), (Long64_t)(-1),
4374 (Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.),(Float_t)(-1.));
4375 } else {
4376 EmitVA("Progress(Long64_t,Long64_t)", 2, (Long64_t)(-1), (Long64_t)(-1));
4377 }
4378}
4379
4380////////////////////////////////////////////////////////////////////////////////
4381/// Activate the a-sync input handler.
4382
4384{
4385 TIter next(fSlaves);
4386 TSlave *sl;
4387
4388 while ((sl = (TSlave*) next()))
4389 if (sl->GetInputHandler())
4390 sl->GetInputHandler()->Add();
4391}
4392
4393////////////////////////////////////////////////////////////////////////////////
4394/// De-activate a-sync input handler.
4395
4397{
4398 TIter next(fSlaves);
4399 TSlave *sl;
4400
4401 while ((sl = (TSlave*) next()))
4402 if (sl->GetInputHandler())
4403 sl->GetInputHandler()->Remove();
4404}
4405
4406////////////////////////////////////////////////////////////////////////////////
4407/// Get the active mergers count
4408
4410{
4411 if (!fMergers) return 0;
4412
4413 Int_t active_mergers = 0;
4414
4415 TIter mergers(fMergers);
4416 TMergerInfo *mi = 0;
4417 while ((mi = (TMergerInfo *)mergers())) {
4418 if (mi->IsActive()) active_mergers++;
4419 }
4420
4421 return active_mergers;
4422}
4423
4424////////////////////////////////////////////////////////////////////////////////
4425/// Create a new merger
4426
4428{
4429 PDB(kSubmerger, 2)
4430 Info("CreateMerger", "worker %s will be merger ", sl->GetOrdinal());
4431
4432 PDB(kSubmerger, 2) Info("CreateMerger","Begin");
4433
4434 if (port <= 0) {
4435 PDB(kSubmerger,2)
4436 Info("CreateMerger", "cannot create merger on port %d - exit", port);
4437 return kFALSE;
4438 }
4439
4440 Int_t workers = -1;
4441 if (!fMergersByHost) {
4442 Int_t mergersToCreate = fMergersCount - fMergers->GetSize();
4443 // Number of pure workers, which are not simply divisible by mergers
4444 Int_t rest = fWorkersToMerge % mergersToCreate;
4445 // We add one more worker for each of the first 'rest' mergers being established
4446 if (rest > 0 && fMergers->GetSize() < rest) {
4447 rest = 1;
4448 } else {
4449 rest = 0;
4450 }
4451 workers = (fWorkersToMerge / mergersToCreate) + rest;
4452 } else {
4453 Int_t workersOnHost = 0;
4454 for (Int_t i = 0; i < fActiveSlaves->GetSize(); i++) {
4455 if(!strcmp(sl->GetName(), fActiveSlaves->At(i)->GetName())) workersOnHost++;
4456 }
4457 workers = workersOnHost - 1;
4458 }
4459
4460 TString msg;
4461 msg.Form("worker %s on host %s will be merger for %d additional workers", sl->GetOrdinal(), sl->GetName(), workers);
4462
4463 if (gProofServ) {
4465 } else {
4466 Printf("%s",msg.Data());
4467 }
4468 TMergerInfo * merger = new TMergerInfo(sl, port, workers);
4469
4470 TMessage bemerger(kPROOF_SUBMERGER);
4471 bemerger << Int_t(kBeMerger);
4472 bemerger << fMergers->GetSize();
4473 bemerger << workers;
4474 sl->GetSocket()->Send(bemerger);
4475
4476 PDB(kSubmerger,2) Info("CreateMerger",
4477 "merger #%d (port: %d) for %d workers started",
4478 fMergers->GetSize(), port, workers);
4479
4480 fMergers->Add(merger);
4481 fWorkersToMerge = fWorkersToMerge - workers;
4482
4483 fRedirectNext = workers / 2;
4484
4485 PDB(kSubmerger, 2) Info("CreateMerger", "exit");
4486 return kTRUE;
4487}
4488
4489////////////////////////////////////////////////////////////////////////////////
4490/// Add a bad slave server to the bad slave list and remove it from
4491/// the active list and from the two monitor objects. Assume that the work
4492/// done by this worker was lost and ask packerizer to reassign it.
4493
4494void TProof::MarkBad(TSlave *wrk, const char *reason)
4495{
4496 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4497
4498 // We may have been invalidated in the meanwhile: nothing to do in such a case
4499 if (!IsValid()) return;
4500
4501 if (!wrk) {
4502 Error("MarkBad", "worker instance undefined: protocol error? ");
4503 return;
4504 }
4505
4506 // Local URL
4507 static TString thisurl;
4508 if (thisurl.IsNull()) {
4509 if (IsMaster()) {
4510 Int_t port = gEnv->GetValue("ProofServ.XpdPort",-1);
4511 thisurl = TUrl(gSystem->HostName()).GetHostFQDN();
4512 if (port > 0) thisurl += TString::Format(":%d", port);
4513 } else {
4514 thisurl.Form("%s@%s:%d", fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort());
4515 }
4516 }
4517
4518 if (!reason || (strcmp(reason, kPROOF_TerminateWorker) && strcmp(reason, kPROOF_WorkerIdleTO))) {
4519 // Message for notification
4520 const char *mastertype = (gProofServ && gProofServ->IsTopMaster()) ? "top master" : "master";
4521 TString src = IsMaster() ? Form("%s at %s", mastertype, thisurl.Data()) : "local session";
4522 TString msg;
4523 msg.Form("\n +++ Message from %s : marking %s:%d (%s) as bad\n +++ Reason: %s",
4524 src.Data(), wrk->GetName(), wrk->GetPort(), wrk->GetOrdinal(),
4525 (reason && strlen(reason)) ? reason : "unknown");
4526 Info("MarkBad", "%s", msg.Data());
4527 // Notify one level up, if the case
4528 // Add some hint for diagnostics
4529 if (gProofServ) {
4530 msg += TString::Format("\n\n +++ Most likely your code crashed on worker %s at %s:%d.\n",
4531 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4532 } else {
4533 msg += TString::Format("\n\n +++ Most likely your code crashed\n");
4534 }
4535 msg += TString::Format(" +++ Please check the session logs for error messages either using\n");
4536 msg += TString::Format(" +++ the 'Show logs' button or executing\n");
4537 msg += TString::Format(" +++\n");
4538 if (gProofServ) {
4539 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4540 "Display(\"%s\",0)\n\n", thisurl.Data(), wrk->GetOrdinal());
4542 } else {
4543 msg += TString::Format(" +++ root [] TProof::Mgr(\"%s\")->GetSessionLogs()->"
4544 "Display(\"*\")\n\n", thisurl.Data());
4545 Printf("%s", msg.Data());
4546 }
4547 } else if (reason) {
4548 if (gDebug > 0 && strcmp(reason, kPROOF_WorkerIdleTO)) {
4549 Info("MarkBad", "worker %s at %s:%d asked to terminate",
4550 wrk->GetOrdinal(), wrk->GetName(), wrk->GetPort());
4551 }
4552 }
4553
4554 if (IsMaster() && reason) {
4555 if (strcmp(reason, kPROOF_TerminateWorker)) {
4556 // if the reason was not a planned termination
4557 TList *listOfMissingFiles = 0;
4558 if (!(listOfMissingFiles = (TList *)GetOutput("MissingFiles"))) {
4559 listOfMissingFiles = new TList();
4560 listOfMissingFiles->SetName("MissingFiles");
4561 if (fPlayer)
4562 fPlayer->AddOutputObject(listOfMissingFiles);
4563 }
4564 // If a query is being processed, assume that the work done by
4565 // the worker was lost and needs to be reassigned.
4566 TVirtualPacketizer *packetizer = fPlayer ? fPlayer->GetPacketizer() : 0;
4567 if (packetizer) {
4568 // the worker was lost so do resubmit the packets
4569 packetizer->MarkBad(wrk, 0, &listOfMissingFiles);
4570 }
4571 } else {
4572 // Tell the coordinator that we are gone
4573 if (gProofServ) {
4574 TString ord(wrk->GetOrdinal());
4575 Int_t id = ord.Last('.');
4576 if (id != kNPOS) ord.Remove(0, id+1);
4578 }
4579 }
4580 } else if (TestBit(TProof::kIsClient) && reason && !strcmp(reason, kPROOF_WorkerIdleTO)) {
4581 // We are invalid after this
4582 fValid = kFALSE;
4583 }
4584
4585 fActiveSlaves->Remove(wrk);
4587
4588 fAllMonitor->Remove(wrk->GetSocket());
4590
4592
4593 if (IsMaster()) {
4594 if (reason && !strcmp(reason, kPROOF_TerminateWorker)) {
4595 // if the reason was a planned termination then delete the worker and
4596 // remove it from all the lists
4597 fSlaves->Remove(wrk);
4598 fBadSlaves->Remove(wrk);
4599 fActiveSlaves->Remove(wrk);
4600 fInactiveSlaves->Remove(wrk);
4601 fUniqueSlaves->Remove(wrk);
4604
4605 // we add it to the list of terminated slave infos instead, so that it
4606 // stays available in the .workers persistent file
4607 TSlaveInfo *si = new TSlaveInfo(
4608 wrk->GetOrdinal(),
4609 Form("%s@%s:%d", wrk->GetUser(), wrk->GetName(), wrk->GetPort()),
4610 0, "", wrk->GetWorkDir());
4612 else delete si;
4613
4614 delete wrk;
4615 } else {
4616 fBadSlaves->Add(wrk);
4617 fActiveSlaves->Remove(wrk);
4618 fUniqueSlaves->Remove(wrk);
4622 wrk->Close();
4623 // Update the mergers count, if needed
4624 if (fMergersSet) {
4625 Int_t mergersCount = -1;
4626 TParameter<Int_t> *mc = dynamic_cast<TParameter<Int_t> *>(GetParameter("PROOF_UseMergers"));
4627 if (mc) mergersCount = mc->GetVal(); // Value set by user
4628 // Mergers count is set dynamically: recalculate it
4629 if (mergersCount == 0) {
4631 if (activeWorkers > 1) {
4632 fMergersCount = TMath::Nint(TMath::Sqrt(activeWorkers));
4633 if (activeWorkers / fMergersCount < 2)
4634 fMergersCount = (Int_t) TMath::Sqrt(activeWorkers);
4635 }
4636 }
4637 }
4638 }
4639
4640 // Update session workers files
4642 } else {
4643 // On clients the proof session should be removed from the lists
4644 // and deleted, since it is not valid anymore
4645 fSlaves->Remove(wrk);
4646 if (fManager)
4647 fManager->DiscardSession(this);
4648 }
4649}
4650
4651////////////////////////////////////////////////////////////////////////////////
4652/// Add slave with socket s to the bad slave list and remove if from
4653/// the active list and from the two monitor objects.
4654
4655void TProof::MarkBad(TSocket *s, const char *reason)
4656{
4657 std::lock_guard<std::recursive_mutex> lock(fCloseMutex);
4658
4659 // We may have been invalidated in the meanwhile: nothing to do in such a case
4660 if (!IsValid()) return;
4661
4662 TSlave *wrk = FindSlave(s);
4663 MarkBad(wrk, reason);
4664}
4665
4666////////////////////////////////////////////////////////////////////////////////
4667/// Ask an active worker 'wrk' to terminate, i.e. to shutdown
4668
4670{
4671 if (!wrk) {
4672 Warning("TerminateWorker", "worker instance undefined: protocol error? ");
4673 return;
4674 }
4675
4676 // Send stop message
4677 if (wrk->GetSocket() && wrk->GetSocket()->IsValid()) {
4678 TMessage mess(kPROOF_STOP);
4679 wrk->GetSocket()->Send(mess);
4680 } else {
4681 if (gDebug > 0)
4682 Info("TerminateWorker", "connection to worker is already down: cannot"
4683 " send termination message");
4684 }
4685
4686 // This is a bad worker from now on
4688}
4689
4690////////////////////////////////////////////////////////////////////////////////
4691/// Ask an active worker 'ord' to terminate, i.e. to shutdown
4692
4693void TProof::TerminateWorker(const char *ord)
4694{
4695 if (ord && strlen(ord) > 0) {
4696 Bool_t all = (ord[0] == '*') ? kTRUE : kFALSE;
4697 if (IsMaster()) {
4698 TIter nxw(fSlaves);
4699 TSlave *wrk = 0;
4700 while ((wrk = (TSlave *)nxw())) {
4701 if (all || !strcmp(wrk->GetOrdinal(), ord)) {
4702 TerminateWorker(wrk);
4703 if (!all) break;
4704 }
4705 }
4706 } else {
4707 TMessage mess(kPROOF_STOP);
4708 mess << TString(ord);
4709 Broadcast(mess);
4710 }
4711 }
4712}
4713
4714////////////////////////////////////////////////////////////////////////////////
4715/// Ping PROOF. Returns 1 if master server responded.
4716
4718{
4719 return Ping(kActive);
4720}
4721
4722////////////////////////////////////////////////////////////////////////////////
4723/// Ping PROOF slaves. Returns the number of slaves that responded.
4724
4726{
4727 TList *slaves = 0;
4728 if (list == kAll) slaves = fSlaves;
4729 if (list == kActive) slaves = fActiveSlaves;
4730 if (list == kUnique) slaves = fUniqueSlaves;
4731 if (list == kAllUnique) slaves = fAllUniqueSlaves;
4732
4733 if (slaves->GetSize() == 0) return 0;
4734
4735 int nsent = 0;
4736 TIter next(slaves);
4737
4738 TSlave *sl;
4739 while ((sl = (TSlave *)next())) {
4740 if (sl->IsValid()) {
4741 if (sl->Ping() == -1) {
4742 MarkBad(sl, "ping unsuccessful");
4743 } else {
4744 nsent++;
4745 }
4746 }
4747 }
4748
4749 return nsent;
4750}
4751
4752////////////////////////////////////////////////////////////////////////////////
4753/// Ping PROOF slaves. Returns the number of slaves that responded.
4754
4756{
4757 TList *slaves = fSlaves;
4758
4759 if (slaves->GetSize() == 0) return;
4760
4761 TIter next(slaves);
4762
4763 TSlave *sl;
4764 while ((sl = (TSlave *)next())) {
4765 if (sl->IsValid()) {
4766 sl->Touch();
4767 }
4768 }
4769
4770 return;
4771}
4772
4773////////////////////////////////////////////////////////////////////////////////
4774/// Print status of PROOF cluster.
4775
4776void TProof::Print(Option_t *option) const
4777{
4778 TString secCont;
4779
4781 Printf("Connected to: %s (%s)", GetMaster(),
4782 IsValid() ? "valid" : "invalid");
4783 Printf("Port number: %d", GetPort());
4784 Printf("User: %s", GetUser());
4785 Printf("ROOT version|rev: %s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4786 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4788 TSlave *sl = (TSlave *)fActiveSlaves->First();
4789 if (sl) {
4790 TString sc;
4791 if (sl->GetSocket()->GetSecContext())
4792 Printf("Security context: %s",
4793 sl->GetSocket()->GetSecContext()->AsString(sc));
4794 Printf("Proofd protocol version: %d", sl->GetSocket()->GetRemoteProtocol());
4795 } else {
4796 Printf("Security context: Error - No connection");
4797 Printf("Proofd protocol version: Error - No connection");
4798 }
4799 Printf("Client protocol version: %d", GetClientProtocol());
4800 Printf("Remote protocol version: %d", GetRemoteProtocol());
4801 Printf("Log level: %d", GetLogLevel());
4802 Printf("Session unique tag: %s", IsValid() ? GetSessionTag() : "");
4803 Printf("Default data pool: %s", IsValid() ? GetDataPoolUrl() : "");
4804 if (IsValid())
4805 const_cast<TProof*>(this)->SendPrint(option);
4806 } else {
4807 const_cast<TProof*>(this)->AskStatistics();
4808 if (IsParallel())
4809 Printf("*** Master server %s (parallel mode, %d workers):",
4811 else
4812 Printf("*** Master server %s (sequential mode):",
4814
4815 Printf("Master host name: %s", gSystem->HostName());
4816 Printf("Port number: %d", GetPort());
4817 if (strlen(gProofServ->GetGroup()) > 0) {
4818 Printf("User/Group: %s/%s", GetUser(), gProofServ->GetGroup());
4819 } else {
4820 Printf("User: %s", GetUser());
4821 }
4822 TString ver;
4823 ver.Form("%s|%s", gROOT->GetVersion(), gROOT->GetGitCommit());
4824 if (gSystem->Getenv("ROOTVERSIONTAG"))
4825 ver.Form("%s|%s", gROOT->GetVersion(), gSystem->Getenv("ROOTVERSIONTAG"));
4826 Printf("ROOT version|rev|tag: %s", ver.Data());
4827 Printf("Architecture-Compiler: %s-%s", gSystem->GetBuildArch(),
4829 Printf("Protocol version: %d", GetClientProtocol());
4830 Printf("Image name: %s", GetImage());
4831 Printf("Working directory: %s", gSystem->WorkingDirectory());
4832 Printf("Config directory: %s", GetConfDir());
4833 Printf("Config file: %s", GetConfFile());
4834 Printf("Log level: %d", GetLogLevel());
4835 Printf("Number of workers: %d", GetNumberOfSlaves());
4836 Printf("Number of active workers: %d", GetNumberOfActiveSlaves());
4837 Printf("Number of unique workers: %d", GetNumberOfUniqueSlaves());
4838 Printf("Number of inactive workers: %d", GetNumberOfInactiveSlaves());
4839 Printf("Number of bad workers: %d", GetNumberOfBadSlaves());
4840 Printf("Total MB's processed: %.2f", float(GetBytesRead())/(1024*1024));
4841 Printf("Total real time used (s): %.3f", GetRealTime());
4842 Printf("Total CPU time used (s): %.3f", GetCpuTime());
4843 if (TString(option).Contains("a", TString::kIgnoreCase) && GetNumberOfSlaves()) {
4844 Printf("List of workers:");
4845 TList masters;
4846 TIter nextslave(fSlaves);
4847 while (TSlave* sl = dynamic_cast<TSlave*>(nextslave())) {
4848 if (!sl->IsValid()) continue;
4849
4850 if (sl->GetSlaveType() == TSlave::kSlave) {
4851 sl->Print(option);
4852 } else if (sl->GetSlaveType() == TSlave::kMaster) {
4853 TMessage mess(kPROOF_PRINT);
4854 mess.WriteString(option);
4855 if (sl->GetSocket()->Send(mess) == -1)
4856 const_cast<TProof*>(this)->MarkBad(sl, "could not send kPROOF_PRINT request");
4857 else
4858 masters.Add(sl);
4859 } else {
4860 Error("Print", "TSlave is neither Master nor Worker");
4861 R__ASSERT(0);
4862 }
4863 }
4864 const_cast<TProof*>(this)->Collect(&masters, fCollectTimeout);
4865 }
4866 }
4867}
4868
4869////////////////////////////////////////////////////////////////////////////////
4870/// Extract from opt information about output handling settings.
4871/// The understood keywords are:
4872/// of=<file>, outfile=<file> output file location
4873/// ds=<dsname>, dataset=<dsname> dataset name ('of' and 'ds' are
4874/// mutually exclusive,execution stops
4875/// if both are found)
4876/// sft[=<opt>], savetofile[=<opt>] control saving to file
4877///
4878/// For 'mvf', the <opt> integer has the following meaning:
4879/// <opt> = <how>*10 + <force>
4880/// <force> = 0 save to file if memory threshold is reached
4881/// (the memory threshold is set by the cluster
4882/// admin); in case an output file is defined, the
4883/// files are merged at the end;
4884/// 1 save results to file.
4885/// <how> = 0 save at the end of the query
4886/// 1 save results after each packet (to reduce the
4887/// loss in case of crash).
4888///
4889/// Setting 'ds' automatically sets 'mvf=1'; it is still possible to set 'mvf=11'
4890/// to save results after each packet.
4891///
4892/// The separator from the next option is either a ' ' or a ';'
4893///
4894/// All recognized settings are removed from the input string opt.
4895/// If action == 0, set up the output file accordingly, if action == 1 clean related
4896/// output file settings.
4897/// If the final target file is local then 'target' is set to the final local path
4898/// when action == 0 and used to retrieve the file with TFile::Cp when action == 1.
4899///
4900/// Output file settings are in the form
4901///
4902/// <previous_option>of=name <next_option>
4903/// <previous_option>outfile=name,...;<next_option>
4904///
4905/// The separator from the next option is either a ' ' or a ';'
4906/// Called interanally by TProof::Process.
4907///
4908/// Returns 0 on success, -1 on error.
4909
4911{
4912 TString outfile, dsname, stfopt;
4913 if (action == 0) {
4914 TString tagf, tagd, tags, oo;
4915 Ssiz_t from = 0, iof = kNPOS, iod = kNPOS, ios = kNPOS;
4916 while (opt.Tokenize(oo, from, "[; ]")) {
4917 if (oo.BeginsWith("of=")) {
4918 tagf = "of=";
4919 iof = opt.Index(tagf);
4920 } else if (oo.BeginsWith("outfile=")) {
4921 tagf = "outfile=";
4922 iof = opt.Index(tagf);
4923 } else if (oo.BeginsWith("ds")) {
4924 tagd = "ds";
4925 iod = opt.Index(tagd);
4926 } else if (oo.BeginsWith("dataset")) {
4927 tagd = "dataset";
4928 iod = opt.Index(tagd);
4929 } else if (oo.BeginsWith("stf")) {
4930 tags = "stf";
4931 ios = opt.Index(tags);
4932 } else if (oo.BeginsWith("savetofile")) {
4933 tags = "savetofile";
4934 ios = opt.Index(tags);
4935 }
4936 }
4937 // Check consistency
4938 if (iof != kNPOS && iod != kNPOS) {
4939 Error("HandleOutputOptions", "options 'of'/'outfile' and 'ds'/'dataset' are incompatible!");
4940 return -1;
4941 }
4942
4943 // Check output file first
4944 if (iof != kNPOS) {
4945 from = iof + tagf.Length();
4946 if (!opt.Tokenize(outfile, from, "[; ]") || outfile.IsNull()) {
4947 Error("HandleOutputOptions", "could not extract output file settings string! (%s)", opt.Data());
4948 return -1;
4949 }
4950 // For removal from original options string
4951 tagf += outfile;
4952 }
4953 // Check dataset
4954 if (iod != kNPOS) {
4955 from = iod + tagd.Length();
4956 if (!opt.Tokenize(dsname, from, "[; ]"))
4957 if (gDebug > 0) Info("HandleOutputOptions", "no dataset name found: use default");
4958 // For removal from original options string
4959 tagd += dsname;
4960 // The name may be empty or beginning with a '='
4961 if (dsname.BeginsWith("=")) dsname.Replace(0, 1, "");
4962 if (dsname.Contains("|V")) {
4963 target = "ds|V";
4964 dsname.ReplaceAll("|V", "");
4965 }
4966 if (dsname.IsNull()) dsname = "dataset_<qtag>";
4967 }
4968 // Check stf
4969 if (ios != kNPOS) {
4970 from = ios + tags.Length();
4971 if (!opt.Tokenize(stfopt, from, "[; ]"))
4972 if (gDebug > 0) Info("HandleOutputOptions", "save-to-file not found: use default");
4973 // For removal from original options string
4974 tags += stfopt;
4975 // It must be digit
4976 if (!stfopt.IsNull()) {
4977 if (stfopt.BeginsWith("=")) stfopt.Replace(0,1,"");
4978 if (!stfopt.IsNull()) {
4979 if (!stfopt.IsDigit()) {
4980 Error("HandleOutputOptions", "save-to-file option must be a digit! (%s)", stfopt.Data());
4981 return -1;
4982 }
4983 } else {
4984 // Default
4985 stfopt = "1";
4986 }
4987 } else {
4988 // Default
4989 stfopt = "1";
4990 }
4991 }
4992 // Remove from original options string
4993 opt.ReplaceAll(tagf, "");
4994 opt.ReplaceAll(tagd, "");
4995 opt.ReplaceAll(tags, "");
4996 }
4997
4998 // Parse now
4999 if (action == 0) {
5000 // Output file
5001 if (!outfile.IsNull()) {
5002 if (!outfile.BeginsWith("master:")) {
5004 Warning("HandleOutputOptions",
5005 "directory '%s' for the output file does not exists or is not writable:"
5006 " saving to master", gSystem->DirName(outfile.Data()));
5007 outfile.Form("master:%s", gSystem->BaseName(outfile.Data()));
5008 } else {
5009 if (!IsLite()) {
5010 // The target file is local, so we need to retrieve it
5011 target = outfile;
5012 if (!stfopt.IsNull()) {
5013 outfile.Form("master:%s", gSystem->BaseName(target.Data()));
5014 } else {
5015 outfile = "";
5016 }
5017 }
5018 }
5019 }
5020 if (outfile.BeginsWith("master:")) {
5021 outfile.ReplaceAll("master:", "");
5022 if (outfile.IsNull() || !gSystem->IsAbsoluteFileName(outfile)) {
5023 // Get the master data dir
5024 TString ddir, emsg;
5025 if (!IsLite()) {
5026 if (Exec("gProofServ->GetDataDir()", "0", kTRUE) == 0) {
5027 TObjString *os = fMacroLog.GetLineWith("const char");
5028 if (os) {
5029 Ssiz_t fst = os->GetString().First('\"');
5030 Ssiz_t lst = os->GetString().Last('\"');
5031 ddir = os->GetString()(fst+1, lst-fst-1);
5032 } else {
5033 emsg = "could not find 'const char *' string in macro log! cannot continue";
5034 }
5035 } else {
5036 emsg = "could not retrieve master data directory info! cannot continue";
5037 }
5038 if (!emsg.IsNull()) {
5039 Error("HandleOutputOptions", "%s", emsg.Data());
5040 return -1;
5041 }
5042 }
5043 if (!ddir.IsNull()) ddir += "/";
5044 if (outfile.IsNull()) {
5045 outfile.Form("%s<file>", ddir.Data());
5046 } else {
5047 outfile.Insert(0, TString::Format("%s", ddir.Data()));
5048 }
5049 }
5050 }
5051 // Set the parameter
5052 if (!outfile.IsNull()) {
5053 if (!outfile.BeginsWith("of:")) outfile.Insert(0, "of:");
5054 SetParameter("PROOF_DefaultOutputOption", outfile.Data());
5055 }
5056 }
5057 // Dataset creation
5058 if (!dsname.IsNull()) {
5059 dsname.Insert(0, "ds:");
5060 // Set the parameter
5061 SetParameter("PROOF_DefaultOutputOption", dsname.Data());
5062 // Check the Save-To-File option
5063 if (!stfopt.IsNull()) {
5064 Int_t ostf = (Int_t) stfopt.Atoi();
5065 if (ostf%10 <= 0) {
5066 Warning("HandleOutputOptions", "Dataset required bu Save-To-File disabled: enabling!");
5067 stfopt.Form("%d", ostf+1);
5068 }
5069 } else {
5070 // Minimal setting
5071 stfopt = "1";
5072 }
5073 }
5074 // Save-To-File options
5075 if (!stfopt.IsNull()) {
5076 // Set the parameter
5077 SetParameter("PROOF_SavePartialResults", (Int_t) stfopt.Atoi());
5078 }
5079 } else {
5080 // Retrieve the file, if required
5081 if (GetOutputList()) {
5082 if (target == "ds|V") {
5083 // Find the dataset
5084 dsname = "";
5085 TIter nxo(GetOutputList());
5086 TObject *o = 0;
5087 while ((o = nxo())) {
5089 VerifyDataSet(o->GetName());
5090 dsname = o->GetName();
5091 break;
5092 }
5093 }
5094 if (!dsname.IsNull()) {
5095 TFileCollection *fc = GetDataSet(dsname);
5096 if (fc) {
5097 fc->Print();
5098 } else {
5099 Warning("HandleOutputOptions", "could not retrieve TFileCollection for dataset '%s'", dsname.Data());
5100 }
5101 } else {
5102 Warning("HandleOutputOptions", "dataset not found!");
5103 }
5104 } else {
5105 Bool_t targetcopied = kFALSE;
5106 TProofOutputFile *pf = 0;
5107 if (!target.IsNull())
5109 if (pf) {
5110 // Copy the file
5111 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5112 TUrl(target, kTRUE).GetUrl())) {
5113 if (TFile::Cp(pf->GetOutputFileName(), target)) {
5114 Printf(" Output successfully copied to %s", target.Data());
5115 targetcopied = kTRUE;
5116 } else {
5117 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5118 }
5119 }
5120 }
5121 TFile *fout = 0;
5122 TObject *o = 0;
5123 TIter nxo(GetOutputList());
5124 Bool_t swapcopied = kFALSE;
5125 while ((o = nxo())) {
5126 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5127 if (pof) {
5128 if (pof->TestBit(TProofOutputFile::kSwapFile) && !target.IsNull()) {
5129 if (pof == pf && targetcopied) continue;
5130 // Copy the file
5131 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5132 TUrl(target, kTRUE).GetUrl())) {
5133 if (TFile::Cp(pof->GetOutputFileName(), target)) {
5134 Printf(" Output successfully copied to %s", target.Data());
5135 swapcopied = kTRUE;
5136 } else {
5137 Warning("HandleOutputOptions", "problems copying output to %s", target.Data());
5138 }
5139 }
5140 } else if (pof->IsRetrieve()) {
5141 // Retrieve this file to the local path indicated in the title
5142 if (strcmp(TUrl(pf->GetOutputFileName(), kTRUE).GetUrl(),
5143 TUrl(pof->GetTitle(), kTRUE).GetUrl())) {
5144 if (TFile::Cp(pof->GetOutputFileName(), pof->GetTitle())) {
5145 Printf(" Output successfully copied to %s", pof->GetTitle());
5146 } else {
5147 Warning("HandleOutputOptions",
5148 "problems copying %s to %s", pof->GetOutputFileName(), pof->GetTitle());
5149 }
5150 }
5151 }
5152 }
5153 }
5154 if (!target.IsNull() && !swapcopied) {
5155 if (!fout && !pf) {
5156 fout = TFile::Open(target, "RECREATE");
5157 if (!fout || (fout && fout->IsZombie())) {
5158 SafeDelete(fout);
5159 Warning("HandleOutputOptions", "problems opening output file %s", target.Data());
5160 }
5161 }
5162 if (fout) {
5163 nxo.Reset();
5164 while ((o = nxo())) {
5165 TProofOutputFile *pof = dynamic_cast<TProofOutputFile *>(o);
5166 if (!pof) {
5167 // Write the object to the open output file
5168 o->Write();
5169 }
5170 }
5171 }
5172 }
5173 // Clean-up
5174 if (fout) {
5175 fout->Close();
5176 SafeDelete(fout);
5177 Printf(" Output saved to %s", target.Data());
5178 }
5179 }
5180 }
5181 // Remove the parameter
5182 DeleteParameters("PROOF_DefaultOutputOption");
5183 // Remove the parameter
5184 DeleteParameters("PROOF_SavePartialResults");
5185 }
5186 // Done
5187 return 0;
5188}
5189
5190////////////////////////////////////////////////////////////////////////////////
5191/// Extract from opt in optfb information about wanted feedback settings.
5192/// Feedback are removed from the input string opt.
5193/// If action == 0, set up feedback accordingly, if action == 1 clean related
5194/// feedback settings (using info in optfb, if available, or reparsing opt).
5195///
5196/// Feedback requirements are in the form
5197///
5198/// <previous_option>fb=name1,name2,name3,... <next_option>
5199/// <previous_option>feedback=name1,name2,name3,...;<next_option>
5200///
5201/// The special name 'stats' triggers feedback about events and packets.
5202/// The separator from the next option is either a ' ' or a ';'.
5203/// Called interanally by TProof::Process.
5204
5205void TProof::SetFeedback(TString &opt, TString &optfb, Int_t action)
5206{
5207 Ssiz_t from = 0;
5208 if (action == 0 || (action == 1 && optfb.IsNull())) {
5209 TString tag("fb=");
5210 Ssiz_t ifb = opt.Index(tag);
5211 if (ifb == kNPOS) {
5212 tag = "feedback=";
5213 ifb = opt.Index(tag);
5214 }
5215 if (ifb == kNPOS) return;
5216 from = ifb + tag.Length();
5217
5218 if (!opt.Tokenize(optfb, from, "[; ]") || optfb.IsNull()) {
5219 Warning("SetFeedback", "could not extract feedback string! Ignoring ...");
5220 return;
5221 }
5222 // Remove from original options string
5223 tag += optfb;
5224 opt.ReplaceAll(tag, "");
5225 }
5226
5227 // Parse now
5228 TString nm, startdraw, stopdraw;
5229 from = 0;
5230 while (optfb.Tokenize(nm, from, ",")) {
5231 // Special name first
5232 if (nm == "stats") {
5233 if (action == 0) {
5234 startdraw.Form("gDirectory->Add(new TStatsFeedback((TProof *)%p))", this);
5235 gROOT->ProcessLine(startdraw.Data());
5236 SetParameter("PROOF_StatsHist", "");
5237 AddFeedback("PROOF_EventsHist");
5238 AddFeedback("PROOF_PacketsHist");
5239 AddFeedback("PROOF_ProcPcktHist");
5240 } else {
5241 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5242 " if (o && strcmp(o->ClassName(), \"TStatsFeedback\")) "
5243 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5244 gROOT->ProcessLine(stopdraw.Data());
5245 DeleteParameters("PROOF_StatsHist");
5246 RemoveFeedback("PROOF_EventsHist");
5247 RemoveFeedback("PROOF_PacketsHist");
5248 RemoveFeedback("PROOF_ProcPcktHist");
5249 }
5250 } else {
5251 if (action == 0) {
5252 // Enable or
5253 AddFeedback(nm);
5254 startdraw.Form("gDirectory->Add(new TDrawFeedback((TProof *)%p))", this);
5255 gROOT->ProcessLine(startdraw.Data());
5256 } else {
5257 // ... or disable
5259 stopdraw.Form("TObject *o = gDirectory->FindObject(\"%s\"); "
5260 " if (o && strcmp(o->ClassName(), \"TDrawFeedback\")) "
5261 " { gDirectory->Remove(o); delete o; }", GetSessionTag());
5262 gROOT->ProcessLine(stopdraw.Data());
5263 }
5264 }
5265 }
5266}
5267
5268////////////////////////////////////////////////////////////////////////////////
5269/// Process a data set (TDSet) using the specified selector (.C) file or
5270/// Tselector object
5271/// Entry- or event-lists should be set in the data set object using
5272/// TDSet::SetEntryList.
5273/// The return value is -1 in case of error and TSelector::GetStatus() in
5274/// in case of success.
5275
5276Long64_t TProof::Process(TDSet *dset, const char *selector, Option_t *option,
5278{
5279 if (!IsValid() || !fPlayer) return -1;
5280
5281 // Set PROOF to running state
5283
5284 TString opt(option), optfb, outfile;
5285 // Enable feedback, if required
5286 if (opt.Contains("fb=") || opt.Contains("feedback=")) SetFeedback(opt, optfb, 0);
5287 // Define output file, either from 'opt' or the default one
5288 if (HandleOutputOptions(opt, outfile, 0) != 0) return -1;
5289
5290 // Resolve query mode
5291 fSync = (GetQueryMode(opt) == kSync);
5292
5293 if (fSync && (!IsIdle() || IsWaiting())) {
5294 // Already queued or processing queries: switch to asynchronous mode
5295 Info("Process", "session is in waiting or processing status: switch to asynchronous mode");
5296 fSync = kFALSE;
5297 opt.ReplaceAll("SYNC","");
5298 opt += "ASYN";
5299 }
5300
5301 // Cleanup old temporary datasets
5302 if ((IsIdle() && !IsWaiting()) && fRunningDSets && fRunningDSets->GetSize() > 0) {
5305 }
5306
5307 // deactivate the default application interrupt handler
5308 // ctrl-c's will be forwarded to PROOF to stop the processing
5309 TSignalHandler *sh = 0;
5310 if (fSync) {
5311 if (gApplication)
5313 }
5314
5315 // Make sure we get a fresh result
5317
5318 // Make sure that the workers ready list is empty
5319 if (fWrksOutputReady) {
5322 }
5323
5324 // Make sure the selector path is in the macro path
5325 TProof::AssertMacroPath(selector);
5326
5327 // Reset time measurements
5328 fQuerySTW.Reset();
5329
5330 Long64_t rv = -1;
5331 if (selector && strlen(selector)) {
5332 rv = fPlayer->Process(dset, selector, opt.Data(), nentries, first);
5333 } else if (fSelector) {
5334 rv = fPlayer->Process(dset, fSelector, opt.Data(), nentries, first);
5335 } else {
5336 Error("Process", "neither a selecrot file nor a selector object have"
5337 " been specified: cannot process!");
5338 }
5339
5340 // This is the end of merging
5341 fQuerySTW.Stop();
5342 Float_t rt = fQuerySTW.RealTime();
5343 // Update the query content
5345 if (qr) {
5346 qr->SetTermTime(rt);
5348 }
5349
5350 // Disable feedback, if required
5351 if (!optfb.IsNull()) SetFeedback(opt, optfb, 1);
5352 // Finalise output file settings (opt is ignored in here)
5353 if (HandleOutputOptions(opt, outfile, 1) != 0) return -1;
5354
5355 // Retrieve status from the output list
5356 if (rv >= 0) {
5358 (TParameter<Long64_t> *) fOutputList.FindObject("PROOF_SelectorStatus");
5359 if (sst) rv = sst->GetVal();
5360 }
5361
5362 if (fSync) {
5363 // reactivate the default application interrupt handler
5364 if (sh)
5366 // Save the performance info, if required
5367 if (!fPerfTree.IsNull()) {
5368 if (SavePerfTree() != 0) Error("Process", "saving performance info ...");
5369 // Must be re-enabled each time
5370 SetPerfTree(0);
5371 }
5372 }
5373
5374 return rv;
5375}
5376
5377////////////////////////////////////////////////////////////////////////////////
5378/// Process a data set (TFileCollection) using the specified selector (.C) file
5379/// or TSelector object.
5380/// The default tree is analyzed (i.e. the first one found). To specify another
5381/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5382/// The return value is -1 in case of error and TSelector::GetStatus() in
5383/// in case of success.
5384
5387{
5388 if (!IsValid() || !fPlayer) return -1;
5389
5390 if (fProtocol < 17) {
5391 Info("Process", "server version < 5.18/00:"
5392 " processing of TFileCollection not supported");
5393 return -1;
5394 }
5395
5396 // We include the TFileCollection to the input list and we create a
5397 // fake TDSet with infor about it
5398 TDSet *dset = new TDSet(TString::Format("TFileCollection:%s", fc->GetName()), 0, 0, "");
5400
5401
5402 Long64_t retval = -1;
5403 if (selector && strlen(selector)) {
5404 retval = Process(dset, selector, option, nentries, first);
5405 } else if (fSelector) {
5406 retval = Process(dset, fSelector, option, nentries, first);
5407 } else {
5408 Error("Process", "neither a selecrot file nor a selector object have"
5409 " been specified: cannot process!");
5410 }
5411 fPlayer->GetInputList()->Remove(fc); // To avoid problems in future
5412
5413 // Cleanup
5414 if (IsLite() && !fSync) {
5415 if (!fRunningDSets) fRunningDSets = new TList;
5416 fRunningDSets->Add(dset);
5417 } else {
5418 delete dset;
5419 }
5420
5421 return retval;
5422}
5423
5424////////////////////////////////////////////////////////////////////////////////
5425/// Process a dataset which is stored on the master with name 'dsetname'.
5426/// The syntax for dsetname is name[#[dir/]objname], e.g.
5427/// "mydset" analysis of the first tree in the top dir of the dataset
5428/// named "mydset"
5429/// "mydset#T" analysis tree "T" in the top dir of the dataset
5430/// named "mydset"
5431/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
5432/// named "mydset"
5433/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
5434/// dataset named "mydset"
5435/// The component 'name' in its more general form contains also the group and
5436/// user name following "/<group>/<user>/<dsname>". Each of these components
5437/// can contain one or more wildcards '*', in which case all the datasets matching
5438/// the expression are added together as a global dataset (wildcard support has
5439/// been added in version 5.27/02).
5440/// The last argument 'elist' specifies an entry- or event-list to be used as
5441/// event selection.
5442/// It is also possible (starting w/ version 5.27/02) to run on multiple datasets
5443/// at once in a more flexible way that the one provided by wildcarding. There
5444/// are three possibilities:
5445/// 1) specifying the dataset names separated by the OR operator '|', e.g.
5446/// dsetname = "<dset1>|<dset2>|<dset3>|..."
5447/// in this case the datasets are a seen as a global unique dataset
5448/// 2) specifying the dataset names separated by a ',' or a ' ', e.g.
5449/// dsetname = "<dset1>,<dset2> <dset3>,..."
5450/// in this case the datasets are processed one after the other and the
5451/// selector is notified when switching dataset via a bit in the current
5452/// processed element.
5453/// 3) giving the path of a textfile where the dataset names are specified
5454/// on one or multiple lines; the lines found are joined as in 1), unless
5455/// the filepath is followed by a ',' (i.e. p->Process("datasets.txt,",...)
5456/// with the dataset names listed in 'datasets.txt') in which case they are
5457/// treated as in 2); the file is open in raw mode with TFile::Open and
5458/// therefore it cane be remote, e.g. on a Web server.
5459/// Each <dsetj> has the format specified above for the single dataset processing,
5460/// included wildcarding (the name of the tree and subdirectory must be same for
5461/// all the datasets).
5462/// In the case of multiple datasets, 'elist' is treated a global entry list.
5463/// It is possible to specify per-dataset entry lists using the syntax
5464/// "mydset[#adir/[T]]?enl=entrylist"
5465/// or
5466/// "mydset[#adir/[T]]<<entrylist"
5467/// Here 'entrylist' is a tag identifying, in the order :
5468/// i. a named entry-list in the input list or in the input data list
5469/// ii. a named entry-list in memory (in gDirectory)
5470/// iii. the path of a file containing the entry-list to be used
5471/// In the case ii) and iii) the entry-list object(s) is(are) added to the input
5472/// data list.
5473/// The return value is -1 in case of error and TSelector::GetStatus() in
5474/// in case of success.
5475
5476Long64_t TProof::Process(const char *dsetname, const char *selector,
5477 Option_t *option, Long64_t nentries,
5478 Long64_t first, TObject *elist)
5479{
5480 if (fProtocol < 13) {
5481 Info("Process", "processing 'by name' not supported by the server");
5482 return -1;
5483 }
5484
5485 TString dsname, fname(dsetname);
5486 // If the 'dsetname' corresponds to an existing and readable file we will try to
5487 // interpretate its content as names of datasets to be processed. One line can contain
5488 // more datasets, separated by ',' or '|'. By default the dataset lines will be added
5489 // (i.e. joined as in option '|'); if the file name ends with ',' the dataset lines are
5490 // joined with ','.
5491 const char *separator = (fname.EndsWith(",")) ? "," : "|";
5492 if (!strcmp(separator, ",") || fname.EndsWith("|")) fname.Remove(fname.Length()-1, 1);
5493 if (!(gSystem->AccessPathName(fname, kReadPermission))) {
5494 TUrl uf(fname, kTRUE);
5495 uf.SetOptions(TString::Format("%sfiletype=raw", uf.GetOptions()));
5496 TFile *f = TFile::Open(uf.GetUrl());
5497 if (f && !(f->IsZombie())) {
5498 const Int_t blen = 8192;
5499 char buf[blen];
5500 Long64_t rest = f->GetSize();
5501 while (rest > 0) {
5502 Long64_t len = (rest > blen - 1) ? blen - 1 : rest;
5503 if (f->ReadBuffer(buf, len)) {
5504 Error("Process", "problems reading from file '%s'", fname.Data());
5505 dsname = "";
5506 break;
5507 }
5508 buf[len] = '\0';
5509 dsname += buf;
5510 rest -= len;
5511 }
5512 f->Close();
5513 SafeDelete(f);
5514 // We fail if a failure occured
5515 if (rest > 0) return -1;
5516 } else {
5517 Error("Process", "could not open file '%s'", fname.Data());
5518 return -1;
5519 }
5520 }
5521 if (dsname.IsNull()) {
5522 dsname = dsetname;
5523 } else {
5524 // Remove trailing '\n'
5525 if (dsname.EndsWith("\n")) dsname.Remove(dsname.Length()-1, 1);
5526 // Replace all '\n' with the proper separator
5527 dsname.ReplaceAll("\n", separator);
5528 if (gDebug > 0) {
5529 Info("Process", "processing multi-dataset read from file '%s':", fname.Data());
5530 Info("Process", " '%s'", dsname.Data());
5531 }
5532 }
5533
5534 TString names(dsname), name, enl, newname;
5535 // If multi-dataset check if server supports it
5536 if (fProtocol < 28 && names.Index(TRegexp("[, |]")) != kNPOS) {
5537 Info("Process", "multi-dataset processing not supported by the server");
5538 return -1;
5539 }
5540
5541 TEntryList *el = 0;
5542 TString dsobj, dsdir;
5543 Int_t from = 0;
5544 while (names.Tokenize(name, from, "[, |]")) {
5545
5546 newname = name;
5547 // Extract the specific entry-list, if any
5548 enl = "";
5549 Int_t ienl = name.Index("?enl=");
5550 if (ienl == kNPOS) {
5551 ienl = name.Index("<<");
5552 if (ienl != kNPOS) {
5553 newname.Remove(ienl);
5554 ienl += strlen("<<");
5555 }
5556 } else {
5557 newname.Remove(ienl);
5558 ienl += strlen("?enl=");
5559 }
5560
5561 // Check the name syntax first
5562 TString obj, dir("/");
5563 Int_t idxc = newname.Index("#");
5564 if (idxc != kNPOS) {
5565 Int_t idxs = newname.Index("/", 1, idxc, TString::kExact);
5566 if (idxs != kNPOS) {
5567 obj = newname(idxs+1, newname.Length());
5568 dir = newname(idxc+1, newname.Length());
5569 dir.Remove(dir.Index("/") + 1);
5570 newname.Remove(idxc);
5571 } else {
5572 obj = newname(idxc+1, newname.Length());
5573 newname.Remove(idxc);
5574 }
5575 } else if (newname.Index(":") != kNPOS && newname.Index("://") == kNPOS) {
5576 // protection against using ':' instead of '#'
5577 Error("Process", "bad name syntax (%s): please use"
5578 " a '#' after the dataset name", name.Data());
5579 dsname.ReplaceAll(name, "");
5580 continue;
5581 }
5582 if (dsobj.IsNull() && dsdir.IsNull()) {
5583 // The first one specifies obj and dir
5584 dsobj = obj;
5585 dsdir = dir;
5586 } else if (obj != dsobj || dir != dsdir) {
5587 // Inconsistent specification: not supported
5588 Warning("Process", "'obj' or 'dir' specification not consistent w/ the first given: ignore");
5589 }
5590 // Process the entry-list name, if any
5591 if (ienl != kNPOS) {
5592 // Get entrylist name or path
5593 enl = name(ienl, name.Length());
5594 el = 0;
5595 TObject *oel = 0;
5596 // If not in the input list ...
5597 TList *inpl = GetInputList();
5598 if (inpl && (oel = inpl->FindObject(enl))) el = dynamic_cast<TEntryList *>(oel);
5599 // ... check the heap
5600 if (!el && gDirectory && (oel = gDirectory->FindObject(enl))) {
5601 if ((el = dynamic_cast<TEntryList *>(oel))) {
5602 // Add to the input list (input data not available on master where
5603 // this info will be processed)
5604 if (fProtocol >= 28)
5605 if (!(inpl->FindObject(el->GetName()))) AddInput(el);
5606 }
5607 }
5608 // If not in the heap, check a file, if any
5609 if (!el) {
5610 if (!gSystem->AccessPathName(enl)) {
5611 TFile *f = TFile::Open(enl);
5612 if (f && !(f->IsZombie()) && f->GetListOfKeys()) {
5613 TIter nxk(f->GetListOfKeys());
5614 TKey *k = 0;
5615 while ((k = (TKey *) nxk())) {
5616 if (!strcmp(k->GetClassName(), "TEntryList")) {
5617 if (!el) {
5618 if ((el = dynamic_cast<TEntryList *>(f->Get(k->GetName())))) {
5619 // Add to the input list (input data not available on master where
5620 // this info will be processed)
5621 if (fProtocol >= 28) {
5622 if (!(inpl->FindObject(el->GetName()))) {
5623 el = (TEntryList *) el->Clone();
5624 AddInput(el);
5625 }
5626 } else {
5627 el = (TEntryList *) el->Clone();
5628 }
5629 }
5630 } else if (strcmp(el->GetName(), k->GetName())) {
5631 Warning("Process", "multiple entry lists found in file '%s': the first one is taken;\n"
5632 "if this is not what you want, load first the content in memory"
5633 "and select it by name ", enl.Data());
5634 }
5635 }
5636 }
5637 } else {
5638 Warning("Process","file '%s' cannot be open or is empty - ignoring", enl.Data());
5639 }
5640 }
5641 }
5642 // Transmit the information
5643 if (fProtocol >= 28) {
5644 newname += "?enl=";
5645 if (el) {
5646 // An entry list object is avalaible in the input list: add its name
5647 newname += el->GetName();
5648 } else {
5649 // The entry list object was not found: send the name, the future entry list manager will
5650 // find it on the server side
5651 newname += enl;
5652 }
5653 }
5654 }
5655 // Adjust the name for this dataset
5656 dsname.ReplaceAll(name, newname);
5657 }
5658
5659 // Create the dataset object
5660 TDSet *dset = new TDSet(dsname, dsobj, dsdir);
5661 // Set entry list
5662 if (el && fProtocol < 28) {
5663 dset->SetEntryList(el);
5664 } else {
5665 dset->SetEntryList(elist);
5666 }
5667 // Run
5668 Long64_t retval = -1;
5669 if (selector && strlen(selector)) {
5670 retval = Process(dset, selector, option, nentries, first);
5671 } else if (fSelector) {
5672 retval = Process(dset, fSelector, option, nentries, first);
5673 } else {
5674 Error("Process", "neither a selector file nor a selector object have"
5675 " been specified: cannot process!");
5676 }
5677 // Cleanup
5678 if (IsLite() && !fSync) {
5679 if (!fRunningDSets) fRunningDSets = new TList;
5680 fRunningDSets->Add(dset);
5681 } else {
5682 delete dset;
5683 }
5684
5685 return retval;
5686}
5687
5688////////////////////////////////////////////////////////////////////////////////
5689/// Generic (non-data based) selector processing: the Process() method of the
5690/// specified selector (.C) or TSelector object is called 'n' times.
5691/// The return value is -1 in case of error and TSelector::GetStatus() in
5692/// in case of success.
5693
5694Long64_t TProof::Process(const char *selector, Long64_t n, Option_t *option)
5695{
5696 if (!IsValid()) return -1;
5697
5698 if (fProtocol < 16) {
5699 Info("Process", "server version < 5.17/04: generic processing not supported");
5700 return -1;
5701 }
5702
5703 // Fake data set
5704 TDSet *dset = new TDSet;
5705 dset->SetBit(TDSet::kEmpty);
5706
5707 Long64_t retval = -1;
5708 if (selector && strlen(selector)) {
5709 retval = Process(dset, selector, option, n);
5710 } else if (fSelector) {
5711 retval = Process(dset, fSelector, option, n);
5712 } else {
5713 Error("Process", "neither a selector file nor a selector object have"
5714 " been specified: cannot process!");
5715 }
5716
5717 // Cleanup
5718 if (IsLite() && !fSync) {
5719 if (!fRunningDSets) fRunningDSets = new TList;
5720 fRunningDSets->Add(dset);
5721 } else {
5722 delete dset;
5723 }
5724 return retval;
5725}
5726
5727////////////////////////////////////////////////////////////////////////////////
5728/// Process a data set (TDSet) using the specified selector object.
5729/// Entry- or event-lists should be set in the data set object using
5730/// TDSet::SetEntryList.
5731/// The return value is -1 in case of error and TSelector::GetStatus() in
5732/// in case of success.
5733
5736{
5737 if (fProtocol < 34) {
5738 Error("Process", "server version < 5.33/02:"
5739 "processing by object not supported");
5740 return -1;
5741 }
5742 if (!selector) {
5743 Error("Process", "selector object undefined!");
5744 return -1;
5745 }
5746 fSelector = selector;
5747 Long64_t rc = Process(dset, (const char*)0, option, nentries, first);
5748 fSelector = 0;
5749 // Done
5750 return rc;
5751}
5752
5753////////////////////////////////////////////////////////////////////////////////
5754/// Process a data set (TFileCollection) using the specified selector object
5755/// The default tree is analyzed (i.e. the first one found). To specify another
5756/// tree, the default tree can be changed using TFileCollection::SetDefaultMetaData .
5757/// The return value is -1 in case of error and TSelector::GetStatus() in
5758/// in case of success.
5759
5762{
5763 if (fProtocol < 34) {
5764 Error("Process", "server version < 5.33/02:"
5765 "processing by object not supported");
5766 return -1;
5767 }
5768 if (!selector) {
5769 Error("Process", "selector object undefined!");
5770 return -1;
5771 }
5772 fSelector = selector;
5773 Long64_t rc = Process(fc, (const char*)0, option, nentries, first);
5774 fSelector = 0;
5775 // Done
5776 return rc;
5777}
5778
5779////////////////////////////////////////////////////////////////////////////////
5780/// Process with name of dataset and TSelector object
5781
5782Long64_t TProof::Process(const char *dsetname, TSelector *selector,
5783 Option_t *option, Long64_t nentries,
5784 Long64_t first, TObject *elist)
5785{
5786 if (fProtocol < 34) {
5787 Error("Process", "server version < 5.33/02:"
5788 "processing by object not supported");
5789 return -1;
5790 }
5791 if (!selector) {
5792 Error("Process", "selector object undefined!");
5793 return -1;
5794 }
5795 fSelector = selector;
5796 Long64_t rc = Process(dsetname, (const char*)0, option, nentries, first, elist);
5797 fSelector = 0;
5798 // Done
5799 return rc;
5800}
5801
5802////////////////////////////////////////////////////////////////////////////////
5803/// Generic (non-data based) selector processing: the Process() method of the
5804/// specified selector is called 'n' times.
5805/// The return value is -1 in case of error and TSelector::GetStatus() in
5806/// in case of success.
5807
5809{
5810 if (fProtocol < 34) {
5811 Error("Process", "server version < 5.33/02:"
5812 "processing by object not supported");
5813 return -1;
5814 }
5815 if (!selector) {
5816 Error("Process", "selector object undefined!");
5817 return -1;
5818 }
5819 fSelector = selector;
5820 Long64_t rc = Process((const char*)0, n, option);
5821 fSelector = 0;
5822 // Done
5823 return rc;
5824}
5825
5826////////////////////////////////////////////////////////////////////////////////
5827/// Get reference for the qry-th query in fQueries (as
5828/// displayed by ShowQueries).
5829
5831{
5832 ref = "";
5833 if (qry > 0) {
5834 if (!fQueries)
5836 if (fQueries) {
5837 TIter nxq(fQueries);
5838 TQueryResult *qr = 0;
5839 while ((qr = (TQueryResult *) nxq()))
5840 if (qr->GetSeqNum() == qry) {
5841 ref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5842 return 0;
5843 }
5844 }
5845 }
5846 return -1;
5847}
5848
5849////////////////////////////////////////////////////////////////////////////////
5850/// Finalize the qry-th query in fQueries.
5851/// If force, force retrieval if the query is found in the local list
5852/// but has already been finalized (default kFALSE).
5853/// If query < 0, finalize current query.
5854/// Return 0 on success, -1 on error
5855
5857{
5858 if (fPlayer) {
5859 if (qry > 0) {
5860 TString ref;
5861 if (GetQueryReference(qry, ref) == 0) {
5862 return Finalize(ref, force);
5863 } else {
5864 Info("Finalize", "query #%d not found", qry);
5865 }
5866 } else {
5867 // The last query
5868 return Finalize("", force);
5869 }
5870 }
5871 return -1;
5872}
5873
5874////////////////////////////////////////////////////////////////////////////////
5875/// Finalize query with reference ref.
5876/// If force, force retrieval if the query is found in the local list
5877/// but has already been finalized (default kFALSE).
5878/// If ref = 0, finalize current query.
5879/// Return 0 on success, -1 on error
5880
5881Long64_t TProof::Finalize(const char *ref, Bool_t force)
5882{
5883 if (fPlayer) {
5884 // Get the pointer to the query
5885 TQueryResult *qr = (ref && strlen(ref) > 0) ? fPlayer->GetQueryResult(ref)
5886 : GetQueryResult();
5888 TString xref(ref);
5889 if (!qr) {
5890 if (!xref.IsNull()) {
5891 retrieve = kTRUE;
5892 }
5893 } else {
5894 if (qr->IsFinalized()) {
5895 if (force) {
5896 retrieve = kTRUE;
5897 } else {
5898 Info("Finalize","query already finalized:"
5899 " use Finalize(<qry>,kTRUE) to force new retrieval");
5900 qr = 0;
5901 }
5902 } else {
5903 retrieve = kTRUE;
5904 xref.Form("%s:%s", qr->GetTitle(), qr->GetName());
5905 }
5906 }
5907 if (retrieve) {
5908 Retrieve(xref.Data());
5909 qr = fPlayer->GetQueryResult(xref.Data());
5910 }
5911 if (qr)
5912 return fPlayer->Finalize(qr);
5913 }
5914 return -1;
5915}
5916
5917////////////////////////////////////////////////////////////////////////////////
5918/// Send retrieve request for the qry-th query in fQueries.
5919/// If path is defined save it to path.
5920
5921Int_t TProof::Retrieve(Int_t qry, const char *path)
5922{
5923 if (qry > 0) {
5924 TString ref;
5925 if (GetQueryReference(qry, ref) == 0)
5926 return Retrieve(ref, path);
5927 else
5928 Info("Retrieve", "query #%d not found", qry);
5929 } else {
5930 Info("Retrieve","positive argument required - do nothing");
5931 }
5932 return -1;
5933}
5934
5935////////////////////////////////////////////////////////////////////////////////
5936/// Send retrieve request for the query specified by ref.
5937/// If path is defined save it to path.
5938/// Generic method working for all queries known by the server.
5939
5940Int_t TProof::Retrieve(const char *ref, const char *path)
5941{
5942 if (ref) {
5944 m << TString(ref);
5947
5948 // Archive it locally, if required
5949 if (path) {
5950
5951 // Get pointer to query
5952 TQueryResult *qr = fPlayer ? fPlayer->GetQueryResult(ref) : 0;
5953
5954 if (qr) {
5955
5956 TFile *farc = TFile::Open(path,"UPDATE");
5957 if (!farc || (farc && !(farc->IsOpen()))) {
5958 Info("Retrieve", "archive file cannot be open (%s)", path);
5959 return 0;
5960 }
5961 farc->cd();
5962
5963 // Update query status
5964 qr->SetArchived(path);
5965
5966 // Write to file
5967 qr->Write();
5968
5969 farc->Close();
5970 SafeDelete(farc);
5971
5972 } else {
5973 Info("Retrieve", "query not found after retrieve");
5974 return -1;
5975 }
5976 }
5977
5978 return 0;
5979 }
5980 return -1;
5981}
5982
5983////////////////////////////////////////////////////////////////////////////////
5984/// Send remove request for the qry-th query in fQueries.
5985
5987{
5988 if (qry > 0) {
5989 TString ref;
5990 if (GetQueryReference(qry, ref) == 0)
5991 return Remove(ref, all);
5992 else
5993 Info("Remove", "query #%d not found", qry);
5994 } else {
5995 Info("Remove","positive argument required - do nothing");
5996 }
5997 return -1;
5998}
5999
6000////////////////////////////////////////////////////////////////////////////////
6001/// Send remove request for the query specified by ref.
6002/// If all = TRUE remove also local copies of the query, if any.
6003/// Generic method working for all queries known by the server.
6004/// This method can be also used to reset the list of queries
6005/// waiting to be processed: for that purpose use ref == "cleanupqueue".
6006
6007Int_t TProof::Remove(const char *ref, Bool_t all)
6008{
6009 if (all) {
6010 // Remove also local copies, if any
6011 if (fPlayer)
6013 }
6014
6015 if (IsLite()) return 0;
6016
6017 if (ref) {
6019 m << TString(ref);
6022 return 0;
6023 }
6024 return -1;
6025}
6026
6027////////////////////////////////////////////////////////////////////////////////
6028/// Send archive request for the qry-th query in fQueries.
6029
6030Int_t TProof::Archive(Int_t qry, const char *path)
6031{
6032 if (qry > 0) {
6033 TString ref;
6034 if (GetQueryReference(qry, ref) == 0)
6035 return Archive(ref, path);
6036 else
6037 Info("Archive", "query #%d not found", qry);
6038 } else {
6039 Info("Archive","positive argument required - do nothing");
6040 }
6041 return -1;
6042}
6043
6044////////////////////////////////////////////////////////////////////////////////
6045/// Send archive request for the query specified by ref.
6046/// Generic method working for all queries known by the server.
6047/// If ref == "Default", path is understood as a default path for
6048/// archiving.
6049
6050Int_t TProof::Archive(const char *ref, const char *path)
6051{
6052 if (ref) {
6054 m << TString(ref) << TString(path);
6057 return 0;
6058 }
6059 return -1;
6060}
6061
6062////////////////////////////////////////////////////////////////////////////////
6063/// Send cleanup request for the session specified by tag.
6064
6065Int_t TProof::CleanupSession(const char *sessiontag)
6066{
6067 if (sessiontag) {
6069 m << TString(sessiontag);
6072 return 0;
6073 }
6074 return -1;
6075}
6076
6077////////////////////////////////////////////////////////////////////////////////
6078/// Change query running mode to the one specified by 'mode'.
6079
6081{
6082 fQueryMode = mode;
6083
6084 if (gDebug > 0)
6085 Info("SetQueryMode","query mode is set to: %s", fQueryMode == kSync ?
6086 "Sync" : "Async");
6087}
6088
6089////////////////////////////////////////////////////////////////////////////////
6090/// Find out the query mode based on the current setting and 'mode'.
6091
6093{
6094 EQueryMode qmode = fQueryMode;
6095
6096 if (mode && (strlen(mode) > 0)) {
6097 TString m(mode);
6098 m.ToUpper();
6099 if (m.Contains("ASYN")) {
6100 qmode = kAsync;
6101 } else if (m.Contains("SYNC")) {
6102 qmode = kSync;
6103 }
6104 }
6105
6106 if (gDebug > 0)
6107 Info("GetQueryMode","query mode is set to: %s", qmode == kSync ?
6108 "Sync" : "Async");
6109
6110 return qmode;
6111}
6112
6113////////////////////////////////////////////////////////////////////////////////
6114/// Execute the specified drawing action on a data set (TDSet).
6115/// Event- or Entry-lists should be set in the data set object using
6116/// TDSet::SetEntryList.
6117/// Returns -1 in case of error or number of selected events otherwise.
6118
6119Long64_t TProof::DrawSelect(TDSet *dset, const char *varexp,
6120 const char *selection, Option_t *option,
6122{
6123 if (!IsValid() || !fPlayer) return -1;
6124
6125 // Make sure that asynchronous processing is not active
6126 if (!IsIdle()) {
6127 Info("DrawSelect","not idle, asynchronous Draw not supported");
6128 return -1;
6129 }
6130 TString opt(option);
6131 Int_t idx = opt.Index("ASYN", 0, TString::kIgnoreCase);
6132 if (idx != kNPOS)
6133 opt.Replace(idx,4,"");
6134
6135 return fPlayer->DrawSelect(dset, varexp, selection, opt, nentries, first);
6136}
6137
6138////////////////////////////////////////////////////////////////////////////////
6139/// Execute the specified drawing action on a data set which is stored on the
6140/// master with name 'dsetname'.
6141/// The syntax for dsetname is name[#[dir/]objname], e.g.
6142/// "mydset" analysis of the first tree in the top dir of the dataset
6143/// named "mydset"
6144/// "mydset#T" analysis tree "T" in the top dir of the dataset
6145/// named "mydset"
6146/// "mydset#adir/T" analysis tree "T" in the dir "adir" of the dataset
6147/// named "mydset"
6148/// "mydset#adir/" analysis of the first tree in the dir "adir" of the
6149/// dataset named "mydset"
6150/// The last argument 'enl' specifies an entry- or event-list to be used as
6151/// event selection.
6152/// The return value is -1 in case of error and TSelector::GetStatus() in
6153/// in case of success.
6154
6155Long64_t TProof::DrawSelect(const char *dsetname, const char *varexp,
6156 const char *selection, Option_t *option,
6158{
6159 if (fProtocol < 13) {
6160 Info("Process", "processing 'by name' not supported by the server");
6161 return -1;
6162 }
6163
6164 TString name(dsetname);
6165 TString obj;
6166 TString dir = "/";
6167 Int_t idxc = name.Index("#");
6168 if (idxc != kNPOS) {
6169 Int_t idxs = name.Index("/", 1, idxc, TString::kExact);
6170 if (idxs != kNPOS) {
6171 obj = name(idxs+1, name.Length());
6172 dir = name(idxc+1, name.Length());
6173 dir.Remove(dir.Index("/") + 1);
6174 name.Remove(idxc);
6175 } else {
6176 obj = name(idxc+1, name.Length());
6177 name.Remove(idxc);
6178 }
6179 } else if (name.Index(":") != kNPOS && name.Index("://") == kNPOS) {
6180 // protection against using ':' instead of '#'
6181 Error("DrawSelect", "bad name syntax (%s): please use"
6182 " a '#' after the dataset name", dsetname);
6183 return -1;
6184 }
6185
6186 TDSet *dset = new TDSet(name, obj, dir);
6187 // Set entry-list, if required
6188 dset->SetEntryList(enl);
6189 Long64_t retval = DrawSelect(dset, varexp, selection, option, nentries, first);
6190 delete dset;
6191 return retval;
6192}
6193
6194////////////////////////////////////////////////////////////////////////////////
6195/// Send STOPPROCESS message to master and workers.
6196
6198{
6199 PDB(kGlobal,2)
6200 Info("StopProcess","enter %d", abort);
6201
6202 if (!IsValid())
6203 return;
6204
6205 // Flag that we have been stopped
6207 SetRunStatus(rst);
6208
6209 if (fPlayer)
6210 fPlayer->StopProcess(abort, timeout);
6211
6212 // Stop any blocking 'Collect' request; on masters we do this only if
6213 // aborting; when stopping, we still need to receive the results
6214 if (TestBit(TProof::kIsClient) || abort)
6216
6217 if (fSlaves->GetSize() == 0)
6218 return;
6219
6220 // Notify the remote counterpart
6221 TSlave *sl;
6222 TIter next(fSlaves);
6223 while ((sl = (TSlave *)next()))
6224 if (sl->IsValid())
6225 // Ask slave to progate the stop/abort request
6226 sl->StopProcess(abort, timeout);
6227}
6228
6229////////////////////////////////////////////////////////////////////////////////
6230/// Signal to disable related switches
6231
6233{
6234 Emit("DisableGoAsyn()");
6235}
6236
6237////////////////////////////////////////////////////////////////////////////////
6238/// Send GOASYNC message to the master.
6239
6241{
6242 if (!IsValid()) return;
6243
6244 if (GetRemoteProtocol() < 22) {
6245 Info("GoAsynchronous", "functionality not supported by the server - ignoring");
6246 return;
6247 }
6248
6249 if (fSync && !IsIdle()) {
6251 Broadcast(m);
6252 } else {
6253 Info("GoAsynchronous", "either idle or already in asynchronous mode - ignoring");
6254 }
6255}
6256
6257////////////////////////////////////////////////////////////////////////////////
6258/// Receive the log file of the slave with socket s.
6259
6261{
6262 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
6263 char buf[kMAXBUF];
6264
6265 // If macro saving is enabled prepare macro
6269 }
6270
6271 // Append messages to active logging unit
6272 Int_t fdout = -1;
6273 if (!fLogToWindowOnly) {
6274 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6275 if (fdout < 0) {
6276 Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
6277 " will not log msgs", fdout);
6278 return;
6279 }
6280 lseek(fdout, (off_t) 0, SEEK_END);
6281 }
6282
6283 Int_t left, rec, r;
6284 Long_t filesize = 0;
6285
6286 while (filesize < size) {
6287 left = Int_t(size - filesize);
6288 if (left >= kMAXBUF)
6289 left = kMAXBUF-1;
6290 rec = s->RecvRaw(&buf, left);
6291 filesize = (rec > 0) ? (filesize + rec) : filesize;
6293 if (rec > 0) {
6294
6295 char *p = buf;
6296 r = rec;
6297 while (r) {
6298 Int_t w;
6299
6300 w = write(fdout, p, r);
6301
6302 if (w < 0) {
6303 SysError("RecvLogFile", "error writing to unit: %d", fdout);
6304 break;
6305 }
6306 r -= w;
6307 p += w;
6308 }
6309 } else if (rec < 0) {
6310 Error("RecvLogFile", "error during receiving log file");
6311 break;
6312 }
6313 }
6314 if (rec > 0) {
6315 buf[rec] = 0;
6316 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6317 // If macro saving is enabled add to TMacro
6319 }
6320 }
6321
6322 // If idle restore logs to main session window
6324 fRedirLog = kFALSE;
6325}
6326
6327////////////////////////////////////////////////////////////////////////////////
6328/// Notify locally 'msg' to the appropriate units (file, stdout, window)
6329/// If defined, 'sfx' is added after 'msg' (typically a line-feed);
6330
6331void TProof::NotifyLogMsg(const char *msg, const char *sfx)
6332{
6333 // Must have somenthing to notify
6334 Int_t len = 0;
6335 if (!msg || (len = strlen(msg)) <= 0)
6336 return;
6337
6338 // Get suffix length if any
6339 Int_t lsfx = (sfx) ? strlen(sfx) : 0;
6340
6341 // Append messages to active logging unit
6342 Int_t fdout = -1;
6343 if (!fLogToWindowOnly) {
6344 fdout = (fRedirLog) ? fileno(fLogFileW) : fileno(stdout);
6345 if (fdout < 0) {
6346 Warning("NotifyLogMsg", "file descriptor for outputs undefined (%d):"
6347 " will not notify msgs", fdout);
6348 return;
6349 }
6350 lseek(fdout, (off_t) 0, SEEK_END);
6351 }
6352
6353 if (!fLogToWindowOnly) {
6354 // Write to output unit (stdout or a log file)
6355 if (len > 0) {
6356 char *p = (char *)msg;
6357 Int_t r = len;
6358 while (r) {
6359 Int_t w = write(fdout, p, r);
6360 if (w < 0) {
6361 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6362 break;
6363 }
6364 r -= w;
6365 p += w;
6366 }
6367 // Add a suffix, if requested
6368 if (lsfx > 0)
6369 if (write(fdout, sfx, lsfx) != lsfx)
6370 SysError("NotifyLogMsg", "error writing to unit: %d", fdout);
6371 }
6372 }
6373 if (len > 0) {
6374 // Publish the message to the separate window (if the latter is missing
6375 // the message will just get lost)
6376 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, kFALSE);
6377 }
6378
6379 // If idle restore logs to main session window
6380 if (fRedirLog && IsIdle())
6381 fRedirLog = kFALSE;
6382}
6383
6384////////////////////////////////////////////////////////////////////////////////
6385/// Log a message into the appropriate window by emitting a signal.
6386
6387void TProof::LogMessage(const char *msg, Bool_t all)
6388{
6389 PDB(kGlobal,1)
6390 Info("LogMessage","Enter ... %s, 'all: %s", msg ? msg : "",
6391 all ? "true" : "false");
6392
6393 if (gROOT->IsBatch()) {
6394 PDB(kGlobal,1) Info("LogMessage","GUI not started - use TProof::ShowLog()");
6395 return;
6396 }
6397
6398 if (msg)
6399 EmitVA("LogMessage(const char*,Bool_t)", 2, msg, all);
6400
6401 // Re-position at the beginning of the file, if requested.
6402 // This is used by the dialog when it re-opens the log window to
6403 // provide all the session messages
6404 if (all)
6405 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
6406
6407 const Int_t kMAXBUF = 32768;
6408 char buf[kMAXBUF];
6409 Int_t len;
6410 do {
6411 while ((len = read(fileno(fLogFileR), buf, kMAXBUF-1)) < 0 &&
6412 TSystem::GetErrno() == EINTR)
6414
6415 if (len < 0) {
6416 Error("LogMessage", "error reading log file");
6417 break;
6418 }
6419
6420 if (len > 0) {
6421 buf[len] = 0;
6422 EmitVA("LogMessage(const char*,Bool_t)", 2, buf, kFALSE);
6423 }
6424
6425 } while (len > 0);
6426}
6427
6428////////////////////////////////////////////////////////////////////////////////
6429/// Send to all active slaves servers the current slave group size
6430/// and their unique id. Returns number of active slaves.
6431/// Returns -1 in case of error.
6432
6434{
6435 if (!IsValid()) return -1;
6436 if (TestBit(TProof::kIsClient)) return 0;
6437 if (!fSendGroupView) return 0;
6439
6440 TIter next(fActiveSlaves);
6441 TSlave *sl;
6442
6443 int bad = 0, cnt = 0, size = GetNumberOfActiveSlaves();
6444 char str[32];
6445
6446 while ((sl = (TSlave *)next())) {
6447 snprintf(str, 32, "%d %d", cnt, size);
6448 if (sl->GetSocket()->Send(str, kPROOF_GROUPVIEW) == -1) {
6449 MarkBad(sl, "could not send kPROOF_GROUPVIEW message");
6450 bad++;
6451 } else
6452 cnt++;
6453 }
6454
6455 // Send the group view again in case there was a change in the
6456 // group size due to a bad slave
6457
6458 if (bad) SendGroupView();
6459
6460 return GetNumberOfActiveSlaves();
6461}
6462
6463////////////////////////////////////////////////////////////////////////////////
6464/// Static method to extract the filename (if any) form a CINT command.
6465/// Returns kTRUE and the filename in 'fn'; returns kFALSE if not found or not
6466/// appliable.
6467
6469{
6470 TString s = cmd;
6471 s = s.Strip(TString::kBoth);
6472
6473 if (s.Length() > 0 &&
6474 (s.BeginsWith(".L") || s.BeginsWith(".x") || s.BeginsWith(".X"))) {
6475 TString file = s(2, s.Length());
6476 TString acm, arg, io;
6477 fn = gSystem->SplitAclicMode(file, acm, arg, io);
6478 if (!fn.IsNull())
6479 return kTRUE;
6480 }
6481
6482 // Not found
6483 return kFALSE;
6484}
6485
6486////////////////////////////////////////////////////////////////////////////////
6487/// Send command to be executed on the PROOF master and/or slaves.
6488/// If plusMaster is kTRUE then exeucte on slaves and master too.
6489/// Command can be any legal command line command. Commands like
6490/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6491/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6492/// succes.
6493
6494Int_t TProof::Exec(const char *cmd, Bool_t plusMaster)
6495{
6496 return Exec(cmd, kActive, plusMaster);
6497}
6498
6499////////////////////////////////////////////////////////////////////////////////
6500/// Send command to be executed on the PROOF master and/or slaves.
6501/// Command can be any legal command line command. Commands like
6502/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6503/// to the PROOF cluster. Returns -1 in case of error, >=0 in case of
6504/// succes.
6505
6506Int_t TProof::Exec(const char *cmd, ESlaves list, Bool_t plusMaster)
6507{
6508 if (!IsValid()) return -1;
6509
6510 TString s = cmd;
6511 s = s.Strip(TString::kBoth);
6512
6513 if (!s.Length()) return 0;
6514
6515 // check for macro file and make sure the file is available on all slaves
6516 TString filename;
6517 if (TProof::GetFileInCmd(s.Data(), filename)) {
6518 char *fn = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
6519 if (fn) {
6520 if (GetNumberOfUniqueSlaves() > 0) {
6521 if (SendFile(fn, kAscii | kForward | kCpBin) < 0) {
6522 Error("Exec", "file %s could not be transfered", fn);
6523 delete [] fn;
6524 return -1;
6525 }
6526 } else {
6527 TString scmd = s(0,3) + fn;
6528 Int_t n = SendCommand(scmd, list);
6529 delete [] fn;
6530 return n;
6531 }
6532 } else {
6533 Error("Exec", "macro %s not found", filename.Data());
6534 return -1;
6535 }
6536 delete [] fn;
6537 }
6538
6539 if (plusMaster) {
6540 if (IsLite()) {
6541 gROOT->ProcessLine(cmd);
6542 } else {
6543 DeactivateWorker("*");
6544 Int_t res = SendCommand(cmd, list);
6545 ActivateWorker("restore");
6546 if (res < 0)
6547 return res;
6548 }
6549 }
6550 return SendCommand(cmd, list);
6551}
6552
6553////////////////////////////////////////////////////////////////////////////////
6554/// Send command to be executed on node of ordinal 'ord' (use "0" for master).
6555/// Command can be any legal command line command. Commands like
6556/// ".x file.C" or ".L file.C" will cause the file file.C to be send
6557/// to the PROOF cluster.
6558/// If logtomacro is TRUE the text result of the action is saved in the fMacroLog
6559/// TMacro, accessible via TMacro::GetMacroLog();
6560/// Returns -1 in case of error, >=0 in case of succes.
6561
6562Int_t TProof::Exec(const char *cmd, const char *ord, Bool_t logtomacro)
6563{
6564 if (!IsValid()) return -1;
6565
6566 TString s = cmd;
6567 s = s.Strip(TString::kBoth);
6568
6569 if (!s.Length()) return 0;
6570
6571 Int_t res = 0;
6572 if (IsLite()) {
6573 gROOT->ProcessLine(cmd);
6574 } else {
6575 Bool_t oldRedirLog = fRedirLog;
6576 fRedirLog = kTRUE;
6577 // Deactivate all workers
6578 DeactivateWorker("*");
6579 fRedirLog = kFALSE;
6580 // Reactivate the target ones, if needed
6581 if (strcmp(ord, "master") && strcmp(ord, "0")) ActivateWorker(ord);
6582 // Honour log-to-macro-saving settings
6583 Bool_t oldSaveLog = fSaveLogToMacro;
6584 fSaveLogToMacro = logtomacro;
6585 res = SendCommand(cmd, kActive);
6586 fSaveLogToMacro = oldSaveLog;
6587 fRedirLog = kTRUE;
6588 ActivateWorker("restore");
6589 fRedirLog = oldRedirLog;
6590 }
6591 // Done
6592 return res;
6593}
6594
6595////////////////////////////////////////////////////////////////////////////////
6596/// Send command to be executed on the PROOF master and/or slaves.
6597/// Command can be any legal command line command, however commands
6598/// like ".x file.C" or ".L file.C" will not cause the file.C to be
6599/// transfered to the PROOF cluster. In that case use TProof::Exec().
6600/// Returns the status send by the remote server as part of the
6601/// kPROOF_LOGDONE message. Typically this is the return code of the
6602/// command on the remote side. Returns -1 in case of error.
6603
6604Int_t TProof::SendCommand(const char *cmd, ESlaves list)
6605{
6606 if (!IsValid()) return -1;
6607
6608 Broadcast(cmd, kMESS_CINT, list);
6609 Collect(list);
6610
6611 return fStatus;
6612}
6613
6614////////////////////////////////////////////////////////////////////////////////
6615/// Get value of environment variable 'env' on node 'ord'
6616
6617TString TProof::Getenv(const char *env, const char *ord)
6618{
6619 // The command to be executed
6620 TString cmd = TString::Format("gSystem->Getenv(\"%s\")", env);
6621 if (Exec(cmd.Data(), ord, kTRUE) != 0) return TString("");
6622 // Get the line
6623 TObjString *os = fMacroLog.GetLineWith("const char");
6624 if (os) {
6625 TString info;
6626 Ssiz_t from = 0;
6627 os->GetString().Tokenize(info, from, "\"");
6628 os->GetString().Tokenize(info, from, "\"");
6629 if (gDebug > 0) Printf("%s: '%s'", env, info.Data());
6630 return info;
6631 }
6632 return TString("");
6633}
6634
6635////////////////////////////////////////////////////////////////////////////////
6636/// Get into 'env' the value of integer RC env variable 'rcenv' on node 'ord'
6637
6638Int_t TProof::GetRC(const char *rcenv, Int_t &env, const char *ord)
6639{
6640 // The command to be executed
6641 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6642 // Exectute the command saving the logs to macro
6643 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6644 // Get the line
6645 TObjString *os = fMacroLog.GetLineWith("const char");
6646 Int_t rc = -1;
6647 if (os) {
6648 Ssiz_t fst = os->GetString().First('\"');
6649 Ssiz_t lst = os->GetString().Last('\"');
6650 TString info = os->GetString()(fst+1, lst-fst-1);
6651 if (info.IsDigit()) {
6652 env = info.Atoi();
6653 rc = 0;
6654 if (gDebug > 0)
6655 Printf("%s: %d", rcenv, env);
6656 }
6657 }
6658 return rc;
6659}
6660
6661////////////////////////////////////////////////////////////////////////////////
6662/// Get into 'env' the value of double RC env variable 'rcenv' on node 'ord'
6663
6664Int_t TProof::GetRC(const char *rcenv, Double_t &env, const char *ord)
6665{
6666 // The command to be executed
6667 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6668 // Exectute the command saving the logs to macro
6669 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6670 // Get the line
6671 TObjString *os = fMacroLog.GetLineWith("const char");
6672 Int_t rc = -1;
6673 if (os) {
6674 Ssiz_t fst = os->GetString().First('\"');
6675 Ssiz_t lst = os->GetString().Last('\"');
6676 TString info = os->GetString()(fst+1, lst-fst-1);
6677 if (info.IsFloat()) {
6678 env = info.Atof();
6679 rc = 0;
6680 if (gDebug > 0)
6681 Printf("%s: %f", rcenv, env);
6682 }
6683 }
6684 return rc;
6685}
6686
6687////////////////////////////////////////////////////////////////////////////////
6688/// Get into 'env' the value of string RC env variable 'rcenv' on node 'ord'
6689
6690Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
6691{
6692 // The command to be executed
6693 TString cmd = TString::Format("if (gEnv->Lookup(\"%s\")) { gEnv->GetValue(\"%s\",\"\"); }", rcenv, rcenv);
6694 // Exectute the command saving the logs to macro
6695 if (Exec(cmd.Data(), ord, kTRUE) != 0) return -1;
6696 // Get the line
6697 TObjString *os = fMacroLog.GetLineWith("const char");
6698 Int_t rc = -1;
6699 if (os) {
6700 Ssiz_t fst = os->GetString().First('\"');
6701 Ssiz_t lst = os->GetString().Last('\"');
6702 env = os->GetString()(fst+1, lst-fst-1);
6703 rc = 0;
6704 if (gDebug > 0)
6705 Printf("%s: %s", rcenv, env.Data());
6706 }
6707 return rc;
6708}
6709
6710////////////////////////////////////////////////////////////////////////////////
6711/// Transfer the current state of the master to the active slave servers.
6712/// The current state includes: the current working directory, etc.
6713/// Returns the number of active slaves. Returns -1 in case of error.
6714
6716{
6717 if (!IsValid()) return -1;
6718
6719 // Go to the new directory, reset the interpreter environment and
6720 // tell slave to delete all objects from its new current directory.
6721 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6722
6723 return GetParallel();
6724}
6725
6726////////////////////////////////////////////////////////////////////////////////
6727/// Transfer the current state of the master to the active slave servers.
6728/// The current state includes: the current working directory, etc.
6729/// Returns the number of active slaves. Returns -1 in case of error.
6730
6732{
6733 if (!IsValid()) return -1;
6734
6735 // Go to the new directory, reset the interpreter environment and
6736 // tell slave to delete all objects from its new current directory.
6737 Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
6738
6739 return GetParallel();
6740}
6741
6742////////////////////////////////////////////////////////////////////////////////
6743/// Transfer the initial (i.e. current) state of the master to all
6744/// slave servers. Currently the initial state includes: log level.
6745/// Returns the number of active slaves. Returns -1 in case of error.
6746
6748{
6749 if (!IsValid()) return -1;
6750
6752
6753 return GetNumberOfActiveSlaves();
6754}
6755
6756////////////////////////////////////////////////////////////////////////////////
6757/// Check if a file needs to be send to the slave. Use the following
6758/// algorithm:
6759/// - check if file appears in file map
6760/// - if yes, get file's modtime and check against time in map,
6761/// if modtime not same get md5 and compare against md5 in map,
6762/// if not same return kTRUE.
6763/// - if no, get file's md5 and modtime and store in file map, ask
6764/// slave if file exists with specific md5, if yes return kFALSE,
6765/// if no return kTRUE.
6766/// The options 'cpopt' define if to copy things from cache to sandbox and what.
6767/// To retrieve from the cache the binaries associated with the file TProof::kCpBin
6768/// must be set in cpopt; the default is copy everything.
6769/// Returns kTRUE in case file needs to be send, returns kFALSE in case
6770/// file is already on remote node.
6771
6772Bool_t TProof::CheckFile(const char *file, TSlave *slave, Long_t modtime, Int_t cpopt)
6773{
6774 Bool_t sendto = kFALSE;
6775
6776 // create worker based filename
6777 TString sn = slave->GetName();
6778 sn += ":";
6779 sn += slave->GetOrdinal();
6780 sn += ":";
6781 sn += gSystem->BaseName(file);
6782
6783 // check if file is in map
6784 FileMap_t::const_iterator it;
6785 if ((it = fFileMap.find(sn)) != fFileMap.end()) {
6786 // file in map
6787 MD5Mod_t md = (*it).second;
6788 if (md.fModtime != modtime) {
6790 if (md5) {
6791 if ((*md5) != md.fMD5) {
6792 sendto = kTRUE;
6793 md.fMD5 = *md5;
6794 md.fModtime = modtime;
6795 fFileMap[sn] = md;
6796 // When on the master, the master and/or slaves may share
6797 // their file systems and cache. Therefore always make a
6798 // check for the file. If the file already exists with the
6799 // expected md5 the kPROOF_CHECKFILE command will cause the
6800 // file to be copied from cache to slave sandbox.
6802 sendto = kFALSE;
6804 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6805 slave->GetSocket()->Send(mess);
6806
6807 fCheckFileStatus = 0;
6809 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6810 }
6811 }
6812 delete md5;
6813 } else {
6814 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6815 return kFALSE;
6816 }
6817 }
6818 } else {
6819 // file not in map
6821 MD5Mod_t md;
6822 if (md5) {
6823 md.fMD5 = *md5;
6824 md.fModtime = modtime;
6825 fFileMap[sn] = md;
6826 delete md5;
6827 } else {
6828 Error("CheckFile", "could not calculate local MD5 check sum - dont send");
6829 return kFALSE;
6830 }
6832 mess << TString(gSystem->BaseName(file)) << md.fMD5 << cpopt;
6833 slave->GetSocket()->Send(mess);
6834
6835 fCheckFileStatus = 0;
6837 sendto = (fCheckFileStatus == 0) ? kTRUE : kFALSE;
6838 }
6839
6840 return sendto;
6841}
6842
6843////////////////////////////////////////////////////////////////////////////////
6844/// Send a file to master or slave servers. Returns number of slaves
6845/// the file was sent to, maybe 0 in case master and slaves have the same
6846/// file system image, -1 in case of error.
6847/// If defined, send to worker 'wrk' only.
6848/// If defined, the full path of the remote path will be rfile.
6849/// If rfile = "cache" the file is copied to the remote cache instead of the sandbox
6850/// (to copy to the cache on a different name use rfile = "cache:newname").
6851/// The mask 'opt' is an or of ESendFileOpt:
6852///
6853/// kAscii (0x0) if set true ascii file transfer is used
6854/// kBinary (0x1) if set true binary file transfer is used
6855/// kForce (0x2) if not set an attempt is done to find out
6856/// whether the file really needs to be downloaded
6857/// (a valid copy may already exist in the cache
6858/// from a previous run); the bit is set by
6859/// UploadPackage, since the check is done elsewhere.
6860/// kForward (0x4) if set, ask server to forward the file to slave
6861/// or submaster (meaningless for slave servers).
6862/// kCpBin (0x8) Retrieve from the cache the binaries associated
6863/// with the file
6864/// kCp (0x10) Retrieve the files from the cache
6865///
6866
6867Int_t TProof::SendFile(const char *file, Int_t opt, const char *rfile, TSlave *wrk)
6868{
6869 if (!IsValid()) return -1;
6870
6871 // Use the active slaves list ...
6872 TList *slaves = (rfile && !strcmp(rfile, "cache")) ? fUniqueSlaves : fActiveSlaves;
6873 // ... or the specified slave, if any
6874 if (wrk) {
6875 slaves = new TList();
6876 slaves->Add(wrk);
6877 }
6878
6879 if (slaves->GetSize() == 0) return 0;
6880
6881#ifndef R__WIN32
6882 Int_t fd = open(file, O_RDONLY);
6883#else
6884 Int_t fd = open(file, O_RDONLY | O_BINARY);
6885#endif
6886 if (fd < 0) {
6887 SysError("SendFile", "cannot open file %s", file);
6888 return -1;
6889 }
6890
6891 // Get info about the file
6892 Long64_t size = -1;
6893 Long_t id, flags, modtime = 0;
6894 if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
6895 Error("SendFile", "cannot stat file %s", file);
6896 close(fd);
6897 return -1;
6898 }
6899 if (size == 0) {
6900 Error("SendFile", "empty file %s", file);
6901 close(fd);
6902 return -1;
6903 }
6904
6905 // Decode options
6906 Bool_t bin = (opt & kBinary) ? kTRUE : kFALSE;
6907 Bool_t force = (opt & kForce) ? kTRUE : kFALSE;
6908 Bool_t fw = (opt & kForward) ? kTRUE : kFALSE;
6909
6910 // Copy options
6911 Int_t cpopt = 0;
6912 if ((opt & kCp)) cpopt |= kCp;
6913 if ((opt & kCpBin)) cpopt |= (kCp | kCpBin);
6914
6915 const Int_t kMAXBUF = 32768; //16384 //65536;
6916 char buf[kMAXBUF];
6917 Int_t nsl = 0;
6918
6919 TIter next(slaves);
6920 TSlave *sl;
6921 TString fnam(rfile);
6922 if (fnam == "cache") {
6923 fnam += TString::Format(":%s", gSystem->BaseName(file));
6924 } else if (fnam.IsNull()) {
6925 fnam = gSystem->BaseName(file);
6926 }
6927 // List on which we will collect the results
6928 fStatus = 0;
6929 while ((sl = (TSlave *)next())) {
6930 if (!sl->IsValid())
6931 continue;
6932
6933 Bool_t sendto = force ? kTRUE : CheckFile(file, sl, modtime, cpopt);
6934 // Don't send the kPROOF_SENDFILE command to real slaves when sendto
6935 // is false. Masters might still need to send the file to newly added
6936 // slaves.
6937 PDB(kPackage,2) {
6938 const char *snd = (sl->fSlaveType == TSlave::kSlave && sendto) ? "" : "not";
6939 Info("SendFile", "%s sending file %s to: %s:%s (%d)", snd,
6940 file, sl->GetName(), sl->GetOrdinal(), sendto);
6941 }
6942 if (sl->fSlaveType == TSlave::kSlave && !sendto)
6943 continue;
6944 // The value of 'size' is used as flag remotely, so we need to
6945 // reset it to 0 if we are not going to send the file
6946 Long64_t siz = sendto ? size : 0;
6947 snprintf(buf, kMAXBUF, "%s %d %lld %d", fnam.Data(), bin, siz, fw);
6948 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
6949 MarkBad(sl, "could not send kPROOF_SENDFILE request");
6950 continue;
6951 }
6952
6953 if (sendto) {
6954
6955 lseek(fd, 0, SEEK_SET);
6956
6957 Int_t len;
6958 do {
6959 while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
6961
6962 if (len < 0) {
6963 SysError("SendFile", "error reading from file %s", file);
6965 close(fd);
6966 return -1;
6967 }
6968
6969 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
6970 SysError("SendFile", "error writing to slave %s:%s (now offline)",
6971 sl->GetName(), sl->GetOrdinal());
6972 MarkBad(sl, "sendraw failure");
6973 sl = 0;
6974 break;
6975 }
6976
6977 } while (len > 0);
6978
6979 nsl++;
6980 }
6981 // Wait for the operation to be done
6982 if (sl)
6984 }
6985
6986 close(fd);
6987
6988 // Cleanup temporary list, if any
6989 if (slaves != fActiveSlaves && slaves != fUniqueSlaves)
6990 SafeDelete(slaves);
6991
6992 // We return failure is at least one unique worker failed
6993 return (fStatus != 0) ? -1 : nsl;
6994}
6995
6996////////////////////////////////////////////////////////////////////////////////
6997/// Sends an object to master and workers and expect them to send back a
6998/// message with the output of its TObject::Print(). Returns -1 on error, the
6999/// number of workers that received the objects on success.
7000
7002{
7003 if (!IsValid() || !obj) return -1;
7004 TMessage mess(kPROOF_ECHO);
7005 mess.WriteObject(obj);
7006 return Broadcast(mess);
7007}
7008
7009////////////////////////////////////////////////////////////////////////////////
7010/// Sends a string to master and workers and expect them to echo it back to
7011/// the client via a message. It is a special case of the generic Echo()
7012/// that works with TObjects. Returns -1 on error, the number of workers that
7013/// received the message on success.
7014
7015Int_t TProof::Echo(const char *str)
7016{
7017 TObjString *os = new TObjString(str);
7018 Int_t rv = Echo(os);
7019 delete os;
7020 return rv;
7021}
7022
7023////////////////////////////////////////////////////////////////////////////////
7024/// Send object to master or slave servers. Returns number of slaves object
7025/// was sent to, -1 in case of error.
7026
7028{
7029 if (!IsValid() || !obj) return -1;
7030
7031 TMessage mess(kMESS_OBJECT);
7032
7033 mess.WriteObject(obj);
7034 return Broadcast(mess, list);
7035}
7036
7037////////////////////////////////////////////////////////////////////////////////
7038/// Send print command to master server. Returns number of slaves message
7039/// was sent to. Returns -1 in case of error.
7040
7042{
7043 if (!IsValid()) return -1;
7044
7045 Broadcast(option, kPROOF_PRINT, kActive);
7047}
7048
7049////////////////////////////////////////////////////////////////////////////////
7050/// Set server logging level.
7051
7053{
7054 char str[32];
7055 fLogLevel = level;
7056 gProofDebugLevel = level;
7058 snprintf(str, 32, "%d %u", level, mask);
7060}
7061
7062////////////////////////////////////////////////////////////////////////////////
7063/// Switch ON/OFF the real-time logging facility. When this option is
7064/// ON, log messages from processing are sent back as they come, instead of
7065/// being sent back at the end in one go. This may help debugging or monitoring
7066/// in some cases, but, depending on the amount of log, it may have significant
7067/// consequencies on the load over the network, so it must be used with care.
7068
7070{
7071 if (IsValid()) {
7073 mess << on;
7074 Broadcast(mess);
7075 } else {
7076 Warning("SetRealTimeLog","session is invalid - do nothing");
7077 }
7078}
7079
7080////////////////////////////////////////////////////////////////////////////////
7081/// Tell PROOF how many slaves to use in parallel. If random is TRUE a random
7082/// selection is done (if nodes is less than the available nodes).
7083/// Returns the number of parallel slaves. Returns -1 in case of error.
7084
7086{
7087 if (!IsValid()) return -1;
7088
7090 if (!fDynamicStartup) GoParallel(nodes, kFALSE, random);
7091 return SendCurrentState();
7092 } else {
7093 if (nodes < 0) {
7094 PDB(kGlobal,1) Info("SetParallelSilent", "request all nodes");
7095 } else {
7096 PDB(kGlobal,1) Info("SetParallelSilent", "request %d node%s", nodes,
7097 nodes == 1 ? "" : "s");
7098 }
7100 mess << nodes << random;
7101 Broadcast(mess);
7103 Int_t n = GetParallel();
7104 PDB(kGlobal,1) Info("SetParallelSilent", "got %d node%s", n, n == 1 ? "" : "s");
7105 return n;
7106 }
7107}
7108
7109////////////////////////////////////////////////////////////////////////////////
7110/// Tell PROOF how many slaves to use in parallel. Returns the number of
7111/// parallel slaves. Returns -1 in case of error.
7112
7114{
7115 // If delayed startup reset settings, if required
7116 if (fDynamicStartup && nodes < 0) {
7117 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7118 }
7119
7120 Int_t n = SetParallelSilent(nodes, random);
7122 if (n < 1) {
7123 Printf("PROOF set to sequential mode");
7124 } else {
7125 TString subfix = (n == 1) ? "" : "s";
7126 if (random)
7127 subfix += ", randomly selected";
7128 Printf("PROOF set to parallel mode (%d worker%s)", n, subfix.Data());
7129 }
7130 } else if (fDynamicStartup && nodes >= 0) {
7131 if (gSystem->Getenv("PROOF_NWORKERS")) gSystem->Unsetenv("PROOF_NWORKERS");
7132 gSystem->Setenv("PROOF_NWORKERS", TString::Format("%d", nodes));
7133 }
7134 return n;
7135}
7136
7137////////////////////////////////////////////////////////////////////////////////
7138/// Add nWorkersToAdd workers to current list of workers. This function is
7139/// works on the master only, and only when an analysis is ongoing. A message
7140/// is sent back to the client when we go "more" parallel.
7141/// Returns -1 on error, number of total (not added!) workers on success.
7142
7144{
7145 if (!IsValid() || !IsMaster() || IsIdle()) {
7146 Error("GoMoreParallel", "can't invoke here -- should not happen!");
7147 return -1;
7148 }
7149 if (!gProofServ && !IsLite()) {
7150 Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
7151 return -1;
7152 }
7153
7154 TSlave *sl = 0x0;
7155 TIter next( fSlaves );
7156 Int_t nAddedWorkers = 0;
7157
7158 while (((nAddedWorkers < nWorkersToAdd) || (nWorkersToAdd == -1)) &&
7159 (( sl = dynamic_cast<TSlave *>( next() ) ))) {
7160
7161 // If worker is of an invalid type, break everything: it should not happen!
7162 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7163 (sl->GetSlaveType() != TSlave::kMaster)) {
7164 Error("GoMoreParallel", "TSlave is neither a Master nor a Slave: %s:%s",
7165 sl->GetName(), sl->GetOrdinal());
7166 R__ASSERT(0);
7167 }
7168
7169 // Skip current worker if it is not a good candidate
7170 if ((!sl->IsValid()) || (fBadSlaves->FindObject(sl)) ||
7171 (strcmp("IGNORE", sl->GetImage()) == 0)) {
7172 PDB(kGlobal, 2)
7173 Info("GoMoreParallel", "Worker %s:%s won't be considered",
7174 sl->GetName(), sl->GetOrdinal());
7175 continue;
7176 }
7177
7178 // Worker is good but it is already active: skip it
7179 if (fActiveSlaves->FindObject(sl)) {
7180 Info("GoMoreParallel", "Worker %s:%s is already active: skipping",
7181 sl->GetName(), sl->GetOrdinal());
7182 continue;
7183 }
7184
7185 //
7186 // From here on: worker is a good candidate
7187 //
7188
7189 if (sl->GetSlaveType() == TSlave::kSlave) {
7191 fActiveSlaves->Add(sl);
7194 nAddedWorkers++;
7195 PDB(kGlobal, 2)
7196 Info("GoMoreParallel", "Worker %s:%s marked as active!",
7197 sl->GetName(), sl->GetOrdinal());
7198 }
7199 else {
7200 // Can't add masters dynamically: this should not happen!
7201 Error("GoMoreParallel", "Dynamic addition of master is not supported");
7202 R__ASSERT(0);
7203 }
7204
7205 } // end loop over all slaves
7206
7207 // Get slave status (will set the slaves fWorkDir correctly)
7208 PDB(kGlobal, 3)
7209 Info("GoMoreParallel", "Will invoke AskStatistics() -- implies a Collect()");
7210 AskStatistics();
7211
7212 // Find active slaves with unique image
7213 PDB(kGlobal, 3)
7214 Info("GoMoreParallel", "Will invoke FindUniqueSlaves()");
7216
7217 // Send new group-view to slaves
7218 PDB(kGlobal, 3)
7219 Info("GoMoreParallel", "Will invoke SendGroupView()");
7220 SendGroupView();
7221
7222 PDB(kGlobal, 3)
7223 Info("GoMoreParallel", "Will invoke GetParallel()");
7224 Int_t nTotalWorkers = GetParallel();
7225
7226 // Notify the client that we've got more workers, and print info on
7227 // Master's log as well
7228 TString s;
7229 s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
7230 nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
7231 nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
7233 Info("GoMoreParallel", "%s", s.Data());
7234
7235 return nTotalWorkers;
7236}
7237
7238////////////////////////////////////////////////////////////////////////////////
7239/// Go in parallel mode with at most "nodes" slaves. Since the fSlaves
7240/// list is sorted by slave performace the active list will contain first
7241/// the most performant nodes. Returns the number of active slaves.
7242/// If random is TRUE, and nodes is less than the number of available workers,
7243/// a random selection is done.
7244/// Returns -1 in case of error.
7245
7247{
7248 if (!IsValid()) return -1;
7249
7252
7253 // Prepare the list of candidates first.
7254 // Algorithm depends on random option.
7255 TSlave *sl = 0;
7256 TList *wlst = new TList;
7257 TIter nxt(fSlaves);
7259 while ((sl = (TSlave *)nxt())) {
7260 if (sl->IsValid() && !fBadSlaves->FindObject(sl)) {
7261 if (strcmp("IGNORE", sl->GetImage()) == 0) continue;
7262 if ((sl->GetSlaveType() != TSlave::kSlave) &&
7263 (sl->GetSlaveType() != TSlave::kMaster)) {
7264 Error("GoParallel", "TSlave is neither Master nor Slave");
7265 R__ASSERT(0);
7266 }
7267 // Good candidate
7268 wlst->Add(sl);
7269 // Set it inactive
7270 fInactiveSlaves->Add(sl);
7272 }
7273 }
7274 Int_t nwrks = (nodes < 0 || nodes > wlst->GetSize()) ? wlst->GetSize() : nodes;
7275 int cnt = 0;
7277 while (cnt < nwrks) {
7278 // Random choice, if requested
7279 if (random) {
7280 Int_t iwrk = (Int_t) (gRandom->Rndm() * wlst->GetSize());
7281 sl = (TSlave *) wlst->At(iwrk);
7282 } else {
7283 // The first available
7284 sl = (TSlave *) wlst->First();
7285 }
7286 if (!sl) {
7287 Error("GoParallel", "attaching to candidate!");
7288 break;
7289 }
7290 // Remove from the list
7291 wlst->Remove(sl);
7292
7293 Int_t slavenodes = 0;
7294 if (sl->GetSlaveType() == TSlave::kSlave) {
7296 fActiveSlaves->Add(sl);
7299 slavenodes = 1;
7300 } else if (sl->GetSlaveType() == TSlave::kMaster) {
7303 if (!attach) {
7304 Int_t nn = (nodes < 0) ? -1 : nodes-cnt;
7305 mess << nn;
7306 } else {
7307 // To get the number of slaves
7308 mess.SetWhat(kPROOF_LOGFILE);
7309 mess << -1 << -1;
7310 }
7311 if (sl->GetSocket()->Send(mess) == -1) {
7312 MarkBad(sl, "could not send kPROOF_PARALLEL or kPROOF_LOGFILE request");
7313 slavenodes = 0;
7314 } else {
7316 if (sl->IsValid()) {
7318 fActiveSlaves->Add(sl);
7321 if (sl->GetParallel() > 0) {
7322 slavenodes = sl->GetParallel();
7323 } else {
7324 // Sequential mode: the master acts as a worker
7325 slavenodes = 1;
7326 }
7327 } else {
7328 MarkBad(sl, "collect failed after kPROOF_PARALLEL or kPROOF_LOGFILE request");
7329 slavenodes = 0;
7330 }
7331 }
7332 }
7333 // 'slavenodes' may be different than 1 in multimaster setups
7334 cnt += slavenodes;
7335 }
7336
7337 // Cleanup list
7338 wlst->SetOwner(0);
7339 SafeDelete(wlst);
7340
7341 // Get slave status (will set the slaves fWorkDir correctly)
7342 AskStatistics();
7343
7344 // Find active slaves with unique image
7346
7347 // Send new group-view to slaves
7348 if (!attach)
7349 SendGroupView();
7350
7351 Int_t n = GetParallel();
7352
7354 if (n < 1)
7355 printf("PROOF set to sequential mode\n");
7356 else
7357 printf("PROOF set to parallel mode (%d worker%s)\n",
7358 n, n == 1 ? "" : "s");
7359 }
7360
7361 PDB(kGlobal,1) Info("GoParallel", "got %d node%s", n, n == 1 ? "" : "s");
7362 return n;
7363}
7364
7365////////////////////////////////////////////////////////////////////////////////
7366/// List contents of the data directory in the sandbox.
7367/// This is the place where files produced by the client queries are kept
7368
7370{
7371 if (!IsValid() || !fManager) return;
7372
7373 // This is run via the manager
7374 fManager->Find("~/data", "-type f", "all");
7375}
7376
7377////////////////////////////////////////////////////////////////////////////////
7378/// Remove files for the data directory.
7379/// The option 'what' can take the values:
7380/// kPurge remove all files and directories under '~/data'
7381/// kUnregistered remove only files not in registered datasets (default)
7382/// kDataset remove files belonging to dataset 'dsname'
7383/// User is prompt for confirmation, unless kForceClear is ORed with the option
7384
7385void TProof::ClearData(UInt_t what, const char *dsname)
7386{
7387 if (!IsValid() || !fManager) return;
7388
7389 // Check whether we need to prompt
7390 TString prompt, a("Y");
7391 Bool_t force = (what & kForceClear) ? kTRUE : kFALSE;
7392 Bool_t doask = (!force && IsTty()) ? kTRUE : kFALSE;
7393
7394 // If all just send the request
7395 if ((what & TProof::kPurge)) {
7396 // Prompt, if requested
7397 if (doask && !Prompt("Do you really want to remove all data files")) return;
7398 if (fManager->Rm("~/data/*", "-rf", "all") < 0)
7399 Warning("ClearData", "problems purging data directory");
7400 return;
7401 } else if ((what & TProof::kDataset)) {
7402 // We must have got a name
7403 if (!dsname || strlen(dsname) <= 0) {
7404 Error("ClearData", "dataset name mandatory when removing a full dataset");
7405 return;
7406 }
7407 // Check if the dataset is registered
7408 if (!ExistsDataSet(dsname)) {
7409 Error("ClearData", "dataset '%s' does not exists", dsname);
7410 return;
7411 }
7412 // Get the file content
7413 TFileCollection *fc = GetDataSet(dsname);
7414 if (!fc) {
7415 Error("ClearData", "could not retrieve info about dataset '%s'", dsname);
7416 return;
7417 }
7418 // Prompt, if requested
7419 TString pmpt = TString::Format("Do you really want to remove all data files"
7420 " of dataset '%s'", dsname);
7421 if (doask && !Prompt(pmpt.Data())) return;
7422
7423 // Loop through the files
7424 Bool_t rmds = kTRUE;
7425 TIter nxf(fc->GetList());
7426 TFileInfo *fi = 0;
7427 Int_t rfiles = 0, nfiles = fc->GetList()->GetSize();
7428 while ((fi = (TFileInfo *) nxf())) {
7429 // Fill the host info
7430 TString host, file;
7431 // Take info from the current url
7432 if (!(fi->GetFirstUrl())) {
7433 Error("ClearData", "GetFirstUrl() returns NULL for '%s' - skipping",
7434 fi->GetName());
7435 continue;
7436 }
7437 TUrl uf(*(fi->GetFirstUrl()));
7438 file = uf.GetFile();
7439 host = uf.GetHost();
7440 // Now search for any "file:" url
7441 Int_t nurl = fi->GetNUrls();
7442 fi->ResetUrl();
7443 TUrl *up = 0;
7444 while (nurl-- && fi->NextUrl()) {
7445 up = fi->GetCurrentUrl();
7446 if (!strcmp(up->GetProtocol(), "file")) {
7447 TString opt(up->GetOptions());
7448 if (opt.BeginsWith("node=")) {
7449 host=opt;
7450 host.ReplaceAll("node=","");
7451 file = up->GetFile();
7452 break;
7453 }
7454 }
7455 }
7456 // Issue a remove request now
7457 if (fManager->Rm(file.Data(), "-f", host.Data()) != 0) {
7458 Error("ClearData", "problems removing '%s'", file.Data());
7459 // Some files not removed: keep the meta info about this dataset
7460 rmds = kFALSE;
7461 }
7462 rfiles++;
7463 ClearDataProgress(rfiles, nfiles);
7464 }
7465 fprintf(stderr, "\n");
7466 if (rmds) {
7467 // All files were removed successfully: remove also the dataset meta info
7468 RemoveDataSet(dsname);
7469 }
7470 } else if (what & TProof::kUnregistered) {
7471
7472 // Get the existing files
7473 TString outtmp("ProofClearData_");
7474 FILE *ftmp = gSystem->TempFileName(outtmp);
7475 if (!ftmp) {
7476 Error("ClearData", "cannot create temp file for logs");
7477 return;
7478 }
7479 fclose(ftmp);
7481 gSystem->RedirectOutput(outtmp.Data(), "w", &h);
7482 ShowData();
7483 gSystem->RedirectOutput(0, 0, &h);
7484 // Parse the output file now
7485 std::ifstream in;
7486 in.open(outtmp.Data());
7487 if (!in.is_open()) {
7488 Error("ClearData", "could not open temp file for logs: %s", outtmp.Data());
7489 gSystem->Unlink(outtmp);
7490 return;
7491 }
7492 // Go through
7493 Int_t nfiles = 0;
7494 TMap *afmap = new TMap;
7495 TString line, host, file;
7496 Int_t from = 0;
7497 while (in.good()) {
7498 line.ReadLine(in);
7499 if (line.IsNull()) continue;
7500 while (line.EndsWith("\n")) { line.Strip(TString::kTrailing, '\n'); }
7501 from = 0;
7502 host = "";
7503 if (!line.Tokenize(host, from, "| ")) continue;
7504 file = "";
7505 if (!line.Tokenize(file, from, "| ")) continue;
7506 if (!host.IsNull() && !file.IsNull()) {
7507 TList *fl = (TList *) afmap->GetValue(host.Data());
7508 if (!fl) {
7509 fl = new TList();
7510 fl->SetName(host);
7511 afmap->Add(new TObjString(host), fl);
7512 }
7513 fl->Add(new TObjString(file));
7514 nfiles++;
7515 PDB(kDataset,2)
7516 Info("ClearData", "added info for: h:%s, f:%s", host.Data(), file.Data());
7517 } else {
7518 Warning("ClearData", "found incomplete line: '%s'", line.Data());
7519 }
7520 }
7521 // Close and remove the file
7522 in.close();
7523 gSystem->Unlink(outtmp);
7524
7525 // Get registered data files
7526 TString sel = TString::Format("/%s/%s/", GetGroup(), GetUser());
7527 TMap *fcmap = GetDataSets(sel);
7528 if (!fcmap || (fcmap && fcmap->GetSize() <= 0)) {
7529 PDB(kDataset,1)
7530 Warning("ClearData", "no dataset beloning to '%s'", sel.Data());
7531 SafeDelete(fcmap);
7532 }
7533
7534 // Go thorugh and prepare the lists per node
7535 TString opt;
7536 TObjString *os = 0;
7537 if (fcmap) {
7538 TIter nxfc(fcmap);
7539 while ((os = (TObjString *) nxfc())) {
7540 TFileCollection *fc = 0;
7541 if ((fc = (TFileCollection *) fcmap->GetValue(os))) {
7542 TFileInfo *fi = 0;
7543 TIter nxfi(fc->GetList());
7544 while ((fi = (TFileInfo *) nxfi())) {
7545 // Get special "file:" url
7546 fi->ResetUrl();
7547 Int_t nurl = fi->GetNUrls();
7548 TUrl *up = 0;
7549 while (nurl-- && fi->NextUrl()) {
7550 up = fi->GetCurrentUrl();
7551 if (!strcmp(up->GetProtocol(), "file")) {
7552 opt = up->GetOptions();
7553 if (opt.BeginsWith("node=")) {
7554 host=opt;
7555 host.ReplaceAll("node=","");
7556 file = up->GetFile();
7557 PDB(kDataset,2)
7558 Info("ClearData", "found: host: %s, file: %s", host.Data(), file.Data());
7559 // Remove this from the full list, if there
7560 TList *fl = (TList *) afmap->GetValue(host.Data());
7561 if (fl) {
7562 TObjString *fn = (TObjString *) fl->FindObject(file.Data());
7563 if (fn) {
7564 fl->Remove(fn);
7565 SafeDelete(fn);
7566 nfiles--;
7567 } else {
7568 Warning("ClearData",
7569 "registered file '%s' not found in the full list!",
7570 file.Data());
7571 }
7572 }
7573 break;
7574 }
7575 }
7576 }
7577 }
7578 }
7579 }
7580 // Clean up the the received map
7581 if (fcmap) fcmap->SetOwner(kTRUE);
7582 SafeDelete(fcmap);
7583 }
7584 // List of the files to be removed
7585 Info("ClearData", "%d unregistered files to be removed:", nfiles);
7586 afmap->Print();
7587 // Prompt, if requested
7588 TString pmpt = TString::Format("Do you really want to remove all %d"
7589 " unregistered data files", nfiles);
7590 if (doask && !Prompt(pmpt.Data())) return;
7591
7592 // Remove one by one; we may implement a bloc remove in the future
7593 Int_t rfiles = 0;
7594 TIter nxls(afmap);
7595 while ((os = (TObjString *) nxls())) {
7596 TList *fl = 0;
7597 if ((fl = (TList *) afmap->GetValue(os))) {
7598 TIter nxf(fl);
7599 TObjString *fn = 0;
7600 while ((fn = (TObjString *) nxf())) {
7601 // Issue a remove request now
7602 if (fManager->Rm(fn->GetName(), "-f", os->GetName()) != 0) {
7603 Error("ClearData", "problems removing '%s' on host '%s'",
7604 fn->GetName(), os->GetName());
7605 }
7606 rfiles++;
7607 ClearDataProgress(rfiles, nfiles);
7608 }
7609 }
7610 }
7611 fprintf(stderr, "\n");
7612 // Final cleanup
7613 afmap->SetOwner(kTRUE);
7614 SafeDelete(afmap);
7615 }
7616}
7617
7618////////////////////////////////////////////////////////////////////////////////
7619/// Prompt the question 'p' requiring an answer y,Y,n,N
7620/// Return kTRUE is the answer was y or Y, kFALSE in all other cases.
7621
7623{
7624 TString pp(p);
7625 if (!pp.Contains("?")) pp += "?";
7626 if (!pp.Contains("[y/N]")) pp += " [y/N]";
7627 TString a = Getline(pp.Data());
7628 if (a != "\n" && a[0] != 'y' && a[0] != 'Y' && a[0] != 'n' && a[0] != 'N') {
7629 Printf("Please answer y, Y, n or N");
7630 // Unclear answer: assume negative
7631 return kFALSE;
7632 } else if (a == "\n" || a[0] == 'n' || a[0] == 'N') {
7633 // Explicitly Negative answer
7634 return kFALSE;
7635 }
7636 // Explicitly Positive answer
7637 return kTRUE;
7638}
7639
7640////////////////////////////////////////////////////////////////////////////////
7641/// Progress bar for clear data
7642
7644{
7645 fprintf(stderr, "[TProof::ClearData] Total %5d files\t|", t);
7646 for (Int_t l = 0; l < 20; l++) {
7647 if (r > 0 && t > 0) {
7648 if (l < 20*r/t)
7649 fprintf(stderr, "=");
7650 else if (l == 20*r/t)
7651 fprintf(stderr, ">");
7652 else if (l > 20*r/t)
7653 fprintf(stderr, ".");
7654 } else
7655 fprintf(stderr, "=");
7656 }
7657 fprintf(stderr, "| %.02f %% \r", 100.0*(t ? (r/t) : 1));
7658}
7659
7660////////////////////////////////////////////////////////////////////////////////
7661/// List contents of file cache. If all is true show all caches also on
7662/// slaves. If everything is ok all caches are to be the same.
7663
7665{
7666 if (!IsValid()) return;
7667
7668 TMessage mess(kPROOF_CACHE);
7669 mess << Int_t(kShowCache) << all;
7670 Broadcast(mess, kUnique);
7671
7672 if (all) {
7673 TMessage mess2(kPROOF_CACHE);
7674 mess2 << Int_t(kShowSubCache) << all;
7676
7678 } else {
7680 }
7681}
7682
7683////////////////////////////////////////////////////////////////////////////////
7684/// Remove file from all file caches. If file is 0 or "" or "*", remove all
7685/// the files
7686
7687void TProof::ClearCache(const char *file)
7688{
7689 if (!IsValid()) return;
7690
7691 TMessage mess(kPROOF_CACHE);
7692 mess << Int_t(kClearCache) << TString(file);
7693 Broadcast(mess, kUnique);
7694
7695 TMessage mess2(kPROOF_CACHE);
7696 mess2 << Int_t(kClearSubCache) << TString(file);
7698
7700
7701 // clear file map so files get send again to remote nodes
7702 fFileMap.clear();
7703}
7704
7705////////////////////////////////////////////////////////////////////////////////
7706/// Exec system command 'cmd'. If fdout > -1, append the output to fdout.
7707
7708void TProof::SystemCmd(const char *cmd, Int_t fdout)
7709{
7710 if (fdout < 0) {
7711 // Exec directly the command
7712 gSystem->Exec(cmd);
7713 } else {
7714 // Exec via a pipe
7715 FILE *fin = gSystem->OpenPipe(cmd, "r");
7716 if (fin) {
7717 // Now we go
7718 char line[2048];
7719 while (fgets(line, 2048, fin)) {
7720 Int_t r = strlen(line);
7721 if (r > 0) {
7722 if (write(fdout, line, r) < 0) {
7723 ::Warning("TProof::SystemCmd",
7724 "errno %d writing to file descriptor %d",
7725 TSystem::GetErrno(), fdout);
7726 }
7727 } else {
7728 // Done
7729 break;
7730 }
7731 }
7732 gSystem->ClosePipe(fin);
7733 }
7734 }
7735}
7736
7737////////////////////////////////////////////////////////////////////////////////
7738/// List contents of package directory. If all is true show all package
7739/// directories also on slaves. If everything is ok all package directories
7740/// should be the same. If redir is kTRUE the result is redirected to the log
7741/// file (option available for internal actions).
7742
7744{
7745 if (!IsValid()) return;
7746
7747 Bool_t oldredir = fRedirLog;
7748 if (redirlog) fRedirLog = kTRUE;
7749
7750 // Active logging unit
7751 FILE *fout = (fRedirLog) ? fLogFileW : stdout;
7752 if (!fout) {
7753 Warning("ShowPackages", "file descriptor for outputs undefined (%p):"
7754 " will not log msgs", fout);
7755 return;
7756 }
7757 lseek(fileno(fout), (off_t) 0, SEEK_END);
7758
7760 fPackMgr->Show();
7761 }
7762
7763 // Nothing more to do if we are a Lite-session
7764 if (IsLite()) {
7765 fRedirLog = oldredir;
7766 return;
7767 }
7768
7769 TMessage mess(kPROOF_CACHE);
7770 mess << Int_t(kShowPackages) << all;
7771 Broadcast(mess, kUnique);
7772
7773 if (all) {
7774 TMessage mess2(kPROOF_CACHE);
7775 mess2 << Int_t(kShowSubPackages) << all;
7777
7779 } else {
7781 }
7782 // Restore logging option
7783 fRedirLog = oldredir;
7784}
7785
7786////////////////////////////////////////////////////////////////////////////////
7787/// List which packages are enabled. If all is true show enabled packages
7788/// for all active slaves. If everything is ok all active slaves should
7789/// have the same packages enabled.
7790
7792{
7793 if (!IsValid()) return;
7794
7796 fPackMgr->ShowEnabled(TString::Format("*** Enabled packages on client on %s\n",
7797 gSystem->HostName()));
7798 }
7799
7800 // Nothing more to do if we are a Lite-session
7801 if (IsLite()) return;
7802
7803 TMessage mess(kPROOF_CACHE);
7804 mess << Int_t(kShowEnabledPackages) << all;
7805 Broadcast(mess);
7807}
7808
7809////////////////////////////////////////////////////////////////////////////////
7810/// Remove all packages.
7811/// Returns 0 in case of success and -1 in case of error.
7812
7814{
7815 if (!IsValid()) return -1;
7816
7817 if (UnloadPackages() == -1)
7818 return -1;
7819
7820 if (DisablePackages() == -1)
7821 return -1;
7822
7823 return fStatus;
7824}
7825
7826////////////////////////////////////////////////////////////////////////////////
7827/// Remove a specific package.
7828/// Returns 0 in case of success and -1 in case of error.
7829
7830Int_t TProof::ClearPackage(const char *package)
7831{
7832 if (!IsValid()) return -1;
7833
7834 if (!package || !package[0]) {
7835 Error("ClearPackage", "need to specify a package name");
7836 return -1;
7837 }
7838
7839 // if name, erroneously, is a par pathname strip off .par and path
7840 TString pac = package;
7841 if (pac.EndsWith(".par"))
7842 pac.Remove(pac.Length()-4);
7843 pac = gSystem->BaseName(pac);
7844
7845 if (UnloadPackage(pac) == -1)
7846 return -1;
7847
7848 if (DisablePackage(pac) == -1)
7849 return -1;
7850
7851 return fStatus;
7852}
7853
7854////////////////////////////////////////////////////////////////////////////////
7855/// Remove a specific package.
7856/// Returns 0 in case of success and -1 in case of error.
7857
7859{
7860 if (!IsValid()) return -1;
7861
7862 if (!pack || strlen(pack) <= 0) {
7863 Error("DisablePackage", "need to specify a package name");
7864 return -1;
7865 }
7866
7867 // if name, erroneously, is a par pathname strip off .par and path
7868 TString pac = pack;
7869 if (pac.EndsWith(".par"))
7870 pac.Remove(pac.Length()-4);
7871 pac = gSystem->BaseName(pac);
7872
7873 if (fPackMgr->Remove(pack) < 0)
7874 Warning("DisablePackage", "problem removing locally package '%s'", pack);
7875
7876 // Nothing more to do if we are a Lite-session
7877 if (IsLite()) return 0;
7878
7879 Int_t st = -1;
7880 Bool_t done = kFALSE;
7881 if (fManager) {
7882 // Try to do it via XROOTD (new way)
7883 TString path;
7884 path.Form("~/packages/%s", pack);
7885 if (fManager->Rm(path, "-rf", "all") != -1) {
7886 path.Append(".par");
7887 if (fManager->Rm(path, "-f", "all") != -1) {
7888 done = kTRUE;
7889 st = 0;
7890 }
7891 }
7892 }
7893 if (!done) {
7894 // Try via TProofServ (old way)
7895 TMessage mess(kPROOF_CACHE);
7896 mess << Int_t(kDisablePackage) << pac;
7897 Broadcast(mess, kUnique);
7898
7899 TMessage mess2(kPROOF_CACHE);
7900 mess2 << Int_t(kDisableSubPackage) << pac;
7902
7904 st = fStatus;
7905 }
7906
7907 // Done
7908 return st;
7909}
7910
7911////////////////////////////////////////////////////////////////////////////////
7912/// Remove all packages.
7913/// Returns 0 in case of success and -1 in case of error.
7914
7916{
7917 if (!IsValid()) return -1;
7918
7919 // remove all packages on client
7920 if (fPackMgr->Remove(nullptr) < 0)
7921 Warning("DisablePackages", "problem removing packages locally");
7922
7923 // Nothing more to do if we are a Lite-session
7924 if (IsLite()) return 0;
7925
7926 Int_t st = -1;
7927 Bool_t done = kFALSE;
7928 if (fManager) {
7929 // Try to do it via XROOTD (new way)
7930 if (fManager->Rm("~/packages/*", "-rf", "all") != -1) {
7931 done = kTRUE;
7932 st = 0;
7933 }
7934 }
7935 if (!done) {
7936
7937 TMessage mess(kPROOF_CACHE);
7938 mess << Int_t(kDisablePackages);
7939 Broadcast(mess, kUnique);
7940
7941 TMessage mess2(kPROOF_CACHE);
7942 mess2 << Int_t(kDisableSubPackages);
7944
7946 st = fStatus;
7947 }
7948
7949 // Done
7950 return st;
7951}
7952
7953////////////////////////////////////////////////////////////////////////////////
7954/// Build specified package. Executes the PROOF-INF/BUILD.sh
7955/// script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
7956/// then submit build command to slaves, but don't wait
7957/// for results. If opt is kCollectBuildResults then collect result
7958/// from slaves. To be used on the master.
7959/// If opt = kBuildAll (default) then submit and wait for results
7960/// (to be used on the client).
7961/// Returns 0 in case of success and -1 in case of error.
7962
7963Int_t TProof::BuildPackage(const char *package,
7964 EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
7965{
7966 if (!IsValid()) return -1;
7967
7968 if (!package || !package[0]) {
7969 Error("BuildPackage", "need to specify a package name");
7970 return -1;
7971 }
7972
7973 // if name, erroneously, is a par pathname strip off .par and path
7974 TString pac = package;
7975 if (pac.EndsWith(".par"))
7976 pac.Remove(pac.Length()-4);
7977 pac = gSystem->BaseName(pac);
7978
7979 Bool_t buildOnClient = kTRUE;
7980 if (opt == kDontBuildOnClient) {
7981 buildOnClient = kFALSE;
7982 opt = kBuildAll;
7983 }
7984 // Prepare the local package
7985 TString pdir;
7986 Int_t st = 0;
7987
7988 if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
7989 if (workers) {
7990 TMessage mess(kPROOF_CACHE);
7991 mess << Int_t(kBuildPackage) << pac << chkveropt;
7992 Broadcast(mess, workers);
7993
7994 } else {
7995 TMessage mess(kPROOF_CACHE);
7996 mess << Int_t(kBuildPackage) << pac << chkveropt;
7997 Broadcast(mess, kUnique);
7998
7999 TMessage mess2(kPROOF_CACHE);
8000 mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
8002 }
8003 }
8004
8005 if (opt >= kBuildAll) {
8006 // by first forwarding the build commands to the master and slaves
8007 // and only then building locally we build in parallel
8008 if (buildOnClient) {
8009 st = fPackMgr->Build(pac, chkveropt);
8010 }
8011
8012
8013 fStatus = 0;
8014 if (!IsLite() || !buildOnClient) {
8015
8016 // On the master, workers that fail are deactivated
8017 // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8018 if (workers) {
8019// Collect(workers, -1, -1, deactivateOnFailure);
8020 Collect(workers);
8021 } else {
8023 }
8024 }
8025
8026 if (fStatus < 0 || st < 0)
8027 return -1;
8028 }
8029
8030 return 0;
8031}
8032
8033////////////////////////////////////////////////////////////////////////////////
8034/// Load specified package. Executes the PROOF-INF/SETUP.C script
8035/// on all active nodes. If notOnClient = true, don't load package
8036/// on the client. The default is to load the package also on the client.
8037/// The argument 'loadopts' specify a list of objects to be passed to the SETUP.
8038/// The objects in the list must be streamable; the SETUP macro will be executed
8039/// like this: SETUP.C(loadopts).
8040/// Returns 0 in case of success and -1 in case of error.
8041
8042Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
8043 TList *loadopts, TList *workers)
8044{
8045 if (!IsValid()) return -1;
8046
8047 if (!package || !package[0]) {
8048 Error("LoadPackage", "need to specify a package name");
8049 return -1;
8050 }
8051
8052 // if name, erroneously, is a par pathname strip off .par and path
8053 TString pac = package;
8054 if (pac.EndsWith(".par"))
8055 pac.Remove(pac.Length()-4);
8056 pac = gSystem->BaseName(pac);
8057
8058 if (!notOnClient && TestBit(TProof::kIsClient))
8059 if (fPackMgr->Load(package, loadopts) == -1) return -1;
8060
8061 TMessage mess(kPROOF_CACHE);
8062 mess << Int_t(kLoadPackage) << pac;
8063 if (loadopts) mess << loadopts;
8064
8065 // On the master, workers that fail are deactivated
8066 Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
8067
8068 Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
8069
8070 if (workers) {
8071 PDB(kPackage, 3)
8072 Info("LoadPackage", "Sending load message to selected workers only");
8073 Broadcast(mess, workers);
8074 if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
8075 } else {
8076 Broadcast(mess);
8077 Collect(kActive, -1, -1, deactivateOnFailure);
8078 }
8079
8080 return fStatus;
8081}
8082
8083////////////////////////////////////////////////////////////////////////////////
8084/// Unload specified package.
8085/// Returns 0 in case of success and -1 in case of error.
8086
8087Int_t TProof::UnloadPackage(const char *package)
8088{
8089 if (!IsValid()) return -1;
8090
8091 if (!package || !package[0]) {
8092 Error("UnloadPackage", "need to specify a package name");
8093 return -1;
8094 }
8095
8096 // if name, erroneously, is a par pathname strip off .par and path
8097 TString pac = package;
8098 if (pac.EndsWith(".par"))
8099 pac.Remove(pac.Length()-4);
8100 pac = gSystem->BaseName(pac);
8101
8102 if (fPackMgr->Unload(package) < 0)
8103 Warning("UnloadPackage", "unable to remove symlink to %s", package);
8104
8105 // Nothing more to do if we are a Lite-session
8106 if (IsLite()) return 0;
8107
8108 TMessage mess(kPROOF_CACHE);
8109 mess << Int_t(kUnloadPackage) << pac;
8110 Broadcast(mess);
8111 Collect();
8112
8113 return fStatus;
8114}
8115
8116////////////////////////////////////////////////////////////////////////////////
8117/// Unload all packages.
8118/// Returns 0 in case of success and -1 in case of error.
8119
8121{
8122 if (!IsValid()) return -1;
8123
8125 if (fPackMgr->Unload(0) < 0) return -1;
8126 }
8127
8128 // Nothing more to do if we are a Lite-session
8129 if (IsLite()) return 0;
8130
8131 TMessage mess(kPROOF_CACHE);
8132 mess << Int_t(kUnloadPackages);
8133 Broadcast(mess);
8134 Collect();
8135
8136 return fStatus;
8137}
8138
8139////////////////////////////////////////////////////////////////////////////////
8140/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8141/// script if it exists followed by the PROOF-INF/SETUP.C script.
8142/// In case notOnClient = true, don't enable the package on the client.
8143/// The default is to enable packages also on the client.
8144/// If specified, enables packages only on the specified workers.
8145/// Returns 0 in case of success and -1 in case of error.
8146/// Provided for backward compatibility.
8147
8148Int_t TProof::EnablePackage(const char *package, Bool_t notOnClient,
8149 TList *workers)
8150{
8151 return EnablePackage(package, (TList *)0, notOnClient, workers);
8152}
8153
8154////////////////////////////////////////////////////////////////////////////////
8155/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8156/// script if it exists followed by the PROOF-INF/SETUP.C script.
8157/// In case notOnClient = true, don't enable the package on the client.
8158/// The default is to enable packages also on the client.
8159/// It is is possible to specify options for the loading step via 'loadopts';
8160/// the string will be passed passed as argument to SETUP.
8161/// Special option 'chkv=<o>' (or 'checkversion=<o>') can be used to control
8162/// plugin version checking during building: possible choices are:
8163/// off no check; failure may occur at loading
8164/// on check ROOT version [default]
8165/// svn check ROOT version and Git commit SHA1.
8166/// (Use ';', ' ' or '|' to separate 'chkv=<o>' from the rest.)
8167/// If specified, enables packages only on the specified workers.
8168/// Returns 0 in case of success and -1 in case of error.
8169
8170Int_t TProof::EnablePackage(const char *package, const char *loadopts,
8171 Bool_t notOnClient, TList *workers)
8172{
8173 TList *optls = 0;
8174 if (loadopts && strlen(loadopts)) {
8175 if (fProtocol > 28) {
8176 TObjString *os = new TObjString(loadopts);
8177 // Filter out 'checkversion=off|on|svn' or 'chkv=...'
8178 os->String().ReplaceAll("checkversion=", "chkv=");
8179 Ssiz_t fcv = kNPOS, lcv = kNPOS;
8180 if ((fcv = os->String().Index("chkv=")) != kNPOS) {
8181 TRegexp re("[; |]");
8182 if ((lcv = os->String().Index(re, fcv)) == kNPOS) {
8183 lcv = os->String().Length();
8184 }
8185 TString ocv = os->String()(fcv, lcv - fcv);
8186 Int_t cvopt = -1;
8187 if (ocv.EndsWith("=off") || ocv.EndsWith("=0"))
8188 cvopt = (Int_t) TPackMgr::kDontCheck;
8189 else if (ocv.EndsWith("=on") || ocv.EndsWith("=1"))
8190 cvopt = (Int_t) TPackMgr::kCheckROOT;
8191 else
8192 Warning("EnablePackage", "'checkversion' option unknown from argument: '%s' - ignored", ocv.Data());
8193 if (cvopt > -1) {
8194 if (gDebug > 0)
8195 Info("EnablePackage", "setting check version option from argument: %d", cvopt);
8196 optls = new TList;
8197 optls->Add(new TParameter<Int_t>("PROOF_Package_CheckVersion", (Int_t) cvopt));
8198 // Remove the special option from; we leave a separator if there were two (one before and one after)
8199 if (lcv != kNPOS && fcv == 0) ocv += os->String()[lcv];
8200 if (fcv > 0 && os->String().Index(re, fcv - 1) == fcv - 1) os->String().Remove(fcv - 1, 1);
8201 os->String().ReplaceAll(ocv.Data(), "");
8202 }
8203 }
8204 if (!os->String().IsNull()) {
8205 if (!optls) optls = new TList;
8206 optls->Add(new TObjString(os->String().Data()));
8207 }
8208 if (optls) optls->SetOwner(kTRUE);
8209 } else {
8210 // Notify
8211 Warning("EnablePackage", "remote server does not support options: ignoring the option string");
8212 }
8213 }
8214 // Run
8215 Int_t rc = EnablePackage(package, optls, notOnClient, workers);
8216 // Clean up
8217 SafeDelete(optls);
8218 // Done
8219 return rc;
8220}
8221
8222////////////////////////////////////////////////////////////////////////////////
8223/// Enable specified package. Executes the PROOF-INF/BUILD.sh
8224/// script if it exists followed by the PROOF-INF/SETUP.C script.
8225/// In case notOnClient = true, don't enable the package on the client.
8226/// The default is to enable packages also on the client.
8227/// It is is possible to specify a list of objects to be passed to the SETUP
8228/// functions via 'loadopts'; the objects must be streamable.
8229/// Returns 0 in case of success and -1 in case of error.
8230
8231Int_t TProof::EnablePackage(const char *package, TList *loadopts,
8232 Bool_t notOnClient, TList *workers)
8233{
8234 if (!IsValid()) return -1;
8235
8236 if (!package || !package[0]) {
8237 Error("EnablePackage", "need to specify a package name");
8238 return -1;
8239 }
8240
8241 // if name, erroneously, is a par pathname strip off .par and path
8242 TString pac = package;
8243 if (pac.EndsWith(".par"))
8244 pac.Remove(pac.Length()-4);
8245 pac = gSystem->BaseName(pac);
8246
8248 if (notOnClient)
8249 opt = kDontBuildOnClient;
8250
8251 // Get check version option; user settings have priority
8252 Int_t chkveropt = TPackMgr::kCheckROOT;
8253 TString ocv = gEnv->GetValue("Proof.Package.CheckVersion", "");
8254 if (!ocv.IsNull()) {
8255 if (ocv == "off" || ocv == "0")
8256 chkveropt = (Int_t) TPackMgr::kDontCheck;
8257 else if (ocv == "on" || ocv == "1")
8258 chkveropt = (Int_t) TPackMgr::kCheckROOT;
8259 else
8260 Warning("EnablePackage", "'checkversion' option unknown from rootrc: '%s' - ignored", ocv.Data());
8261 }
8262 if (loadopts) {
8263 TParameter<Int_t> *pcv = (TParameter<Int_t> *) loadopts->FindObject("PROOF_Package_CheckVersion");
8264 if (pcv) {
8265 chkveropt = pcv->GetVal();
8266 loadopts->Remove(pcv);
8267 delete pcv;
8268 }
8269 }
8270 if (gDebug > 0)
8271 Info("EnablePackage", "using check version option: %d", chkveropt);
8272
8273 if (BuildPackage(pac, opt, chkveropt, workers) == -1)
8274 return -1;
8275
8276 TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
8277 if (optls && fProtocol <= 28) {
8278 Warning("EnablePackage", "remote server does not support options: ignoring the option list");
8279 optls = 0;
8280 }
8281
8282 if (LoadPackage(pac, notOnClient, optls, workers) == -1)
8283 return -1;
8284
8285 // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
8289 }
8291 TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
8292 : new TPair(new TObjString(pac), 0);
8294 }
8295
8296 return 0;
8297}
8298
8299////////////////////////////////////////////////////////////////////////////////
8300/// Download a PROOF archive (PAR file) from the master package repository.
8301/// The PAR file is downloaded in the current directory or in the directory
8302/// specified by 'dstdir'. If a package with the same name already exists
8303/// at destination, a check on the MD5 sum is done and the user warned or
8304/// prompted for action, depending is the file is equal or different.
8305/// Returns 0 in case of success and -1 in case of error.
8306
8307Int_t TProof::DownloadPackage(const char *pack, const char *dstdir)
8308{
8309 if (!fManager || !(fManager->IsValid())) {
8310 Error("DownloadPackage", "the manager is undefined!");
8311 return -1;
8312 }
8313
8314 // Create the default source and destination paths
8315 TString parname(gSystem->BaseName(pack)), src, dst;
8316 if (!parname.EndsWith(".par")) parname += ".par";
8317 src.Form("packages/%s", parname.Data());
8318 if (!dstdir || strlen(dstdir) <= 0) {
8319 dst.Form("./%s", parname.Data());
8320 } else {
8321 // Check the destination directory
8322 FileStat_t st;
8323 if (gSystem->GetPathInfo(dstdir, st) != 0) {
8324 // Directory does not exit: create it
8325 if (gSystem->mkdir(dstdir, kTRUE) != 0) {
8326 Error("DownloadPackage",
8327 "could not create the destination directory '%s' (errno: %d)",
8328 dstdir, TSystem::GetErrno());
8329 return -1;
8330 }
8331 } else if (!R_ISDIR(st.fMode) && !R_ISLNK(st.fMode)) {
8332 Error("DownloadPackage",
8333 "destination path '%s' exist but is not a directory!", dstdir);
8334 return -1;
8335 }
8336 dst.Form("%s/%s", dstdir, parname.Data());
8337 }
8338
8339 // Make sure the source file exists
8340 FileStat_t stsrc;
8342 if (gSystem->RedirectOutput(fLogFileName, "a", &rh) != 0)
8343 Warning("DownloadPackage", "problems redirecting output to '%s'", fLogFileName.Data());
8344 Int_t rc = fManager->Stat(src, stsrc);
8345 if (gSystem->RedirectOutput(0, 0, &rh) != 0)
8346 Warning("DownloadPackage", "problems restoring output");
8347 if (rc != 0) {
8348 // Check if there is another possible source
8350 TMacro *mp = GetLastLog();
8351 if (mp) {
8352 // Look for global directories
8353 Bool_t isGlobal = kFALSE;
8354 TIter nxl(mp->GetListOfLines());
8355 TObjString *os = 0;
8356 TString globaldir;
8357 while ((os = (TObjString *) nxl())) {
8358 TString s(os->GetName());
8359 if (s.Contains("*** Global Package cache")) {
8360 // Get the directory
8361 s.Remove(0, s.Last(':') + 1);
8362 s.Remove(s.Last(' '));
8363 globaldir = s;
8364 isGlobal = kTRUE;
8365 } else if (s.Contains("*** Package cache")) {
8366 isGlobal = kFALSE;
8367 globaldir = "";
8368 }
8369 // Check for the package
8370 if (isGlobal && s.Contains(parname)) {
8371 src.Form("%s/%s", globaldir.Data(), parname.Data());
8372 break;
8373 }
8374 }
8375 // Cleanup
8376 delete mp;
8377 }
8378 }
8379
8380 // Do it via the manager
8381 if (fManager->GetFile(src, dst, "silent") != 0) {
8382 Error("DownloadPackage", "problems downloading '%s' (src:%s, dst:%s)",
8383 pack, src.Data(), dst.Data());
8384 return -1;
8385 } else {
8386 Info("DownloadPackage", "'%s' cross-checked against master repository (local path: %s)",
8387 pack, dst.Data());
8388 }
8389 // Done
8390 return 0;
8391}
8392
8393////////////////////////////////////////////////////////////////////////////////
8394/// Upload a PROOF archive (PAR file). A PAR file is a compressed
8395/// tar file with one special additional directory, PROOF-INF
8396/// (blatantly copied from Java's jar format). It must have the extension
8397/// .par. A PAR file can be directly a binary or a source with a build
8398/// procedure. In the PROOF-INF directory there can be a build script:
8399/// BUILD.sh to be called to build the package, in case of a binary PAR
8400/// file don't specify a build script or make it a no-op. Then there is
8401/// SETUP.C which sets the right environment variables to use the package,
8402/// like LD_LIBRARY_PATH, etc.
8403/// The 'opt' allows to specify whether the .PAR should be just unpacked
8404/// in the existing dir (opt = kUntar, default) or a remove of the existing
8405/// directory should be executed (opt = kRemoveOld), so triggering a full
8406/// re-build. The option if effective only for PROOF protocol > 8 .
8407/// The lab 'dirlab' (e.g. 'G0') indicates that the package is to uploaded to
8408/// an alternative global directory for global usage. This may require special
8409/// privileges.
8410/// If download is kTRUE and the package is not found locally, then it is downloaded
8411/// from the master repository.
8412/// Returns 0 in case of success and -1 in case of error.
8413
8415 TList *workers)
8416{
8417 if (!IsValid()) return -1;
8418
8419 // Remote PAR ?
8421 Bool_t remotepar = (ft == TFile::kWeb || ft == TFile::kNet) ? kTRUE : kFALSE;
8422
8423 TString par(pack), base, name;
8424 if (par.EndsWith(".par")) {
8425 base = gSystem->BaseName(par);
8426 name = base(0, base.Length() - strlen(".par"));
8427 } else {
8428 name = gSystem->BaseName(par);
8429 base.Form("%s.par", name.Data());
8430 par += ".par";
8431 }
8432
8433 // Default location is the local working dir; then the package dir
8434 gSystem->ExpandPathName(par);
8436 Int_t xrc = -1;
8437 if (!remotepar) xrc = TPackMgr::FindParPath(fPackMgr, name, par);
8438 if (xrc == 0) {
8439 // Package is in the global dirs
8440 if (gDebug > 0)
8441 Info("UploadPackage", "global package found (%s): no upload needed",
8442 par.Data());
8443 return 0;
8444 } else if (xrc < 0) {
8445 Error("UploadPackage", "PAR file '%s' not found", par.Data());
8446 return -1;
8447 }
8448 }
8449
8450 // Strategy:
8451 // On the client:
8452 // get md5 of package and check if it is different
8453 // from the one stored in the local package directory. If it is lock
8454 // the package directory and copy the package, unlock the directory.
8455 // On the masters:
8456 // get md5 of package and check if it is different from the
8457 // one stored on the remote node. If it is different lock the remote
8458 // package directory and use TFTP or SendFile to ftp the package to the
8459 // remote node, unlock the directory.
8460
8461
8463 Bool_t rmold = (opt == TProof::kRemoveOld) ? kTRUE : kFALSE;
8464 if (fPackMgr->Install(par, rmold) < 0) {
8465 Error("UploadPackage", "installing '%s' failed", gSystem->BaseName(par));
8466 return -1;
8467 }
8468 }
8469
8470 // Nothing more to do if we are a Lite-session
8471 if (IsLite()) return 0;
8472
8473 TMD5 *md5 = fPackMgr->ReadMD5(name);
8474
8475 TString smsg;
8476 if (remotepar && GetRemoteProtocol() > 36) {
8477 smsg.Form("+%s", par.Data());
8478 } else {
8479 smsg.Form("+%s", base.Data());
8480 }
8481
8483 mess << smsg << (*md5);
8485 smsg.Replace(0, 1, "-");
8486 mess2 << smsg << (*md5);
8488 smsg.Replace(0, 1, "=");
8489 mess3 << smsg << (*md5);
8490
8491 delete md5;
8492
8493 if (fProtocol > 8) {
8494 // Send also the option
8495 mess << (UInt_t) opt;
8496 mess2 << (UInt_t) opt;
8497 mess3 << (UInt_t) opt;
8498 }
8499
8500 // Loop over all slaves with unique fs image, or to a selected
8501 // list of workers, if specified
8502 if (!workers)
8503 workers = fUniqueSlaves;
8504 TIter next(workers);
8505 TSlave *sl = 0;
8506 while ((sl = (TSlave *) next())) {
8507 if (!sl->IsValid())
8508 continue;
8509
8510 sl->GetSocket()->Send(mess);
8511
8512 fCheckFileStatus = 0;
8514 if (fCheckFileStatus == 0) {
8515
8516 if (fProtocol > 5) {
8517 // remote directory is locked, upload file over the open channel
8518 smsg.Form("%s/%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir, base.Data());
8519 if (SendFile(par, (kBinary | kForce | kCpBin | kForward), smsg.Data(), sl) < 0) {
8520 Error("UploadPackage", "%s: problems uploading file %s",
8521 sl->GetOrdinal(), par.Data());
8522 return -1;
8523 }
8524 } else {
8525 // old servers receive it via TFTP
8526 TFTP ftp(TString("root://")+sl->GetName(), 1);
8527 if (!ftp.IsZombie()) {
8528 smsg.Form("%s/%s", sl->GetProofWorkDir(), kPROOF_PackDir);
8529 ftp.cd(smsg.Data());
8530 ftp.put(par, base.Data());
8531 }
8532 }
8533
8534 // install package and unlock dir
8535 sl->GetSocket()->Send(mess2);
8536 fCheckFileStatus = 0;
8538 if (fCheckFileStatus == 0) {
8539 Error("UploadPackage", "%s: unpacking of package %s failed",
8540 sl->GetOrdinal(), base.Data());
8541 return -1;
8542 }
8543 }
8544 }
8545
8546 // loop over all other master nodes
8547 TIter nextmaster(fNonUniqueMasters);
8548 TSlave *ma;
8549 while ((ma = (TSlave *) nextmaster())) {
8550 if (!ma->IsValid())
8551 continue;
8552
8553 ma->GetSocket()->Send(mess3);
8554
8555 fCheckFileStatus = 0;
8557 if (fCheckFileStatus == 0) {
8558 // error -> package should have been found
8559 Error("UploadPackage", "package %s did not exist on submaster %s",
8560 base.Data(), ma->GetOrdinal());
8561 return -1;
8562 }
8563 }
8564
8565 return 0;
8566}
8567
8568
8569////////////////////////////////////////////////////////////////////////////////
8570/// Make sure that the directory path contained by macro is in the macro path
8571
8572void TProof::AssertMacroPath(const char *macro)
8573{
8574 static TString macrop(gROOT->GetMacroPath());
8575 if (macro && strlen(macro) > 0) {
8576 TString dirn(gSystem->DirName(macro));
8577 if (!macrop.Contains(dirn)) {
8578 macrop += TString::Format("%s:", dirn.Data());
8579 gROOT->SetMacroPath(macrop);
8580 }
8581 }
8582}
8583
8584
8585////////////////////////////////////////////////////////////////////////////////
8586/// Load the specified macro on master, workers and, if notOnClient is
8587/// kFALSE, on the client. The macro file is uploaded if new or updated.
8588/// Additional files to be uploaded (or updated, if needed) can be specified
8589/// after a comma, e.g. "mymacro.C+,thisheader.h,thatheader.h".
8590/// If existing in the same directory, a header basename(macro).h or .hh, is also
8591/// uploaded.
8592/// The default is to load the macro also on the client; notOnClient can be used
8593/// to avoid loading on the client.
8594/// On masters, if uniqueWorkers is kTRUE, the macro is loaded on unique workers
8595/// only, and collection is not done; if uniqueWorkers is kFALSE, collection
8596/// from the previous request is done, and broadcasting + collection from the
8597/// other workers is done.
8598/// The wrks arg can be used on the master to limit the set of workers.
8599/// Returns 0 in case of success and -1 in case of error.
8600
8601Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
8602 TList *wrks)
8603{
8604 if (!IsValid()) return -1;
8605
8606 if (!macro || !macro[0]) {
8607 Error("Load", "need to specify a macro name");
8608 return -1;
8609 }
8610
8611 // Make sure the path is in the macro path
8613
8614 if (TestBit(TProof::kIsClient) && !wrks) {
8615
8616 // Extract the file implementation name first
8617 TString addsname, implname = macro;
8618 Ssiz_t icom = implname.Index(",");
8619 if (icom != kNPOS) {
8620 addsname = implname(icom + 1, implname.Length());
8621 implname.Remove(icom);
8622 }
8623 TString basemacro = gSystem->BaseName(implname), mainmacro(implname);
8624 TString bmsg(basemacro), acmode, args, io;
8625 implname = gSystem->SplitAclicMode(implname, acmode, args, io);
8626
8627 // Macro names must have a standard format
8628 Int_t dot = implname.Last('.');
8629 if (dot == kNPOS) {
8630 Info("Load", "macro '%s' does not contain a '.': do nothing", macro);
8631 return -1;
8632 }
8633
8634 // Is there any associated header file
8635 Bool_t hasHeader = kTRUE;
8636 TString headname = implname;
8637 headname.Remove(dot);
8638 headname += ".h";
8639 if (gSystem->AccessPathName(headname, kReadPermission)) {
8640 TString h = headname;
8641 headname.Remove(dot);
8642 headname += ".hh";
8643 if (gSystem->AccessPathName(headname, kReadPermission)) {
8644 hasHeader = kFALSE;
8645 if (gDebug > 0)
8646 Info("Load", "no associated header file found: tried: %s %s",
8647 h.Data(), headname.Data());
8648 }
8649 }
8650
8651 // Is there any additional file ?
8652 TString addincs;
8653 TList addfiles;
8654 if (!addsname.IsNull()) {
8655 TString fn;
8656 Int_t from = 0;
8657 while (addsname.Tokenize(fn, from, ",")) {
8659 Error("Load", "additional file '%s' not found", fn.Data());
8660 return -1;
8661 }
8662 // Create the additional include statement
8663 if (!notOnClient) {
8664 TString dirn(gSystem->DirName(fn));
8665 if (addincs.IsNull()) {
8666 addincs.Form("-I%s", dirn.Data());
8667 } else if (!addincs.Contains(dirn)) {
8668 addincs += TString::Format(" -I%s", dirn.Data());
8669 }
8670 }
8671 // Remember these files ...
8672 addfiles.Add(new TObjString(fn));
8673 }
8674 }
8675
8676 // Send files now; the md5 check is run here; see SendFile for more
8677 // details.
8678 if (SendFile(implname, kAscii | kForward , "cache") == -1) {
8679 Error("Load", "problems sending implementation file %s", implname.Data());
8680 return -1;
8681 }
8682 if (hasHeader)
8683 if (SendFile(headname, kAscii | kForward , "cache") == -1) {
8684 Error("Load", "problems sending header file %s", headname.Data());
8685 return -1;
8686 }
8687 // Additional files
8688 if (addfiles.GetSize() > 0) {
8689 TIter nxfn(&addfiles);
8690 TObjString *os = 0;
8691 while ((os = (TObjString *) nxfn())) {
8692 // These files need to be available everywhere, cache and sandbox
8693 if (SendFile(os->GetName(), kAscii | kForward, "cache") == -1) {
8694 Error("Load", "problems sending additional file %s", os->GetName());
8695 return -1;
8696 }
8697 // Add the base names to the message broadcasted
8698 bmsg += TString::Format(",%s", gSystem->BaseName(os->GetName()));
8699 }
8700 addfiles.SetOwner(kTRUE);
8701 }
8702
8703 // The files are now on the workers: now we send the loading request
8704 TMessage mess(kPROOF_CACHE);
8705 if (GetRemoteProtocol() < 34) {
8706 mess << Int_t(kLoadMacro) << basemacro;
8707 // This may be needed
8708 AddIncludePath("../../cache");
8709 } else {
8710 mess << Int_t(kLoadMacro) << bmsg;
8711 }
8712 Broadcast(mess, kActive);
8713
8714 // Load locally, if required
8715 if (!notOnClient) {
8716 // Mofify the include path
8717 TString oldincs = gSystem->GetIncludePath();
8718 if (!addincs.IsNull()) gSystem->AddIncludePath(addincs);
8719
8720 // By first forwarding the load command to the master and workers
8721 // and only then loading locally we load/build in parallel
8722 gROOT->ProcessLine(TString::Format(".L %s", mainmacro.Data()));
8723
8724 // Restore include path
8725 if (!addincs.IsNull()) gSystem->SetIncludePath(oldincs);
8726
8727 // Update the macro path
8729 TString np(gSystem->DirName(macro));
8730 if (!np.IsNull()) {
8731 np += ":";
8732 if (!mp.BeginsWith(np) && !mp.Contains(":"+np)) {
8733 Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
8734 mp.Insert(ip, np);
8736 if (gDebug > 0)
8737 Info("Load", "macro path set to '%s'", TROOT::GetMacroPath());
8738 }
8739 }
8740 }
8741
8742 // Wait for master and workers to be done
8744
8745 if (IsLite()) {
8746 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8747 if (!fLoadedMacros) {
8748 fLoadedMacros = new TList();
8750 }
8751 // if wrks is specified the macro should already be loaded on the master.
8752 fLoadedMacros->Add(new TObjString(macro));
8753 }
8754
8755 } else {
8756 // On master
8757
8758 // The files are now on the workers: now we send the loading request first
8759 // to the unique workers, so that the eventual compilation occurs only once.
8760 TString basemacro = gSystem->BaseName(macro);
8761 TMessage mess(kPROOF_CACHE);
8762
8763 if (uniqueWorkers) {
8764 mess << Int_t(kLoadMacro) << basemacro;
8765 if (wrks) {
8766 Broadcast(mess, wrks);
8767 Collect(wrks);
8768 } else {
8769 Broadcast(mess, kUnique);
8770 }
8771 } else {
8772 // Wait for the result of the previous sending
8774
8775 // We then send a tuned loading request to the other workers
8776 TList others;
8777 TSlave *wrk = 0;
8778 TIter nxw(fActiveSlaves);
8779 while ((wrk = (TSlave *)nxw())) {
8780 if (!fUniqueSlaves->FindObject(wrk)) {
8781 others.Add(wrk);
8782 }
8783 }
8784
8785 // Do not force compilation, if it was requested
8786 Int_t ld = basemacro.Last('.');
8787 if (ld != kNPOS) {
8788 Int_t lpp = basemacro.Index("++", ld);
8789 if (lpp != kNPOS) basemacro.Replace(lpp, 2, "+");
8790 }
8791 mess << Int_t(kLoadMacro) << basemacro;
8792 Broadcast(mess, &others);
8793 Collect(&others);
8794 }
8795
8796 PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
8797 if (!fLoadedMacros) {
8798 fLoadedMacros = new TList();
8800 }
8801 // if wrks is specified the macro should already be loaded on the master.
8802 if (!wrks)
8803 fLoadedMacros->Add(new TObjString(macro));
8804 }
8805
8806 // Done
8807 return 0;
8808}
8809
8810////////////////////////////////////////////////////////////////////////////////
8811/// Add 'libpath' to the lib path search.
8812/// Multiple paths can be specified at once separating them with a comma or
8813/// a blank.
8814/// Return 0 on success, -1 otherwise
8815
8816Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
8817 Bool_t doCollect)
8818{
8819 if ((!libpath || !libpath[0])) {
8820 if (gDebug > 0)
8821 Info("AddDynamicPath", "list is empty - nothing to do");
8822 return 0;
8823 }
8824
8825 // Do it also on clients, if required
8826 if (onClient)
8827 HandleLibIncPath("lib", kTRUE, libpath);
8828
8830 m << TString("lib") << (Bool_t)kTRUE;
8831
8832 // Add paths
8833 if (libpath && strlen(libpath)) {
8834 m << TString(libpath);
8835 } else {
8836 m << TString("-");
8837 }
8838
8839 // Tell the server to send back or not
8840 m << (Int_t)doCollect;
8841
8842 // Forward the request
8843 if (wrks) {
8844 Broadcast(m, wrks);
8845 if (doCollect)
8846 Collect(wrks, fCollectTimeout);
8847 } else {
8848 Broadcast(m);
8850 }
8851
8852 return 0;
8853}
8854
8855////////////////////////////////////////////////////////////////////////////////
8856/// Add 'incpath' to the inc path search.
8857/// Multiple paths can be specified at once separating them with a comma or
8858/// a blank.
8859/// Return 0 on success, -1 otherwise
8860
8861Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
8862 Bool_t doCollect)
8863{
8864 if ((!incpath || !incpath[0])) {
8865 if (gDebug > 0)
8866 Info("AddIncludePath", "list is empty - nothing to do");
8867 return 0;
8868 }
8869
8870 // Do it also on clients, if required
8871 if (onClient)
8872 HandleLibIncPath("inc", kTRUE, incpath);
8873
8875 m << TString("inc") << (Bool_t)kTRUE;
8876
8877 // Add paths
8878 if (incpath && strlen(incpath)) {
8879 m << TString(incpath);
8880 } else {
8881 m << TString("-");
8882 }
8883
8884 // Tell the server to send back or not
8885 m << (Int_t)doCollect;
8886
8887 // Forward the request
8888 if (wrks) {
8889 Broadcast(m, wrks);
8890 if (doCollect)
8891 Collect(wrks, fCollectTimeout);
8892 } else {
8893 Broadcast(m);
8895 }
8896
8897 return 0;
8898}
8899
8900////////////////////////////////////////////////////////////////////////////////
8901/// Remove 'libpath' from the lib path search.
8902/// Multiple paths can be specified at once separating them with a comma or
8903/// a blank.
8904/// Return 0 on success, -1 otherwise
8905
8906Int_t TProof::RemoveDynamicPath(const char *libpath, Bool_t onClient)
8907{
8908 if ((!libpath || !libpath[0])) {
8909 if (gDebug > 0)
8910 Info("RemoveDynamicPath", "list is empty - nothing to do");
8911 return 0;
8912 }
8913
8914 // Do it also on clients, if required
8915 if (onClient)
8916 HandleLibIncPath("lib", kFALSE, libpath);
8917
8919 m << TString("lib") <<(Bool_t)kFALSE;
8920
8921 // Add paths
8922 if (libpath && strlen(libpath))
8923 m << TString(libpath);
8924 else
8925 m << TString("-");
8926
8927 // Forward the request
8928 Broadcast(m);
8930
8931 return 0;
8932}
8933
8934////////////////////////////////////////////////////////////////////////////////
8935/// Remove 'incpath' from the inc path search.
8936/// Multiple paths can be specified at once separating them with a comma or
8937/// a blank.
8938/// Return 0 on success, -1 otherwise
8939
8940Int_t TProof::RemoveIncludePath(const char *incpath, Bool_t onClient)
8941{
8942 if ((!incpath || !incpath[0])) {
8943 if (gDebug > 0)
8944 Info("RemoveIncludePath", "list is empty - nothing to do");
8945 return 0;
8946 }
8947
8948 // Do it also on clients, if required
8949 if (onClient)
8950 HandleLibIncPath("in", kFALSE, incpath);
8951
8953 m << TString("inc") << (Bool_t)kFALSE;
8954
8955 // Add paths
8956 if (incpath && strlen(incpath))
8957 m << TString(incpath);
8958 else
8959 m << TString("-");
8960
8961 // Forward the request
8962 Broadcast(m);
8964
8965 return 0;
8966}
8967
8968////////////////////////////////////////////////////////////////////////////////
8969/// Handle lib, inc search paths modification request
8970
8971void TProof::HandleLibIncPath(const char *what, Bool_t add, const char *dirs)
8972{
8973 TString type(what);
8974 TString path(dirs);
8975
8976 // Check type of action
8977 if ((type != "lib") && (type != "inc")) {
8978 Error("HandleLibIncPath","unknown action type: %s - protocol error?", type.Data());
8979 return;
8980 }
8981
8982 // Separators can be either commas or blanks
8983 path.ReplaceAll(","," ");
8984
8985 // Decompose lists
8986 TObjArray *op = 0;
8987 if (path.Length() > 0 && path != "-") {
8988 if (!(op = path.Tokenize(" "))) {
8989 Warning("HandleLibIncPath","decomposing path %s", path.Data());
8990 return;
8991 }
8992 }
8993
8994 if (add) {
8995
8996 if (type == "lib") {
8997
8998 // Add libs
8999 TIter nxl(op, kIterBackward);
9000 TObjString *lib = 0;
9001 while ((lib = (TObjString *) nxl())) {
9002 // Expand path
9003 TString xlib = lib->GetName();
9004 gSystem->ExpandPathName(xlib);
9005 // Add to the dynamic lib search path if it exists and can be read
9006 if (!gSystem->AccessPathName(xlib, kReadPermission)) {
9007 TString newlibpath = gSystem->GetDynamicPath();
9008 // In the first position after the working dir
9009 Int_t pos = 0;
9010 if (newlibpath.BeginsWith(".:"))
9011 pos = 2;
9012 if (newlibpath.Index(xlib) == kNPOS) {
9013 newlibpath.Insert(pos,TString::Format("%s:", xlib.Data()));
9014 gSystem->SetDynamicPath(newlibpath);
9015 }
9016 } else {
9017 if (gDebug > 0)
9018 Info("HandleLibIncPath",
9019 "libpath %s does not exist or cannot be read - not added", xlib.Data());
9020 }
9021 }
9022
9023 } else {
9024
9025 // Add incs
9026 TIter nxi(op);
9027 TObjString *inc = 0;
9028 while ((inc = (TObjString *) nxi())) {
9029 // Expand path
9030 TString xinc = inc->GetName();
9031 gSystem->ExpandPathName(xinc);
9032 // Add to the dynamic lib search path if it exists and can be read
9033 if (!gSystem->AccessPathName(xinc, kReadPermission)) {
9034 TString curincpath = gSystem->GetIncludePath();
9035 if (curincpath.Index(xinc) == kNPOS)
9036 gSystem->AddIncludePath(TString::Format("-I%s", xinc.Data()));
9037 } else
9038 if (gDebug > 0)
9039 Info("HandleLibIncPath",
9040 "incpath %s does not exist or cannot be read - not added", xinc.Data());
9041 }
9042 }
9043
9044
9045 } else {
9046
9047 if (type == "lib") {
9048
9049 // Remove libs
9050 TIter nxl(op);
9051 TObjString *lib = 0;
9052 while ((lib = (TObjString *) nxl())) {
9053 // Expand path
9054 TString xlib = lib->GetName();
9055 gSystem->ExpandPathName(xlib);
9056 // Remove from the dynamic lib search path
9057 TString newlibpath = gSystem->GetDynamicPath();
9058 newlibpath.ReplaceAll(TString::Format("%s:", xlib.Data()),"");
9059 gSystem->SetDynamicPath(newlibpath);
9060 }
9061
9062 } else {
9063
9064 // Remove incs
9065 TIter nxi(op);
9066 TObjString *inc = 0;
9067 while ((inc = (TObjString *) nxi())) {
9068 TString newincpath = gSystem->GetIncludePath();
9069 newincpath.ReplaceAll(TString::Format("-I%s", inc->GetName()),"");
9070 // Remove the interpreter path (added anyhow internally)
9071 newincpath.ReplaceAll(gInterpreter->GetIncludePath(),"");
9072 gSystem->SetIncludePath(newincpath);
9073 }
9074 }
9075 }
9076}
9077
9078////////////////////////////////////////////////////////////////////////////////
9079/// Get from the master the list of names of the packages available.
9080
9082{
9083 if (!IsValid())
9084 return (TList *)0;
9085
9086 TMessage mess(kPROOF_CACHE);
9087 mess << Int_t(kListPackages);
9088 Broadcast(mess);
9090
9091 return fAvailablePackages;
9092}
9093
9094////////////////////////////////////////////////////////////////////////////////
9095/// Get from the master the list of names of the packages enabled.
9096
9098{
9099 if (!IsValid())
9100 return (TList *)0;
9101
9102 TMessage mess(kPROOF_CACHE);
9103 mess << Int_t(kListEnabledPackages);
9104 Broadcast(mess);
9106
9107 return fEnabledPackages;
9108}
9109
9110////////////////////////////////////////////////////////////////////////////////
9111/// Print a progress bar on stderr. Used in batch mode.
9112
9114 Float_t procTime, Long64_t bytesread)
9115{
9116 if (fPrintProgress) {
9117 Bool_t redirlog = fRedirLog;
9118 fRedirLog = kFALSE;
9119 // Call the external function
9120 (*fPrintProgress)(total, processed, procTime, bytesread);
9121 fRedirLog = redirlog;
9122 return;
9123 }
9124
9125 fprintf(stderr, "[TProof::Progress] Total %lld events\t|", total);
9126
9127 for (int l = 0; l < 20; l++) {
9128 if (total > 0) {
9129 if (l < 20*processed/total)
9130 fprintf(stderr, "=");
9131 else if (l == 20*processed/total)
9132 fprintf(stderr, ">");
9133 else if (l > 20*processed/total)
9134 fprintf(stderr, ".");
9135 } else
9136 fprintf(stderr, "=");
9137 }
9138 Float_t evtrti = (procTime > 0. && processed > 0) ? processed / procTime : -1.;
9139 Float_t mbsrti = (procTime > 0. && bytesread > 0) ? bytesread / procTime : -1.;
9140 TString sunit("B/s");
9141 if (evtrti > 0.) {
9142 Float_t remainingTime = (total >= processed) ? (total - processed) / evtrti : -1;
9143 if (mbsrti > 0.) {
9144 const Float_t toK = 1024., toM = 1048576., toG = 1073741824.;
9145 if (mbsrti >= toG) {
9146 mbsrti /= toG;
9147 sunit = "GB/s";
9148 } else if (mbsrti >= toM) {
9149 mbsrti /= toM;
9150 sunit = "MB/s";
9151 } else if (mbsrti >= toK) {
9152 mbsrti /= toK;
9153 sunit = "kB/s";
9154 }
9155 fprintf(stderr, "| %.02f %% [%.1f evts/s, %.1f %s, time left: %.1f s]\r",
9156 (total ? ((100.0*processed)/total) : 100.0), evtrti, mbsrti, sunit.Data(), remainingTime);
9157 } else {
9158 fprintf(stderr, "| %.02f %% [%.1f evts/s, time left: %.1f s]\r",
9159 (total ? ((100.0*processed)/total) : 100.0), evtrti, remainingTime);
9160 }
9161 } else {
9162 fprintf(stderr, "| %.02f %%\r",
9163 (total ? ((100.0*processed)/total) : 100.0));
9164 }
9165 if (processed >= total) {
9166 fprintf(stderr, "\n Query processing time: %.1f s\n", procTime);
9167 }
9168}
9169
9170////////////////////////////////////////////////////////////////////////////////
9171/// Get query progress information. Connect a slot to this signal
9172/// to track progress.
9173
9175{
9176 if (fPrintProgress) {
9177 // Call the external function
9178 return (*fPrintProgress)(total, processed, -1., -1);
9179 }
9180
9181 PDB(kGlobal,1)
9182 Info("Progress","%2f (%lld/%lld)", 100.*processed/total, processed, total);
9183
9184 if (gROOT->IsBatch()) {
9185 // Simple progress bar
9186 if (total > 0)
9187 PrintProgress(total, processed);
9188 } else {
9189 EmitVA("Progress(Long64_t,Long64_t)", 2, total, processed);
9190 }
9191}
9192
9193////////////////////////////////////////////////////////////////////////////////
9194/// Get query progress information. Connect a slot to this signal
9195/// to track progress.
9196
9198 Float_t initTime, Float_t procTime,
9199 Float_t evtrti, Float_t mbrti)
9200{
9201 PDB(kGlobal,1)
9202 Info("Progress","%lld %lld %lld %f %f %f %f", total, processed, bytesread,
9203 initTime, procTime, evtrti, mbrti);
9204
9205 if (gROOT->IsBatch()) {
9206 // Simple progress bar
9207 if (total > 0)
9208 PrintProgress(total, processed, procTime, bytesread);
9209 } else {
9210 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t)",
9211 7, total, processed, bytesread, initTime, procTime, evtrti, mbrti);
9212 }
9213}
9214
9215////////////////////////////////////////////////////////////////////////////////
9216/// Get query progress information. Connect a slot to this signal
9217/// to track progress.
9218
9220 Float_t initTime, Float_t procTime,
9221 Float_t evtrti, Float_t mbrti, Int_t actw, Int_t tses, Float_t eses)
9222{
9223 PDB(kGlobal,1)
9224 Info("Progress","%lld %lld %lld %f %f %f %f %d %f", total, processed, bytesread,
9225 initTime, procTime, evtrti, mbrti, actw, eses);
9226
9227 if (gROOT->IsBatch()) {
9228 // Simple progress bar
9229 if (total > 0)
9230 PrintProgress(total, processed, procTime, bytesread);
9231 } else {
9232 EmitVA("Progress(Long64_t,Long64_t,Long64_t,Float_t,Float_t,Float_t,Float_t,Int_t,Int_t,Float_t)",
9233 10, total, processed, bytesread, initTime, procTime, evtrti, mbrti, actw, tses, eses);
9234 }
9235}
9236
9237////////////////////////////////////////////////////////////////////////////////
9238/// Get list of feedback objects. Connect a slot to this signal
9239/// to monitor the feedback object.
9240
9242{
9243 PDB(kGlobal,1)
9244 Info("Feedback","%d objects", objs->GetSize());
9245 PDB(kFeedback,1) {
9246 Info("Feedback","%d objects", objs->GetSize());
9247 objs->ls();
9248 }
9249
9250 Emit("Feedback(TList *objs)", (Long_t) objs);
9251}
9252
9253////////////////////////////////////////////////////////////////////////////////
9254/// Close progress dialog.
9255
9257{
9258 PDB(kGlobal,1)
9259 Info("CloseProgressDialog",
9260 "called: have progress dialog: %d", fProgressDialogStarted);
9261
9262 // Nothing to do if not there
9264 return;
9265
9266 Emit("CloseProgressDialog()");
9267}
9268
9269////////////////////////////////////////////////////////////////////////////////
9270/// Reset progress dialog.
9271
9272void TProof::ResetProgressDialog(const char *sel, Int_t sz, Long64_t fst,
9273 Long64_t ent)
9274{
9275 PDB(kGlobal,1)
9276 Info("ResetProgressDialog","(%s,%d,%lld,%lld)", sel, sz, fst, ent);
9277
9278 EmitVA("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
9279 4, sel, sz, fst, ent);
9280}
9281
9282////////////////////////////////////////////////////////////////////////////////
9283/// Send startup message.
9284
9285void TProof::StartupMessage(const char *msg, Bool_t st, Int_t done, Int_t total)
9286{
9287 PDB(kGlobal,1)
9288 Info("StartupMessage","(%s,%d,%d,%d)", msg, st, done, total);
9289
9290 EmitVA("StartupMessage(const char*,Bool_t,Int_t,Int_t)",
9291 4, msg, st, done, total);
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295/// Send dataset preparation status.
9296
9297void TProof::DataSetStatus(const char *msg, Bool_t st, Int_t done, Int_t total)
9298{
9299 PDB(kGlobal,1)
9300 Info("DataSetStatus","(%s,%d,%d,%d)", msg, st, done, total);
9301
9302 EmitVA("DataSetStatus(const char*,Bool_t,Int_t,Int_t)",
9303 4, msg, st, done, total);
9304}
9305
9306////////////////////////////////////////////////////////////////////////////////
9307/// Send or notify data set status
9308
9309void TProof::SendDataSetStatus(const char *action, UInt_t done,
9310 UInt_t tot, Bool_t st)
9311{
9312 if (IsLite()) {
9313 if (tot) {
9314 TString type = "files";
9315 Int_t frac = (Int_t) (done*100.)/tot;
9316 char msg[512] = {0};
9317 if (frac >= 100) {
9318 snprintf(msg, 512, "%s: OK (%d %s) \n",
9319 action,tot, type.Data());
9320 } else {
9321 snprintf(msg, 512, "%s: %d out of %d (%d %%)\r",
9322 action, done, tot, frac);
9323 }
9324 if (fSync)
9325 fprintf(stderr,"%s", msg);
9326 else
9327 NotifyLogMsg(msg, 0);
9328 }
9329 return;
9330 }
9331
9334 mess << TString(action) << tot << done << st;
9335 gProofServ->GetSocket()->Send(mess);
9336 }
9337}
9338
9339////////////////////////////////////////////////////////////////////////////////
9340/// Notify availability of a query result.
9341
9342void TProof::QueryResultReady(const char *ref)
9343{
9344 PDB(kGlobal,1)
9345 Info("QueryResultReady","ref: %s", ref);
9346
9347 Emit("QueryResultReady(const char*)",ref);
9348}
9349
9350////////////////////////////////////////////////////////////////////////////////
9351/// Validate a TDSet.
9352
9354{
9355 if (dset->ElementsValid()) return;
9356
9357 TList nodes;
9358 nodes.SetOwner();
9359
9360 TList slholder;
9361 slholder.SetOwner();
9362 TList elemholder;
9363 elemholder.SetOwner();
9364
9365 // build nodelist with slaves and elements
9366 TIter nextSlave(GetListOfActiveSlaves());
9367 while (TSlave *sl = dynamic_cast<TSlave*>(nextSlave())) {
9368 TList *sllist = 0;
9369 TPair *p = dynamic_cast<TPair*>(nodes.FindObject(sl->GetName()));
9370 if (!p) {
9371 sllist = new TList;
9372 sllist->SetName(sl->GetName());
9373 slholder.Add(sllist);
9374 TList *elemlist = new TList;
9375 elemlist->SetName(TString(sl->GetName())+"_elem");
9376 elemholder.Add(elemlist);
9377 nodes.Add(new TPair(sllist, elemlist));
9378 } else {
9379 sllist = dynamic_cast<TList*>(p->Key());
9380 }
9381 if (sllist) sllist->Add(sl);
9382 }
9383
9384 // add local elements to nodes
9385 TList nonLocal; // list of nonlocal elements
9386 // make two iterations - first add local elements - then distribute nonlocals
9387 for (Int_t i = 0; i < 2; i++) {
9388 Bool_t local = i>0?kFALSE:kTRUE;
9389 TIter nextElem(local ? dset->GetListOfElements() : &nonLocal);
9390 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
9391 if (elem->GetValid()) continue;
9392 TPair *p = dynamic_cast<TPair*>(local?nodes.FindObject(TUrl(elem->GetFileName()).GetHost()):nodes.At(0));
9393 if (p) {
9394 TList *eli = dynamic_cast<TList*>(p->Value());
9395 TList *sli = dynamic_cast<TList*>(p->Key());
9396 if (eli && sli) {
9397 eli->Add(elem);
9398
9399 // order list by elements/slave
9400 TPair *p2 = p;
9401 Bool_t stop = kFALSE;
9402 while (!stop) {
9403 TPair *p3 = dynamic_cast<TPair*>(nodes.After(p2->Key()));
9404 if (p3) {
9405 TList *p3v = dynamic_cast<TList*>(p3->Value());
9406 TList *p3k = dynamic_cast<TList*>(p3->Key());
9407 if (p3v && p3k) {
9408 Int_t nelem = p3v->GetSize();
9409 Int_t nsl = p3k->GetSize();
9410 if (nelem*sli->GetSize() < eli->GetSize()*nsl) p2 = p3;
9411 else stop = kTRUE;
9412 }
9413 } else {
9414 stop = kTRUE;
9415 }
9416 }
9417
9418 if (p2!=p) {
9419 nodes.Remove(p->Key());
9420 nodes.AddAfter(p2->Key(), p);
9421 }
9422 } else {
9423 Warning("ValidateDSet", "invalid values from TPair! Protocol error?");
9424 continue;
9425 }
9426
9427 } else {
9428 if (local) {
9429 nonLocal.Add(elem);
9430 } else {
9431 Warning("ValidateDSet", "no node to allocate TDSetElement to - ignoring");
9432 }
9433 }
9434 }
9435 }
9436
9437 // send to slaves
9438 TList usedslaves;
9439 TIter nextNode(&nodes);
9440 SetDSet(dset); // set dset to be validated in Collect()
9441 while (TPair *node = dynamic_cast<TPair*>(nextNode())) {
9442 TList *slaves = dynamic_cast<TList*>(node->Key());
9443 TList *setelements = dynamic_cast<TList*>(node->Value());
9444 if (!slaves || !setelements) continue;
9445 // distribute elements over the slaves
9446 Int_t nslaves = slaves->GetSize();
9447 Int_t nelements = setelements->GetSize();
9448 for (Int_t i=0; i<nslaves; i++) {
9449
9450 TDSet copyset(dset->GetType(), dset->GetObjName(),
9451 dset->GetDirectory());
9452 for (Int_t j = (i*nelements)/nslaves;
9453 j < ((i+1)*nelements)/nslaves;
9454 j++) {
9455 TDSetElement *elem =
9456 dynamic_cast<TDSetElement*>(setelements->At(j));
9457 if (elem) {
9458 copyset.Add(elem->GetFileName(), elem->GetObjName(),
9459 elem->GetDirectory(), elem->GetFirst(),
9460 elem->GetNum(), elem->GetMsd());
9461 }
9462 }
9463
9464 if (copyset.GetListOfElements()->GetSize()>0) {
9466 mesg << &copyset;
9467
9468 TSlave *sl = dynamic_cast<TSlave*>(slaves->At(i));
9469 if (sl) {
9470 PDB(kGlobal,1) Info("ValidateDSet",
9471 "Sending TDSet with %d elements to slave %s"
9472 " to be validated",
9473 copyset.GetListOfElements()->GetSize(),
9474 sl->GetOrdinal());
9475 sl->GetSocket()->Send(mesg);
9476 usedslaves.Add(sl);
9477 }
9478 }
9479 }
9480 }
9481
9482 PDB(kGlobal,1)
9483 Info("ValidateDSet","Calling Collect");
9484 Collect(&usedslaves);
9485 SetDSet(0);
9486}
9487
9488////////////////////////////////////////////////////////////////////////////////
9489/// Add data objects that might be needed during the processing of
9490/// the selector (see Process()). This object can be very large, so they
9491/// are distributed in an optimized way using a dedicated file.
9492/// If push is TRUE the input data are sent over even if no apparent change
9493/// occured to the list.
9494
9496{
9497 if (obj) {
9498 if (!fInputData) fInputData = new TList;
9499 if (!fInputData->FindObject(obj)) {
9500 fInputData->Add(obj);
9502 }
9503 }
9504 if (push) SetBit(TProof::kNewInputData);
9505}
9506
9507////////////////////////////////////////////////////////////////////////////////
9508/// Remove obj form the input data list; if obj is null (default), clear the
9509/// input data info.
9510
9512{
9513 if (!obj) {
9514 if (fInputData) {
9517 }
9519
9520 // Also remove any info about input data in the input list
9521 TObject *o = 0;
9522 TList *in = GetInputList();
9523 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9524 in->Remove(o);
9525 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9526 in->Remove(o);
9527
9528 // ... and reset the file
9529 fInputDataFile = "";
9531
9532 } else if (fInputData) {
9533 Int_t sz = fInputData->GetSize();
9534 while (fInputData->FindObject(obj))
9535 fInputData->Remove(obj);
9536 // Flag for update, if anything changed
9537 if (sz != fInputData->GetSize())
9539 }
9540}
9541
9542////////////////////////////////////////////////////////////////////////////////
9543/// Remove obj 'name' form the input data list;
9544
9546{
9547 TObject *obj = (fInputData && name) ? fInputData->FindObject(name) : 0;
9548 if (obj) ClearInputData(obj);
9549}
9550
9551////////////////////////////////////////////////////////////////////////////////
9552/// Set the file to be used to optimally distribute the input data objects.
9553/// If the file exists the object in the file are added to those in the
9554/// fInputData list. If the file path is null, a default file will be created
9555/// at the moment of sending the processing request with the content of
9556/// the fInputData list. See also SendInputDataFile.
9557
9558void TProof::SetInputDataFile(const char *datafile)
9559{
9560 if (datafile && strlen(datafile) > 0) {
9561 if (fInputDataFile != datafile && strcmp(datafile, kPROOF_InputDataFile))
9563 fInputDataFile = datafile;
9564 } else {
9565 if (!fInputDataFile.IsNull())
9567 fInputDataFile = "";
9568 }
9569 // Make sure that the chosen file is readable
9572 fInputDataFile = "";
9573 }
9574}
9575
9576////////////////////////////////////////////////////////////////////////////////
9577/// Send the input data objects to the master; the objects are taken from the
9578/// dedicated list and / or the specified file.
9579/// If the fInputData is empty the specified file is sent over.
9580/// If there is no specified file, a file named "inputdata.root" is created locally
9581/// with the content of fInputData and sent over to the master.
9582/// If both fInputData and the specified file are not empty, a copy of the file
9583/// is made locally and augmented with the content of fInputData.
9584
9586{
9587 // Prepare the file
9588 TString dataFile;
9589 PrepareInputDataFile(dataFile);
9590
9591 // Send it, if not empty
9592 if (dataFile.Length() > 0) {
9593
9594 Info("SendInputDataFile", "broadcasting %s", dataFile.Data());
9595 BroadcastFile(dataFile.Data(), kBinary, "cache", kActive);
9596
9597 // Set the name in the input list
9598 TString t = TString::Format("cache:%s", gSystem->BaseName(dataFile));
9599 AddInput(new TNamed("PROOF_InputDataFile", t.Data()));
9600 }
9601}
9602
9603////////////////////////////////////////////////////////////////////////////////
9604/// Prepare the file with the input data objects to be sent the master; the
9605/// objects are taken from the dedicated list and / or the specified file.
9606/// If the fInputData is empty the specified file is sent over.
9607/// If there is no specified file, a file named "inputdata.root" is created locally
9608/// with the content of fInputData and sent over to the master.
9609/// If both fInputData and the specified file are not empty, a copy of the file
9610/// is made locally and augmented with the content of fInputData.
9611
9613{
9614 // Save info about new data for usage in this call;
9616 // Next time we need some change
9618
9619 // Check the list
9620 Bool_t list_ok = (fInputData && fInputData->GetSize() > 0) ? kTRUE : kFALSE;
9621 // Check the file
9622 Bool_t file_ok = kFALSE;
9625 // It must contain something
9627 if (f && f->GetListOfKeys() && f->GetListOfKeys()->GetSize() > 0)
9628 file_ok = kTRUE;
9629 }
9630
9631 // Remove any info about input data in the input list
9632 TObject *o = 0;
9633 TList *in = GetInputList();
9634 while ((o = GetInputList()->FindObject("PROOF_InputDataFile")))
9635 in->Remove(o);
9636 while ((o = GetInputList()->FindObject("PROOF_InputData")))
9637 in->Remove(o);
9638
9639 // We must have something to send
9640 dataFile = "";
9641 if (!list_ok && !file_ok) return;
9642
9643 // Three cases:
9644 if (file_ok && !list_ok) {
9645 // Just send the file
9646 dataFile = fInputDataFile;
9647 } else if (!file_ok && list_ok) {
9649 // Nothing to do, if no new data
9650 if (!newdata && !gSystem->AccessPathName(fInputDataFile)) return;
9651 // Create the file first
9652 TFile *f = TFile::Open(fInputDataFile, "RECREATE");
9653 if (f) {
9654 f->cd();
9655 TIter next(fInputData);
9656 TObject *obj;
9657 while ((obj = next())) {
9658 obj->Write(0, TObject::kSingleKey, 0);
9659 }
9660 f->Close();
9661 SafeDelete(f);
9662 } else {
9663 Error("PrepareInputDataFile", "could not (re-)create %s", fInputDataFile.Data());
9664 return;
9665 }
9666 dataFile = fInputDataFile;
9667 } else if (file_ok && list_ok) {
9668 dataFile = kPROOF_InputDataFile;
9669 // Create the file if not existing or there are new data
9670 if (newdata || gSystem->AccessPathName(dataFile)) {
9671 // Cleanup previous file if obsolete
9672 if (!gSystem->AccessPathName(dataFile))
9673 gSystem->Unlink(dataFile);
9674 if (dataFile != fInputDataFile) {
9675 // Make a local copy first
9676 if (gSystem->CopyFile(fInputDataFile, dataFile, kTRUE) != 0) {
9677 Error("PrepareInputDataFile", "could not make local copy of %s", fInputDataFile.Data());
9678 return;
9679 }
9680 }
9681 // Add the input data list
9682 TFile *f = TFile::Open(dataFile, "UPDATE");
9683 if (f) {
9684 f->cd();
9685 TIter next(fInputData);
9686 TObject *obj = 0;
9687 while ((obj = next())) {
9688 obj->Write(0, TObject::kSingleKey, 0);
9689 }
9690 f->Close();
9691 SafeDelete(f);
9692 } else {
9693 Error("PrepareInputDataFile", "could not open %s for updating", dataFile.Data());
9694 return;
9695 }
9696 }
9697 }
9698
9699 // Done
9700 return;
9701}
9702
9703////////////////////////////////////////////////////////////////////////////////
9704/// Add objects that might be needed during the processing of
9705/// the selector (see Process()).
9706
9708{
9709 if (fPlayer) fPlayer->AddInput(obj);
9710}
9711
9712////////////////////////////////////////////////////////////////////////////////
9713/// Clear input object list.
9714
9716{
9717 if (fPlayer) fPlayer->ClearInput();
9718
9719 // the system feedback list is always in the input list
9721}
9722
9723////////////////////////////////////////////////////////////////////////////////
9724/// Get input list.
9725
9727{
9728 return (fPlayer ? fPlayer->GetInputList() : (TList *)0);
9729}
9730
9731////////////////////////////////////////////////////////////////////////////////
9732/// Get specified object that has been produced during the processing
9733/// (see Process()).
9734
9736{
9737
9739 // Can be called by MarkBad on the master before the player is initialized
9740 return (fPlayer) ? fPlayer->GetOutput(name) : (TObject *)0;
9741
9742 // This checks also associated output files
9743 return (GetOutputList()) ? GetOutputList()->FindObject(name) : (TObject *)0;
9744}
9745
9746////////////////////////////////////////////////////////////////////////////////
9747/// Find object 'name' in list 'out' or in the files specified in there
9748
9750{
9751 TObject *o = 0;
9752 if (!name || (name && strlen(name) <= 0) ||
9753 !out || (out && out->GetSize() <= 0)) return o;
9754 if ((o = out->FindObject(name))) return o;
9755
9756 // For the time being we always check for all the files; this may require
9757 // some caching
9758 TProofOutputFile *pf = 0;
9759 TIter nxo(out);
9760 while ((o = nxo())) {
9761 if ((pf = dynamic_cast<TProofOutputFile *> (o))) {
9762 TFile *f = 0;
9763 if (!(f = (TFile *) gROOT->GetListOfFiles()->FindObject(pf->GetOutputFileName()))) {
9764 TString fn = TString::Format("%s/%s", pf->GetDir(), pf->GetFileName());
9765 f = TFile::Open(fn.Data());
9766 if (!f || (f && f->IsZombie())) {
9767 ::Warning("TProof::GetOutput", "problems opening file %s", fn.Data());
9768 }
9769 }
9770 if (f && (o = f->Get(name))) return o;
9771 }
9772 }
9773
9774 // Done, unsuccessfully
9775 return o;
9776}
9777
9778////////////////////////////////////////////////////////////////////////////////
9779/// Get list with all object created during processing (see Process()).
9780
9782{
9783 if (fOutputList.GetSize() > 0) return &fOutputList;
9784 if (fPlayer) {
9786 return &fOutputList;
9787 }
9788 return (TList *)0;
9789}
9790
9791////////////////////////////////////////////////////////////////////////////////
9792/// Set input list parameter. If the parameter is already
9793/// set it will be set to the new value.
9794
9795void TProof::SetParameter(const char *par, const char *value)
9796{
9797 if (!fPlayer) {
9798 Warning("SetParameter", "player undefined! Ignoring");
9799 return;
9800 }
9801
9802 TList *il = fPlayer->GetInputList();
9803 TObject *item = il->FindObject(par);
9804 if (item) {
9805 il->Remove(item);
9806 delete item;
9807 }
9808 il->Add(new TNamed(par, value));
9809}
9810
9811////////////////////////////////////////////////////////////////////////////////
9812/// Set an input list parameter.
9813
9814void TProof::SetParameter(const char *par, Int_t value)
9815{
9816 if (!fPlayer) {
9817 Warning("SetParameter", "player undefined! Ignoring");
9818 return;
9819 }
9820
9821 TList *il = fPlayer->GetInputList();
9822 TObject *item = il->FindObject(par);
9823 if (item) {
9824 il->Remove(item);
9825 delete item;
9826 }
9827 il->Add(new TParameter<Int_t>(par, value));
9828}
9829
9830////////////////////////////////////////////////////////////////////////////////
9831/// Set an input list parameter.
9832
9833void TProof::SetParameter(const char *par, Long_t value)
9834{
9835 if (!fPlayer) {
9836 Warning("SetParameter", "player undefined! Ignoring");
9837 return;
9838 }
9839
9840 TList *il = fPlayer->GetInputList();
9841 TObject *item = il->FindObject(par);
9842 if (item) {
9843 il->Remove(item);
9844 delete item;
9845 }
9846 il->Add(new TParameter<Long_t>(par, value));
9847}
9848
9849////////////////////////////////////////////////////////////////////////////////
9850/// Set an input list parameter.
9851
9852void TProof::SetParameter(const char *par, Long64_t value)
9853{
9854 if (!fPlayer) {
9855 Warning("SetParameter", "player undefined! Ignoring");
9856 return;
9857 }
9858
9859 TList *il = fPlayer->GetInputList();
9860 TObject *item = il->FindObject(par);
9861 if (item) {
9862 il->Remove(item);
9863 delete item;
9864 }
9865 il->Add(new TParameter<Long64_t>(par, value));
9866}
9867
9868////////////////////////////////////////////////////////////////////////////////
9869/// Set an input list parameter.
9870
9871void TProof::SetParameter(const char *par, Double_t value)
9872{
9873 if (!fPlayer) {
9874 Warning("SetParameter", "player undefined! Ignoring");
9875 return;
9876 }
9877
9878 TList *il = fPlayer->GetInputList();
9879 TObject *item = il->FindObject(par);
9880 if (item) {
9881 il->Remove(item);
9882 delete item;
9883 }
9884 il->Add(new TParameter<Double_t>(par, value));
9885}
9886
9887////////////////////////////////////////////////////////////////////////////////
9888/// Get specified parameter. A parameter set via SetParameter() is either
9889/// a TParameter or a TNamed or 0 in case par is not defined.
9890
9891TObject *TProof::GetParameter(const char *par) const
9892{
9893 if (!fPlayer) {
9894 Warning("GetParameter", "player undefined! Ignoring");
9895 return (TObject *)0;
9896 }
9897
9898 TList *il = fPlayer->GetInputList();
9899 return il->FindObject(par);
9900}
9901
9902////////////////////////////////////////////////////////////////////////////////
9903/// Delete the input list parameters specified by a wildcard (e.g. PROOF_*)
9904/// or exact name (e.g. PROOF_MaxSlavesPerNode).
9905
9906void TProof::DeleteParameters(const char *wildcard)
9907{
9908 if (!fPlayer) return;
9909
9910 if (!wildcard) wildcard = "";
9911 TRegexp re(wildcard, kTRUE);
9912 Int_t nch = strlen(wildcard);
9913
9914 TList *il = fPlayer->GetInputList();
9915 if (il) {
9916 TObject *p = 0;
9917 TIter next(il);
9918 while ((p = next())) {
9919 TString s = p->GetName();
9920 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9921 il->Remove(p);
9922 delete p;
9923 }
9924 }
9925}
9926
9927////////////////////////////////////////////////////////////////////////////////
9928/// Show the input list parameters specified by the wildcard.
9929/// Default is the special PROOF control parameters (PROOF_*).
9930
9931void TProof::ShowParameters(const char *wildcard) const
9932{
9933 if (!fPlayer) return;
9934
9935 if (!wildcard) wildcard = "";
9936 TRegexp re(wildcard, kTRUE);
9937 Int_t nch = strlen(wildcard);
9938
9939 TList *il = fPlayer->GetInputList();
9940 TObject *p;
9941 TIter next(il);
9942 while ((p = next())) {
9943 TString s = p->GetName();
9944 if (nch && s != wildcard && s.Index(re) == kNPOS) continue;
9945 if (p->IsA() == TNamed::Class()) {
9946 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9947 } else if (p->IsA() == TParameter<Long_t>::Class()) {
9948 Printf("%s\t\t\t%ld", s.Data(), dynamic_cast<TParameter<Long_t>*>(p)->GetVal());
9949 } else if (p->IsA() == TParameter<Long64_t>::Class()) {
9950 Printf("%s\t\t\t%lld", s.Data(), dynamic_cast<TParameter<Long64_t>*>(p)->GetVal());
9951 } else if (p->IsA() == TParameter<Double_t>::Class()) {
9952 Printf("%s\t\t\t%f", s.Data(), dynamic_cast<TParameter<Double_t>*>(p)->GetVal());
9953 } else {
9954 Printf("%s\t\t\t%s", s.Data(), p->GetTitle());
9955 }
9956 }
9957}
9958
9959////////////////////////////////////////////////////////////////////////////////
9960/// Add object to feedback list.
9961
9962void TProof::AddFeedback(const char *name)
9963{
9964 PDB(kFeedback, 3)
9965 Info("AddFeedback", "Adding object \"%s\" to feedback", name);
9966 if (fFeedback->FindObject(name) == 0)
9968}
9969
9970////////////////////////////////////////////////////////////////////////////////
9971/// Remove object from feedback list.
9972
9974{
9976 if (obj != 0) {
9977 fFeedback->Remove(obj);
9978 delete obj;
9979 }
9980}
9981
9982////////////////////////////////////////////////////////////////////////////////
9983/// Clear feedback list.
9984
9986{
9987 fFeedback->Delete();
9988}
9989
9990////////////////////////////////////////////////////////////////////////////////
9991/// Show items in feedback list.
9992
9994{
9995 if (fFeedback->GetSize() == 0) {
9996 Info("","no feedback requested");
9997 return;
9998 }
9999
10000 fFeedback->Print();
10001}
10002
10003////////////////////////////////////////////////////////////////////////////////
10004/// Return feedback list.
10005
10007{
10008 return fFeedback;
10009}
10010
10011////////////////////////////////////////////////////////////////////////////////
10012/// Creates a tree header (a tree with nonexisting files) object for
10013/// the DataSet.
10014
10016{
10018 TSlave *sl = (TSlave*) l->First();
10019 if (sl == 0) {
10020 Error("GetTreeHeader", "No connection");
10021 return 0;
10022 }
10023
10024 TSocket *soc = sl->GetSocket();
10026
10027 msg << dset;
10028
10029 soc->Send(msg);
10030
10031 TMessage *reply;
10032 Int_t d = -1;
10033 if (fProtocol >= 20) {
10035 reply = (TMessage *) fRecvMessages->First();
10036 } else {
10037 d = soc->Recv(reply);
10038 }
10039 if (!reply) {
10040 Error("GetTreeHeader", "Error getting a replay from the master.Result %d", (int) d);
10041 return 0;
10042 }
10043
10044 TString s1;
10045 TTree *t = 0;
10046 (*reply) >> s1;
10047 if (s1 == "Success")
10048 (*reply) >> t;
10049
10050 PDB(kGlobal, 1) {
10051 if (t) {
10052 Info("GetTreeHeader", "%s, message size: %d, entries: %d",
10053 s1.Data(), reply->BufferSize(), (int) t->GetMaxEntryLoop());
10054 } else {
10055 Info("GetTreeHeader", "tree header retrieval failed");
10056 }
10057 }
10058 delete reply;
10059
10060 return t;
10061}
10062
10063////////////////////////////////////////////////////////////////////////////////
10064/// Draw feedback creation proxy. When accessed via TProof avoids
10065/// link dependency on libProofPlayer.
10066
10068{
10069 return (fPlayer ? fPlayer->CreateDrawFeedback(this) : (TDrawFeedback *)0);
10070}
10071
10072////////////////////////////////////////////////////////////////////////////////
10073/// Set draw feedback option.
10074
10076{
10078}
10079
10080////////////////////////////////////////////////////////////////////////////////
10081/// Delete draw feedback object.
10082
10084{
10086}
10087
10088////////////////////////////////////////////////////////////////////////////////
10089/// FIXME: to be written
10090
10092{
10093 return 0;
10094/*
10095 TMessage msg(kPROOF_GETOUTPUTLIST);
10096 TList* slaves = fActiveSlaves;
10097 Broadcast(msg, slaves);
10098 TMonitor mon;
10099 TList* outputList = new TList();
10100
10101 TIter si(slaves);
10102 TSlave *slave;
10103 while ((slave = (TSlave*)si.Next()) != 0) {
10104 PDB(kGlobal,4) Info("GetOutputNames","Socket added to monitor: %p (%s)",
10105 slave->GetSocket(), slave->GetName());
10106 mon.Add(slave->GetSocket());
10107 }
10108 mon.ActivateAll();
10109 ((TProof*)gProof)->DeActivateAsyncInput();
10110 ((TProof*)gProof)->fCurrentMonitor = &mon;
10111
10112 while (mon.GetActive() != 0) {
10113 TSocket *sock = mon.Select();
10114 if (!sock) {
10115 Error("GetOutputList","TMonitor::.Select failed!");
10116 break;
10117 }
10118 mon.DeActivate(sock);
10119 TMessage *reply;
10120 if (sock->Recv(reply) <= 0) {
10121 MarkBad(slave, "receive failed after kPROOF_GETOUTPUTLIST request");
10122// Error("GetOutputList","Recv failed! for slave-%d (%s)",
10123// slave->GetOrdinal(), slave->GetName());
10124 continue;
10125 }
10126 if (reply->What() != kPROOF_GETOUTPUTNAMES ) {
10127// Error("GetOutputList","unexpected message %d from slawe-%d (%s)", reply->What(),
10128// slave->GetOrdinal(), slave->GetName());
10129 MarkBad(slave, "wrong reply to kPROOF_GETOUTPUTLIST request");
10130 continue;
10131 }
10132 TList* l;
10133
10134 (*reply) >> l;
10135 TIter next(l);
10136 TNamed *n;
10137 while ( (n = dynamic_cast<TNamed*> (next())) ) {
10138 if (!outputList->FindObject(n->GetName()))
10139 outputList->Add(n);
10140 }
10141 delete reply;
10142 }
10143 ((TProof*)gProof)->fCurrentMonitor = 0;
10144
10145 return outputList;
10146*/
10147}
10148
10149////////////////////////////////////////////////////////////////////////////////
10150/// Build the PROOF's structure in the browser.
10151
10153{
10154 b->Add(fActiveSlaves, fActiveSlaves->Class(), "fActiveSlaves");
10155 b->Add(&fMaster, fMaster.Class(), "fMaster");
10156 b->Add(fFeedback, fFeedback->Class(), "fFeedback");
10157 b->Add(fChains, fChains->Class(), "fChains");
10158
10159 if (fPlayer) {
10160 b->Add(fPlayer->GetInputList(), fPlayer->GetInputList()->Class(), "InputList");
10161 if (fPlayer->GetOutputList())
10162 b->Add(fPlayer->GetOutputList(), fPlayer->GetOutputList()->Class(), "OutputList");
10164 b->Add(fPlayer->GetListOfResults(),
10165 fPlayer->GetListOfResults()->Class(), "ListOfResults");
10166 }
10167}
10168
10169////////////////////////////////////////////////////////////////////////////////
10170/// Set a new PROOF player.
10171
10173{
10174 if (fPlayer)
10175 delete fPlayer;
10176 fPlayer = player;
10177};
10178
10179////////////////////////////////////////////////////////////////////////////////
10180/// Construct a TProofPlayer object. The player string specifies which
10181/// player should be created: remote, slave, sm (supermaster) or base.
10182/// Default is remote. Socket is needed in case a slave player is created.
10183
10185{
10186 if (!player)
10187 player = "remote";
10188
10189 SetPlayer(TVirtualProofPlayer::Create(player, this, s));
10190 return GetPlayer();
10191}
10192
10193////////////////////////////////////////////////////////////////////////////////
10194/// Add chain to data set
10195
10197{
10198 fChains->Add(chain);
10199}
10200
10201////////////////////////////////////////////////////////////////////////////////
10202/// Remove chain from data set
10203
10205{
10206 fChains->Remove(chain);
10207}
10208
10209////////////////////////////////////////////////////////////////////////////////
10210/// Ask for remote logs in the range [start, end]. If start == -1 all the
10211/// messages not yet received are sent back.
10212
10214{
10215 if (!IsValid() || TestBit(TProof::kIsMaster)) return;
10216
10218
10219 msg << start << end;
10220
10221 Broadcast(msg, kActive);
10223}
10224
10225////////////////////////////////////////////////////////////////////////////////
10226/// Fill a TMacro with the log lines since the last reading (fLogFileR)
10227/// Return (TMacro *)0 if no line was logged.
10228/// The returned TMacro must be deleted by the caller.
10229
10231{
10232 TMacro *maclog = 0;
10233
10234 // Save present offset
10235 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10236 if (nowlog < 0) {
10237 SysError("GetLastLog",
10238 "problem lseeking log file to current position (errno: %d)", TSystem::GetErrno());
10239 return maclog;
10240 }
10241
10242 // Get extremes
10243 off_t startlog = nowlog;
10244 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10245 if (endlog < 0) {
10246 SysError("GetLastLog",
10247 "problem lseeking log file to end position (errno: %d)", TSystem::GetErrno());
10248 return maclog;
10249 }
10250
10251 // Perhaps nothing to log
10252 UInt_t tolog = (UInt_t)(endlog - startlog);
10253 if (tolog <= 0) return maclog;
10254
10255 // Set starting point
10256 if (lseek(fileno(fLogFileR), startlog, SEEK_SET) < 0) {
10257 SysError("GetLastLog",
10258 "problem lseeking log file to start position (errno: %d)", TSystem::GetErrno());
10259 return maclog;
10260 }
10261
10262 // Create the output object
10263 maclog = new TMacro;
10264
10265 // Now we go
10266 char line[2048];
10267 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10268 while (fgets(line, wanted, fLogFileR)) {
10269 Int_t r = strlen(line);
10270 if (r > 0) {
10271 if (line[r-1] == '\n') line[r-1] = '\0';
10272 maclog->AddLine(line);
10273 } else {
10274 // Done
10275 break;
10276 }
10277 tolog -= r;
10278 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10279 }
10280
10281 // Restore original pointer
10282 if (lseek(fileno(fLogFileR), nowlog, SEEK_SET) < 0) {
10283 Warning("GetLastLog",
10284 "problem lseeking log file to original position (errno: %d)", TSystem::GetErrno());
10285 }
10286
10287 // Done
10288 return maclog;
10289}
10290
10291////////////////////////////////////////////////////////////////////////////////
10292/// Display log of query pq into the log window frame
10293
10295{
10296 if (!pq) return;
10297
10298 TList *lines = pq->GetLogFile()->GetListOfLines();
10299 if (lines) {
10300 TIter nxl(lines);
10301 TObjString *l = 0;
10302 while ((l = (TObjString *)nxl()))
10303 EmitVA("LogMessage(const char*,Bool_t)", 2, l->GetName(), kFALSE);
10304 }
10305}
10306
10307////////////////////////////////////////////////////////////////////////////////
10308/// Display on screen the content of the temporary log file for query
10309/// in reference
10310
10311void TProof::ShowLog(const char *queryref)
10312{
10313 // Make sure we have all info (GetListOfQueries retrieves the
10314 // head info only)
10315 Retrieve(queryref);
10316
10317 if (fPlayer) {
10318 if (queryref) {
10319 if (fPlayer->GetListOfResults()) {
10321 TQueryResult *qr = 0;
10322 while ((qr = (TQueryResult *) nxq()))
10323 if (strstr(queryref, qr->GetTitle()) &&
10324 strstr(queryref, qr->GetName()))
10325 break;
10326 if (qr) {
10327 PutLog(qr);
10328 return;
10329 }
10330
10331 }
10332 }
10333 }
10334}
10335
10336////////////////////////////////////////////////////////////////////////////////
10337/// Display on screen the content of the temporary log file.
10338/// If qry == -2 show messages from the last (current) query.
10339/// If qry == -1 all the messages not yet displayed are shown (default).
10340/// If qry == 0, all the messages in the file are shown.
10341/// If qry > 0, only the messages related to query 'qry' are shown.
10342/// For qry != -1 the original file offset is restored at the end
10343
10345{
10346 // Save present offset
10347 off_t nowlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_CUR);
10348 if (nowlog < 0) {
10349 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10350 return;
10351 }
10352
10353 // Get extremes
10354 off_t startlog = nowlog;
10355 off_t endlog = lseek(fileno(fLogFileR), (off_t) 0, SEEK_END);
10356 if (endlog < 0) {
10357 SysError("ShowLog", "problem lseeking log file (errno: %d)", TSystem::GetErrno());
10358 return;
10359 }
10360
10361 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10362 if (qry == 0) {
10363 startlog = 0;
10364 lseek(fileno(fLogFileR), (off_t) 0, SEEK_SET);
10365 } else if (qry != -1) {
10366
10367 TQueryResult *pq = 0;
10368 if (qry == -2) {
10369 // Pickup the last one
10370 pq = (GetQueryResults()) ? ((TQueryResult *)(GetQueryResults()->Last())) : 0;
10371 if (!pq) {
10373 if (fQueries)
10374 pq = (TQueryResult *)(fQueries->Last());
10375 }
10376 } else if (qry > 0) {
10377 TList *queries = GetQueryResults();
10378 if (queries) {
10379 TIter nxq(queries);
10380 while ((pq = (TQueryResult *)nxq()))
10381 if (qry == pq->GetSeqNum())
10382 break;
10383 }
10384 if (!pq) {
10385 queries = GetListOfQueries();
10386 TIter nxq(queries);
10387 while ((pq = (TQueryResult *)nxq()))
10388 if (qry == pq->GetSeqNum())
10389 break;
10390 }
10391 }
10392 if (pq) {
10393 PutLog(pq);
10394 return;
10395 } else {
10396 if (gDebug > 0)
10397 Info("ShowLog","query %d not found in list", qry);
10398 qry = -1;
10399 }
10400 }
10401
10402 // Number of bytes to log
10403 UInt_t tolog = (UInt_t)(endlog - startlog);
10404
10405 // Perhaps nothing
10406 if (tolog <= 0) {
10407 // Set starting point
10408 lseek(fileno(fLogFileR), startlog, SEEK_SET);
10409 }
10410
10411 // Now we go
10412 Int_t np = 0;
10413 char line[2048];
10414 Int_t wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10415 while (fgets(line, wanted, fLogFileR)) {
10416
10417 Int_t r = strlen(line);
10418 if (!SendingLogToWindow()) {
10419 if (line[r-1] != '\n') line[r-1] = '\n';
10420 if (r > 0) {
10421 char *p = line;
10422 while (r) {
10423 Int_t w = write(fileno(stdout), p, r);
10424 if (w < 0) {
10425 SysError("ShowLog", "error writing to stdout");
10426 break;
10427 }
10428 r -= w;
10429 p += w;
10430 }
10431 }
10432 tolog -= strlen(line);
10433 np++;
10434
10435 // Ask if more is wanted
10436 if (!(np%10)) {
10437 const char *opt = Getline("More (y/n)? [y]");
10438 if (opt[0] == 'n')
10439 break;
10440 }
10441
10442 // We may be over
10443 if (tolog <= 0)
10444 break;
10445
10446 // Update wanted bytes
10447 wanted = (tolog > sizeof(line)) ? sizeof(line) : tolog;
10448 } else {
10449 // Log to window
10450 if (line[r-1] == '\n') line[r-1] = 0;
10452 }
10453 }
10454 if (!SendingLogToWindow()) {
10455 // Avoid screwing up the prompt
10456 if (write(fileno(stdout), "\n", 1) != 1)
10457 SysError("ShowLog", "error writing to stdout");
10458 }
10459
10460 // Restore original pointer
10461 if (qry > -1)
10462 lseek(fileno(fLogFileR), nowlog, SEEK_SET);
10463}
10464
10465////////////////////////////////////////////////////////////////////////////////
10466/// Set session with 'id' the default one. If 'id' is not found in the list,
10467/// the current session is set as default
10468
10470{
10471 if (GetManager()) {
10473 if (d) {
10474 if (d->GetProof()) {
10475 gProof = d->GetProof();
10476 return;
10477 }
10478 }
10479
10480 // Id not found or undefined: set as default this session
10481 gProof = this;
10482 }
10483
10484 return;
10485}
10486
10487////////////////////////////////////////////////////////////////////////////////
10488/// Detach this instance to its proofserv.
10489/// If opt is 'S' or 's' the remote server is shutdown
10490
10492{
10493 // Nothing to do if not in contact with proofserv
10494 if (!IsValid()) return;
10495
10496 // Get worker and socket instances
10497 TSlave *sl = (TSlave *) fActiveSlaves->First();
10498 TSocket *s = 0;
10499 if (!sl || !(sl->IsValid()) || !(s = sl->GetSocket())) {
10500 Error("Detach","corrupted worker instance: wrk:%p, sock:%p", sl, s);
10501 return;
10502 }
10503
10504 Bool_t shutdown = (strchr(opt,'s') || strchr(opt,'S')) ? kTRUE : kFALSE;
10505
10506 // If processing, try to stop processing first
10507 if (shutdown && !IsIdle()) {
10508 // Remove pending requests
10509 Remove("cleanupqueue");
10510 // Do not wait for ever, but al least 20 seconds
10511 Long_t timeout = gEnv->GetValue("Proof.ShutdownTimeout", 60);
10512 timeout = (timeout > 20) ? timeout : 20;
10513 // Send stop signal
10514 StopProcess(kFALSE, (Long_t) (timeout / 2));
10515 // Receive results
10516 Collect(kActive, timeout);
10517 }
10518
10519 // Avoid spurious messages: deactivate new inputs ...
10521
10522 // ... and discard existing ones
10523 sl->FlushSocket();
10524
10525 // Close session (we always close the connection)
10526 Close(opt);
10527
10528 // Close the progress dialog, if any
10531
10532 // Update info in the table of our manager, if any
10533 if (GetManager() && GetManager()->QuerySessions("L")) {
10534 TIter nxd(GetManager()->QuerySessions("L"));
10535 TProofDesc *d = 0;
10536 while ((d = (TProofDesc *)nxd())) {
10537 if (d->GetProof() == this) {
10538 d->SetProof(0);
10539 GetManager()->QuerySessions("L")->Remove(d);
10540 break;
10541 }
10542 }
10543 }
10544
10545 // Invalidate this instance
10546 fValid = kFALSE;
10547
10548 return;
10549}
10550
10551////////////////////////////////////////////////////////////////////////////////
10552/// Set an alias for this session. If reconnection is supported, the alias
10553/// will be communicated to the remote coordinator so that it can be recovered
10554/// when reconnecting
10555
10556void TProof::SetAlias(const char *alias)
10557{
10558 // Set it locally
10559 TNamed::SetTitle(alias);
10561 // Set the name at the same value
10562 TNamed::SetName(alias);
10563
10564 // Nothing to do if not in contact with coordinator
10565 if (!IsValid()) return;
10566
10567 if (!IsProofd() && TestBit(TProof::kIsClient)) {
10568 TSlave *sl = (TSlave *) fActiveSlaves->First();
10569 if (sl)
10570 sl->SetAlias(alias);
10571 }
10572
10573 return;
10574}
10575
10576////////////////////////////////////////////////////////////////////////////////
10577/// *** This function is deprecated and will disappear in future versions ***
10578/// *** It is just a wrapper around TFile::Cp.
10579/// *** Please use TProofMgr::UploadFiles.
10580///
10581/// Upload a set of files and save the list of files by name dataSetName.
10582/// The 'files' argument is a list of TFileInfo objects describing the files
10583/// as first url.
10584/// The mask 'opt' is a combination of EUploadOpt:
10585/// kAppend (0x1) if set true files will be appended to
10586/// the dataset existing by given name
10587/// kOverwriteDataSet (0x2) if dataset with given name exited it
10588/// would be overwritten
10589/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10590/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10591/// kOverwriteNoFiles (0x10) overwrite none
10592/// kAskUser (0x0) ask user before overwriteng dataset/files
10593/// The default value is kAskUser.
10594/// The user will be asked to confirm overwriting dataset or files unless
10595/// specified opt provides the answer!
10596/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10597/// skippedFiles argument. The function will add to this list TFileInfo
10598/// objects describing all files that existed on the cluster and were
10599/// not uploaded.
10600///
10601/// Communication Summary
10602/// Client Master
10603/// |------------>DataSetName----------->|
10604/// |<-------kMESS_OK/kMESS_NOTOK<-------| (Name OK/file exist)
10605/// (*)|-------> call RegisterDataSet ------->|
10606/// (*) - optional
10607
10608Int_t TProof::UploadDataSet(const char *, TList *, const char *, Int_t, TList *)
10609{
10610 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10611
10612 return -1;
10613}
10614
10615////////////////////////////////////////////////////////////////////////////////
10616/// *** This function is deprecated and will disappear in future versions ***
10617/// *** It is just a wrapper around TFile::Cp.
10618/// *** Please use TProofMgr::UploadFiles.
10619///
10620/// Upload a set of files and save the list of files by name dataSetName.
10621/// The mask 'opt' is a combination of EUploadOpt:
10622/// kAppend (0x1) if set true files will be appended to
10623/// the dataset existing by given name
10624/// kOverwriteDataSet (0x2) if dataset with given name exited it
10625/// would be overwritten
10626/// kNoOverwriteDataSet (0x4) do not overwirte if the dataset exists
10627/// kOverwriteAllFiles (0x8) overwrite all files that may exist
10628/// kOverwriteNoFiles (0x10) overwrite none
10629/// kAskUser (0x0) ask user before overwriteng dataset/files
10630/// The default value is kAskUser.
10631/// The user will be asked to confirm overwriting dataset or files unless
10632/// specified opt provides the answer!
10633/// If kOverwriteNoFiles is set, then a pointer to TList must be passed as
10634/// skippedFiles argument. The function will add to this list TFileInfo
10635/// objects describing all files that existed on the cluster and were
10636/// not uploaded.
10637///
10638
10639Int_t TProof::UploadDataSet(const char *, const char *, const char *, Int_t, TList *)
10640{
10641 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10642
10643 return -1;
10644}
10645
10646////////////////////////////////////////////////////////////////////////////////
10647/// *** This function is deprecated and will disappear in future versions ***
10648/// *** It is just a wrapper around TFile::Cp.
10649/// *** Please use TProofMgr::UploadFiles.
10650///
10651/// Upload files listed in "file" to PROOF cluster.
10652/// Where file = name of file containing list of files and
10653/// dataset = dataset name and opt is a combination of EUploadOpt bits.
10654/// Each file description (line) can include wildcards.
10655/// Check TFileInfo compatibility
10656
10657Int_t TProof::UploadDataSetFromFile(const char *, const char *, const char *, Int_t, TList *)
10658{
10659 Printf(" *** WARNING: this function is obsolete: it has been replaced by TProofMgr::UploadFiles ***");
10660
10661 // Done
10662 return -1;
10663}
10664
10665////////////////////////////////////////////////////////////////////////////////
10666/// Register the 'dataSet' on the cluster under the current
10667/// user, group and the given 'dataSetName'.
10668/// If a dataset with the same name already exists the action fails unless 'opts'
10669/// contains 'O', in which case the old dataset is overwritten, or contains 'U',
10670/// in which case 'newDataSet' is added to the existing dataset (duplications are
10671/// ignored, if any).
10672/// If 'opts' contains 'V' the dataset files are also verified (if the dataset manager
10673/// is configured to allow so). By default the dataset is not verified.
10674/// If 'opts' contains 'T' the in the dataset object (status bits, meta,...)
10675/// is trusted, i.e. not reset (if the dataset manager is configured to allow so).
10676/// If 'opts' contains 'S' validation would be run serially (meaningful only if
10677/// validation is required).
10678/// Returns kTRUE on success.
10679
10680Bool_t TProof::RegisterDataSet(const char *dataSetName,
10681 TFileCollection *dataSet, const char *optStr)
10682{
10683 // Check TFileInfo compatibility
10684 if (fProtocol < 17) {
10685 Info("RegisterDataSet",
10686 "functionality not available: the server does not have dataset support");
10687 return kFALSE;
10688 }
10689
10690 if (!dataSetName || strlen(dataSetName) <= 0) {
10691 Info("RegisterDataSet", "specifying a dataset name is mandatory");
10692 return kFALSE;
10693 }
10694
10695 Bool_t parallelverify = kFALSE;
10696 TString sopt(optStr);
10697 if (sopt.Contains("V") && fProtocol >= 34 && !sopt.Contains("S")) {
10698 // We do verification in parallel later on; just register for now
10699 parallelverify = kTRUE;
10700 sopt.ReplaceAll("V", "");
10701 }
10702 // This would screw up things remotely, make sure is not there
10703 sopt.ReplaceAll("S", "");
10704
10706 mess << Int_t(kRegisterDataSet);
10707 mess << TString(dataSetName);
10708 mess << sopt;
10709 mess.WriteObject(dataSet);
10710 Broadcast(mess);
10711
10712 Bool_t result = kTRUE;
10713 Collect();
10714 if (fStatus != 0) {
10715 Error("RegisterDataSet", "dataset was not saved");
10716 result = kFALSE;
10717 return result;
10718 }
10719
10720 // If old server or not verifying in parallel we are done
10721 if (!parallelverify) return result;
10722
10723 // If we are here it means that we will verify in parallel
10724 sopt += "V";
10725 if (VerifyDataSet(dataSetName, sopt) < 0){
10726 Error("RegisterDataSet", "problems verifying dataset '%s'", dataSetName);
10727 return kFALSE;
10728 }
10729
10730 // We are done
10731 return kTRUE;
10732}
10733
10734////////////////////////////////////////////////////////////////////////////////
10735/// Set/Change the name of the default tree. The tree name may contain
10736/// subdir specification in the form "subdir/name".
10737/// Returns 0 on success, -1 otherwise.
10738
10739Int_t TProof::SetDataSetTreeName(const char *dataset, const char *treename)
10740{
10741 // Check TFileInfo compatibility
10742 if (fProtocol < 23) {
10743 Info("SetDataSetTreeName", "functionality not supported by the server");
10744 return -1;
10745 }
10746
10747 if (!dataset || strlen(dataset) <= 0) {
10748 Info("SetDataSetTreeName", "specifying a dataset name is mandatory");
10749 return -1;
10750 }
10751
10752 if (!treename || strlen(treename) <= 0) {
10753 Info("SetDataSetTreeName", "specifying a tree name is mandatory");
10754 return -1;
10755 }
10756
10757 TUri uri(dataset);
10758 TString fragment(treename);
10759 if (!fragment.BeginsWith("/")) fragment.Insert(0, "/");
10760 uri.SetFragment(fragment);
10761
10763 mess << Int_t(kSetDefaultTreeName);
10764 mess << uri.GetUri();
10765 Broadcast(mess);
10766
10767 Collect();
10768 if (fStatus != 0) {
10769 Error("SetDataSetTreeName", "some error occured: default tree name not changed");
10770 return -1;
10771 }
10772 return 0;
10773}
10774
10775////////////////////////////////////////////////////////////////////////////////
10776/// Lists all datasets that match given uri.
10777/// The 'optStr' can contain a comma-separated list of servers for which the
10778/// information is wanted. If ':lite:' (case insensitive) is specified in 'optStr'
10779/// only the global information in the TFileCollection is retrieved; useful to only
10780/// get the list of available datasets.
10781
10782TMap *TProof::GetDataSets(const char *uri, const char *optStr)
10783{
10784 if (fProtocol < 15) {
10785 Info("GetDataSets",
10786 "functionality not available: the server does not have dataset support");
10787 return 0;
10788 }
10789 if (fProtocol < 31 && strstr(optStr, ":lite:"))
10790 Warning("GetDataSets", "'lite' option not supported by the server");
10791
10793 mess << Int_t(kGetDataSets);
10794 mess << TString(uri ? uri : "");
10795 mess << TString(optStr ? optStr : "");
10796 Broadcast(mess);
10798
10799 TMap *dataSetMap = 0;
10800 if (fStatus != 0) {
10801 Error("GetDataSets", "error receiving datasets information");
10802 } else {
10803 // Look in the list
10804 TMessage *retMess = (TMessage *) fRecvMessages->First();
10805 if (retMess && retMess->What() == kMESS_OK) {
10806 if (!(dataSetMap = (TMap *)(retMess->ReadObject(TMap::Class()))))
10807 Error("GetDataSets", "error receiving datasets");
10808 } else
10809 Error("GetDataSets", "message not found or wrong type (%p)", retMess);
10810 }
10811
10812 return dataSetMap;
10813}
10814
10815////////////////////////////////////////////////////////////////////////////////
10816/// Shows datasets in locations that match the uri.
10817/// By default shows the user's datasets and global ones
10818
10819void TProof::ShowDataSets(const char *uri, const char* optStr)
10820{
10821 if (fProtocol < 15) {
10822 Info("ShowDataSets",
10823 "functionality not available: the server does not have dataset support");
10824 return;
10825 }
10826
10828 mess << Int_t(kShowDataSets);
10829 mess << TString(uri ? uri : "");
10830 mess << TString(optStr ? optStr : "");
10831 Broadcast(mess);
10832
10834 if (fStatus != 0)
10835 Error("ShowDataSets", "error receiving datasets information");
10836}
10837
10838////////////////////////////////////////////////////////////////////////////////
10839/// Returns kTRUE if 'dataset' exists, kFALSE otherwise
10840
10841Bool_t TProof::ExistsDataSet(const char *dataset)
10842{
10843 if (fProtocol < 15) {
10844 Info("ExistsDataSet", "functionality not available: the server has an"
10845 " incompatible version of TFileInfo");
10846 return kFALSE;
10847 }
10848
10849 if (!dataset || strlen(dataset) <= 0) {
10850 Error("ExistsDataSet", "dataset name missing");
10851 return kFALSE;
10852 }
10853
10855 msg << Int_t(kCheckDataSetName) << TString(dataset);
10856 Broadcast(msg);
10858 if (fStatus == -1) {
10859 // The dataset exists
10860 return kTRUE;
10861 }
10862 // The dataset does not exists
10863 return kFALSE;
10864}
10865
10866////////////////////////////////////////////////////////////////////////////////
10867/// Clear the content of the dataset cache, if any (matching 'dataset', if defined).
10868
10869void TProof::ClearDataSetCache(const char *dataset)
10870{
10871 if (fProtocol < 28) {
10872 Info("ClearDataSetCache", "functionality not available on server");
10873 return;
10874 }
10875
10877 msg << Int_t(kCache) << TString(dataset) << TString("clear");
10878 Broadcast(msg);
10880 // Done
10881 return;
10882}
10883
10884////////////////////////////////////////////////////////////////////////////////
10885/// Display the content of the dataset cache, if any (matching 'dataset', if defined).
10886
10887void TProof::ShowDataSetCache(const char *dataset)
10888{
10889 if (fProtocol < 28) {
10890 Info("ShowDataSetCache", "functionality not available on server");
10891 return;
10892 }
10893
10895 msg << Int_t(kCache) << TString(dataset) << TString("show");
10896 Broadcast(msg);
10898 // Done
10899 return;
10900}
10901
10902////////////////////////////////////////////////////////////////////////////////
10903/// Get a list of TFileInfo objects describing the files of the specified
10904/// dataset.
10905/// To get the short version (containing only the global meta information)
10906/// specify optStr = "S:" or optStr = "short:".
10907/// To get the sub-dataset of files located on a given server(s) specify
10908/// the list of servers (comma-separated) in the 'optStr' field.
10909
10910TFileCollection *TProof::GetDataSet(const char *uri, const char *optStr)
10911{
10912 if (fProtocol < 15) {
10913 Info("GetDataSet", "functionality not available: the server has an"
10914 " incompatible version of TFileInfo");
10915 return 0;
10916 }
10917
10918 if (!uri || strlen(uri) <= 0) {
10919 Info("GetDataSet", "specifying a dataset name is mandatory");
10920 return 0;
10921 }
10922
10923 TMessage nameMess(kPROOF_DATASETS);
10924 nameMess << Int_t(kGetDataSet);
10925 nameMess << TString(uri);
10926 nameMess << TString(optStr ? optStr: "");
10927 if (Broadcast(nameMess) < 0)
10928 Error("GetDataSet", "sending request failed");
10929
10931 TFileCollection *fileList = 0;
10932 if (fStatus != 0) {
10933 Error("GetDataSet", "error receiving datasets information");
10934 } else {
10935 // Look in the list
10936 TMessage *retMess = (TMessage *) fRecvMessages->First();
10937 if (retMess && retMess->What() == kMESS_OK) {
10938 if (!(fileList = (TFileCollection*)(retMess->ReadObject(TFileCollection::Class()))))
10939 Error("GetDataSet", "error reading list of files");
10940 } else
10941 Error("GetDataSet", "message not found or wrong type (%p)", retMess);
10942 }
10943
10944 return fileList;
10945}
10946
10947////////////////////////////////////////////////////////////////////////////////
10948/// display meta-info for given dataset usi
10949
10950void TProof::ShowDataSet(const char *uri, const char* opt)
10951{
10952 TFileCollection *fileList = 0;
10953 if ((fileList = GetDataSet(uri))) {
10954 fileList->Print(opt);
10955 delete fileList;
10956 } else
10957 Warning("ShowDataSet","no such dataset: %s", uri);
10958}
10959
10960////////////////////////////////////////////////////////////////////////////////
10961/// Remove the specified dataset from the PROOF cluster.
10962/// Files are not deleted.
10963
10964Int_t TProof::RemoveDataSet(const char *uri, const char* optStr)
10965{
10966 TMessage nameMess(kPROOF_DATASETS);
10967 nameMess << Int_t(kRemoveDataSet);
10968 nameMess << TString(uri?uri:"");
10969 nameMess << TString(optStr?optStr:"");
10970 if (Broadcast(nameMess) < 0)
10971 Error("RemoveDataSet", "sending request failed");
10973
10974 if (fStatus != 0)
10975 return -1;
10976 else
10977 return 0;
10978}
10979
10980////////////////////////////////////////////////////////////////////////////////
10981/// Find datasets, returns in a TList all found datasets.
10982
10983TList* TProof::FindDataSets(const char* /*searchString*/, const char* /*optStr*/)
10984{
10985 Error ("FindDataSets", "not yet implemented");
10986 return (TList *) 0;
10987}
10988
10989////////////////////////////////////////////////////////////////////////////////
10990/// Allows users to request staging of a particular dataset. Requests are
10991/// saved in a special dataset repository and must be honored by the endpoint.
10992
10994{
10995 if (fProtocol < 35) {
10996 Error("RequestStagingDataSet",
10997 "functionality not supported by the server");
10998 return kFALSE;
10999 }
11000
11002 mess << Int_t(kRequestStaging);
11003 mess << TString(dataset);
11004 Broadcast(mess);
11005
11006 Collect();
11007 if (fStatus != 0) {
11008 Error("RequestStagingDataSet", "staging request was unsuccessful");
11009 return kFALSE;
11010 }
11011
11012 return kTRUE;
11013}
11014
11015////////////////////////////////////////////////////////////////////////////////
11016/// Cancels a dataset staging request. Returns kTRUE on success, kFALSE on
11017/// failure. Dataset not found equals to a failure.
11018
11020{
11021 if (fProtocol < 36) {
11022 Error("CancelStagingDataSet",
11023 "functionality not supported by the server");
11024 return kFALSE;
11025 }
11026
11028 mess << Int_t(kCancelStaging);
11029 mess << TString(dataset);
11030 Broadcast(mess);
11031
11032 Collect();
11033 if (fStatus != 0) {
11034 Error("CancelStagingDataSet", "cancel staging request was unsuccessful");
11035 return kFALSE;
11036 }
11037
11038 return kTRUE;
11039}
11040
11041////////////////////////////////////////////////////////////////////////////////
11042/// Obtains a TFileCollection showing the staging status of the specified
11043/// dataset. A valid dataset manager and dataset staging requests repository
11044/// must be present on the endpoint.
11045
11047{
11048 if (fProtocol < 35) {
11049 Error("GetStagingStatusDataSet",
11050 "functionality not supported by the server");
11051 return NULL;
11052 }
11053
11054 TMessage nameMess(kPROOF_DATASETS);
11055 nameMess << Int_t(kStagingStatus);
11056 nameMess << TString(dataset);
11057 if (Broadcast(nameMess) < 0) {
11058 Error("GetStagingStatusDataSet", "sending request failed");
11059 return NULL;
11060 }
11061
11063 TFileCollection *fc = NULL;
11064
11065 if (fStatus < 0) {
11066 Error("GetStagingStatusDataSet", "problem processing the request");
11067 }
11068 else if (fStatus == 0) {
11069 TMessage *retMess = (TMessage *)fRecvMessages->First();
11070 if (retMess && (retMess->What() == kMESS_OK)) {
11071 fc = (TFileCollection *)(
11072 retMess->ReadObject(TFileCollection::Class()) );
11073 if (!fc)
11074 Error("GetStagingStatusDataSet", "error reading list of files");
11075 }
11076 else {
11077 Error("GetStagingStatusDataSet",
11078 "response message not found or wrong type (%p)", retMess);
11079 }
11080 }
11081 //else {}
11082
11083 return fc;
11084}
11085
11086////////////////////////////////////////////////////////////////////////////////
11087/// Like GetStagingStatusDataSet, but displays results immediately.
11088
11089void TProof::ShowStagingStatusDataSet(const char *dataset, const char *opt)
11090{
11092 if (fc) {
11093 fc->Print(opt);
11094 delete fc;
11095 }
11096}
11097
11098////////////////////////////////////////////////////////////////////////////////
11099/// Verify if all files in the specified dataset are available.
11100/// Print a list and return the number of missing files.
11101/// Returns -1 in case of error.
11102
11103Int_t TProof::VerifyDataSet(const char *uri, const char *optStr)
11104{
11105 if (fProtocol < 15) {
11106 Info("VerifyDataSet", "functionality not available: the server has an"
11107 " incompatible version of TFileInfo");
11108 return -1;
11109 }
11110
11111 // Sanity check
11112 if (!uri || (uri && strlen(uri) <= 0)) {
11113 Error("VerifyDataSet", "dataset name is is mandatory");
11114 return -1;
11115 }
11116
11117 Int_t nmissingfiles = 0;
11118
11119 TString sopt(optStr);
11120 if (fProtocol < 34 || sopt.Contains("S")) {
11121 sopt.ReplaceAll("S", "");
11122 Info("VerifyDataSet", "Master-only verification");
11123 TMessage nameMess(kPROOF_DATASETS);
11124 nameMess << Int_t(kVerifyDataSet);
11125 nameMess << TString(uri);
11126 nameMess << sopt;
11127 Broadcast(nameMess);
11128
11130
11131 if (fStatus < 0) {
11132 Info("VerifyDataSet", "no such dataset %s", uri);
11133 return -1;
11134 } else
11135 nmissingfiles = fStatus;
11136 return nmissingfiles;
11137 }
11138
11139 // Request for parallel verification: can only be done if we have workers
11140 if (!IsParallel() && !fDynamicStartup) {
11141 Error("VerifyDataSet", "PROOF is in sequential mode (no workers): cannot do parallel verification.");
11142 Error("VerifyDataSet", "Either start PROOF with some workers or force sequential adding 'S' as option.");
11143 return -1;
11144 }
11145
11146 // Do parallel verification
11147 return VerifyDataSetParallel(uri, optStr);
11148}
11149
11150////////////////////////////////////////////////////////////////////////////////
11151/// Internal function for parallel dataset verification used TProof::VerifyDataSet and
11152/// TProofLite::VerifyDataSet
11153
11154Int_t TProof::VerifyDataSetParallel(const char *uri, const char *optStr)
11155{
11156 Int_t nmissingfiles = 0;
11157
11158 // Let PROOF master prepare node-files map
11159 SetParameter("PROOF_FilesToProcess", Form("dataset:%s", uri));
11160
11161 // Use TPacketizerFile
11162 TString oldpack;
11163 if (TProof::GetParameter(GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
11164 SetParameter("PROOF_Packetizer", "TPacketizerFile");
11165
11166 // Add dataset name
11167 SetParameter("PROOF_VerifyDataSet", uri);
11168 // Add options
11169 SetParameter("PROOF_VerifyDataSetOption", optStr);
11170 SetParameter("PROOF_SavePartialResults", (Int_t)0);
11171 Int_t oldifiip = -1;
11172 if (TProof::GetParameter(GetInputList(), "PROOF_IncludeFileInfoInPacket", oldifiip) != 0) oldifiip = -1;
11173 SetParameter("PROOF_IncludeFileInfoInPacket", (Int_t)1);
11174
11175 // TO DO : figure out mss and stageoption
11176 const char* mss="";
11177 SetParameter("PROOF_MSS", mss);
11178 const char* stageoption="";
11179 SetParameter("PROOF_StageOption", stageoption);
11180
11181 // Process verification in parallel
11182 Process("TSelVerifyDataSet", (Long64_t) 1);
11183
11184 // Restore packetizer
11185 if (!oldpack.IsNull())
11186 SetParameter("PROOF_Packetizer", oldpack);
11187 else
11188 DeleteParameters("PROOF_Packetizer");
11189
11190 // Delete or restore parameters
11191 DeleteParameters("PROOF_FilesToProcess");
11192 DeleteParameters("PROOF_VerifyDataSet");
11193 DeleteParameters("PROOF_VerifyDataSetOption");
11194 DeleteParameters("PROOF_MSS");
11195 DeleteParameters("PROOF_StageOption");
11196 if (oldifiip > -1) {
11197 SetParameter("PROOF_IncludeFileInfoInPacket", oldifiip);
11198 } else {
11199 DeleteParameters("PROOF_IncludeFileInfoInPacket");
11200 }
11201 DeleteParameters("PROOF_SavePartialResults");
11202
11203 // Merge outputs
11204 Int_t nopened = 0;
11205 Int_t ntouched = 0;
11206 Bool_t changed_ds = kFALSE;
11207
11208 TIter nxtout(GetOutputList());
11209 TObject* obj;
11210 TList *lfiindout = new TList;
11211 while ((obj = nxtout())) {
11212 TList *l = dynamic_cast<TList *>(obj);
11213 if (l && TString(l->GetName()).BeginsWith("PROOF_ListFileInfos_")) {
11214 TIter nxt(l);
11215 TFileInfo *fiindout = 0;
11216 while ((fiindout = (TFileInfo*) nxt())) {
11217 lfiindout->Add(fiindout);
11218 }
11219 }
11220 // Add up number of disppeared files
11221 TParameter<Int_t>* pdisappeared = dynamic_cast<TParameter<Int_t>*>(obj);
11222 if ( pdisappeared && TString(pdisappeared->GetName()).BeginsWith("PROOF_NoFilesDisppeared_")) {
11223 nmissingfiles += pdisappeared->GetVal();
11224 }
11225 TParameter<Int_t>* pnopened = dynamic_cast<TParameter<Int_t>*>(obj);
11226 if (pnopened && TString(pnopened->GetName()).BeginsWith("PROOF_NoFilesOpened_")) {
11227 nopened += pnopened->GetVal();
11228 }
11229 TParameter<Int_t>* pntouched = dynamic_cast<TParameter<Int_t>*>(obj);
11230 if (pntouched && TString(pntouched->GetName()).BeginsWith("PROOF_NoFilesTouched_")) {
11231 ntouched += pntouched->GetVal();
11232 }
11233 TParameter<Bool_t>* pchanged_ds = dynamic_cast<TParameter<Bool_t>*>(obj);
11234 if (pchanged_ds && TString(pchanged_ds->GetName()).BeginsWith("PROOF_DataSetChanged_")) {
11235 if (pchanged_ds->GetVal() == kTRUE) changed_ds = kTRUE;
11236 }
11237 }
11238
11239 Info("VerifyDataSetParallel", "%s: changed? %d (# files opened = %d, # files touched = %d,"
11240 " # missing files = %d)",
11241 uri, changed_ds, nopened, ntouched, nmissingfiles);
11242 // Done
11243 return nmissingfiles;
11244}
11245
11246////////////////////////////////////////////////////////////////////////////////
11247/// returns a map of the quotas of all groups
11248
11249TMap *TProof::GetDataSetQuota(const char* optStr)
11250{
11251 if (IsLite()) {
11252 Info("UploadDataSet", "Lite-session: functionality not implemented");
11253 return (TMap *)0;
11254 }
11255
11257 mess << Int_t(kGetQuota);
11258 mess << TString(optStr?optStr:"");
11259 Broadcast(mess);
11260
11262 TMap *groupQuotaMap = 0;
11263 if (fStatus < 0) {
11264 Info("GetDataSetQuota", "could not receive quota");
11265 } else {
11266 // Look in the list
11267 TMessage *retMess = (TMessage *) fRecvMessages->First();
11268 if (retMess && retMess->What() == kMESS_OK) {
11269 if (!(groupQuotaMap = (TMap*)(retMess->ReadObject(TMap::Class()))))
11270 Error("GetDataSetQuota", "error getting quotas");
11271 } else
11272 Error("GetDataSetQuota", "message not found or wrong type (%p)", retMess);
11273 }
11274
11275 return groupQuotaMap;
11276}
11277
11278////////////////////////////////////////////////////////////////////////////////
11279/// shows the quota and usage of all groups
11280/// if opt contains "U" shows also distribution of usage on user-level
11281
11283{
11284 if (fProtocol < 15) {
11285 Info("ShowDataSetQuota",
11286 "functionality not available: the server does not have dataset support");
11287 return;
11288 }
11289
11290 if (IsLite()) {
11291 Info("UploadDataSet", "Lite-session: functionality not implemented");
11292 return;
11293 }
11294
11296 mess << Int_t(kShowQuota);
11297 mess << TString(opt?opt:"");
11298 Broadcast(mess);
11299
11300 Collect();
11301 if (fStatus != 0)
11302 Error("ShowDataSetQuota", "error receiving quota information");
11303}
11304
11305////////////////////////////////////////////////////////////////////////////////
11306/// If in active in a monitor set ready state
11307
11309{
11310 if (fCurrentMonitor)
11312}
11313
11314////////////////////////////////////////////////////////////////////////////////
11315/// Make sure that the worker identified by the ordinal number 'ord' is
11316/// in the active list. The request will be forwarded to the master
11317/// in direct contact with the worker. If needed, this master will move
11318/// the worker from the inactive to the active list and rebuild the list
11319/// of unique workers.
11320/// Use ord = "*" to activate all inactive workers.
11321/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11322/// status of which will be modified at once.
11323/// Return <0 if something went wrong (-2 if at least one worker was not found)
11324/// or the number of workers with status change (on master; 0 on client).
11325
11327{
11328 return ModifyWorkerLists(ord, kTRUE, save);
11329}
11330
11331////////////////////////////////////////////////////////////////////////////////
11332/// Remove the worker identified by the ordinal number 'ord' from the
11333/// the active list. The request will be forwarded to the master
11334/// in direct contact with the worker. If needed, this master will move
11335/// the worker from the active to the inactive list and rebuild the list
11336/// of unique workers.
11337/// Use ord = "*" to deactivate all active workers.
11338/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11339/// status of which will be modified at once.
11340/// Return <0 if something went wrong (-2 if at least one worker was not found)
11341/// or the number of workers with status change (on master; 0 on client).
11342
11344{
11345 return ModifyWorkerLists(ord, kFALSE, save);
11346}
11347
11348////////////////////////////////////////////////////////////////////////////////
11349/// Modify the worker active/inactive list by making the worker identified by
11350/// the ordinal number 'ord' active (add == TRUE) or inactive (add == FALSE).
11351/// The string 'ord' can also be a comma-separated list of ordinal numbers the
11352/// status of which will be modified at once.
11353/// If needed, the request will be forwarded to the master in direct contact
11354/// with the worker. The end-master will move the worker from one list to the
11355/// other active and rebuild the list of unique active workers.
11356/// Use ord = "*" to deactivate all active workers.
11357/// If save is TRUE the current active list is saved before any modification is
11358/// done; re-running with ord = "restore" restores the saved list
11359/// Return <0 if something went wrong (-2 if at least one worker was not found)
11360/// or the number of workers with status change (on master; 0 on client).
11361
11363{
11364 // Make sure the input make sense
11365 if (!ord || strlen(ord) <= 0) {
11366 Info("ModifyWorkerLists",
11367 "an ordinal number - e.g. \"0.4\" or \"*\" for all - is required as input");
11368 return -1;
11369 }
11370 if (gDebug > 0)
11371 Info("ModifyWorkerLists", "ord: '%s' (add: %d, save: %d)", ord, add, save);
11372
11373 Int_t nwc = 0;
11374 Bool_t restoring = !strcmp(ord, "restore") ? kTRUE : kFALSE;
11375 if (IsEndMaster()) {
11376 if (restoring) {
11377 // We are asked to restore the previous settings
11378 nwc = RestoreActiveList();
11379 } else {
11380 if (save) SaveActiveList();
11381 }
11382 }
11383
11384 Bool_t allord = strcmp(ord, "*") ? kFALSE : kTRUE;
11385
11386 // Check if this is for us
11388 if (!allord &&
11389 strncmp(ord, gProofServ->GetOrdinal(), strlen(gProofServ->GetOrdinal())))
11390 return 0;
11391 }
11392
11393 Bool_t fw = kTRUE; // Whether to forward one step down
11394 Bool_t rs = kFALSE; // Whether to rescan for unique workers
11395
11396 // Appropriate list pointing
11397 TList *in = (add) ? fInactiveSlaves : fActiveSlaves;
11398 TList *out = (add) ? fActiveSlaves : fInactiveSlaves;
11399
11400 if (IsEndMaster() && !restoring) {
11401 // Create the hash list of ordinal numbers
11402 THashList *ords = 0;
11403 if (!allord) {
11404 ords = new THashList();
11405 const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
11406 TString oo(ord), o;
11407 Int_t from = 0;
11408 while(oo.Tokenize(o, from, ","))
11409 if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
11410 }
11411 // We do not need to send forward
11412 fw = kFALSE;
11413 // Look for the worker in the initial list
11414 TObject *os = 0;
11415 TSlave *wrk = 0;
11416 if (in->GetSize() > 0) {
11417 TIter nxw(in);
11418 while ((wrk = (TSlave *) nxw())) {
11419 os = 0;
11420 if (allord || (ords && (os = ords->FindObject(wrk->GetOrdinal())))) {
11421 // Add it to the final list
11422 if (!out->FindObject(wrk)) {
11423 out->Add(wrk);
11424 if (add)
11425 fActiveMonitor->Add(wrk->GetSocket());
11426 }
11427 // Remove it from the initial list
11428 in->Remove(wrk);
11429 if (!add) {
11432 } else
11434 // Count
11435 nwc++;
11436 // Nothing to forward (ord is unique)
11437 fw = kFALSE;
11438 // Rescan for unique workers (active list modified)
11439 rs = kTRUE;
11440 // We may be done, if not option 'all'
11441 if (!allord && ords) {
11442 if (os) ords->Remove(os);
11443 if (ords->GetSize() == 0) break;
11444 SafeDelete(os);
11445 }
11446 }
11447 }
11448 }
11449 // If some worker not found, notify it if at the end
11450 if (!fw && ords && ords->GetSize() > 0) {
11451 TString oo;
11452 TIter nxo(ords);
11453 while ((os = nxo())) {
11454 TIter nxw(out);
11455 while ((wrk = (TSlave *) nxw()))
11456 if (!strcmp(os->GetName(), wrk->GetOrdinal())) break;
11457 if (!wrk) {
11458 if (!oo.IsNull()) oo += ",";
11459 oo += os->GetName();
11460 }
11461 }
11462 if (!oo.IsNull()) {
11463 Warning("ModifyWorkerLists", "worker(s) '%s' not found!", oo.Data());
11464 nwc = -2;
11465 }
11466 }
11467 // Cleanup hash list
11468 if (ords) {
11469 ords->Delete();
11470 SafeDelete(ords);
11471 }
11472 }
11473
11474 // Rescan for unique workers
11475 if (rs)
11477
11478 // Forward the request one step down, if needed
11479 Int_t action = (add) ? (Int_t) kActivateWorker : (Int_t) kDeactivateWorker;
11480 if (fw) {
11481 if (fProtocol > 32) {
11483 mess << action << TString(ord);
11484 Broadcast(mess);
11486 if (fStatus != 0) {
11487 nwc = (fStatus < nwc) ? fStatus : nwc;
11488 if (fStatus == -2) {
11489 if (gDebug > 0)
11490 Warning("ModifyWorkerLists", "request not completely full filled");
11491 } else {
11492 Error("ModifyWorkerLists", "request failed");
11493 }
11494 }
11495 } else {
11496 TString oo(ord), o;
11497 if (oo.Contains(","))
11498 Warning("ModifyWorkerLists", "block request not supported by server: splitting into pieces ...");
11499 Int_t from = 0;
11500 while(oo.Tokenize(o, from, ",")) {
11502 mess << action << o;
11503 Broadcast(mess);
11505 }
11506 }
11507 }
11508 // Done
11509 return nwc;
11510}
11511
11512////////////////////////////////////////////////////////////////////////////////
11513/// Save current list of active workers
11514
11516{
11518 if (fInactiveSlaves->GetSize() == 0) {
11519 fActiveSlavesSaved = "*";
11520 } else {
11521 TIter nxw(fActiveSlaves);
11522 TSlave *wk = 0;
11523 while ((wk = (TSlave *)nxw())) { fActiveSlavesSaved += TString::Format("%s,", wk->GetOrdinal()); }
11524 }
11525}
11526
11527////////////////////////////////////////////////////////////////////////////////
11528/// Restore saved list of active workers
11529
11531{
11532 // Clear the current active list
11534 // Restore the previous active list
11537
11538 return 0;
11539}
11540
11541////////////////////////////////////////////////////////////////////////////////
11542/// Start a PROOF session on a specific cluster. If cluster is 0 (the
11543/// default) then the PROOF Session Viewer GUI pops up and 0 is returned.
11544/// If cluster is "lite://" we start a PROOF-lite session.
11545/// If cluster is "" (empty string) then we connect to the cluster specified
11546/// by 'Proof.LocalDefault', defaulting to "lite://".
11547/// If cluster is "pod://" (case insensitive), then we connect to a PROOF cluster
11548/// managed by PROOF on Demand (PoD, http://pod.gsi.de ).
11549/// Via conffile a specific PROOF config file in the confir directory can be specified.
11550/// Use loglevel to set the default loging level for debugging.
11551/// The appropriate instance of TProofMgr is created, if not
11552/// yet existing. The instantiated TProof object is returned.
11553/// Use TProof::cd() to switch between PROOF sessions.
11554/// For more info on PROOF see the TProof ctor.
11555
11556TProof *TProof::Open(const char *cluster, const char *conffile,
11557 const char *confdir, Int_t loglevel)
11558{
11559 const char *pn = "TProof::Open";
11560
11561 // Make sure libProof and dependents are loaded and TProof can be created,
11562 // dependents are loaded via the information in the [system].rootmap file
11563 if (!cluster) {
11564
11565 TPluginManager *pm = gROOT->GetPluginManager();
11566 if (!pm) {
11567 ::Error(pn, "plugin manager not found");
11568 return 0;
11569 }
11570
11571 if (gROOT->IsBatch()) {
11572 ::Error(pn, "we are in batch mode, cannot show PROOF Session Viewer");
11573 return 0;
11574 }
11575 // start PROOF Session Viewer
11576 TPluginHandler *sv = pm->FindHandler("TSessionViewer", "");
11577 if (!sv) {
11578 ::Error(pn, "no plugin found for TSessionViewer");
11579 return 0;
11580 }
11581 if (sv->LoadPlugin() == -1) {
11582 ::Error(pn, "plugin for TSessionViewer could not be loaded");
11583 return 0;
11584 }
11585 sv->ExecPlugin(0);
11586 return 0;
11587
11588 } else {
11589
11590 TString clst(cluster);
11591
11592 // Check for PoD cluster
11593 if (PoDCheckUrl( &clst ) < 0) return 0;
11594
11595 if (clst.BeginsWith("workers=")) clst.Insert(0, "lite:///?");
11596 if (clst.BeginsWith("tunnel=")) clst.Insert(0, "/?");
11597
11598 // Parse input URL
11599 TUrl u(clst);
11600
11601 // *** GG, 060711: this does not seem to work any more (at XrdClient level)
11602 // *** to be investigated (it is not really needed; static tunnels work).
11603 // Dynamic tunnel:
11604 // Parse any tunning info ("<cluster>/?tunnel=[<tunnel_host>:]tunnel_port)
11605 TString opts(u.GetOptions());
11606 if (!opts.IsNull()) {
11607 Int_t it = opts.Index("tunnel=");
11608 if (it != kNPOS) {
11609 TString sport = opts(it + strlen("tunnel="), opts.Length());
11610 TString host("127.0.0.1");
11611 Int_t port = -1;
11612 Int_t ic = sport.Index(":");
11613 if (ic != kNPOS) {
11614 // Isolate the host
11615 host = sport(0, ic);
11616 sport.Remove(0, ic + 1);
11617 }
11618 if (!sport.IsDigit()) {
11619 // Remove the non digit part
11620 TRegexp re("[^0-9]");
11621 Int_t ind = sport.Index(re);
11622 if (ind != kNPOS)
11623 sport.Remove(ind);
11624 }
11625 // Set the port
11626 if (sport.IsDigit())
11627 port = sport.Atoi();
11628 if (port > 0) {
11629 // Set the relevant variables
11630 ::Info("TProof::Open","using tunnel at %s:%d", host.Data(), port);
11631 gEnv->SetValue("XNet.SOCKS4Host", host);
11632 gEnv->SetValue("XNet.SOCKS4Port", port);
11633 } else {
11634 // Warn parsing problems
11635 ::Warning("TProof::Open",
11636 "problems parsing tunnelling info from options: %s", opts.Data());
11637 }
11638 }
11639 }
11640
11641 // Find out if we are required to attach to a specific session
11642 Int_t locid = -1;
11643 Bool_t create = kFALSE;
11644 if (opts.Length() > 0) {
11645 if (opts.BeginsWith("N",TString::kIgnoreCase)) {
11646 create = kTRUE;
11647 opts.Remove(0,1);
11648 u.SetOptions(opts);
11649 } else if (opts.IsDigit()) {
11650 locid = opts.Atoi();
11651 }
11652 }
11653
11654 // Attach-to or create the appropriate manager
11656
11657 TProof *proof = 0;
11658 if (mgr && mgr->IsValid()) {
11659
11660 // If XProofd we always attempt an attach first (unless
11661 // explicitly not requested).
11662 Bool_t attach = (create || mgr->IsProofd() || mgr->IsLite()) ? kFALSE : kTRUE;
11663 if (attach) {
11664 TProofDesc *d = 0;
11665 if (locid < 0)
11666 // Get the list of sessions
11667 d = (TProofDesc *) mgr->QuerySessions("")->First();
11668 else
11669 d = (TProofDesc *) mgr->GetProofDesc(locid);
11670 if (d) {
11671 proof = (TProof*) mgr->AttachSession(d);
11672 if (!proof || !proof->IsValid()) {
11673 if (locid)
11674 ::Error(pn, "new session could not be attached");
11675 SafeDelete(proof);
11676 }
11677 }
11678 }
11679
11680 // start the PROOF session
11681 if (!proof) {
11682 proof = (TProof*) mgr->CreateSession(conffile, confdir, loglevel);
11683 if (!proof || !proof->IsValid()) {
11684 ::Error(pn, "new session could not be created");
11685 SafeDelete(proof);
11686 }
11687 }
11688 }
11689 return proof;
11690 }
11691}
11692
11693////////////////////////////////////////////////////////////////////////////////
11694/// Get instance of the effective manager for 'url'
11695/// Return 0 on failure.
11696
11697TProofMgr *TProof::Mgr(const char *url)
11698{
11699 if (!url)
11700 return (TProofMgr *)0;
11701
11702 // Attach or create the relevant instance
11703 return TProofMgr::Create(url);
11704}
11705
11706////////////////////////////////////////////////////////////////////////////////
11707/// Wrapper around TProofMgr::Reset(...).
11708
11709void TProof::Reset(const char *url, Bool_t hard)
11710{
11711 if (url) {
11712 TProofMgr *mgr = TProof::Mgr(url);
11713 if (mgr && mgr->IsValid())
11714 mgr->Reset(hard);
11715 else
11716 ::Error("TProof::Reset",
11717 "unable to initialize a valid manager instance");
11718 }
11719}
11720
11721////////////////////////////////////////////////////////////////////////////////
11722/// Get environemnt variables.
11723
11725{
11726 return fgProofEnvList;
11727}
11728
11729////////////////////////////////////////////////////////////////////////////////
11730/// Add an variable to the list of environment variables passed to proofserv
11731/// on the master and slaves
11732
11733void TProof::AddEnvVar(const char *name, const char *value)
11734{
11735 if (gDebug > 0) ::Info("TProof::AddEnvVar","%s=%s", name, value);
11736
11737 if (fgProofEnvList == 0) {
11738 // initialize the list if needed
11739 fgProofEnvList = new TList;
11741 } else {
11742 // replace old entries with the same name
11744 if (o != 0) {
11746 }
11747 }
11748 fgProofEnvList->Add(new TNamed(name, value));
11749}
11750
11751////////////////////////////////////////////////////////////////////////////////
11752/// Remove an variable from the list of environment variables passed to proofserv
11753/// on the master and slaves
11754
11755void TProof::DelEnvVar(const char *name)
11756{
11757 if (fgProofEnvList == 0) return;
11758
11760 if (o != 0) {
11762 }
11763}
11764
11765////////////////////////////////////////////////////////////////////////////////
11766/// Clear the list of environment variables passed to proofserv
11767/// on the master and slaves
11768
11770{
11771 if (fgProofEnvList == 0) return;
11772
11774}
11775
11776////////////////////////////////////////////////////////////////////////////////
11777/// Save information about the worker set in the file .workers in the working
11778/// dir. Called each time there is a change in the worker setup, e.g. by
11779/// TProof::MarkBad().
11780
11782{
11783 // We must be masters
11785 return;
11786
11787 // We must have a server defined
11788 if (!gProofServ) {
11789 Error("SaveWorkerInfo","gProofServ undefined");
11790 return;
11791 }
11792
11793 // The relevant lists must be defined
11794 if (!fSlaves && !fBadSlaves) {
11795 Warning("SaveWorkerInfo","all relevant worker lists is undefined");
11796 return;
11797 }
11798
11799 // Create or truncate the file first
11800 TString fnwrk = TString::Format("%s/.workers",
11802 FILE *fwrk = fopen(fnwrk.Data(),"w");
11803 if (!fwrk) {
11804 Error("SaveWorkerInfo",
11805 "cannot open %s for writing (errno: %d)", fnwrk.Data(), errno);
11806 return;
11807 }
11808
11809 // Do we need to register an additional line for another log?
11810 TString addlogext;
11811 TString addLogTag;
11812 if (gSystem->Getenv("PROOF_ADDITIONALLOG")) {
11813 addlogext = gSystem->Getenv("PROOF_ADDITIONALLOG");
11814 TPMERegexp reLogTag("^__(.*)__\\.log"); // $
11815 if (reLogTag.Match(addlogext) == 2) {
11816 addLogTag = reLogTag[1];
11817 }
11818 else {
11819 addLogTag = "+++";
11820 }
11821 if (gDebug > 0)
11822 Info("SaveWorkerInfo", "request for additional line with ext: '%s'", addlogext.Data());
11823 }
11824
11825 // Used to eliminate datetime and PID from workdir to obtain log file name
11826 TPMERegexp re("(.*?)-[0-9]+-[0-9]+$");
11827
11828 // Loop over the list of workers (active is any worker not flagged as bad)
11829 TIter nxa(fSlaves);
11830 TSlave *wrk = 0;
11831 TString logfile;
11832 while ((wrk = (TSlave *) nxa())) {
11833 Int_t status = (fBadSlaves && fBadSlaves->FindObject(wrk)) ? 0 : 1;
11834 logfile = wrk->GetWorkDir();
11835 if (re.Match(logfile) == 2) logfile = re[1];
11836 else continue; // invalid (should not happen)
11837 // Write out record for this worker
11838 fprintf(fwrk,"%s@%s:%d %d %s %s.log\n",
11839 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11840 wrk->GetOrdinal(), logfile.Data());
11841 // Additional line, if required
11842 if (addlogext.Length() > 0) {
11843 fprintf(fwrk,"%s@%s:%d %d %s(%s) %s.%s\n",
11844 wrk->GetUser(), wrk->GetName(), wrk->GetPort(), status,
11845 wrk->GetOrdinal(), addLogTag.Data(), logfile.Data(), addlogext.Data());
11846 }
11847
11848 }
11849
11850 // Loop also over the list of bad workers (if they failed to startup they are not in
11851 // the overall list
11852 TIter nxb(fBadSlaves);
11853 while ((wrk = (TSlave *) nxb())) {
11854 logfile = wrk->GetWorkDir();
11855 if (re.Match(logfile) == 2) logfile = re[1];
11856 else continue; // invalid (should not happen)
11857 if (!fSlaves->FindObject(wrk)) {
11858 // Write out record for this worker
11859 fprintf(fwrk,"%s@%s:%d 0 %s %s.log\n",
11860 wrk->GetUser(), wrk->GetName(), wrk->GetPort(),
11861 wrk->GetOrdinal(), logfile.Data());
11862 }
11863 }
11864
11865 // Eventually loop over the list of gracefully terminated workers: we'll get
11866 // logfiles from those workers as well. They'll be shown with a special
11867 // status of "2"
11869 TSlaveInfo *sli;
11870 while (( sli = (TSlaveInfo *)nxt() )) {
11871 logfile = sli->GetDataDir();
11872 if (re.Match(logfile) == 2) logfile = re[1];
11873 else continue; // invalid (should not happen)
11874 fprintf(fwrk, "%s 2 %s %s.log\n",
11875 sli->GetName(), sli->GetOrdinal(), logfile.Data());
11876 // Additional line, if required
11877 if (addlogext.Length() > 0) {
11878 fprintf(fwrk, "%s 2 %s(%s) %s.%s\n",
11879 sli->GetName(), sli->GetOrdinal(), addLogTag.Data(),
11880 logfile.Data(), addlogext.Data());
11881 }
11882 }
11883
11884 // Close file
11885 fclose(fwrk);
11886
11887 // We are done
11888 return;
11889}
11890
11891////////////////////////////////////////////////////////////////////////////////
11892/// Get the value from the specified parameter from the specified collection.
11893/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11894/// or value type does not match), 0 otherwise.
11895
11897{
11898 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11899 if (obj) {
11900 TNamed *p = dynamic_cast<TNamed*>(obj);
11901 if (p) {
11902 value = p->GetTitle();
11903 return 0;
11904 }
11905 }
11906 return -1;
11907
11908}
11909
11910////////////////////////////////////////////////////////////////////////////////
11911/// Get the value from the specified parameter from the specified collection.
11912/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11913/// or value type does not match), 0 otherwise.
11914
11916{
11917 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11918 if (obj) {
11919 TParameter<Int_t> *p = dynamic_cast<TParameter<Int_t>*>(obj);
11920 if (p) {
11921 value = p->GetVal();
11922 return 0;
11923 }
11924 }
11925 return -1;
11926}
11927
11928////////////////////////////////////////////////////////////////////////////////
11929/// Get the value from the specified parameter from the specified collection.
11930/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11931/// or value type does not match), 0 otherwise.
11932
11934{
11935 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11936 if (obj) {
11937 TParameter<Long_t> *p = dynamic_cast<TParameter<Long_t>*>(obj);
11938 if (p) {
11939 value = p->GetVal();
11940 return 0;
11941 }
11942 }
11943 return -1;
11944}
11945
11946////////////////////////////////////////////////////////////////////////////////
11947/// Get the value from the specified parameter from the specified collection.
11948/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11949/// or value type does not match), 0 otherwise.
11950
11952{
11953 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11954 if (obj) {
11955 TParameter<Long64_t> *p = dynamic_cast<TParameter<Long64_t>*>(obj);
11956 if (p) {
11957 value = p->GetVal();
11958 return 0;
11959 }
11960 }
11961 return -1;
11962}
11963
11964////////////////////////////////////////////////////////////////////////////////
11965/// Get the value from the specified parameter from the specified collection.
11966/// Returns -1 in case of error (i.e. list is 0, parameter does not exist
11967/// or value type does not match), 0 otherwise.
11968
11970{
11971 TObject *obj = c ? c->FindObject(par) : (TObject *)0;
11972 if (obj) {
11973 TParameter<Double_t> *p = dynamic_cast<TParameter<Double_t>*>(obj);
11974 if (p) {
11975 value = p->GetVal();
11976 return 0;
11977 }
11978 }
11979 return -1;
11980}
11981
11982////////////////////////////////////////////////////////////////////////////////
11983/// Make sure that dataset is in the form to be processed. This may mean
11984/// retrieving the relevant info from the dataset manager or from the
11985/// attached input list.
11986/// Returns 0 on success, -1 on error
11987
11989 TDataSetManager *mgr, TString &emsg)
11990{
11991 emsg = "";
11992
11993 // We must have something to process
11994 if (!dset || !input || !mgr) {
11995 emsg.Form("invalid inputs (%p, %p, %p)", dset, input, mgr);
11996 return -1;
11997 }
11998
11999 TList *datasets = new TList;
12000 TFileCollection *dataset = 0;
12001 TString lookupopt;
12002 TString dsname(dset->GetName());
12003
12004 // First extract the "entry list" part on the global name, if any
12005 TString dsns(dsname), enlname;
12006 Ssiz_t eli = dsns.Index("?enl=");
12007 if (eli != kNPOS) {
12008 enlname = dsns(eli + strlen("?enl="), dsns.Length());
12009 dsns.Remove(eli, dsns.Length()-eli);
12010 }
12011
12012 // The dataset maybe in the form of a TFileCollection in the input list
12013 if (dsname.BeginsWith("TFileCollection:")) {
12014 // Isolate the real name
12015 dsname.ReplaceAll("TFileCollection:", "");
12016 // Get the object
12017 dataset = (TFileCollection *) input->FindObject(dsname);
12018 if (!dataset) {
12019 emsg.Form("TFileCollection %s not found in input list", dset->GetName());
12020 return -1;
12021 }
12022 // Remove from everywhere
12023 input->RecursiveRemove(dataset);
12024 // Add it to the local list
12025 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12026 // Make sure we lookup everything (unless the client or the administrator
12027 // required something else)
12028 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12029 lookupopt = gEnv->GetValue("Proof.LookupOpt", "all");
12030 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12031 }
12032 }
12033
12034 // This is the name we parse for additional specifications, such directory
12035 // and object name; for multiple datasets we assume that the directory and
12036 // and object name are the same for all datasets
12037 TString dsnparse;
12038 // The received message included an empty dataset, with only the name
12039 // defined: assume that a dataset, stored on the PROOF master by that
12040 // name, should be processed.
12041 if (!dataset) {
12042
12043 TFileCollection *fc = nullptr;
12044
12045 // Check if the entry list and dataset name are valid. If they have spaces,
12046 // commas, or pipes, they are not considered as valid and we revert to the
12047 // "multiple datasets" case
12048 TRegexp rg("[, |]");
12049 Bool_t validEnl = (enlname.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12050 Bool_t validSdsn = (dsns.Index(rg) == kNPOS) ? kTRUE : kFALSE;
12051
12052 if (validEnl && validSdsn && (( fc = mgr->GetDataSet(dsns) ))) {
12053
12054 //
12055 // String corresponds to ONE dataset only
12056 //
12057
12058 TIter nxfi(fc->GetList());
12059 TFileInfo *fi;
12060 while (( fi = (TFileInfo *)nxfi() ))
12061 fi->SetTitle(dsns.Data());
12062 dataset = fc;
12063 dsnparse = dsns; // without entry list
12064
12065 // Adds the entry list (or empty string if not specified)
12066 datasets->Add( new TPair(dataset, new TObjString( enlname.Data() )) );
12067
12068 } else {
12069
12070 //
12071 // String does NOT correspond to one dataset: check if many datasets
12072 // were specified instead
12073 //
12074
12075 dsns = dsname.Data();
12076 TString dsn1;
12077 Int_t from1 = 0;
12078 while (dsns.Tokenize(dsn1, from1, "[, ]")) {
12079 TString dsn2;
12080 Int_t from2 = 0;
12081 while (dsn1.Tokenize(dsn2, from2, "|")) {
12082 enlname = "";
12083 Int_t ienl = dsn2.Index("?enl=");
12084 if (ienl != kNPOS) {
12085 enlname = dsn2(ienl + 5, dsn2.Length());
12086 dsn2.Remove(ienl);
12087 }
12088 if ((fc = mgr->GetDataSet(dsn2.Data()))) {
12089 // Save dataset name in TFileInfo's title to use it in TDset
12090 TIter nxfi(fc->GetList());
12091 TFileInfo *fi;
12092 while ((fi = (TFileInfo *) nxfi())) { fi->SetTitle(dsn2.Data()); }
12093 dsnparse = dsn2;
12094 if (!dataset) {
12095 // This is our dataset
12096 dataset = fc;
12097 } else {
12098 // Add it to the dataset
12099 dataset->Add(fc);
12100 SafeDelete(fc);
12101 }
12102 }
12103 }
12104 // The dataset name(s) in the first element
12105 if (dataset) {
12106 if (dataset->GetList()->First())
12107 ((TFileInfo *)(dataset->GetList()->First()))->SetTitle(dsn1.Data());
12108 // Add it to the local list
12109 datasets->Add(new TPair(dataset, new TObjString(enlname.Data())));
12110 }
12111 // Reset the pointer
12112 dataset = 0;
12113 }
12114
12115 }
12116
12117 //
12118 // At this point the dataset(s) to be processed, if any, are found in the
12119 // "datasets" variable
12120 //
12121
12122 if (!datasets || datasets->GetSize() <= 0) {
12123 emsg.Form("no dataset(s) found on the master corresponding to: %s", dsname.Data());
12124 return -1;
12125 } else {
12126 // Make 'dataset' to point to the first one in the list
12127 if (!(dataset = (TFileCollection *) ((TPair *)(datasets->First()))->Key())) {
12128 emsg.Form("dataset pointer is null: corruption? - aborting");
12129 return -1;
12130 }
12131 }
12132 // Apply the lookup option requested by the client or the administartor
12133 // (by default we trust the information in the dataset)
12134 if (TProof::GetParameter(input, "PROOF_LookupOpt", lookupopt) != 0) {
12135 lookupopt = gEnv->GetValue("Proof.LookupOpt", "stagedOnly");
12136 input->Add(new TNamed("PROOF_LookupOpt", lookupopt.Data()));
12137 }
12138 } else {
12139 // We were given a named, single, TFileCollection
12140 dsnparse = dsname;
12141 }
12142
12143 // Logic for the subdir/obj names: try first to see if the dataset name contains
12144 // some info; if not check the settings in the TDSet object itself; if still empty
12145 // check the default tree name / path in the TFileCollection object; if still empty
12146 // use the default as the flow will determine
12147 TString dsTree;
12148 // Get the [subdir/]tree, if any
12149 mgr->ParseUri(dsnparse.Data(), 0, 0, 0, &dsTree);
12150 if (dsTree.IsNull()) {
12151 // Use what we have in the original dataset; we need this to locate the
12152 // meta data information
12153 dsTree += dset->GetDirectory();
12154 dsTree += dset->GetObjName();
12155 }
12156 if (!dsTree.IsNull() && dsTree != "/") {
12157 TString tree(dsTree);
12158 Int_t idx = tree.Index("/");
12159 if (idx != kNPOS) {
12160 TString dir = tree(0, idx+1);
12161 tree.Remove(0, idx);
12162 dset->SetDirectory(dir);
12163 }
12164 dset->SetObjName(tree);
12165 } else {
12166 // Use the default obj name from the TFileCollection
12167 dsTree = dataset->GetDefaultTreeName();
12168 }
12169
12170 // Pass dataset server mapping instructions, if any
12172 TList *srvmapslist = srvmapsref;
12173 TString srvmaps;
12174 if (TProof::GetParameter(input, "PROOF_DataSetSrvMaps", srvmaps) == 0) {
12175 srvmapslist = TDataSetManager::ParseDataSetSrvMaps(srvmaps);
12176 if (gProofServ) {
12177 TString msg;
12178 if (srvmapsref && !srvmapslist) {
12179 msg.Form("+++ Info: dataset server mapping(s) DISABLED by user");
12180 } else if (srvmapsref && srvmapslist && srvmapslist != srvmapsref) {
12181 msg.Form("+++ Info: dataset server mapping(s) modified by user");
12182 } else if (!srvmapsref && srvmapslist) {
12183 msg.Form("+++ Info: dataset server mapping(s) added by user");
12184 }
12186 }
12187 }
12188
12189 // Flag multi-datasets
12190 if (datasets->GetSize() > 1) dset->SetBit(TDSet::kMultiDSet);
12191 // Loop over the list of datasets
12192 TList *listOfMissingFiles = new TList;
12193 TEntryList *entrylist = 0;
12194 TPair *pair = 0;
12195 TIter nxds(datasets);
12196 while ((pair = (TPair *) nxds())) {
12197 // File Collection
12198 dataset = (TFileCollection *) pair->Key();
12199 // Entry list, if any
12200 TEntryList *enl = 0;
12201 TObjString *os = (TObjString *) pair->Value();
12202 if (strlen(os->GetName())) {
12203 if (!(enl = dynamic_cast<TEntryList *>(input->FindObject(os->GetName())))) {
12204 if (gProofServ)
12206 " entry list %s not found", os->GetName()));
12207 }
12208 if (enl && (!(enl->GetLists()) || enl->GetLists()->GetSize() <= 0)) {
12209 if (gProofServ)
12211 " no sub-lists in entry-list!"));
12212 }
12213 }
12214 TList *missingFiles = new TList;
12215 TSeqCollection* files = dataset->GetList();
12216 if (gDebug > 0) files->Print();
12217 Bool_t availableOnly = (lookupopt != "all") ? kTRUE : kFALSE;
12218 if (dset->TestBit(TDSet::kMultiDSet)) {
12219 TDSet *ds = new TDSet(dataset->GetName(), dset->GetObjName(), dset->GetDirectory());
12220 ds->SetSrvMaps(srvmapslist);
12221 if (!ds->Add(files, dsTree, availableOnly, missingFiles)) {
12222 emsg.Form("error integrating dataset %s", dataset->GetName());
12223 continue;
12224 }
12225 // Add the TDSet object to the multi-dataset
12226 dset->Add(ds);
12227 // Add entry list if any
12228 if (enl) ds->SetEntryList(enl);
12229 } else {
12230 dset->SetSrvMaps(srvmapslist);
12231 if (!dset->Add(files, dsTree, availableOnly, missingFiles)) {
12232 emsg.Form("error integrating dataset %s", dataset->GetName());
12233 continue;
12234 }
12235 if (enl) entrylist = enl;
12236 }
12237 if (missingFiles) {
12238 // The missing files objects have to be removed from the dataset
12239 // before delete.
12240 TIter next(missingFiles);
12241 TObject *file;
12242 while ((file = next())) {
12243 dataset->GetList()->Remove(file);
12244 listOfMissingFiles->Add(file);
12245 }
12246 missingFiles->SetOwner(kFALSE);
12247 missingFiles->Clear();
12248 }
12249 SafeDelete(missingFiles);
12250 }
12251 // Cleanup; we need to do this because pairs do no delete their content
12252 nxds.Reset();
12253 while ((pair = (TPair *) nxds())) {
12254 if (pair->Key()) delete pair->Key();
12255 if (pair->Value()) delete pair->Value();
12256 }
12257 datasets->SetOwner(kTRUE);
12258 SafeDelete(datasets);
12259
12260 // Cleanup the server mapping list, if created by the user
12261 if (srvmapslist && srvmapslist != srvmapsref) {
12262 srvmapslist->SetOwner(kTRUE);
12263 SafeDelete(srvmapslist);
12264 }
12265
12266 // Set the global entrylist, if required
12267 if (entrylist) dset->SetEntryList(entrylist);
12268
12269 // Make sure it will be sent back merged with other similar lists created
12270 // during processing; this list will be transferred by the player to the
12271 // output list, once the latter has been created (see TProofPlayerRemote::Process)
12272 if (listOfMissingFiles && listOfMissingFiles->GetSize() > 0) {
12273 listOfMissingFiles->SetName("MissingFiles");
12274 input->Add(listOfMissingFiles);
12275 }
12276
12277 // Done
12278 return 0;
12279}
12280
12281////////////////////////////////////////////////////////////////////////////////
12282/// Save input data file from 'cachedir' into the sandbox or create a the file
12283/// with input data objects
12284
12285Int_t TProof::SaveInputData(TQueryResult *qr, const char *cachedir, TString &emsg)
12286{
12287 TList *input = 0;
12288
12289 // We must have got something to process
12290 if (!qr || !(input = qr->GetInputList()) ||
12291 !cachedir || strlen(cachedir) <= 0) return 0;
12292
12293 // There must be some input data or input data file
12294 TNamed *data = (TNamed *) input->FindObject("PROOF_InputDataFile");
12295 TList *inputdata = (TList *) input->FindObject("PROOF_InputData");
12296 if (!data && !inputdata) return 0;
12297 // Default dstination filename
12298 if (!data)
12299 input->Add((data = new TNamed("PROOF_InputDataFile", kPROOF_InputDataFile)));
12300
12301 TString dstname(data->GetTitle()), srcname;
12302 Bool_t fromcache = kFALSE;
12303 if (dstname.BeginsWith("cache:")) {
12304 fromcache = kTRUE;
12305 dstname.ReplaceAll("cache:", "");
12306 srcname.Form("%s/%s", cachedir, dstname.Data());
12307 if (gSystem->AccessPathName(srcname)) {
12308 emsg.Form("input data file not found in cache (%s)", srcname.Data());
12309 return -1;
12310 }
12311 }
12312
12313 // If from cache, just move the cache file
12314 if (fromcache) {
12315 if (gSystem->CopyFile(srcname, dstname, kTRUE) != 0) {
12316 emsg.Form("problems copying %s to %s", srcname.Data(), dstname.Data());
12317 return -1;
12318 }
12319 } else {
12320 // Create the file
12321 if (inputdata && inputdata->GetSize() > 0) {
12322 TFile *f = TFile::Open(dstname.Data(), "RECREATE");
12323 if (f) {
12324 f->cd();
12325 inputdata->Write();
12326 f->Close();
12327 delete f;
12328 } else {
12329 emsg.Form("could not create %s", dstname.Data());
12330 return -1;
12331 }
12332 } else {
12333 emsg.Form("no input data!");
12334 return -1;
12335 }
12336 }
12337 ::Info("TProof::SaveInputData", "input data saved to %s", dstname.Data());
12338
12339 // Save the file name and clean up the data list
12340 data->SetTitle(dstname);
12341 if (inputdata) {
12342 input->Remove(inputdata);
12343 inputdata->SetOwner();
12344 delete inputdata;
12345 }
12346
12347 // Done
12348 return 0;
12349}
12350
12351////////////////////////////////////////////////////////////////////////////////
12352/// Send the input data file to the workers
12353
12355{
12356 TList *input = 0;
12357
12358 // We must have got something to process
12359 if (!qr || !(input = qr->GetInputList())) return 0;
12360
12361 // There must be some input data or input data file
12362 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12363 if (!inputdata) return 0;
12364
12365 TString fname(inputdata->GetTitle());
12366 if (gSystem->AccessPathName(fname)) {
12367 emsg.Form("input data file not found in sandbox (%s)", fname.Data());
12368 return -1;
12369 }
12370
12371 // PROOF session must available
12372 if (!p || !p->IsValid()) {
12373 emsg.Form("TProof object undefined or invalid: protocol error!");
12374 return -1;
12375 }
12376
12377 // Send to unique workers and submasters
12378 p->BroadcastFile(fname, TProof::kBinary, "cache");
12379
12380 // Done
12381 return 0;
12382}
12383
12384////////////////////////////////////////////////////////////////////////////////
12385/// Get the input data from the file defined in the input list
12386
12387Int_t TProof::GetInputData(TList *input, const char *cachedir, TString &emsg)
12388{
12389 // We must have got something to process
12390 if (!input || !cachedir || strlen(cachedir) <= 0) return 0;
12391
12392 // There must be some input data or input data file
12393 TNamed *inputdata = (TNamed *) input->FindObject("PROOF_InputDataFile");
12394 if (!inputdata) return 0;
12395
12396 TString fname;
12397 fname.Form("%s/%s", cachedir, inputdata->GetTitle());
12398 if (gSystem->AccessPathName(fname)) {
12399 emsg.Form("input data file not found in cache (%s)", fname.Data());
12400 return -1;
12401 }
12402
12403 // List of added objects (for proper cleaning ...)
12404 TList *added = new TList;
12405 added->SetName("PROOF_InputObjsFromFile");
12406 // Read the input data into the input list
12407 TFile *f = TFile::Open(fname.Data());
12408 if (f) {
12409 TList *keys = (TList *) f->GetListOfKeys();
12410 if (!keys) {
12411 emsg.Form("could not get list of object keys from file");
12412 return -1;
12413 }
12414 TIter nxk(keys);
12415 TKey *k = 0;
12416 while ((k = (TKey *)nxk())) {
12417 TObject *o = f->Get(k->GetName());
12418 if (o) {
12419 input->Add(o);
12420 added->Add(o);
12421 }
12422 }
12423 // Add the file as last one
12424 if (added->GetSize() > 0) {
12425 added->Add(f);
12426 input->Add(added);
12427 } else {
12428 // Cleanup the file now
12429 f->Close();
12430 delete f;
12431 }
12432 } else {
12433 emsg.Form("could not open %s", fname.Data());
12434 return -1;
12435 }
12436
12437 // Done
12438 return 0;
12439}
12440
12441////////////////////////////////////////////////////////////////////////////////
12442/// Start the log viewer window usign the plugin manager
12443
12444void TProof::LogViewer(const char *url, Int_t idx)
12445{
12446 if (!gROOT->IsBatch()) {
12447 // Get the handler, if not yet done
12448 if (!fgLogViewer) {
12449 if ((fgLogViewer =
12450 gROOT->GetPluginManager()->FindHandler("TProofProgressLog"))) {
12451 if (fgLogViewer->LoadPlugin() == -1) {
12452 fgLogViewer = 0;
12453 ::Error("TProof::LogViewer", "cannot load the relevant plug-in");
12454 return;
12455 }
12456 }
12457 }
12458 if (fgLogViewer) {
12459 // Execute the plug-in
12460 TString u = (url && strlen(url) <= 0) ? "lite" : url;
12461 fgLogViewer->ExecPlugin(2, u.Data(), idx);
12462 }
12463 } else {
12464 if (url && strlen(url) > 0) {
12465 ::Info("TProof::LogViewer",
12466 "batch mode: use TProofLog *pl = TProof::Mgr(\"%s\")->GetSessionLogs(%d)", url, idx);
12467 } else if (url && strlen(url) <= 0) {
12468 ::Info("TProof::LogViewer",
12469 "batch mode: use TProofLog *pl = TProof::Mgr(\"lite\")->GetSessionLogs(%d)", idx);
12470 } else {
12471 ::Info("TProof::LogViewer",
12472 "batch mode: use TProofLog *pl = TProof::Mgr(\"<master>\")->GetSessionLogs(%d)", idx);
12473 }
12474 }
12475 // Done
12476 return;
12477}
12478
12479////////////////////////////////////////////////////////////////////////////////
12480/// Enable/Disable the graphic progress dialog.
12481/// By default the dialog is enabled
12482
12484{
12485 if (on)
12487 else
12489}
12490
12491////////////////////////////////////////////////////////////////////////////////
12492/// Show information about missing files during query described by 'qr' or the
12493/// last query if qr is null (default).
12494/// A short summary is printed in the end.
12495
12497{
12498 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12499 if (!xqr) {
12500 Warning("ShowMissingFiles", "no (last) query found: do nothing");
12501 return;
12502 }
12503
12504 // Get the list, if any
12505 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12506 if (!missing) {
12507 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12508 return;
12509 }
12510
12511 Int_t nmf = 0, ncf = 0;
12512 Long64_t msz = 0, mszzip = 0, mev = 0;
12513 // Scan the list
12514 TFileInfo *fi = 0;
12515 TIter nxf(missing);
12516 while ((fi = (TFileInfo *) nxf())) {
12517 char status = 'M';
12518 if (fi->TestBit(TFileInfo::kCorrupted)) {
12519 ncf++;
12520 status = 'C';
12521 } else {
12522 nmf++;
12523 }
12524 TFileInfoMeta *im = fi->GetMetaData();
12525 if (im) {
12526 if (im->GetTotBytes() > 0) msz += im->GetTotBytes();
12527 if (im->GetZipBytes() > 0) mszzip += im->GetZipBytes();
12528 mev += im->GetEntries();
12529 Printf(" %d. (%c) %s %s %lld", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl(), im->GetName(), im->GetEntries());
12530 } else {
12531 Printf(" %d. (%c) %s '' -1", ncf+nmf, status, fi->GetCurrentUrl()->GetUrl());
12532 }
12533 }
12534
12535 // Final notification
12536 if (msz <= 0) msz = -1;
12537 if (mszzip <= 0) mszzip = -1;
12538 Double_t xf = (Double_t)mev / (mev + xqr->GetEntries()) ;
12539 if (msz > 0. || mszzip > 0.) {
12540 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12541 " about %.2f%% of the total (%lld bytes, %lld zipped)",
12542 nmf, ncf, mev, xf * 100., msz, mszzip);
12543 } else {
12544 Printf(" +++ %d file(s) missing, %d corrupted, i.e. %lld unprocessed events -->"
12545 " about %.2f%% of the total", nmf, ncf, mev, xf * 100.);
12546 }
12547}
12548
12549////////////////////////////////////////////////////////////////////////////////
12550/// Get a TFileCollection with the files missing in the query described by 'qr'
12551/// or the last query if qr is null (default).
12552/// Return a null pointer if none were found, for whatever reason.
12553/// The caller is responsible for the returned object.
12554
12556{
12557 TFileCollection *fc = 0;
12558
12559 TQueryResult *xqr = (qr) ? qr : GetQueryResult();
12560 if (!xqr) {
12561 Warning("GetMissingFiles", "no (last) query found: do nothing");
12562 return fc;
12563 }
12564
12565 // Get the list, if any
12566 TList *missing = (xqr->GetOutputList()) ? (TList *) xqr->GetOutputList()->FindObject("MissingFiles") : 0;
12567 if (!missing) {
12568 if (gDebug > 0)
12569 Info("ShowMissingFiles", "no files missing in query %s:%s", xqr->GetTitle(), xqr->GetName());
12570 return fc;
12571 }
12572
12573 // Create collection: name is <dsname>.m<j>, where 'j' is the first giving a non existing name
12574 TString fcname("unknown");
12575 TDSet *ds = (TDSet *) xqr->GetInputObject("TDSet");
12576 if (ds) {
12577 fcname.Form("%s.m0", ds->GetName());
12578 Int_t j = 1;
12579 while (gDirectory->FindObject(fcname) && j < 1000)
12580 fcname.Form("%s.m%d", ds->GetName(), j++);
12581 }
12582 fc = new TFileCollection(fcname, "Missing Files");
12583 if (ds) fc->SetDefaultTreeName(ds->GetObjName());
12584 // Scan the list
12585 TFileInfo *fi = 0;
12586 TIter nxf(missing);
12587 while ((fi = (TFileInfo *) nxf())) {
12588 fc->Add((TFileInfo *) fi->Clone());
12589 }
12590 fc->Update();
12591 // Done
12592 return fc;
12593}
12594
12595////////////////////////////////////////////////////////////////////////////////
12596/// Enable/Disable saving of the performance tree
12597
12598void TProof::SetPerfTree(const char *pf, Bool_t withWrks)
12599{
12600 if (pf && strlen(pf) > 0) {
12601 fPerfTree = pf;
12602 SetParameter("PROOF_StatsHist", "");
12603 SetParameter("PROOF_StatsTrace", "");
12604 if (withWrks) SetParameter("PROOF_SlaveStatsTrace", "");
12605 Info("SetPerfTree", "saving of the performance tree enabled (%s)", fPerfTree.Data());
12606 } else {
12607 fPerfTree = "";
12608 DeleteParameters("PROOF_StatsHist");
12609 DeleteParameters("PROOF_StatsTrace");
12610 DeleteParameters("PROOF_SlaveStatsTrace");
12611 Info("SetPerfTree", "saving of the performance tree disabled");
12612 }
12613}
12614
12615////////////////////////////////////////////////////////////////////////////////
12616/// Save performance information from TPerfStats to file 'pf'.
12617/// If 'ref' is defined, do it for query 'ref'.
12618/// Return 0 on sucecss, -1 in case of any error
12619
12620Int_t TProof::SavePerfTree(const char *pf, const char *ref)
12621{
12622 if (!IsValid()) {
12623 Error("SafePerfTree", "this TProof instance is invalid!");
12624 return -1;
12625 }
12626
12627 TList *outls = GetOutputList();
12628 TString sref;
12629 if (ref && strlen(ref) > 0) {
12630 if (!fPlayer) {
12631 Error("SafePerfTree", "requested to use query '%s' but player instance undefined!", ref);
12632 return -1;
12633 }
12635 if (!qr) {
12636 Error("SafePerfTree", "TQueryResult instance for query '%s' could not be retrieved", ref);
12637 return -1;
12638 }
12639 outls = qr->GetOutputList();
12640 sref.Form(" for requested query '%s'", ref);
12641 }
12642 if (!outls || (outls && outls->GetSize() <= 0)) {
12643 Error("SafePerfTree", "outputlist%s undefined or empty", sref.Data());
12644 return -1;
12645 }
12646
12647 TString fn = fPerfTree;
12648 if (pf && strlen(pf)) fn = pf;
12649 if (fn.IsNull()) fn = "perftree.root";
12650
12651 TFile f(fn, "RECREATE");
12652 if (f.IsZombie()) {
12653 Error("SavePerfTree", "could not open file '%s' for writing", fn.Data());
12654 } else {
12655 f.cd();
12656 TIter nxo(outls);
12657 TObject* obj = 0;
12658 while ((obj = nxo())) {
12659 TString objname(obj->GetName());
12660 if (objname.BeginsWith("PROOF_")) {
12661 // Must list the objects since other PROOF_ objects exist
12662 // besides timing objects
12663 if (objname == "PROOF_PerfStats" ||
12664 objname == "PROOF_PacketsHist" ||
12665 objname == "PROOF_EventsHist" ||
12666 objname == "PROOF_NodeHist" ||
12667 objname == "PROOF_LatencyHist" ||
12668 objname == "PROOF_ProcTimeHist" ||
12669 objname == "PROOF_CpuTimeHist")
12670 obj->Write();
12671 }
12672 }
12673 f.Close();
12674 }
12675 Info("SavePerfTree", "performance information%s saved in %s ...", sref.Data(), fn.Data());
12676
12677 // Done
12678 return 0;
12679}
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:550
#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:166
const Bool_t kIterBackward
Definition: TCollection.h:41
#define gDirectory
Definition: TDirectory.h:223
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:555
const Bool_t kSortDescending
Definition: TList.h:38
R__EXTERN TProofDebug::EProofDebugMask gProofDebugMask
Definition: TProofDebug.h:53
#define PDB(mask, level)
Definition: TProofDebug.h:56
R__EXTERN Int_t gProofDebugLevel
Definition: TProofDebug.h:54
R__EXTERN TProofServ * gProofServ
Definition: TProofServ.h:347
static Int_t PoDCheckUrl(TString *_cluster)
This a private API function.
Definition: TProof.cxx:341
TProof * gProof
Definition: TProof.cxx:102
const char *const kPROOF_WorkerIdleTO
Definition: TProof.h:135
const char *const kPROOF_PackDir
Definition: TProof.h:126
const char *const kPROOF_ConfFile
Definition: TProof.h:122
const char *const kPROOF_WorkDir
Definition: TProof.h:124
const Long64_t kPROOF_DynWrkPollInt_s
Definition: TProof.h:138
const char *const kPROOF_InputDataFile
Definition: TProof.h:136
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:415
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
TObject * ReadObject(const TClass *cl) override
Read object from I/O buffer.
void WriteString(const char *s) override
Write string to I/O buffer.
char * ReadString(char *s, Int_t max) override
Read string from I/O buffer.
void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
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.
Bool_t cd(const char *path=nullptr) override
Change current directory to "this" directory.
Utility class to draw objects in the feedback list during queries.
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 Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1362
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=nullptr)
Resolve the file type as a function of the protocol field in 'name'.
Definition: TFile.cxx:4637
EFileType
File type.
Definition: TFile.h:189
@ kWeb
Definition: TFile.h:189
@ kNet
Definition: TFile.h:189
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:4820
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3923
void Close(Option_t *option="") override
Close a file.
Definition: TFile.cxx:856
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:72
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:325
Bool_t AreAllWorkersMerged()
Return if merger has already merged all workers, i.e. if it has finished its merging job.
Definition: TProof.cxx:317
TSlave * GetMerger()
Definition: TProof.h:274
virtual ~TMergerInfo()
Destructor.
Definition: TProof.cxx:281
Int_t fWorkersToMerge
Definition: TProof.h:254
Bool_t IsActive()
Definition: TProof.h:288
TList * fWorkers
Definition: TProof.h:259
void SetMergedWorker()
Increase number of already merged workers by 1.
Definition: TProof.cxx:292
void AddWorker(TSlave *sl)
Add new worker to the list of workers to be merged by this merger.
Definition: TProof.cxx:303
void Deactivate()
Definition: TProof.h:287
Int_t fMergedWorkers
Definition: TProof.h:256
TList * GetWorkers()
Definition: TProof.h:272
Int_t GetPort()
Definition: TProof.h:275
void AddMergedObjects(Int_t objects)
Definition: TProof.h:282
static void EnableSchemaEvolutionForAll(Bool_t enable=kTRUE)
Static function enabling or disabling the automatic schema evolution.
Definition: TMessage.cxx:116
UInt_t What() const
Definition: TMessage.h:75
void SetWhat(UInt_t what)
Using this method one can change the message type a-posteriori In case you OR "what" with kMESS_ACK,...
Definition: TMessage.cxx:222
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition: TMonitor.cxx:241
virtual void ActivateAll()
Activate all de-activated sockets.
Definition: TMonitor.cxx:268
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition: TMonitor.cxx:322
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition: TMonitor.cxx:250
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition: TMonitor.cxx:168
void ResetInterrupt()
Definition: TMonitor.h:72
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition: TMonitor.cxx:438
virtual void DeActivateAll()
De-activate all activated sockets.
Definition: TMonitor.cxx:302
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition: TMonitor.cxx:284
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition: TMonitor.cxx:498
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition: TMonitor.cxx:214
void Interrupt()
Definition: TMonitor.h:71
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TNamed()
Definition: TNamed.h:36
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Collectable string class.
Definition: TObjString.h:28
const char * GetName() const
Returns name of object.
Definition: TObjString.h:38
const TString & GetString() const
Definition: TObjString.h:46
TString & String()
Definition: TObjString.h:48
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
@ kSingleKey
write collection with single key
Definition: TObject.h:87
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
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:163
TSocket * fSocket
Definition: TProof.h:200
Bool_t Notify()
TProof interrupt handler.
Definition: TProof.cxx:116
void IncreaseIdx()
Definition: TProof.h:311
void DecreaseNWrks()
Definition: TProof.h:309
void Reset(Int_t n=-1)
Definition: TProof.h:312
const char * Export(Bool_t &changed)
Definition: TProof.h:304
static char fgCr[4]
Definition: TProof.h:300
void IncreaseNWrks()
Definition: TProof.h:310
void SetNWrks(Int_t n)
Definition: TProof.h:313
The PROOF manager interacts with the PROOF server coordinator to create or destroy a PROOF session,...
Definition: TProofMgr.h:43
virtual Int_t Reset(Bool_t hard=kFALSE, const char *usr=0)
Send a cleanup request for the sessions associated with the current user.
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:8971
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:6506
Int_t GetNumberOfInactiveSlaves() const
Return number of inactive slaves, i.e.
Definition: TProof.cxx:1975
void ShowPackages(Bool_t all=kFALSE, Bool_t redirlog=kFALSE)
List contents of package directory.
Definition: TProof.cxx:7743
virtual void ShowData()
List contents of the data directory in the sandbox.
Definition: TProof.cxx:7369
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:7041
static TProofMgr * Mgr(const char *url)
Get instance of the effective manager for 'url' Return 0 on failure.
Definition: TProof.cxx:11697
Bool_t CreateMerger(TSlave *sl, Int_t port)
Create a new merger.
Definition: TProof.cxx:4427
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:2430
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:2084
TProofMgr * fManager
Definition: TProof.h:587
void ActivateAsyncInput()
Activate the a-sync input handler.
Definition: TProof.cxx:4383
TList * GetOutputNames()
FIXME: to be written.
Definition: TProof.cxx:10091
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:6232
void PutLog(TQueryResult *qr)
Display log of query pq into the log window frame.
Definition: TProof.cxx:10294
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:6331
void Activate(TList *slaves=0)
Activate slave server list.
Definition: TProof.cxx:2368
Int_t UploadPackage(const char *par, EUploadPackageOpt opt=kUntar, TList *workers=0)
Upload a PROOF archive (PAR file).
Definition: TProof.cxx:8414
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:5205
Int_t SendCurrentState(ESlaves list=kActive)
Transfer the current state of the master to the active slave servers.
Definition: TProof.cxx:6731
void Close(Option_t *option="")
Close all open slave servers.
Definition: TProof.cxx:1777
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:7085
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:7915
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:8307
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:11249
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:12285
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:2144
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:7963
Bool_t IsTty() const
Definition: TProof.h:938
virtual void Print(Option_t *option="") const
Print status of PROOF cluster.
Definition: TProof.cxx:4776
Int_t GetClientProtocol() const
Definition: TProof.h:914
Int_t fCollectTimeout
Definition: TProof.h:583
virtual ~TProof()
Clean up PROOF environment.
Definition: TProof.cxx:646
EQueryMode fQueryMode
Definition: TProof.h:588
void RemoveChain(TChain *chain)
Remove chain from data set.
Definition: TProof.cxx:10204
void SetupWorkersEnv(TList *wrks, Bool_t increasingpool=kFALSE)
Set up packages, loaded macros, include and lib paths ...
Definition: TProof.cxx:1513
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:12387
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:7027
Int_t HandleOutputOptions(TString &opt, TString &target, Int_t action)
Extract from opt information about output handling settings.
Definition: TProof.cxx:4910
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:9962
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:12444
TVirtualProofPlayer * GetPlayer() const
Definition: TProof.h:716
void CleanGDirectory(TList *ol)
Remove links to objects in list 'ol' from gDirectory.
Definition: TProof.cxx:3019
void DeActivateAsyncInput()
De-activate a-sync input handler.
Definition: TProof.cxx:4396
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:2546
static void ResetEnvVars()
Clear the list of environment variables passed to proofserv on the master and slaves.
Definition: TProof.cxx:11769
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:9495
void AskParallel()
Ask the for the number of parallel slaves.
Definition: TProof.cxx:2056
FileMap_t fFileMap
Definition: TProof.h:502
virtual void ClearCache(const char *file=0)
Remove file from all file caches.
Definition: TProof.cxx:7687
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:10869
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:11326
Int_t CleanupSession(const char *sessiontag)
Send cleanup request for the session specified by tag.
Definition: TProof.cxx:6065
virtual Bool_t CancelStagingDataSet(const char *dataset)
Cancels a dataset staging request.
Definition: TProof.cxx:11019
TList * fChains
Definition: TProof.h:496
TObject * GetParameter(const char *par) const
Get specified parameter.
Definition: TProof.cxx:9891
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:6030
void AskForOutput(TSlave *sl)
Master asks for output from worker sl.
Definition: TProof.cxx:4307
TList * GetListOfPackages()
Get from the master the list of names of the packages available.
Definition: TProof.cxx:9081
TQueryResult * GetQueryResult(const char *ref=0)
Return pointer to the full TQueryResult instance owned by the player and referenced by 'ref'.
Definition: TProof.cxx:2127
Int_t GetNumberOfSlaves() const
Return number of slaves as described in the config file.
Definition: TProof.cxx:1957
void StartupMessage(const char *msg, Bool_t status, Int_t done, Int_t total)
Send startup message.
Definition: TProof.cxx:9285
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:8572
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:8861
virtual TMap * GetDataSets(const char *uri="", const char *optStr="")
Lists all datasets that match given uri.
Definition: TProof.cxx:10782
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:7664
void ClearFeedback()
Clear feedback list.
Definition: TProof.cxx:9985
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:11556
void Browse(TBrowser *b)
Build the PROOF's structure in the browser.
Definition: TProof.cxx:10152
Int_t GetPort() const
Definition: TProof.h:912
void InterruptCurrentMonitor()
If in active in a monitor set ready state.
Definition: TProof.cxx:11308
void ResetMergePrg()
Reset the merge progress notificator.
Definition: TProof.cxx:2444
void SetPerfTree(const char *pf="perftree.root", Bool_t withWrks=kFALSE)
Enable/Disable saving of the performance tree.
Definition: TProof.cxx:12598
void ClearData(UInt_t what=kUnregistered, const char *dsname=0)
Remove files for the data directory.
Definition: TProof.cxx:7385
Bool_t IsValid() const
Definition: TProof.h:937
void Touch()
Ping PROOF slaves. Returns the number of slaves that responded.
Definition: TProof.cxx:4755
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:1254
virtual void ShowStagingStatusDataSet(const char *dataset, const char *optStr="filter:SsCc")
Like GetStagingStatusDataSet, but displays results immediately.
Definition: TProof.cxx:11089
Int_t VerifyDataSetParallel(const char *uri, const char *optStr)
Internal function for parallel dataset verification used TProof::VerifyDataSet and TProofLite::Verify...
Definition: TProof.cxx:11154
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:11362
Int_t SetParallel(Int_t nodes=-1, Bool_t random=kFALSE)
Tell PROOF how many slaves to use in parallel.
Definition: TProof.cxx:7113
Int_t GoMoreParallel(Int_t nWorkersToAdd)
Add nWorkersToAdd workers to current list of workers.
Definition: TProof.cxx:7143
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:10887
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:4277
@ 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:6638
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:11733
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:6468
virtual void ShowDataSets(const char *uri="", const char *optStr="")
Shows datasets in locations that match the uri.
Definition: TProof.cxx:10819
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:2648
Float_t GetCpuTime() const
Definition: TProof.h:931
void ClearDataProgress(Int_t r, Int_t t)
Progress bar for clear data.
Definition: TProof.cxx:7643
static Int_t SendInputData(TQueryResult *qr, TProof *p, TString &emsg)
Send the input data file to the workers.
Definition: TProof.cxx:12354
void SetPlayer(TVirtualProofPlayer *player)
Set a new PROOF player.
Definition: TProof.cxx:10172
Int_t ClearPackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7830
Int_t SendInitialState()
Transfer the initial (i.e.
Definition: TProof.cxx:6747
Int_t AddWorkers(TList *wrks)
Works on the master node only.
Definition: TProof.cxx:1305
void GetStatistics(Bool_t verbose=kFALSE)
Get statistics about CPU time, real time and bytes read.
Definition: TProof.cxx:2014
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:10680
Int_t Broadcast(const TMessage &mess, TList *slaves)
Broadcast a message to all slaves in the specified list.
Definition: TProof.cxx:2454
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:9906
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:9612
void InitMembers()
Default initializations.
Definition: TProof.cxx:521
void RedirectWorker(TSocket *s, TSlave *sl, Int_t output_size)
Redirect output of worker sl to some merger.
Definition: TProof.cxx:4231
void HandleSubmerger(TMessage *mess, TSlave *sl)
Process a message of type kPROOF_SUBMERGER.
Definition: TProof.cxx:3987
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:9558
Int_t fStatus
Definition: TProof.h:470
TList * fRunningDSets
Definition: TProof.h:581
Int_t ClearPackages()
Remove all packages.
Definition: TProof.cxx:7813
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:9795
virtual Bool_t StartSlaves(Bool_t attach=kFALSE)
Start up PROOF slaves.
Definition: TProof.cxx:1639
Int_t Ping()
Ping PROOF. Returns 1 if master server responded.
Definition: TProof.cxx:4717
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:1854
void SaveActiveList()
Save current list of active workers.
Definition: TProof.cxx:11515
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:10739
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:12496
Int_t RemoveIncludePath(const char *incpath, Bool_t onClient=kFALSE)
Remove 'incpath' from the inc path search.
Definition: TProof.cxx:8940
void SetMonitor(TMonitor *mon=0, Bool_t on=kTRUE)
Activate (on == TRUE) or deactivate (on == FALSE) all sockets monitored by 'mon'.
Definition: TProof.cxx:2387
Int_t GetParallel() const
Returns number of slaves active in parallel mode.
Definition: TProof.cxx:2283
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:8087
void RemoveFeedback(const char *name)
Remove object from feedback list.
Definition: TProof.cxx:9973
Int_t Remove(Int_t query, Bool_t all=kFALSE)
Send remove request for the qry-th query in fQueries.
Definition: TProof.cxx:5986
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:4326
void AskStatistics()
Ask the for the statistics of the slaves.
Definition: TProof.cxx:2001
virtual void SetAlias(const char *alias="")
Set an alias for this session.
Definition: TProof.cxx:10556
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:10491
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:9113
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:746
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:6119
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:11343
@ 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:7069
void cd(Int_t id=-1)
Set session with 'id' the default one.
Definition: TProof.cxx:10469
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:12555
void ParseConfigField(const char *config)
The config file field may contain special instructions which need to be parsed at the beginning,...
Definition: TProof.cxx:1032
Int_t GetNumberOfBadSlaves() const
Return number of bad slaves.
Definition: TProof.cxx:1993
Int_t Retrieve(Int_t query, const char *path=0)
Send retrieve request for the qry-th query in fQueries.
Definition: TProof.cxx:5921
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:2589
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:9931
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:9309
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:10964
void LogMessage(const char *msg, Bool_t all)
Log a message into the appropriate window by emitting a signal.
Definition: TProof.cxx:6387
static void Reset(const char *url, Bool_t hard=kFALSE)
Wrapper around TProofMgr::Reset(...).
Definition: TProof.cxx:11709
virtual Int_t PollForNewWorkers()
Asks the PROOF Serv for new workers in Dynamic Startup mode and activates them.
Definition: TProof.cxx:2943
Int_t fLastAssignedMerger
Definition: TProof.h:552
TList * GetQueryResults()
Return pointer to the list of query results in the player.
Definition: TProof.cxx:2118
void ShowFeedback() const
Show items in feedback list.
Definition: TProof.cxx:9993
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:7246
void SetQueryMode(EQueryMode mode)
Change query running mode to the one specified by 'mode'.
Definition: TProof.cxx:6080
Int_t UnloadPackages()
Unload all packages.
Definition: TProof.cxx:8120
virtual TVirtualProofPlayer * MakePlayer(const char *player=0, TSocket *s=0)
Construct a TProofPlayer object.
Definition: TProof.cxx:10184
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:10983
Int_t SavePerfTree(const char *pf=0, const char *qref=0)
Save performance information from TPerfStats to file 'pf'.
Definition: TProof.cxx:12620
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:8601
@ 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:8816
TProof()
Protected constructor to be used by classes deriving from TProof (they have to call Init themselves a...
Definition: TProof.cxx:507
Bool_t fDynamicStartup
Definition: TProof.h:589
Int_t RemoveWorkers(TList *wrks)
Used for shuting down the workres after a query is finished.
Definition: TProof.cxx:1576
void Progress(Long64_t total, Long64_t processed)
Get query progress information.
Definition: TProof.cxx:9174
Long64_t Finalize(Int_t query=-1, Bool_t force=kFALSE)
Finalize the qry-th query in fQueries.
Definition: TProof.cxx:5856
Int_t RemoveDynamicPath(const char *libpath, Bool_t onClient=kFALSE)
Remove 'libpath' from the lib path search.
Definition: TProof.cxx:8906
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:11282
Bool_t fIsPollingWorkers
Definition: TProof.h:475
void DeleteDrawFeedback(TDrawFeedback *f)
Delete draw feedback object.
Definition: TProof.cxx:10083
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:11046
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:6772
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:7622
void SetProgressDialog(Bool_t on=kTRUE)
Enable/Disable the graphic progress dialog.
Definition: TProof.cxx:12483
TString fLogFileName
Definition: TProof.h:511
void GoAsynchronous()
Send GOASYNC message to the master.
Definition: TProof.cxx:6240
Int_t fCheckFileStatus
Definition: TProof.h:471
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:9781
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:1286
TString Getenv(const char *env, const char *ord="0")
Get value of environment variable 'env' on node 'ord'.
Definition: TProof.cxx:6617
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:6197
TList * GetEnabledPackages() const
Definition: TProof.h:735
Int_t GetNumberOfActiveSlaves() const
Return number of active slaves, i.e.
Definition: TProof.cxx:1966
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:1832
void GetMaxQueries()
Get max number of queries whose full results are kept in the remote sandbox.
Definition: TProof.cxx:2107
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:6867
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:11988
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:2255
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:10608
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:4494
Int_t SendGroupView()
Send to all active slaves servers the current slave group size and their unique id.
Definition: TProof.cxx:6433
Bool_t IsProofd() const
Definition: TProof.h:934
Int_t RestoreActiveList()
Restore saved list of active workers.
Definition: TProof.cxx:11530
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:7001
void ShowLog(Int_t qry=-1)
Display on screen the content of the temporary log file.
Definition: TProof.cxx:10344
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:9511
Int_t SendCommand(const char *cmd, ESlaves list=kActive)
Send command to be executed on the PROOF master and/or slaves.
Definition: TProof.cxx:6604
void Feedback(TList *objs)
Get list of feedback objects.
Definition: TProof.cxx:9241
virtual Bool_t RequestStagingDataSet(const char *dataset)
Allows users to request staging of a particular dataset.
Definition: TProof.cxx:10993
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:9735
TList * GetListOfSlaveInfos()
Returns list of TSlaveInfo's. In case of error return 0.
Definition: TProof.cxx:2300
virtual TTree * GetTreeHeader(TDSet *tdset)
Creates a tree header (a tree with nonexisting files) object for the DataSet.
Definition: TProof.cxx:10015
virtual void ValidateDSet(TDSet *dset)
Validate a TDSet.
Definition: TProof.cxx:9353
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:10657
@ 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:1891
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:4669
static void SystemCmd(const char *cmd, Int_t fdout)
Exec system command 'cmd'. If fdout > -1, append the output to fdout.
Definition: TProof.cxx:7708
EQueryMode GetQueryMode(Option_t *mode=0) const
Find out the query mode based on the current setting and 'mode'.
Definition: TProof.cxx:6092
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:8042
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:9272
void SetDrawFeedbackOption(TDrawFeedback *f, Option_t *opt)
Set draw feedback option.
Definition: TProof.cxx:10075
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:10910
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:10067
void AddChain(TChain *chain)
Add chain to data set.
Definition: TProof.cxx:10196
static const TList * GetEnvVars()
Get environemnt variables.
Definition: TProof.cxx:11724
TSlave * FindSlave(TSocket *s) const
Find slave that has TSocket s. Returns 0 in case slave is not found.
Definition: TProof.cxx:1870
TString fGroup
Definition: TProof.h:468
TList * GetListOfEnabledPackages()
Get from the master the list of names of the packages enabled.
Definition: TProof.cxx:9097
TList * GetFeedbackList() const
Return feedback list.
Definition: TProof.cxx:10006
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:9585
TList * fEnabledPackages
Definition: TProof.h:580
virtual TList * GetListOfQueries(Option_t *opt="")
Ask the master for the list of queries.
Definition: TProof.cxx:2067
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:11755
Int_t BroadcastObject(const TObject *obj, Int_t kind, TList *slaves)
Broadcast an object to all slaves in the specified list.
Definition: TProof.cxx:2522
void SetLogLevel(Int_t level, UInt_t mask=TProofDebug::kAll)
Set server logging level.
Definition: TProof.cxx:7052
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:5276
void ClearInput()
Clear input object list.
Definition: TProof.cxx:9715
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:1005
Int_t DisablePackage(const char *package)
Remove a specific package.
Definition: TProof.cxx:7858
Int_t GetQueryReference(Int_t qry, TString &ref)
Get reference for the qry-th query in fQueries (as displayed by ShowQueries).
Definition: TProof.cxx:5830
Int_t GetNumberOfUniqueSlaves() const
Return number of unique slaves, i.e.
Definition: TProof.cxx:1984
virtual Bool_t ExistsDataSet(const char *dataset)
Returns kTRUE if 'dataset' exists, kFALSE otherwise.
Definition: TProof.cxx:10841
void ShowDataSet(const char *dataset="", const char *opt="filter:SsCc")
display meta-info for given dataset usi
Definition: TProof.cxx:10950
Int_t HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail=kFALSE)
Analyze the received message.
Definition: TProof.cxx:3078
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:9707
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:6260
Bool_t IsMaster() const
Definition: TProof.h:936
void CloseProgressDialog()
Close progress dialog.
Definition: TProof.cxx:9256
TProofOutputList fOutputList
Definition: TProof.h:538
Int_t GetActiveMergersCount()
Get the active mergers count.
Definition: TProof.cxx:4409
void DataSetStatus(const char *msg, Bool_t status, Int_t done, Int_t total)
Send dataset preparation status.
Definition: TProof.cxx:9297
TMacro * GetLastLog()
Fill a TMacro with the log lines since the last reading (fLogFileR) Return (TMacro *)0 if no line was...
Definition: TProof.cxx:10230
TList * GetInputList()
Get input list.
Definition: TProof.cxx:9726
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:2633
void ShowEnabledPackages(Bool_t all=kFALSE)
List which packages are enabled.
Definition: TProof.cxx:7791
void SetMaxDrawQueries(Int_t max)
Set max number of draw queries whose results are saved.
Definition: TProof.cxx:2094
void GetLog(Int_t start=-1, Int_t end=-1)
Ask for remote logs in the range [start, end].
Definition: TProof.cxx:10213
Int_t CollectInputFrom(TSocket *s, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Collect and analyze available input from socket s.
Definition: TProof.cxx:3033
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:9342
virtual void SaveWorkerInfo()
Save information about the worker set in the file .workers in the working dir.
Definition: TProof.cxx:11781
Int_t EnablePackage(const char *package, Bool_t notOnClient=kFALSE, TList *workers=0)
Enable specified package.
Definition: TProof.cxx:8148
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:2219
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:11103
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:2741
static void SetMacroPath(const char *newpath)
Set or extend the macro search path.
Definition: TROOT.cxx:2767
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:177
TString fMsd
Definition: TProof.h:218
SysInfo_t GetSysInfo() const
Definition: TProof.h:233
TString fDataDir
Definition: TProof.h:219
Int_t fPerfIndex
Definition: TProof.h:220
void SetStatus(ESlaveStatus stat)
Definition: TProof.h:234
@ 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:262
void SetOrdinal(const char *ord)
Definition: TProof.h:236
SysInfo_t fSysInfo
Definition: TProof.h:221
const char * GetName() const
Returns name of object.
Definition: TProof.h:231
Bool_t IsEqual(const TObject *obj) const
Used to compare slaveinfos by ordinal.
Definition: TProof.cxx:205
const char * GetDataDir() const
Definition: TProof.h:229
void Print(Option_t *option="") const
Print slave info.
Definition: TProof.cxx:219
Class describing a PROOF worker server.
Definition: TSlave.h:46
Int_t fStatus
Definition: TSlave.h:96
Int_t fParallel
Definition: TSlave.h:97
virtual void SetAlias(const char *alias)
Set an alias for this session.
Definition: TSlave.cxx: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:3881
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:286
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1265
const char * pwd()
Definition: TSystem.h:425
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:270
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:4133
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:1497
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1014
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:717
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1332
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1653
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3955
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4232
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:914
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:663
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:4168
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:672
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:1389
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:1287
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:1488
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:681
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:942
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:542
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1783
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:690
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:313
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1645
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:959
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1794
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:879
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1537
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2336
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:552
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1637
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3865
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1372
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1589
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:1703
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1473
A TTree represents a columnar dataset.
Definition: TTree.h:72
virtual Long64_t GetMaxEntryLoop() const
Definition: TTree.h:484
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:71
void SetUser(const char *user)
Definition: TUrl.h:84
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:67
const char * GetHost() const
Definition: TUrl.h:69
void SetOptions(const char *opt)
Definition: TUrl.h:89
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
const char * GetOptions() const
Definition: TUrl.h:73
void SetHost(const char *host)
Definition: TUrl.h:86
const char * GetProtocol() const
Definition: TUrl.h:66
void SetPort(Int_t port)
Definition: TUrl.h:90
Int_t GetPort() const
Definition: TUrl.h:80
void SetPasswd(const char *pw)
Definition: TUrl.h:85
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:703
Double_t Sqrt(Double_t x)
Definition: TMath.h:681
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