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.19 2006/11/06 14:23:04 jgrosseo
19 major update (Alberto)
20 o) reading of run parameters from the logbook
21 o) online offline naming conversion
22 o) standalone DCSclient package
24 Revision 1.18 2006/10/20 15:22:59 jgrosseo
25 o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
26 o) Merging Collect, CollectAll, CollectNew function
27 o) Removing implementation of empty copy constructors (declaration still there!)
29 Revision 1.17 2006/10/05 16:20:55 jgrosseo
30 adapting to new CDB classes
32 Revision 1.16 2006/10/05 15:46:26 jgrosseo
33 applying to the new interface
35 Revision 1.15 2006/10/02 16:38:39 jgrosseo
38 storing of objects that failed to be stored to the grid before
39 interfacing of shuttle status table in daq system
41 Revision 1.14 2006/08/29 09:16:05 jgrosseo
44 Revision 1.13 2006/08/15 10:50:00 jgrosseo
45 effc++ corrections (alberto)
47 Revision 1.12 2006/08/08 14:19:29 jgrosseo
48 Update to shuttle classes (Alberto)
50 - Possibility to set the full object's path in the Preprocessor's and
51 Shuttle's Store functions
52 - Possibility to extend the object's run validity in the same classes
53 ("startValidity" and "validityInfinite" parameters)
54 - Implementation of the StoreReferenceData function to store reference
55 data in a dedicated CDB storage.
57 Revision 1.11 2006/07/21 07:37:20 jgrosseo
58 last run is stored after each run
60 Revision 1.10 2006/07/20 09:54:40 jgrosseo
61 introducing status management: The processing per subdetector is divided into several steps,
62 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
63 can keep track of the number of failures and skips further processing after a certain threshold is
64 exceeded. These thresholds can be configured in LDAP.
66 Revision 1.9 2006/07/19 10:09:55 jgrosseo
67 new configuration, accesst to DAQ FES (Alberto)
69 Revision 1.8 2006/07/11 12:44:36 jgrosseo
70 adding parameters for extended validity range of data produced by preprocessor
72 Revision 1.7 2006/07/10 14:37:09 jgrosseo
73 small fix + todo comment
75 Revision 1.6 2006/07/10 13:01:41 jgrosseo
76 enhanced storing of last sucessfully processed run (alberto)
78 Revision 1.5 2006/07/04 14:59:57 jgrosseo
79 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
81 Revision 1.4 2006/06/12 09:11:16 jgrosseo
82 coding conventions (Alberto)
84 Revision 1.3 2006/06/06 14:26:40 jgrosseo
85 o) removed files that were moved to STEER
86 o) shuttle updated to follow the new interface (Alberto)
88 Revision 1.2 2006/03/07 07:52:34 hristov
89 New version (B.Yordanov)
91 Revision 1.6 2005/11/19 17:19:14 byordano
92 RetrieveDATEEntries and RetrieveConditionsData added
94 Revision 1.5 2005/11/19 11:09:27 byordano
95 AliShuttle declaration added
97 Revision 1.4 2005/11/17 17:47:34 byordano
98 TList changed to TObjArray
100 Revision 1.3 2005/11/17 14:43:23 byordano
103 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
104 Initial import as subdirectory in AliRoot
106 Revision 1.2 2005/09/13 08:41:15 byordano
107 default startTime endTime added
109 Revision 1.4 2005/08/30 09:13:02 byordano
112 Revision 1.3 2005/08/29 21:15:47 byordano
118 // This class is the main manager for AliShuttle.
119 // It organizes the data retrieval from DCS and call the
120 // interface methods of AliPreprocessor.
121 // For every detector in AliShuttleConfgi (see AliShuttleConfig),
122 // data for its set of aliases is retrieved. If there is registered
123 // AliPreprocessor for this detector then it will be used
124 // accroding to the schema (see AliPreprocessor).
125 // If there isn't registered AliPreprocessor than the retrieved
126 // data is stored automatically to the undelying AliCDBStorage.
127 // For detSpec is used the alias name.
130 #include "AliShuttle.h"
132 #include "AliCDBManager.h"
133 #include "AliCDBStorage.h"
134 #include "AliCDBId.h"
135 #include "AliCDBRunRange.h"
136 #include "AliCDBPath.h"
137 #include "AliCDBEntry.h"
138 #include "AliShuttleConfig.h"
139 #include "DCSClient/AliDCSClient.h"
141 #include "AliPreprocessor.h"
142 #include "AliShuttleStatus.h"
143 #include "AliShuttleLogbookEntry.h"
148 #include <TTimeStamp.h>
149 #include <TObjString.h>
150 #include <TSQLServer.h>
151 #include <TSQLResult.h>
157 #include <sys/types.h>
158 #include <sys/wait.h>
162 TString AliShuttle::fgkMainCDB("alien://folder=ShuttleCDB");
163 TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
164 TString AliShuttle::fgkMainRefStorage("alien://folder=ShuttleReference");
165 TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
167 Bool_t AliShuttle::fgkProcessDCS(kTRUE);
169 const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
170 const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
172 //______________________________________________________________________________________________
173 AliShuttle::AliShuttle(const AliShuttleConfig* config,
174 UInt_t timeout, Int_t retries):
176 fTimeout(timeout), fRetries(retries),
187 // config: AliShuttleConfig used
188 // timeout: timeout used for AliDCSClient connection
189 // retries: the number of retries in case of connection error.
192 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
193 for(int iSys=0;iSys<4;iSys++) {
196 fFESlist[iSys].SetOwner(kTRUE);
198 fPreprocessorMap.SetOwner(kTRUE);
200 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
201 fFirstUnprocessed[iDet] = kFALSE;
203 fMonitoringMutex = new TMutex();
206 //______________________________________________________________________________________________
207 AliShuttle::~AliShuttle()
211 fPreprocessorMap.DeleteAll();
212 for(int iSys=0;iSys<4;iSys++)
214 fServer[iSys]->Close();
215 delete fServer[iSys];
224 if (fMonitoringMutex)
226 delete fMonitoringMutex;
227 fMonitoringMutex = 0;
231 //______________________________________________________________________________________________
232 void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
235 // Registers new AliPreprocessor.
236 // It uses GetName() for indentificator of the pre processor.
237 // The pre processor is registered it there isn't any other
238 // with the same identificator (GetName()).
241 const char* detName = preprocessor->GetName();
242 if(GetDetPos(detName) < 0)
243 AliFatal(Form("********** !!!!! Invalid detector name: %s !!!!! **********", detName));
245 if (fPreprocessorMap.GetValue(detName)) {
246 AliWarning(Form("AliPreprocessor %s is already registered!", detName));
250 fPreprocessorMap.Add(new TObjString(detName), preprocessor);
252 //______________________________________________________________________________________________
253 UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
254 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
256 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
257 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
258 // using this function. Use StoreReferenceData instead!
259 // It calls WriteToCDB function which perform actual storage
261 return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
262 metaData, validityStart, validityInfinite);
266 //______________________________________________________________________________________________
267 UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
269 // Stores a CDB object in the storage for reference data. This objects will not be available during
270 // offline reconstrunction. Use this function for reference data only!
271 // It calls WriteToCDB function which perform actual storage
273 return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object, metaData);
277 //______________________________________________________________________________________________
278 UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
279 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
280 Int_t validityStart, Bool_t validityInfinite)
282 // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
283 // The parameters are:
284 // 1) Uri of the main storage (Grid)
285 // 2) Uri of the backup storage (Local)
286 // 3) the object's path.
287 // 4) the object to be stored
288 // 5) the metaData to be associated with the object
289 // 6) the validity start run number w.r.t. the current run,
290 // if the data is valid only for this run leave the default 0
291 // 7) specifies if the calibration data is valid for infinity (this means until updated),
292 // typical for calibration runs, the default is kFALSE
295 // 1 if stored in main (Grid) storage
296 // 2 if stored in backup (Local) storage
298 const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
300 Int_t firstRun = GetCurrentRun() - validityStart;
302 AliError("First valid run happens to be less than 0! Setting it to 0.");
307 if(validityInfinite) {
308 lastRun = AliCDBRunRange::Infinity();
310 lastRun = GetCurrentRun();
313 AliCDBId id(path, firstRun, lastRun, -1, -1);
315 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
316 TObjString runUsed = Form("%d", GetCurrentRun());
317 metaData->SetProperty("RunUsed(TObjString)",&runUsed);
322 if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
323 AliError(Form("WriteToCDB - Cannot activate main %s storage", cdbType));
325 result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
326 ->Put(object, id, metaData);
331 Log(fCurrentDetector,
332 Form("WriteToCDB - Problem with main %s storage. Putting <%s> into backup storage",
333 cdbType, path.GetPath().Data()));
335 // Set Grid version to current run number, to ease retrieval later
336 id.SetVersion(GetCurrentRun());
338 result = AliCDBManager::Instance()->GetStorage(localUri)
339 ->Put(object, id, metaData);
345 Log(fCurrentDetector, "WriteToCDB - Can't store data!");
353 //______________________________________________________________________________________________
354 AliShuttleStatus* AliShuttle::ReadShuttleStatus()
356 // Reads the AliShuttleStatus from the CDB
363 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
364 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
366 if (!fStatusEntry) return 0;
367 fStatusEntry->SetOwner(1);
369 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
371 AliError("Invalid object stored to CDB!");
378 //______________________________________________________________________________________________
379 Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
381 // writes the status for one subdetector
388 Int_t run = GetCurrentRun();
390 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
392 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
393 fStatusEntry->SetOwner(1);
395 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
398 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), run));
405 //______________________________________________________________________________________________
406 void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
408 // changes the AliShuttleStatus for the given detector and run to the given status
411 AliError("UNEXPECTED: fStatusEntry empty");
415 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
418 AliError("UNEXPECTED: status could not be read from current CDB entry");
422 TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
423 fCurrentDetector.Data(),
424 status->GetStatusName(),
425 status->GetStatusName(newStatus));
426 Log("SHUTTLE", actionStr);
427 SetLastAction(actionStr);
429 status->SetStatus(newStatus);
430 if (increaseCount) status->IncreaseCount();
432 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
434 //______________________________________________________________________________________________
435 Bool_t AliShuttle::ContinueProcessing()
437 // this function reads the AliShuttleStatus information from CDB and
438 // checks if the processing should be continued
439 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
441 AliShuttleLogbookEntry::Status entryStatus =
442 fLogbookEntry->GetDetectorStatus(fCurrentDetector);
444 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
445 Log("SHUTTLE", Form("ContinueProcessing - %s is %s",
446 fCurrentDetector.Data(),
447 fLogbookEntry->GetDetectorStatusName(entryStatus)));
451 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
453 // check if current run is first unprocessed run for current detector
454 if (fConfig->StrictRunOrder(fCurrentDetector) &&
455 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
457 Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering but this is not the first unprocessed run!"));
461 AliShuttleStatus* status = ReadShuttleStatus();
464 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
465 fCurrentDetector.Data()));
466 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
467 return WriteShuttleStatus(status);
470 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
471 // If it happens it may mean Logbook updating failed... let's do it now!
472 if (status->GetStatus() == AliShuttleStatus::kDone ||
473 status->GetStatus() == AliShuttleStatus::kFailed){
474 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
475 fCurrentDetector.Data(),
476 status->GetStatusName(status->GetStatus())));
477 UpdateShuttleLogbook(fCurrentDetector.Data(),
478 status->GetStatusName(status->GetStatus()));
482 if (status->GetStatus() == AliShuttleStatus::kStoreFailed) {
484 Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now",
485 fCurrentDetector.Data()));
486 if(TryToStoreAgain()){
487 Log(fCurrentDetector.Data(), "ContinueProcessing - All objects successfully stored into OCDB");
488 UpdateShuttleStatus(AliShuttleStatus::kDone);
489 UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
492 Form("ContinueProcessing - %s: Grid storage failed again",
493 fCurrentDetector.Data()));
498 // if we get here, there is a restart
501 if (status->GetCount() >= fConfig->GetMaxRetries()) {
503 Form("ContinueProcessing - %s failed %d times in status %s - Updating Shuttle Logbook",
504 fCurrentDetector.Data(),
505 status->GetCount(), status->GetStatusName()));
506 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
510 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. Aborted before with %s. Retry number %d.",
511 fCurrentDetector.Data(),
512 status->GetStatusName(), status->GetCount()));
514 UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
519 //______________________________________________________________________________________________
520 Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
523 // Makes data retrieval for all detectors in the configuration.
524 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
525 // (Unprocessed, Inactive, Failed or Done).
526 // Returns kFALSE in case of error occured and kTRUE otherwise
529 if(!entry) return kFALSE;
531 fLogbookEntry = entry;
533 if(fLogbookEntry->IsDone()){
534 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
535 UpdateShuttleLogbook("shuttle_done");
541 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n",
544 fLogbookEntry->Print("all");
547 Bool_t hasError = kFALSE;
548 for(Int_t iSys=0;iSys<3;iSys++) fFESCalled[iSys]=kFALSE;
550 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
551 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
552 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
553 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
555 // Loop on detectors in the configuration
556 TIter iter(fConfig->GetDetectors());
557 TObjString* aDetector = 0;
559 while ((aDetector = (TObjString*) iter.Next()))
561 fCurrentDetector = aDetector->String();
563 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
565 AliPreprocessor* aPreprocessor =
566 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
569 Log("SHUTTLE",Form("Process - %s: no preprocessor registered. Skipping",
570 fCurrentDetector.Data()));
574 if (ContinueProcessing() == kFALSE) continue;
576 AliInfo(Form("\n\n \t\t\t****** run %d - %s: START ******",
577 GetCurrentRun(), aDetector->GetName()));
584 Log("SHUTTLE", "ERROR: Forking failed");
589 AliInfo(Form("In parent process of %d - %s: Starting monitoring",
590 GetCurrentRun(), aDetector->GetName()));
592 Long_t begin = time(0);
594 int status; // to be used with waitpid, on purpose an int (not Int_t)!
595 while (waitpid(pid, &status, WNOHANG) == 0)
597 Long_t expiredTime = time(0) - begin;
599 if (expiredTime > fConfig->GetPPTimeOut())
601 Log("SHUTTLE", Form("Process time out. Run time: %d seconds. Killing...",
608 gSystem->Sleep(1000);
612 if (expiredTime % 60 == 0)
613 Log("SHUTTLE", Form("Checked process. Run time: %d seconds.",
615 gSystem->Sleep(1000);
619 AliInfo(Form("In parent process of %d - %s: Client has terminated.",
620 GetCurrentRun(), aDetector->GetName()));
622 if (WIFEXITED(status))
624 Int_t returnCode = WEXITSTATUS(status);
626 Log("SHUTTLE", Form("The return code is %d", returnCode));
635 AliInfo(Form("In client process of %d - %s", GetCurrentRun(), aDetector->GetName()));
637 UInt_t result = ProcessCurrentDetector();
639 Int_t returnCode = 0; // will be set to 1 in case of an error
644 AliInfo(Form("\n \t\t\t****** run %d - %s: PREPROCESSOR ERROR ****** \n\n",
645 GetCurrentRun(), aDetector->GetName()));
647 else if (result == 2)
649 AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n",
650 GetCurrentRun(), aDetector->GetName()));
653 AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n",
654 GetCurrentRun(), aDetector->GetName()));
659 // Process successful: Update time_processed field in FES logbooks!
660 if (fFESCalled[kDAQ])
662 if (UpdateDAQTable() == kFALSE)
664 fFESlist[kDAQ].Clear();
666 //if(fFESCalled[kDCS]) {
667 // if (UpdateDCSTable(aDetector->GetName()) == kFALSE)
669 // fFESlist[kDCS].Clear();
671 //if(fFESCalled[kHLT]) {
672 // if (UpdateHLTTable(aDetector->GetName()) == kFALSE)
674 // fFESlist[kHLT].Clear();
678 AliInfo(Form("Client process of %d - %s is exiting now with %d.",
679 GetCurrentRun(), aDetector->GetName(), returnCode));
681 // the client exits here
682 gSystem->Exit(returnCode);
684 AliError("We should never get here!!!");
688 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n",
691 //check if shuttle is done for this run, if so update logbook
692 TObjArray checkEntryArray;
693 checkEntryArray.SetOwner(1);
694 TString whereClause = Form("where run=%d",GetCurrentRun());
695 if (QueryShuttleLogbook(whereClause.Data(), checkEntryArray)) {
697 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
698 (checkEntryArray.At(0));
702 if (checkEntry->IsDone())
704 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
705 UpdateShuttleLogbook("shuttle_done");
709 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
711 if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
713 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
714 checkEntry->GetRun(), GetDetName(iDet)));
715 fFirstUnprocessed[iDet] = kFALSE;
724 return hasError == kFALSE;
727 //______________________________________________________________________________________________
728 UInt_t AliShuttle::ProcessCurrentDetector()
731 // Makes data retrieval just for a specific detector (fCurrentDetector).
732 // Threre should be a configuration for this detector.
734 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun()));
736 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
738 TString host(fConfig->GetDCSHost(fCurrentDetector));
739 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
741 TIter iter(fConfig->GetDCSAliases(fCurrentDetector));
744 aliasMap.SetOwner(1);
746 Bool_t aDCSError = kFALSE;
749 while ((anAlias = (TObjString*) iter.Next())) {
750 TObjArray *valueSet = new TObjArray();
751 valueSet->SetOwner(1);
752 // TODO Test only... I've added a flag that allows to
753 // exclude DCS archive DB query
755 AliInfo("Querying DCS archive DB data...");
756 aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet) == 0);
758 AliInfo(Form("Skipping DCS processing. Port = %d",port));
762 aliasMap.Add(anAlias->Clone(), valueSet);
764 Log(fCurrentDetector, Form("ProcessCurrentDetector - Error while retrieving alias %s",
765 anAlias->GetName()));
766 UpdateShuttleStatus(AliShuttleStatus::kDCSError, kTRUE);
767 aliasMap.DeleteAll();
772 // DCS Archive DB processing successful. Call Preprocessor!
773 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
775 AliPreprocessor* aPreprocessor =
776 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
778 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
779 UInt_t aPPResult = aPreprocessor->Process(&aliasMap);
781 UInt_t returnValue = 0;
782 if (aPPResult == 0) { // Preprocessor error
783 UpdateShuttleStatus(AliShuttleStatus::kPPError);
785 } else if (fGridError == kFALSE) { // process and Grid storage ok!
786 UpdateShuttleStatus(AliShuttleStatus::kDone);
787 UpdateShuttleLogbook(fCurrentDetector, "DONE");
788 Log(fCurrentDetector.Data(),
789 "ProcessCurrentDetector - Preprocessor and Grid storage ended successfully");
791 } else { // Grid storage error (process ok, but object put in local storage)
792 UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
796 aliasMap.DeleteAll();
801 //______________________________________________________________________________________________
802 Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
805 // Query DAQ's Shuttle logbook and fills detector status object.
806 // Call QueryRunParameters to query DAQ logbook for run parameters.
808 // check connection, in case connect
809 if(!Connect(3)) return kFALSE;
812 sqlQuery = Form("select * from logbook_shuttle %s order by run", whereClause);
814 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
816 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
820 if(aResult->GetRowCount() == 0) {
821 if(sqlQuery.Contains("where shuttle_done=0")){
822 Log("SHUTTLE", "QueryShuttleLogbook - All runs in Shuttle Logbook are already DONE");
826 AliError("No entries in Shuttle Logbook match request");
832 // TODO Check field count!
833 const UInt_t nCols = 24;
834 if (aResult->GetFieldCount() != (Int_t) nCols) {
835 AliError("Invalid SQL result field number!");
843 while ((aRow = aResult->Next())) {
844 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
845 Int_t run = runString.Atoi();
847 AliShuttleLogbookEntry *entry = QueryRunParameters(run);
852 for(UInt_t ii = 0; ii < nCols; ii++)
853 entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
855 entries.AddLast(entry);
859 if(sqlQuery.Contains("where shuttle_done=0"))
860 Log("SHUTTLE", Form("QueryShuttleLogbook - Found %d unprocessed runs in Shuttle Logbook",
861 entries.GetEntriesFast()));
866 //______________________________________________________________________________________________
867 AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
870 // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
873 // check connection, in case connect
878 sqlQuery.Form("select * from logbook where run=%d", run);
880 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
882 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
886 if (aResult->GetRowCount() == 0) {
887 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
892 if (aResult->GetRowCount() > 1) {
893 AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run));
898 TSQLRow* aRow = aResult->Next();
901 AliError(Form("Could not retrieve row for run %d. Skipping", run));
906 AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
908 for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
909 entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
911 UInt_t startTime = entry->GetStartTime();
912 UInt_t endTime = entry->GetEndTime();
914 if (!startTime || !endTime || startTime > endTime) {
916 Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d",
917 run, startTime, endTime));
930 //______________________________________________________________________________________________
931 Bool_t AliShuttle::TryToStoreAgain()
933 // Called in case the detector failed to store the object in Grid OCDB
934 // It tries to store the object again, if it does not find more recent and overlapping objects
935 // Calls underlying TryToStoreAgain(const char*) function twice, for OCDB and Reference storage.
937 AliInfo("Trying to store OCDB data again...");
938 Bool_t resultCDB = TryToStoreAgain(fgkMainCDB);
940 AliInfo("Trying to store reference data again...");
941 Bool_t resultRef = TryToStoreAgain(fgkMainRefStorage);
943 return resultCDB && resultRef;
946 //______________________________________________________________________________________________
947 Bool_t AliShuttle::TryToStoreAgain(TString& gridURI)
949 // Called by TryToStoreAgain(), performs actual storage retry
951 TObjArray* gridIds=0;
953 Bool_t result = kTRUE;
955 const char* type = 0;
957 if(gridURI == fgkMainCDB) {
959 backupURI = fgkLocalCDB;
960 } else if(gridURI == fgkMainRefStorage) {
962 backupURI = fgkLocalRefStorage;
964 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
968 AliCDBManager* man = AliCDBManager::Instance();
970 AliCDBStorage *gridSto = man->GetStorage(gridURI);
972 Log(fCurrentDetector.Data(),
973 Form("TryToStoreAgain - cannot activate main %s storage", type));
977 gridIds = gridSto->GetQueryCDBList();
979 // get objects previously stored in local CDB
980 AliCDBStorage *backupSto = man->GetStorage(backupURI);
981 AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
982 // Local objects were stored with current run as Grid version!
983 TList* localEntries = backupSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
984 localEntries->SetOwner(1);
986 // loop on local stored objects
987 TIter localIter(localEntries);
988 AliCDBEntry *aLocEntry = 0;
989 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
990 aLocEntry->SetOwner(1);
991 AliCDBId aLocId = aLocEntry->GetId();
992 aLocEntry->SetVersion(-1);
993 aLocEntry->SetSubVersion(-1);
995 // loop on Grid valid Id's
996 Bool_t store = kTRUE;
997 TIter gridIter(gridIds);
998 AliCDBId* aGridId = 0;
999 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
1000 // If local object is valid up to infinity we store it only if it is
1001 // the first unprocessed run!
1002 if (aLocId.GetLastRun() == AliCDBRunRange::Infinity())
1004 if (!fFirstUnprocessed[GetDetPos(fCurrentDetector)])
1006 Log(fCurrentDetector.Data(),
1007 ("TryToStoreAgain - This object has validity infinite but there are previous unprocessed runs!"));
1013 if(aGridId->GetPath() != aLocId.GetPath()) continue;
1014 // skip all objects valid up to infinity
1015 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
1016 // if we get here, it means there's already some more recent object stored on Grid!
1022 Log(fCurrentDetector.Data(),
1023 Form("TryToStoreAgain - A more recent object already exists in %s storage: <%s>",
1024 type, aGridId->ToString().Data()));
1025 // removing local filename...
1026 // TODO maybe it's better not to remove it, it was not copied to the Grid!
1028 backupSto->IdToFilename(aLocId, filename);
1029 AliInfo(Form("Removing local file %s", filename.Data()));
1030 gSystem->Exec(Form("rm %s",filename.Data()));
1034 // If we get here, the file can be stored!
1035 Bool_t storeOk = gridSto->Put(aLocEntry);
1037 Log(fCurrentDetector.Data(),
1038 Form("TryToStoreAgain - Object <%s> successfully put into %s storage",
1039 aLocId.ToString().Data(), type));
1041 // removing local filename...
1043 backupSto->IdToFilename(aLocId, filename);
1044 AliInfo(Form("Removing local file %s", filename.Data()));
1045 gSystem->Exec(Form("rm %s", filename.Data()));
1048 Log(fCurrentDetector.Data(),
1049 Form("TryToStoreAgain - Grid %s storage of object <%s> failed again",
1050 type, aLocId.ToString().Data()));
1054 localEntries->Clear();
1059 //______________________________________________________________________________________________
1060 Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* alias,
1061 TObjArray* valueSet)
1063 // Retrieve all "alias" data points from the DCS server
1064 // host, port: TSocket connection parameters
1065 // alias: name of the alias
1066 // valueSet: array of retrieved AliDCSValue's
1068 AliDCSClient client(host, port, fTimeout, fRetries);
1069 if (!client.IsConnected()) {
1073 Int_t result = client.GetAliasValues(alias,
1074 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
1077 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s",
1078 alias, AliDCSClient::GetErrorString(result)));
1080 if (result == AliDCSClient::fgkServerError) {
1081 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s",
1082 client.GetServerError().Data()));
1091 //______________________________________________________________________________________________
1092 const char* AliShuttle::GetFile(Int_t system, const char* detector,
1093 const char* id, const char* source)
1095 // Get calibration file from file exchange servers
1096 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
1100 return GetDAQFileName(detector, id, source);
1103 return GetDCSFileName(detector, id, source);
1106 return GetHLTFileName(detector, id, source);
1109 AliError(Form("No valid system index: %d",system));
1115 //______________________________________________________________________________________________
1116 TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
1118 // Get sources producing the condition file Id from file exchange servers
1119 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
1123 return GetDAQFileSources(detector, id);
1126 return GetDCSFileSources(detector, id);
1129 return GetHLTFileSources(detector, id);
1132 AliError(Form("No valid system index: %d",system));
1138 //______________________________________________________________________________________________
1139 Bool_t AliShuttle::Connect(Int_t system)
1141 // Connect to MySQL Server of the system's FES logbook
1142 // DAQ Logbook, Shuttle Logbook and DAQ FES Logbook are on the same host
1144 // check connection: if already connected return
1145 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
1147 TString lbHost, lbUser, lbPass;
1149 if (system < 3) // FES logbook servers
1151 lbHost = Form("mysql://%s", fConfig->GetFESlbHost(system));
1152 lbUser = fConfig->GetFESlbUser(system);
1153 lbPass = fConfig->GetFESlbPass(system);
1154 } else { // Run & Shuttle logbook servers
1155 // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
1156 lbHost = Form("mysql://%s", fConfig->GetDAQlbHost());
1157 lbUser = fConfig->GetDAQlbUser();
1158 lbPass = fConfig->GetDAQlbPass();
1161 fServer[system] = TSQLServer::Connect(lbHost.Data(), lbUser.Data(), lbPass.Data());
1162 if (!fServer[system] || !fServer[system]->IsConnected()) {
1165 AliError(Form("Can't establish connection to FES logbook for %s",
1166 AliShuttleInterface::GetSystemName(system)));
1168 AliError("Can't establish connection to Run logbook.");
1170 if(fServer[system]) delete fServer[system];
1175 // TODO in the configuration should the table name be there too?
1176 TSQLResult* aResult=0;
1179 aResult = fServer[kDAQ]->GetTables("REFSYSLOG");
1182 //aResult = fServer[kDCS]->GetTables("REFSYSLOG");
1185 //aResult = fServer[kHLT]->GetTables("REFSYSLOG");
1188 aResult = fServer[3]->GetTables("REFSYSLOG");
1196 //______________________________________________________________________________________________
1197 const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source)
1199 // Retrieves a file from the DAQ FES.
1200 // First queris the DAQ logbook_fs for the DAQ file name, using the run, detector, id and source info
1201 // then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
1202 // run: current run being processed (given by Logbook entry fLogbookEntry)
1203 // detector: the Preprocessor name
1204 // id: provided as a parameter by the Preprocessor
1205 // source: provided by the Preprocessor through GetFileSources function
1207 // check connection, in case connect
1210 Log(detector, "GetDAQFileName - Couldn't connect to DAQ Logbook");
1214 // Query preparation
1215 TString sqlQueryStart = "select filePath from logbook_fs where";
1216 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
1217 GetCurrentRun(), detector, id, source);
1218 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1220 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1223 TSQLResult* aResult = 0;
1224 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1226 Log(detector, Form("GetDAQFileName - Can't execute SQL query for: id = %s, source = %s",
1231 if(aResult->GetRowCount() == 0)
1234 Form("GetDAQFileName - No entry in FES table for: id = %s, source = %s",
1240 if (aResult->GetRowCount() > 1) {
1242 Form("GetDAQFileName - More than one entry in FES table for: id = %s, source = %s",
1248 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
1251 Log(detector, Form("GetDAQFileName - Empty set result from query: id = %s, source = %s",
1257 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
1262 AliDebug(2, Form("filePath = %s",filePath.Data()));
1264 // retrieved file is renamed to make it unique
1265 TString localFileName = Form("%s_%d_%s_%s.shuttle",
1266 detector, GetCurrentRun(), id, source);
1268 // file retrieval from DAQ FES
1269 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
1271 Log(detector, Form("GetDAQFileName - Copy of file %s from DAQ FES failed", filePath.Data()));
1274 AliInfo(Form("File %s copied from DAQ FES into %s/%s",
1275 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
1279 fFESCalled[kDAQ]=kTRUE;
1280 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
1281 fFESlist[kDAQ].Add(fileParams);
1283 return localFileName.Data();
1287 //______________________________________________________________________________________________
1288 Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName)
1291 // check temp directory: trying to cd to temp; if it does not exist, create it
1292 AliDebug(2, Form("Copy file %s from DAQ FES into folder %s and rename it as %s",
1293 daqFileName,fgkShuttleTempDir, localFileName));
1295 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
1297 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
1298 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1303 gSystem->FreeDirectory(dir);
1306 TString baseDAQFESFolder = "DAQ";
1307 TString command = Form("scp %s@%s:%s/%s %s/%s",
1308 fConfig->GetFESUser(kDAQ),
1309 fConfig->GetFESHost(kDAQ),
1310 baseDAQFESFolder.Data(),
1315 AliDebug(2, Form("%s",command.Data()));
1317 UInt_t nRetries = 0;
1318 UInt_t maxRetries = 3;
1320 // copy!! if successful TSystem::Exec returns 0
1321 while(nRetries++ < maxRetries) {
1322 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
1323 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
1330 //______________________________________________________________________________________________
1331 TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id)
1333 // Retrieves a file from the DCS FES.
1335 // check connection, in case connect
1337 Log(detector, "GetDAQFileSources - Couldn't connect to DAQ Logbook");
1341 // Query preparation
1342 TString sqlQueryStart = "select DAQsource from logbook_fs where";
1343 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
1344 GetCurrentRun(), detector, id);
1345 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1347 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1350 TSQLResult* aResult;
1351 aResult = fServer[kDAQ]->Query(sqlQuery);
1353 Log(detector, Form("GetDAQFileSources - Can't execute SQL query for id: %s", id));
1357 if (aResult->GetRowCount() == 0) {
1359 Form("GetDAQFileSources - No entry in FES table for id: %s", id));
1365 TList *list = new TList();
1368 while((aRow = aResult->Next())){
1370 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
1371 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
1372 list->Add(new TObjString(daqSource));
1381 //______________________________________________________________________________________________
1382 const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1383 // Retrieves a file from the DCS FES.
1385 return "You're in DCS";
1389 //______________________________________________________________________________________________
1390 TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
1391 // Retrieves a file from the DCS FES.
1397 //______________________________________________________________________________________________
1398 const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1399 // Retrieves a file from the HLT FES.
1401 return "You're in HLT";
1405 //______________________________________________________________________________________________
1406 TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1407 // Retrieves a file from the HLT FES.
1413 //______________________________________________________________________________________________
1414 Bool_t AliShuttle::UpdateDAQTable()
1416 // Update DAQ table filling time_processed field in all rows corresponding to current run and detector
1418 // check connection, in case connect
1420 Log(fCurrentDetector, "UpdateDAQTable - Couldn't connect to DAQ Logbook");
1424 TTimeStamp now; // now
1426 // Loop on FES list entries
1427 TIter iter(&fFESlist[kDAQ]);
1428 TObjString *aFESentry=0;
1429 while((aFESentry = dynamic_cast<TObjString*> (iter.Next()))){
1430 TString aFESentrystr = aFESentry->String();
1431 TObjArray *aFESarray = aFESentrystr.Tokenize("_!?!_");
1432 if(!aFESarray || aFESarray->GetEntries() != 2 ) {
1433 Log(fCurrentDetector, Form("UpdateDAQTable - error updating FES entry. Check string: <%s>",
1434 aFESentrystr.Data()));
1435 if(aFESarray) delete aFESarray;
1438 const char* fileId = ((TObjString*) aFESarray->At(0))->GetName();
1439 const char* daqSource = ((TObjString*) aFESarray->At(1))->GetName();
1440 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
1441 GetCurrentRun(), fCurrentDetector.Data(), fileId, daqSource);
1445 TString sqlQuery = Form("update logbook_fs set time_processed=%d %s", now.GetSec(), whereClause.Data());
1447 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1450 TSQLResult* aResult;
1451 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
1453 Log(fCurrentDetector, Form("UpdateDAQTable - Can't execute SQL query <%s>", sqlQuery.Data()));
1463 //______________________________________________________________________________________________
1464 Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
1466 // Update Shuttle logbook filling detector or shuttle_done column
1467 // ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
1469 // check connection, in case connect
1471 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
1475 TString detName(detector);
1477 if(detName == "shuttle_done") {
1478 setClause = "set shuttle_done=1";
1480 TString statusStr(status);
1481 if(statusStr.Contains("done", TString::kIgnoreCase) ||
1482 statusStr.Contains("failed", TString::kIgnoreCase)){
1483 setClause = Form("set %s=\"%s\"", detector, status);
1486 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
1492 TString whereClause = Form("where run=%d", GetCurrentRun());
1494 TString sqlQuery = Form("update logbook_shuttle %s %s",
1495 setClause.Data(), whereClause.Data());
1497 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1500 TSQLResult* aResult;
1501 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
1503 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
1511 //______________________________________________________________________________________________
1512 Int_t AliShuttle::GetCurrentRun() const
1514 // Get current run from logbook entry
1516 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
1519 //______________________________________________________________________________________________
1520 UInt_t AliShuttle::GetCurrentStartTime() const
1522 // get current start time
1524 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
1527 //______________________________________________________________________________________________
1528 UInt_t AliShuttle::GetCurrentEndTime() const
1530 // get current end time from logbook entry
1532 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
1535 //______________________________________________________________________________________________
1536 void AliShuttle::Log(const char* detector, const char* message)
1538 // Fill log string with a message
1540 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1542 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
1543 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1548 gSystem->FreeDirectory(dir);
1551 TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
1552 if(GetCurrentRun()>=0 ) toLog += Form("run %d - ", GetCurrentRun());
1553 toLog += Form("%s", message);
1555 AliInfo(toLog.Data());
1558 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1559 gSystem->ExpandPathName(fileName);
1562 logFile.open(fileName, ofstream::out | ofstream::app);
1564 if (!logFile.is_open()) {
1565 AliError(Form("Could not open file %s", fileName.Data()));
1569 logFile << toLog.Data() << "\n";
1574 //______________________________________________________________________________________________
1575 Bool_t AliShuttle::Collect(Int_t run)
1578 // Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
1579 // If a dedicated run is given this run is processed
1581 // In operational mode, this is the Shuttle function triggered by the EOR signal.
1585 Log("SHUTTLE","Collect - Shuttle called. Collecting conditions data for unprocessed runs");
1587 Log("SHUTTLE", Form("Collect - Shuttle called. Collecting conditions data for run %d", run));
1589 SetLastAction("Starting");
1591 TString whereClause("where shuttle_done=0");
1593 whereClause += Form(" and run=%d", run);
1595 TObjArray shuttleLogbookEntries;
1596 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries))
1598 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
1602 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
1603 fFirstUnprocessed[iDet] = kTRUE;
1607 // query Shuttle logbook for earlier runs, check if some detectors are unprocessed,
1608 // flag them into fFirstUnprocessed array
1609 TString whereClause(Form("where shuttle_done=0 and run < %d", run));
1610 TObjArray tmpLogbookEntries;
1611 if (!QueryShuttleLogbook(whereClause, tmpLogbookEntries))
1613 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
1617 TIter iter(&tmpLogbookEntries);
1618 AliShuttleLogbookEntry* anEntry = 0;
1619 while ((anEntry = dynamic_cast<AliShuttleLogbookEntry*> (iter.Next())))
1621 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
1623 if (anEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
1625 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
1626 anEntry->GetRun(), GetDetName(iDet)));
1627 fFirstUnprocessed[iDet] = kFALSE;
1635 if (!RetrieveConditionsData(shuttleLogbookEntries))
1637 Log("SHUTTLE", "Collect - Process of at least one run failed");
1644 //______________________________________________________________________________________________
1645 Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
1647 // Retrieve conditions data for all runs that aren't processed yet
1649 Bool_t hasError = kFALSE;
1651 TIter iter(&dateEntries);
1652 AliShuttleLogbookEntry* anEntry;
1654 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
1655 if (!Process(anEntry)){
1660 return hasError == kFALSE;
1663 //______________________________________________________________________________________________
1664 ULong_t AliShuttle::GetTimeOfLastAction() const
1668 fMonitoringMutex->Lock();
1670 tmp = fLastActionTime;
1672 fMonitoringMutex->UnLock();
1677 //______________________________________________________________________________________________
1678 const TString AliShuttle::GetLastAction() const
1680 // returns a string description of the last action
1684 fMonitoringMutex->Lock();
1688 fMonitoringMutex->UnLock();
1693 //______________________________________________________________________________________________
1694 void AliShuttle::SetLastAction(const char* action)
1696 // updates the monitoring variables
1698 fMonitoringMutex->Lock();
1700 fLastAction = action;
1701 fLastActionTime = time(0);
1703 fMonitoringMutex->UnLock();
1706 //______________________________________________________________________________________________
1707 const char* AliShuttle::GetRunParameter(const char* param)
1709 // returns run parameter read from DAQ logbook
1711 if(!fLogbookEntry) {
1712 AliError("No logbook entry!");
1716 return fLogbookEntry->GetRunParameter(param);