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.7 2006/07/20 09:54:40 jgrosseo
19 introducing status management: The processing per subdetector is divided into several steps,
20 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
21 can keep track of the number of failures and skips further processing after a certain threshold is
22 exceeded. These thresholds can be configured in LDAP.
24 Revision 1.6 2006/07/19 10:09:55 jgrosseo
25 new configuration, accesst to DAQ FES (Alberto)
27 Revision 1.5 2006/07/10 13:01:41 jgrosseo
28 enhanced storing of last sucessfully processed run (alberto)
30 Revision 1.4 2006/07/04 14:59:57 jgrosseo
31 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
33 Revision 1.3 2006/06/12 09:11:16 jgrosseo
34 coding conventions (Alberto)
36 Revision 1.2 2006/06/06 14:26:40 jgrosseo
37 o) removed files that were moved to STEER
38 o) shuttle updated to follow the new interface (Alberto)
40 Revision 1.1 2006/03/07 07:52:34 hristov
41 New version (B.Yordanov)
43 Revision 1.5 2005/11/21 09:03:48 byordano
46 Revision 1.4 2005/11/20 10:12:37 byordano
47 comments added to AliShuttleTrigger
53 // This class is to deal with DAQ LogBook and DAQ "end of run" notification.
54 // It has severeal two modes:
55 // 1) syncrhnized - Collect(), CollectNew() and CollectAll methods
56 // 2) asynchronized - Run() - starts listening for DAQ "end of run"
57 // notification by DIM service.
60 #include "AliShuttleTrigger.h"
62 #include <TSQLServer.h>
63 #include <TSQLResult.h>
65 #include <TObjArray.h>
69 #include "AliCDBManager.h"
70 #include "AliCDBStorage.h"
71 #include "AliCDBEntry.h"
73 #include "AliDCSValue.h"
74 #include "AliShuttleConfig.h"
75 #include "AliShuttle.h"
76 #include "DATENotifier.h"
78 ClassImp(TerminateSignalHandler)
80 //______________________________________________________________________
81 TerminateSignalHandler::TerminateSignalHandler(const TerminateSignalHandler& /*other*/):
84 // copy constructor (not implemented)
88 //______________________________________________________________________
89 TerminateSignalHandler &TerminateSignalHandler::operator=(const TerminateSignalHandler& /*other*/)
91 // assignment operator (not implemented)
96 //______________________________________________________________________________________________
97 Bool_t TerminateSignalHandler::Notify()
99 // Sentd terminate command to the Shuttle trigger
101 AliInfo("Terminate signal received ...");
102 fTrigger->Terminate();
107 //______________________________________________________________________________________________
108 //______________________________________________________________________________________________
110 ClassImp(AliShuttleTrigger)
112 //______________________________________________________________________________________________
113 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleConfig* config,
114 UInt_t timeout, Int_t retries):
115 fConfig(config), fShuttle(NULL),
116 fNotified(kFALSE), fTerminate(kFALSE), fLastRun(0), fCondition(&fMutex),
117 fQuitSignalHandler(this, kSigQuit),
118 fInterruptSignalHandler(this, kSigInterrupt)
121 // config - pointer to the AliShuttleConfig object which represents
123 // mainStorage - pointer to AliCDBStorage for the undelying CDBStorage
124 // localStorage (local) CDB storage to be used if mainStorage is unavailable
127 fShuttle = new AliShuttle(config, timeout, retries);
129 gSystem->AddSignalHandler(&fQuitSignalHandler);
130 gSystem->AddSignalHandler(&fInterruptSignalHandler);
135 //______________________________________________________________________
136 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleTrigger& /*other*/):
139 // copy constructor (not implemented)
143 //______________________________________________________________________
144 AliShuttleTrigger &AliShuttleTrigger::operator=(const AliShuttleTrigger& /*other*/)
146 // assignment operator (not implemented)
155 //______________________________________________________________________________________________
156 AliShuttleTrigger::~AliShuttleTrigger()
160 gSystem->RemoveSignalHandler(&fQuitSignalHandler);
161 gSystem->RemoveSignalHandler(&fInterruptSignalHandler);
166 //______________________________________________________________________________________________
167 Bool_t AliShuttleTrigger::Notify() {
169 // Trigger CollectNew() methods in asynchronized (listen) mode.
170 // Usually called automaticly by DATENotifier on "end of run"
171 // notification event.
184 //______________________________________________________________________________________________
185 void AliShuttleTrigger::Terminate() {
187 // Stop triggers listen mode and exist from Run()
188 // Usually called automaticly by TerminateSignalHandler.
195 //______________________________________________________________________________________________
196 void AliShuttleTrigger::Run() {
198 // AliShuttleTrigger main loop for asynchronized (listen) mode.
199 // It spawns DIM service listener and waits for DAQ "end of run"
200 // notification. Calls CollectNew() on notification.
205 DATENotifier* notifier = new DATENotifier(this, "/DATE/LOGBOOK/UPDATE");
211 while (!(fNotified || fTerminate)) {
220 AliInfo("Terminated.");
230 //______________________________________________________________________________________________
231 Bool_t AliShuttleTrigger::RetrieveDATEEntries(const char* whereClause,
234 // Retrieve start time and end time for all runs in the DAQ logbook
235 // that aren't processed yet
238 sqlQuery = Form("select run, time_start, time_end from logbook %s order by run",
242 TString logbookHost=Form("mysql://%s", fConfig->GetDAQlbHost());
244 aServer = TSQLServer::Connect(logbookHost,
245 fConfig->GetDAQlbUser(),
246 fConfig->GetDAQlbPass());
248 AliError("Can't establish connection to DAQ log book DB!");
252 aServer->GetTables("REFSYSLOG");
255 aResult = aServer->Query(sqlQuery);
257 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
262 if (aResult->GetFieldCount() != 3) {
263 AliError("Invalid SQL result field number!");
270 while ((aRow = aResult->Next())) {
271 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
272 Int_t run = runString.Atoi();
274 TString startTimeString(aRow->GetField(1),
275 aRow->GetFieldLength(1));
276 Int_t startTime = startTimeString.Atoi();
278 AliWarning(Form("Zero StartTime for run <%d>!", run));
279 AliWarning("Going to skip this run!");
283 TString endTimeString(aRow->GetField(2),
284 aRow->GetFieldLength(2));
285 Int_t endTime = endTimeString.Atoi();
287 AliWarning(Form("Zero EndTime for run <%d>!", run));
288 AliWarning("Going to skip this run!");
292 if (startTime > endTime) {
293 AliWarning(Form("StartTime bigger than EndTime for run <%d>", run));
294 AliWarning("Going to skip this run!");
298 entries.AddLast(new AliShuttleTriggerDATEEntry(run, startTime, endTime));
312 //______________________________________________________________________________________________
313 Bool_t AliShuttleTrigger::RetrieveConditionsData(const TObjArray& dateEntries, Bool_t updateLastRun)
315 // Retrieve conditions data for all runs that aren't processed yet
317 Bool_t hasError = kFALSE;
319 TIter iter(&dateEntries);
320 AliShuttleTriggerDATEEntry* anEntry;
322 while ((anEntry = (AliShuttleTriggerDATEEntry*) iter.Next()))
324 if (!fShuttle->Process(anEntry->GetRun(),
325 anEntry->GetStartTime(),
326 anEntry->GetEndTime()))
331 if (!hasError && updateLastRun && fLastRun < anEntry->GetRun())
333 fLastRun = anEntry->GetRun();
338 return hasError == kFALSE;
341 //______________________________________________________________________________________________
342 Bool_t AliShuttleTrigger::ReadLastRun()
344 // reads the last processed run from local CDB
346 AliCDBEntry* cdbEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
347 ->Get("/SHUTTLE/SYSTEM/LASTRUN", 0);
351 TObject* anObject = cdbEntry->GetObject();
352 if (anObject == NULL || anObject->IsA() != AliDCSValue::Class())
354 AliError("Invalid last run object stored to CDB!");
357 AliDCSValue* dcsValue = (AliDCSValue*) anObject;
358 fLastRun = dcsValue->GetInt();
364 AliFatal("No last run number stored. Please set first. Aborting");
368 AliInfo(Form("Last run number <%d>", fLastRun));
373 //______________________________________________________________________________________________
374 Bool_t AliShuttleTrigger::WriteLastRun()
376 // writes the last succesfully processed run to local CDB
378 AliDCSValue lastRunObj(fLastRun, 0);
379 AliCDBMetaData metaData;
380 AliCDBId cdbID(AliCDBPath("SHUTTLE", "SYSTEM", "LASTRUN"), 0, 0);
382 UInt_t result = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
383 ->Put(&lastRunObj, cdbID, &metaData);
386 AliError("Can't store last run to CDB!");
393 //______________________________________________________________________________________________
394 Bool_t AliShuttleTrigger::SetNewLastRun(Int_t run)
396 // sets a new run manually, use with caution!
398 fShuttle->Log("SHUTTLE", Form("Setting last run manually to %d", run));
401 return WriteLastRun();
404 //______________________________________________________________________________________________
405 Bool_t AliShuttleTrigger::Collect(Int_t run)
408 // Collects conditions date for the given run.
411 AliInfo(Form("Collecting conditions data for run <%d> ...", run));
413 TString whereClause("where run = ");
416 TObjArray dateEntries;
417 if (!RetrieveDATEEntries(whereClause, dateEntries)) {
418 AliError("Can't retrieve entries from DAQ log book.");
422 if (!dateEntries.GetEntriesFast()) {
423 AliError(Form("There isn't entry for run <%d> in DAQ log book!",
428 if (dateEntries.GetEntriesFast() > 1) {
429 AliError(Form("There is more than one entry for run <%d> in DAQ log book", run));
433 if (!RetrieveConditionsData(dateEntries, kFALSE)) {
434 AliError("An error occured during conditions data retrieval!");
441 //______________________________________________________________________________________________
442 Bool_t AliShuttleTrigger::CollectNew()
445 // Collects conditions data for all new run written to DAQ LogBook.
448 AliInfo("Collecting conditions data for new runs ...");
452 AliError("Retrieving of last run failed");
456 TString whereClause("where run > ");
457 whereClause += fLastRun;
459 TObjArray dateEntries;
460 if (!RetrieveDATEEntries(whereClause, dateEntries)) {
461 AliError("Can't retrieve entries from DAQ log book.");
465 if (!RetrieveConditionsData(dateEntries, kTRUE)) {
466 AliError("Process of at least one run failed!");
473 //______________________________________________________________________________________________
474 Bool_t AliShuttleTrigger::CollectAll()
477 // Collects conditions data for all run written in DAQ LogBook.
482 AliError("Retrieving of last run failed");
486 AliInfo("Collecting conditions data for all runs ...");
488 TObjArray dateEntries;
489 if (!RetrieveDATEEntries("", dateEntries)) {
490 AliError("Can't retrieve entries from DAQ log book.");
494 if (!RetrieveConditionsData(dateEntries, kTRUE)) {
495 AliError("An error occured during conditions data retrieval!");