1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.21 2006/12/07 08:51:26 jgrosseo
20 table, db names in ldap configuration
21 added GRP preprocessor
22 DCS data can also be retrieved by data point
24 Revision 1.20 2006/11/16 16:16:48 jgrosseo
25 introducing strict run ordering flag
26 removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
28 Revision 1.19 2006/11/06 14:23:04 jgrosseo
29 major update (Alberto)
30 o) reading of run parameters from the logbook
31 o) online offline naming conversion
32 o) standalone DCSclient package
34 Revision 1.18 2006/10/20 15:22:59 jgrosseo
35 o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
36 o) Merging Collect, CollectAll, CollectNew function
37 o) Removing implementation of empty copy constructors (declaration still there!)
39 Revision 1.17 2006/10/05 16:20:55 jgrosseo
40 adapting to new CDB classes
42 Revision 1.16 2006/10/05 15:46:26 jgrosseo
43 applying to the new interface
45 Revision 1.15 2006/10/02 16:38:39 jgrosseo
48 storing of objects that failed to be stored to the grid before
49 interfacing of shuttle status table in daq system
51 Revision 1.14 2006/08/29 09:16:05 jgrosseo
54 Revision 1.13 2006/08/15 10:50:00 jgrosseo
55 effc++ corrections (alberto)
57 Revision 1.12 2006/08/08 14:19:29 jgrosseo
58 Update to shuttle classes (Alberto)
60 - Possibility to set the full object's path in the Preprocessor's and
61 Shuttle's Store functions
62 - Possibility to extend the object's run validity in the same classes
63 ("startValidity" and "validityInfinite" parameters)
64 - Implementation of the StoreReferenceData function to store reference
65 data in a dedicated CDB storage.
67 Revision 1.11 2006/07/21 07:37:20 jgrosseo
68 last run is stored after each run
70 Revision 1.10 2006/07/20 09:54:40 jgrosseo
71 introducing status management: The processing per subdetector is divided into several steps,
72 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
73 can keep track of the number of failures and skips further processing after a certain threshold is
74 exceeded. These thresholds can be configured in LDAP.
76 Revision 1.9 2006/07/19 10:09:55 jgrosseo
77 new configuration, accesst to DAQ FES (Alberto)
79 Revision 1.8 2006/07/11 12:44:36 jgrosseo
80 adding parameters for extended validity range of data produced by preprocessor
82 Revision 1.7 2006/07/10 14:37:09 jgrosseo
83 small fix + todo comment
85 Revision 1.6 2006/07/10 13:01:41 jgrosseo
86 enhanced storing of last sucessfully processed run (alberto)
88 Revision 1.5 2006/07/04 14:59:57 jgrosseo
89 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
91 Revision 1.4 2006/06/12 09:11:16 jgrosseo
92 coding conventions (Alberto)
94 Revision 1.3 2006/06/06 14:26:40 jgrosseo
95 o) removed files that were moved to STEER
96 o) shuttle updated to follow the new interface (Alberto)
98 Revision 1.2 2006/03/07 07:52:34 hristov
99 New version (B.Yordanov)
101 Revision 1.6 2005/11/19 17:19:14 byordano
102 RetrieveDATEEntries and RetrieveConditionsData added
104 Revision 1.5 2005/11/19 11:09:27 byordano
105 AliShuttle declaration added
107 Revision 1.4 2005/11/17 17:47:34 byordano
108 TList changed to TObjArray
110 Revision 1.3 2005/11/17 14:43:23 byordano
113 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
114 Initial import as subdirectory in AliRoot
116 Revision 1.2 2005/09/13 08:41:15 byordano
117 default startTime endTime added
119 Revision 1.4 2005/08/30 09:13:02 byordano
122 Revision 1.3 2005/08/29 21:15:47 byordano
128 // This class is the main manager for AliShuttle.
129 // It organizes the data retrieval from DCS and call the
130 // interface methods of AliPreprocessor.
131 // For every detector in AliShuttleConfgi (see AliShuttleConfig),
132 // data for its set of aliases is retrieved. If there is registered
133 // AliPreprocessor for this detector then it will be used
134 // accroding to the schema (see AliPreprocessor).
135 // If there isn't registered AliPreprocessor than the retrieved
136 // data is stored automatically to the undelying AliCDBStorage.
137 // For detSpec is used the alias name.
140 #include "AliShuttle.h"
142 #include "AliCDBManager.h"
143 #include "AliCDBStorage.h"
144 #include "AliCDBId.h"
145 #include "AliCDBRunRange.h"
146 #include "AliCDBPath.h"
147 #include "AliCDBEntry.h"
148 #include "AliShuttleConfig.h"
149 #include "DCSClient/AliDCSClient.h"
151 #include "AliPreprocessor.h"
152 #include "AliShuttleStatus.h"
153 #include "AliShuttleLogbookEntry.h"
158 #include <TTimeStamp.h>
159 #include <TObjString.h>
160 #include <TSQLServer.h>
161 #include <TSQLResult.h>
167 #include <sys/types.h>
168 #include <sys/wait.h>
172 TString AliShuttle::fgkMainCDB("alien://folder=ShuttleCDB");
173 TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
174 TString AliShuttle::fgkMainRefStorage("alien://folder=ShuttleReference");
175 TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
177 Bool_t AliShuttle::fgkProcessDCS(kTRUE);
179 const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
180 const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
182 //______________________________________________________________________________________________
183 AliShuttle::AliShuttle(const AliShuttleConfig* config,
184 UInt_t timeout, Int_t retries):
186 fTimeout(timeout), fRetries(retries),
197 // config: AliShuttleConfig used
198 // timeout: timeout used for AliDCSClient connection
199 // retries: the number of retries in case of connection error.
202 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
203 for(int iSys=0;iSys<4;iSys++) {
206 fFXSlist[iSys].SetOwner(kTRUE);
208 fPreprocessorMap.SetOwner(kTRUE);
210 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
211 fFirstUnprocessed[iDet] = kFALSE;
213 fMonitoringMutex = new TMutex();
216 //______________________________________________________________________________________________
217 AliShuttle::~AliShuttle()
221 fPreprocessorMap.DeleteAll();
222 for(int iSys=0;iSys<4;iSys++)
224 fServer[iSys]->Close();
225 delete fServer[iSys];
234 if (fMonitoringMutex)
236 delete fMonitoringMutex;
237 fMonitoringMutex = 0;
241 //______________________________________________________________________________________________
242 void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
245 // Registers new AliPreprocessor.
246 // It uses GetName() for indentificator of the pre processor.
247 // The pre processor is registered it there isn't any other
248 // with the same identificator (GetName()).
251 const char* detName = preprocessor->GetName();
252 if(GetDetPos(detName) < 0)
253 AliFatal(Form("********** !!!!! Invalid detector name: %s !!!!! **********", detName));
255 if (fPreprocessorMap.GetValue(detName)) {
256 AliWarning(Form("AliPreprocessor %s is already registered!", detName));
260 fPreprocessorMap.Add(new TObjString(detName), preprocessor);
262 //______________________________________________________________________________________________
263 UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
264 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
266 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
267 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
268 // using this function. Use StoreReferenceData instead!
269 // It calls WriteToCDB function which perform actual storage
271 return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
272 metaData, validityStart, validityInfinite);
276 //______________________________________________________________________________________________
277 UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
279 // Stores a CDB object in the storage for reference data. This objects will not be available during
280 // offline reconstrunction. Use this function for reference data only!
281 // It calls WriteToCDB function which perform actual storage
283 return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object, metaData);
287 //______________________________________________________________________________________________
288 UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
289 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
290 Int_t validityStart, Bool_t validityInfinite)
292 // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
293 // The parameters are:
294 // 1) Uri of the main storage (Grid)
295 // 2) Uri of the backup storage (Local)
296 // 3) the object's path.
297 // 4) the object to be stored
298 // 5) the metaData to be associated with the object
299 // 6) the validity start run number w.r.t. the current run,
300 // if the data is valid only for this run leave the default 0
301 // 7) specifies if the calibration data is valid for infinity (this means until updated),
302 // typical for calibration runs, the default is kFALSE
305 // 1 if stored in main (Grid) storage
306 // 2 if stored in backup (Local) storage
308 const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
310 Int_t firstRun = GetCurrentRun() - validityStart;
312 AliError("First valid run happens to be less than 0! Setting it to 0.");
317 if(validityInfinite) {
318 lastRun = AliCDBRunRange::Infinity();
320 lastRun = GetCurrentRun();
323 AliCDBId id(path, firstRun, lastRun, -1, -1);
325 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
326 TObjString runUsed = Form("%d", GetCurrentRun());
327 metaData->SetProperty("RunUsed(TObjString)",&runUsed);
332 if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
333 AliError(Form("WriteToCDB - Cannot activate main %s storage", cdbType));
335 result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
336 ->Put(object, id, metaData);
341 Log(fCurrentDetector,
342 Form("WriteToCDB - Problem with main %s storage. Putting <%s> into backup storage",
343 cdbType, path.GetPath().Data()));
345 // Set Grid version to current run number, to ease retrieval later
346 id.SetVersion(GetCurrentRun());
348 result = AliCDBManager::Instance()->GetStorage(localUri)
349 ->Put(object, id, metaData);
355 Log(fCurrentDetector, "WriteToCDB - Can't store data!");
363 //______________________________________________________________________________________________
364 AliShuttleStatus* AliShuttle::ReadShuttleStatus()
366 // Reads the AliShuttleStatus from the CDB
373 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
374 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
376 if (!fStatusEntry) return 0;
377 fStatusEntry->SetOwner(1);
379 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
381 AliError("Invalid object stored to CDB!");
388 //______________________________________________________________________________________________
389 Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
391 // writes the status for one subdetector
398 Int_t run = GetCurrentRun();
400 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
402 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
403 fStatusEntry->SetOwner(1);
405 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
408 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), run));
415 //______________________________________________________________________________________________
416 void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
418 // changes the AliShuttleStatus for the given detector and run to the given status
421 AliError("UNEXPECTED: fStatusEntry empty");
425 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
428 AliError("UNEXPECTED: status could not be read from current CDB entry");
432 TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
433 fCurrentDetector.Data(),
434 status->GetStatusName(),
435 status->GetStatusName(newStatus));
436 Log("SHUTTLE", actionStr);
437 SetLastAction(actionStr);
439 status->SetStatus(newStatus);
440 if (increaseCount) status->IncreaseCount();
442 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
444 //______________________________________________________________________________________________
445 Bool_t AliShuttle::ContinueProcessing()
447 // this function reads the AliShuttleStatus information from CDB and
448 // checks if the processing should be continued
449 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
451 AliShuttleLogbookEntry::Status entryStatus =
452 fLogbookEntry->GetDetectorStatus(fCurrentDetector);
454 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
455 Log("SHUTTLE", Form("ContinueProcessing - %s is %s",
456 fCurrentDetector.Data(),
457 fLogbookEntry->GetDetectorStatusName(entryStatus)));
461 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
463 // check if current run is first unprocessed run for current detector
464 if (fConfig->StrictRunOrder(fCurrentDetector) &&
465 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
467 Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering but this is not the first unprocessed run!"));
471 AliShuttleStatus* status = ReadShuttleStatus();
474 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
475 fCurrentDetector.Data()));
476 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
477 return WriteShuttleStatus(status);
480 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
481 // If it happens it may mean Logbook updating failed... let's do it now!
482 if (status->GetStatus() == AliShuttleStatus::kDone ||
483 status->GetStatus() == AliShuttleStatus::kFailed){
484 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
485 fCurrentDetector.Data(),
486 status->GetStatusName(status->GetStatus())));
487 UpdateShuttleLogbook(fCurrentDetector.Data(),
488 status->GetStatusName(status->GetStatus()));
492 if (status->GetStatus() == AliShuttleStatus::kStoreFailed) {
494 Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now",
495 fCurrentDetector.Data()));
496 if(TryToStoreAgain()){
497 Log(fCurrentDetector.Data(), "ContinueProcessing - All objects successfully stored into OCDB");
498 UpdateShuttleStatus(AliShuttleStatus::kDone);
499 UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
502 Form("ContinueProcessing - %s: Grid storage failed again",
503 fCurrentDetector.Data()));
508 // if we get here, there is a restart
511 if (status->GetCount() >= fConfig->GetMaxRetries()) {
513 Form("ContinueProcessing - %s failed %d times in status %s - Updating Shuttle Logbook",
514 fCurrentDetector.Data(),
515 status->GetCount(), status->GetStatusName()));
516 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
520 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. Aborted before with %s. Retry number %d.",
521 fCurrentDetector.Data(),
522 status->GetStatusName(), status->GetCount()));
524 UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
529 //______________________________________________________________________________________________
530 Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
533 // Makes data retrieval for all detectors in the configuration.
534 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
535 // (Unprocessed, Inactive, Failed or Done).
536 // Returns kFALSE in case of error occured and kTRUE otherwise
539 if(!entry) return kFALSE;
541 fLogbookEntry = entry;
543 if(fLogbookEntry->IsDone()){
544 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
545 UpdateShuttleLogbook("shuttle_done");
551 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n",
554 fLogbookEntry->Print("all");
557 Bool_t hasError = kFALSE;
558 for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE;
560 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
561 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
562 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
563 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
565 // Loop on detectors in the configuration
566 TIter iter(fConfig->GetDetectors());
567 TObjString* aDetector = 0;
569 while ((aDetector = (TObjString*) iter.Next()))
571 fCurrentDetector = aDetector->String();
573 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
575 AliPreprocessor* aPreprocessor =
576 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
579 Log("SHUTTLE",Form("Process - %s: no preprocessor registered. Skipping",
580 fCurrentDetector.Data()));
584 if (ContinueProcessing() == kFALSE) continue;
586 AliInfo(Form("\n\n \t\t\t****** run %d - %s: START ******",
587 GetCurrentRun(), aDetector->GetName()));
594 Log("SHUTTLE", "ERROR: Forking failed");
599 AliInfo(Form("In parent process of %d - %s: Starting monitoring",
600 GetCurrentRun(), aDetector->GetName()));
602 Long_t begin = time(0);
604 int status; // to be used with waitpid, on purpose an int (not Int_t)!
605 while (waitpid(pid, &status, WNOHANG) == 0)
607 Long_t expiredTime = time(0) - begin;
609 if (expiredTime > fConfig->GetPPTimeOut())
611 Log("SHUTTLE", Form("Process time out. Run time: %d seconds. Killing...",
618 gSystem->Sleep(1000);
622 if (expiredTime % 60 == 0)
623 Log("SHUTTLE", Form("Checked process. Run time: %d seconds.",
625 gSystem->Sleep(1000);
629 AliInfo(Form("In parent process of %d - %s: Client has terminated.",
630 GetCurrentRun(), aDetector->GetName()));
632 if (WIFEXITED(status))
634 Int_t returnCode = WEXITSTATUS(status);
636 Log("SHUTTLE", Form("The return code is %d", returnCode));
645 AliInfo(Form("In client process of %d - %s", GetCurrentRun(), aDetector->GetName()));
647 UInt_t result = ProcessCurrentDetector();
649 Int_t returnCode = 0; // will be set to 1 in case of an error
654 AliInfo(Form("\n \t\t\t****** run %d - %s: PREPROCESSOR ERROR ****** \n\n",
655 GetCurrentRun(), aDetector->GetName()));
657 else if (result == 2)
659 AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n",
660 GetCurrentRun(), aDetector->GetName()));
663 AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n",
664 GetCurrentRun(), aDetector->GetName()));
669 // Process successful: Update time_processed field in FXS logbooks!
670 if (fFXSCalled[kDAQ])
672 if (UpdateDAQTable() == kFALSE)
674 fFXSlist[kDAQ].Clear();
676 //if(fFXSCalled[kDCS]) {
677 // if (UpdateDCSTable(aDetector->GetName()) == kFALSE)
679 // fFXSlist[kDCS].Clear();
681 //if(fFXSCalled[kHLT]) {
682 // if (UpdateHLTTable(aDetector->GetName()) == kFALSE)
684 // fFXSlist[kHLT].Clear();
688 AliInfo(Form("Client process of %d - %s is exiting now with %d.",
689 GetCurrentRun(), aDetector->GetName(), returnCode));
691 // the client exits here
692 gSystem->Exit(returnCode);
694 AliError("We should never get here!!!");
698 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n",
701 //check if shuttle is done for this run, if so update logbook
702 TObjArray checkEntryArray;
703 checkEntryArray.SetOwner(1);
704 TString whereClause = Form("where run=%d",GetCurrentRun());
705 if (QueryShuttleLogbook(whereClause.Data(), checkEntryArray)) {
707 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
708 (checkEntryArray.At(0));
712 if (checkEntry->IsDone())
714 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
715 UpdateShuttleLogbook("shuttle_done");
719 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
721 if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
723 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
724 checkEntry->GetRun(), GetDetName(iDet)));
725 fFirstUnprocessed[iDet] = kFALSE;
734 return hasError == kFALSE;
737 //______________________________________________________________________________________________
738 UInt_t AliShuttle::ProcessCurrentDetector()
741 // Makes data retrieval just for a specific detector (fCurrentDetector).
742 // Threre should be a configuration for this detector.
744 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun()));
746 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
751 Bool_t aDCSError = kFALSE;
754 // TODO Test only... I've added a flag that allows to
755 // exclude DCS archive DB query
758 AliInfo("Skipping DCS processing!");
761 TString host(fConfig->GetDCSHost(fCurrentDetector));
762 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
764 // Retrieval of Aliases
765 TObjString* anAlias = 0;
766 TIter iterAliases(fConfig->GetDCSAliases(fCurrentDetector));
767 while ((anAlias = (TObjString*) iterAliases.Next()))
769 TObjArray *valueSet = new TObjArray();
770 valueSet->SetOwner(1);
772 AliInfo("Querying DCS archive DB (Aliases)...");
773 aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet, kAlias) == 0);
777 dcsMap.Add(anAlias->Clone(), valueSet);
779 Log(fCurrentDetector,
780 Form("ProcessCurrentDetector - Error while retrieving alias %s",
781 anAlias->GetName()));
782 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
788 // Retrieval of Data Points
790 TIter iterDP(fConfig->GetDCSDataPoints(fCurrentDetector));
791 while ((aDP = (TObjString*) iterDP.Next()))
793 TObjArray *valueSet = new TObjArray();
794 valueSet->SetOwner(1);
795 AliInfo("Querying DCS archive DB (Data Points)...");
796 aDCSError = (GetValueSet(host, port, aDP->String(), valueSet, kDP) == 0);
800 dcsMap.Add(aDP->Clone(), valueSet);
802 Log(fCurrentDetector,
803 Form("ProcessCurrentDetector - Error while retrieving data point %s",
805 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
812 // DCS Archive DB processing successful. Call Preprocessor!
813 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
815 AliPreprocessor* aPreprocessor =
816 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
818 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
819 UInt_t aPPResult = aPreprocessor->Process(&dcsMap);
821 UInt_t returnValue = 0;
822 if (aPPResult == 0) { // Preprocessor error
823 UpdateShuttleStatus(AliShuttleStatus::kPPError);
825 } else if (fGridError == kFALSE) { // process and Grid storage ok!
826 UpdateShuttleStatus(AliShuttleStatus::kDone);
827 UpdateShuttleLogbook(fCurrentDetector, "DONE");
828 Log(fCurrentDetector.Data(),
829 "ProcessCurrentDetector - Preprocessor and Grid storage ended successfully");
831 } else { // Grid storage error (process ok, but object put in local storage)
832 UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
841 //______________________________________________________________________________________________
842 Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
845 // Query DAQ's Shuttle logbook and fills detector status object.
846 // Call QueryRunParameters to query DAQ logbook for run parameters.
850 // check connection, in case connect
851 if(!Connect(3)) return kFALSE;
854 sqlQuery = Form("select * from logbook_shuttle %s order by run", whereClause);
856 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
858 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
862 AliDebug(2,Form("Query = %s", sqlQuery.Data()));
864 if(aResult->GetRowCount() == 0) {
865 if(sqlQuery.EndsWith("where shuttle_done=0 order by run")){
866 Log("SHUTTLE", "QueryShuttleLogbook - All runs in Shuttle Logbook are already DONE");
870 AliError("No entries in Shuttle Logbook match request");
876 // TODO Check field count!
877 const UInt_t nCols = 22;
878 if (aResult->GetFieldCount() != (Int_t) nCols) {
879 AliError("Invalid SQL result field number!");
885 while ((aRow = aResult->Next())) {
886 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
887 Int_t run = runString.Atoi();
889 AliShuttleLogbookEntry *entry = QueryRunParameters(run);
894 for(UInt_t ii = 0; ii < nCols; ii++)
895 entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
897 entries.AddLast(entry);
901 if(sqlQuery.EndsWith("where shuttle_done=0 order by run"))
902 Log("SHUTTLE", Form("QueryShuttleLogbook - Found %d unprocessed runs in Shuttle Logbook",
903 entries.GetEntriesFast()));
908 //______________________________________________________________________________________________
909 AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
912 // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
915 // check connection, in case connect
920 sqlQuery.Form("select * from %s where run=%d", fConfig->GetDAQlbTable(), run);
922 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
924 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
928 if (aResult->GetRowCount() == 0) {
929 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
934 if (aResult->GetRowCount() > 1) {
935 AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run));
940 TSQLRow* aRow = aResult->Next();
943 AliError(Form("Could not retrieve row for run %d. Skipping", run));
948 AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
950 for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
951 entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
953 UInt_t startTime = entry->GetStartTime();
954 UInt_t endTime = entry->GetEndTime();
956 if (!startTime || !endTime || startTime > endTime) {
958 Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d",
959 run, startTime, endTime));
972 //______________________________________________________________________________________________
973 Bool_t AliShuttle::TryToStoreAgain()
975 // Called in case the detector failed to store the object in Grid OCDB
976 // It tries to store the object again, if it does not find more recent and overlapping objects
977 // Calls underlying TryToStoreAgain(const char*) function twice, for OCDB and Reference storage.
979 AliInfo("Trying to store OCDB data again...");
980 Bool_t resultCDB = TryToStoreAgain(fgkMainCDB);
982 AliInfo("Trying to store reference data again...");
983 Bool_t resultRef = TryToStoreAgain(fgkMainRefStorage);
985 return resultCDB && resultRef;
988 //______________________________________________________________________________________________
989 Bool_t AliShuttle::TryToStoreAgain(TString& gridURI)
991 // Called by TryToStoreAgain(), performs actual storage retry
993 TObjArray* gridIds=0;
995 Bool_t result = kTRUE;
997 const char* type = 0;
999 if(gridURI == fgkMainCDB) {
1001 backupURI = fgkLocalCDB;
1002 } else if(gridURI == fgkMainRefStorage) {
1004 backupURI = fgkLocalRefStorage;
1006 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
1010 AliCDBManager* man = AliCDBManager::Instance();
1012 AliCDBStorage *gridSto = man->GetStorage(gridURI);
1014 Log(fCurrentDetector.Data(),
1015 Form("TryToStoreAgain - cannot activate main %s storage", type));
1019 gridIds = gridSto->GetQueryCDBList();
1021 // get objects previously stored in local CDB
1022 AliCDBStorage *backupSto = man->GetStorage(backupURI);
1023 AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
1024 // Local objects were stored with current run as Grid version!
1025 TList* localEntries = backupSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
1026 localEntries->SetOwner(1);
1028 // loop on local stored objects
1029 TIter localIter(localEntries);
1030 AliCDBEntry *aLocEntry = 0;
1031 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
1032 aLocEntry->SetOwner(1);
1033 AliCDBId aLocId = aLocEntry->GetId();
1034 aLocEntry->SetVersion(-1);
1035 aLocEntry->SetSubVersion(-1);
1037 // loop on Grid valid Id's
1038 Bool_t store = kTRUE;
1039 TIter gridIter(gridIds);
1040 AliCDBId* aGridId = 0;
1041 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
1042 // If local object is valid up to infinity we store it only if it is
1043 // the first unprocessed run!
1044 if (aLocId.GetLastRun() == AliCDBRunRange::Infinity())
1046 if (!fFirstUnprocessed[GetDetPos(fCurrentDetector)])
1048 Log(fCurrentDetector.Data(),
1049 ("TryToStoreAgain - This object has validity infinite but "
1050 "there are previous unprocessed runs!"));
1056 if(aGridId->GetPath() != aLocId.GetPath()) continue;
1057 // skip all objects valid up to infinity
1058 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
1059 // if we get here, it means there's already some more recent object stored on Grid!
1065 Log(fCurrentDetector.Data(),
1066 Form("TryToStoreAgain - A more recent object already exists in %s storage: <%s>",
1067 type, aGridId->ToString().Data()));
1068 // removing local filename...
1069 // TODO maybe it's better not to remove it, it was not copied to the Grid!
1071 backupSto->IdToFilename(aLocId, filename);
1072 AliInfo(Form("Removing local file %s", filename.Data()));
1073 gSystem->Exec(Form("rm %s",filename.Data()));
1077 // If we get here, the file can be stored!
1078 Bool_t storeOk = gridSto->Put(aLocEntry);
1080 Log(fCurrentDetector.Data(),
1081 Form("TryToStoreAgain - Object <%s> successfully put into %s storage",
1082 aLocId.ToString().Data(), type));
1084 // removing local filename...
1086 backupSto->IdToFilename(aLocId, filename);
1087 AliInfo(Form("Removing local file %s", filename.Data()));
1088 gSystem->Exec(Form("rm %s", filename.Data()));
1091 Log(fCurrentDetector.Data(),
1092 Form("TryToStoreAgain - Grid %s storage of object <%s> failed again",
1093 type, aLocId.ToString().Data()));
1097 localEntries->Clear();
1102 //______________________________________________________________________________________________
1103 Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* entry,
1104 TObjArray* valueSet, DCSType type)
1106 // Retrieve all "entry" data points from the DCS server
1107 // host, port: TSocket connection parameters
1108 // entry: name of the alias or data point
1109 // valueSet: array of retrieved AliDCSValue's
1110 // type: kAlias or kDP
1112 AliDCSClient client(host, port, fTimeout, fRetries);
1113 if (!client.IsConnected())
1122 result = client.GetAliasValues(entry,
1123 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
1127 result = client.GetDPValues(entry,
1128 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
1133 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s",
1134 entry, AliDCSClient::GetErrorString(result)));
1136 if (result == AliDCSClient::fgkServerError)
1138 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s",
1139 client.GetServerError().Data()));
1148 //______________________________________________________________________________________________
1149 const char* AliShuttle::GetFile(Int_t system, const char* detector,
1150 const char* id, const char* source)
1152 // Get calibration file from file exchange servers
1153 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
1157 return GetDAQFileName(detector, id, source);
1160 return GetDCSFileName(detector, id, source);
1163 return GetHLTFileName(detector, id, source);
1166 AliError(Form("No valid system index: %d",system));
1172 //______________________________________________________________________________________________
1173 TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
1175 // Get sources producing the condition file Id from file exchange servers
1176 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
1180 return GetDAQFileSources(detector, id);
1183 return GetDCSFileSources(detector, id);
1186 return GetHLTFileSources(detector, id);
1189 AliError(Form("No valid system index: %d",system));
1195 //______________________________________________________________________________________________
1196 Bool_t AliShuttle::Connect(Int_t system)
1198 // Connect to MySQL Server of the system's FXS MySQL databases
1199 // DAQ Logbook, Shuttle Logbook and DAQ FXS db are on the same host
1201 // check connection: if already connected return
1202 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
1204 TString dbHost, dbUser, dbPass, dbName;
1206 if (system < 3) // FXS db servers
1208 dbHost = Form("mysql://%s:%d", fConfig->GetFXSdbHost(system), fConfig->GetFXSdbPort(system));
1209 dbUser = fConfig->GetFXSdbUser(system);
1210 dbPass = fConfig->GetFXSdbPass(system);
1211 dbName = fConfig->GetFXSdbName(system);
1212 } else { // Run & Shuttle logbook servers
1213 // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
1214 dbHost = Form("mysql://%s:%d", fConfig->GetDAQlbHost(), fConfig->GetDAQlbPort());
1215 dbUser = fConfig->GetDAQlbUser();
1216 dbPass = fConfig->GetDAQlbPass();
1217 dbName = fConfig->GetDAQlbDB();
1220 fServer[system] = TSQLServer::Connect(dbHost.Data(), dbUser.Data(), dbPass.Data());
1221 if (!fServer[system] || !fServer[system]->IsConnected()) {
1224 AliError(Form("Can't establish connection to FXS database for %s",
1225 AliShuttleInterface::GetSystemName(system)));
1227 AliError("Can't establish connection to Run logbook.");
1229 if(fServer[system]) delete fServer[system];
1234 // TODO in the configuration should the table name be there too?
1235 TSQLResult* aResult=0;
1238 aResult = fServer[kDAQ]->GetTables(dbName.Data());
1241 //aResult = fServer[kDCS]->GetTables(dbName.Data());
1244 //aResult = fServer[kHLT]->GetTables(dbName.Data());
1247 aResult = fServer[3]->GetTables(dbName.Data());
1255 //______________________________________________________________________________________________
1256 const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source)
1258 // Retrieves a file from the DAQ FXS.
1259 // First queris the DAQ FXS database for the DAQ file name, using the run, detector, id and source info
1260 // then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
1261 // run: current run being processed (given by Logbook entry fLogbookEntry)
1262 // detector: the Preprocessor name
1263 // id: provided as a parameter by the Preprocessor
1264 // source: provided by the Preprocessor through GetFileSources function
1266 // check connection, in case connect
1269 Log(detector, "GetDAQFileName - Couldn't connect to DAQ FXS database");
1273 // Query preparation
1274 TString sqlQueryStart = Form("select filePath from %s where", fConfig->GetFXSdbTable(kDAQ));
1275 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
1276 GetCurrentRun(), detector, id, source);
1277 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1279 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1282 TSQLResult* aResult = 0;
1283 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1285 Log(detector, Form("GetDAQFileName - Can't execute SQL query for: id = %s, source = %s",
1290 if(aResult->GetRowCount() == 0)
1293 Form("GetDAQFileName - No entry in FXS table for: id = %s, source = %s",
1299 if (aResult->GetRowCount() > 1) {
1301 Form("GetDAQFileName - More than one entry in FXS table for: id = %s, source = %s",
1307 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
1310 Log(detector, Form("GetDAQFileName - Empty set result from query: id = %s, source = %s",
1316 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
1321 AliDebug(2, Form("filePath = %s",filePath.Data()));
1323 // retrieved file is renamed to make it unique
1324 TString localFileName = Form("%s_%d_%s_%s.shuttle",
1325 detector, GetCurrentRun(), id, source);
1327 // file retrieval from DAQ FXS
1328 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
1330 Log(detector, Form("GetDAQFileName - Copy of file %s from DAQ FXS failed", filePath.Data()));
1333 AliInfo(Form("File %s copied from DAQ FXS into %s/%s",
1334 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
1338 fFXSCalled[kDAQ]=kTRUE;
1339 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
1340 fFXSlist[kDAQ].Add(fileParams);
1342 return localFileName.Data();
1346 //______________________________________________________________________________________________
1347 Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName)
1350 // check temp directory: trying to cd to temp; if it does not exist, create it
1351 AliDebug(2, Form("Copy file %s from DAQ FXS into folder %s and rename it as %s",
1352 daqFileName,fgkShuttleTempDir, localFileName));
1354 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
1356 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
1357 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1362 gSystem->FreeDirectory(dir);
1365 TString baseDAQFXSFolder = "DAQ";
1366 TString command = Form("scp -oPort=%d -2 %s@%s:%s/%s %s/%s",
1367 fConfig->GetFXSPort(kDAQ),
1368 fConfig->GetFXSUser(kDAQ),
1369 fConfig->GetFXSHost(kDAQ),
1370 baseDAQFXSFolder.Data(),
1375 AliDebug(2, Form("%s",command.Data()));
1377 UInt_t nRetries = 0;
1378 UInt_t maxRetries = 3;
1380 // copy!! if successful TSystem::Exec returns 0
1381 while(nRetries++ < maxRetries) {
1382 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
1383 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
1390 //______________________________________________________________________________________________
1391 TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id)
1393 // Retrieves a file from the DCS FXS.
1395 // check connection, in case connect
1397 Log(detector, "GetDAQFileSources - Couldn't connect to DAQ FXS database");
1401 // Query preparation
1402 TString sqlQueryStart = Form("select DAQsource from %s where", fConfig->GetFXSdbTable(kDAQ));
1403 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
1404 GetCurrentRun(), detector, id);
1405 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1407 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1410 TSQLResult* aResult;
1411 aResult = fServer[kDAQ]->Query(sqlQuery);
1413 Log(detector, Form("GetDAQFileSources - Can't execute SQL query for id: %s", id));
1417 if (aResult->GetRowCount() == 0) {
1419 Form("GetDAQFileSources - No entry in FXS table for id: %s", id));
1425 TList *list = new TList();
1428 while((aRow = aResult->Next())){
1430 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
1431 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
1432 list->Add(new TObjString(daqSource));
1441 //______________________________________________________________________________________________
1442 const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1443 // Retrieves a file from the DCS FXS.
1445 return "You're in DCS";
1449 //______________________________________________________________________________________________
1450 TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
1451 // Retrieves file sources from the DCS FXS.
1457 //______________________________________________________________________________________________
1458 const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1459 // Retrieves a file from the HLT FXS.
1461 return "You're in HLT";
1465 //______________________________________________________________________________________________
1466 TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1467 // Retrieves file sources from the HLT FXS.
1473 //______________________________________________________________________________________________
1474 Bool_t AliShuttle::UpdateDAQTable()
1476 // Update DAQ table filling time_processed field in all rows corresponding to current run and detector
1478 // check connection, in case connect
1480 Log(fCurrentDetector, "UpdateDAQTable - Couldn't connect to DAQ FXS database");
1484 TTimeStamp now; // now
1486 // Loop on FXS list entries
1487 TIter iter(&fFXSlist[kDAQ]);
1488 TObjString *aFXSentry=0;
1489 while((aFXSentry = dynamic_cast<TObjString*> (iter.Next()))){
1490 TString aFXSentrystr = aFXSentry->String();
1491 TObjArray *aFXSarray = aFXSentrystr.Tokenize("_!?!_");
1492 if(!aFXSarray || aFXSarray->GetEntries() != 2 ) {
1493 Log(fCurrentDetector, Form("UpdateDAQTable - error updating FXS entry. Check string: <%s>",
1494 aFXSentrystr.Data()));
1495 if(aFXSarray) delete aFXSarray;
1498 const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
1499 const char* daqSource = ((TObjString*) aFXSarray->At(1))->GetName();
1500 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
1501 GetCurrentRun(), fCurrentDetector.Data(), fileId, daqSource);
1505 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(kDAQ),
1506 now.GetSec(), whereClause.Data());
1508 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1511 TSQLResult* aResult;
1512 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
1514 Log(fCurrentDetector, Form("UpdateDAQTable - Can't execute SQL query <%s>", sqlQuery.Data()));
1524 //______________________________________________________________________________________________
1525 Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
1527 // Update Shuttle logbook filling detector or shuttle_done column
1528 // ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
1530 // check connection, in case connect
1532 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
1536 TString detName(detector);
1538 if(detName == "shuttle_done") {
1539 setClause = "set shuttle_done=1";
1541 TString statusStr(status);
1542 if(statusStr.Contains("done", TString::kIgnoreCase) ||
1543 statusStr.Contains("failed", TString::kIgnoreCase)){
1544 setClause = Form("set %s=\"%s\"", detector, status);
1547 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
1553 TString whereClause = Form("where run=%d", GetCurrentRun());
1555 TString sqlQuery = Form("update logbook_shuttle %s %s",
1556 setClause.Data(), whereClause.Data());
1558 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1561 TSQLResult* aResult;
1562 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
1564 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
1572 //______________________________________________________________________________________________
1573 Int_t AliShuttle::GetCurrentRun() const
1575 // Get current run from logbook entry
1577 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
1580 //______________________________________________________________________________________________
1581 UInt_t AliShuttle::GetCurrentStartTime() const
1583 // get current start time
1585 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
1588 //______________________________________________________________________________________________
1589 UInt_t AliShuttle::GetCurrentEndTime() const
1591 // get current end time from logbook entry
1593 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
1596 //______________________________________________________________________________________________
1597 void AliShuttle::Log(const char* detector, const char* message)
1599 // Fill log string with a message
1601 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1603 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
1604 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1609 gSystem->FreeDirectory(dir);
1612 TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
1613 if(GetCurrentRun()>=0 ) toLog += Form("run %d - ", GetCurrentRun());
1614 toLog += Form("%s", message);
1616 AliInfo(toLog.Data());
1619 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1620 gSystem->ExpandPathName(fileName);
1623 logFile.open(fileName, ofstream::out | ofstream::app);
1625 if (!logFile.is_open()) {
1626 AliError(Form("Could not open file %s", fileName.Data()));
1630 logFile << toLog.Data() << "\n";
1635 //______________________________________________________________________________________________
1636 Bool_t AliShuttle::Collect(Int_t run)
1639 // Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
1640 // If a dedicated run is given this run is processed
1642 // In operational mode, this is the Shuttle function triggered by the EOR signal.
1646 Log("SHUTTLE","Collect - Shuttle called. Collecting conditions data for unprocessed runs");
1648 Log("SHUTTLE", Form("Collect - Shuttle called. Collecting conditions data for run %d", run));
1650 SetLastAction("Starting");
1652 TString whereClause("where shuttle_done=0");
1654 whereClause += Form(" and run=%d", run);
1656 TObjArray shuttleLogbookEntries;
1657 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries))
1659 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
1663 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
1664 fFirstUnprocessed[iDet] = kTRUE;
1668 // query Shuttle logbook for earlier runs, check if some detectors are unprocessed,
1669 // flag them into fFirstUnprocessed array
1670 TString whereClause(Form("where shuttle_done=0 and run < %d", run));
1671 TObjArray tmpLogbookEntries;
1672 if (!QueryShuttleLogbook(whereClause, tmpLogbookEntries))
1674 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
1678 TIter iter(&tmpLogbookEntries);
1679 AliShuttleLogbookEntry* anEntry = 0;
1680 while ((anEntry = dynamic_cast<AliShuttleLogbookEntry*> (iter.Next())))
1682 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
1684 if (anEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
1686 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
1687 anEntry->GetRun(), GetDetName(iDet)));
1688 fFirstUnprocessed[iDet] = kFALSE;
1696 if (!RetrieveConditionsData(shuttleLogbookEntries))
1698 Log("SHUTTLE", "Collect - Process of at least one run failed");
1705 //______________________________________________________________________________________________
1706 Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
1708 // Retrieve conditions data for all runs that aren't processed yet
1710 Bool_t hasError = kFALSE;
1712 TIter iter(&dateEntries);
1713 AliShuttleLogbookEntry* anEntry;
1715 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
1716 if (!Process(anEntry)){
1721 return hasError == kFALSE;
1724 //______________________________________________________________________________________________
1725 ULong_t AliShuttle::GetTimeOfLastAction() const
1729 fMonitoringMutex->Lock();
1731 tmp = fLastActionTime;
1733 fMonitoringMutex->UnLock();
1738 //______________________________________________________________________________________________
1739 const TString AliShuttle::GetLastAction() const
1741 // returns a string description of the last action
1745 fMonitoringMutex->Lock();
1749 fMonitoringMutex->UnLock();
1754 //______________________________________________________________________________________________
1755 void AliShuttle::SetLastAction(const char* action)
1757 // updates the monitoring variables
1759 fMonitoringMutex->Lock();
1761 fLastAction = action;
1762 fLastActionTime = time(0);
1764 fMonitoringMutex->UnLock();
1767 //______________________________________________________________________________________________
1768 const char* AliShuttle::GetRunParameter(const char* param)
1770 // returns run parameter read from DAQ logbook
1772 if(!fLogbookEntry) {
1773 AliError("No logbook entry!");
1777 return fLogbookEntry->GetRunParameter(param);