]> git.uio.no Git - u/mrichter/AliRoot.git/blob - SHUTTLE/AliShuttleTrigger.cxx
Generator for ISAJET events (A. Bogdanov)
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttleTrigger.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /*
17  $Log$
18  Revision 1.9  2006/08/08 14:19:29  jgrosseo
19  Update to shuttle classes (Alberto)
20
21  - Possibility to set the full object's path in the Preprocessor's and
22  Shuttle's  Store functions
23  - Possibility to extend the object's run validity in the same classes
24  ("startValidity" and "validityInfinite" parameters)
25  - Implementation of the StoreReferenceData function to store reference
26  data in a dedicated CDB storage.
27
28  Revision 1.8  2006/07/21 07:37:20  jgrosseo
29  last run is stored after each run
30
31  Revision 1.7  2006/07/20 09:54:40  jgrosseo
32  introducing status management: The processing per subdetector is divided into several steps,
33  after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
34  can keep track of the number of failures and skips further processing after a certain threshold is
35  exceeded. These thresholds can be configured in LDAP.
36
37  Revision 1.6  2006/07/19 10:09:55  jgrosseo
38  new configuration, accesst to DAQ FES (Alberto)
39
40  Revision 1.5  2006/07/10 13:01:41  jgrosseo
41  enhanced storing of last sucessfully processed run (alberto)
42
43  Revision 1.4  2006/07/04 14:59:57  jgrosseo
44  revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
45
46  Revision 1.3  2006/06/12 09:11:16  jgrosseo
47  coding conventions (Alberto)
48
49  Revision 1.2  2006/06/06 14:26:40  jgrosseo
50  o) removed files that were moved to STEER
51  o) shuttle updated to follow the new interface (Alberto)
52
53  Revision 1.1  2006/03/07 07:52:34  hristov
54  New version (B.Yordanov)
55
56  Revision 1.5  2005/11/21 09:03:48  byordano
57  one more print added
58
59  Revision 1.4  2005/11/20 10:12:37  byordano
60  comments added to AliShuttleTrigger
61
62  */
63
64
65 // 
66 // This class is to deal with DAQ LogBook and DAQ "end of run" notification.
67 // It has severeal two modes:
68 //      1) syncrhnized - Collect(), CollectNew() and CollectAll methods
69 //      2) asynchronized - Run() - starts listening for DAQ "end of run"
70 //              notification by DIM service.
71 //
72
73 #include "AliShuttleTrigger.h"
74
75 #include <TSQLServer.h>
76 #include <TSQLResult.h>
77 #include <TSQLRow.h>
78 #include <TObjArray.h>
79 #include <TSystem.h>
80
81 #include "AliLog.h"
82 #include "AliCDBManager.h"
83 #include "AliCDBStorage.h"
84 #include "AliCDBEntry.h"
85
86 #include "AliDCSValue.h"
87 #include "AliShuttleConfig.h"
88 #include "AliShuttle.h"
89 #include "DATENotifier.h"
90
91 ClassImp(TerminateSignalHandler)
92
93 //______________________________________________________________________
94 TerminateSignalHandler::TerminateSignalHandler(const TerminateSignalHandler& /*other*/):
95 TSignalHandler(), fTrigger()
96 {
97 // copy constructor (not implemented)
98
99 }
100
101 //______________________________________________________________________
102 TerminateSignalHandler &TerminateSignalHandler::operator=(const TerminateSignalHandler& /*other*/)
103 {
104 // assignment operator (not implemented)
105
106 return *this;
107 }
108
109 //______________________________________________________________________________________________
110 Bool_t TerminateSignalHandler::Notify() 
111 {
112 // Sentd terminate command to the Shuttle trigger
113
114         AliInfo("Terminate signal received ...");
115         fTrigger->Terminate();
116
117         return kTRUE;
118 }
119
120 //______________________________________________________________________________________________
121 //______________________________________________________________________________________________
122
123 ClassImp(AliShuttleTrigger)
124
125 //______________________________________________________________________________________________
126 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleConfig* config,
127                 UInt_t timeout, Int_t retries):
128         fConfig(config), fShuttle(NULL),
129         fNotified(kFALSE), fTerminate(kFALSE), fLastRun(0),
130         fMutex(), fCondition(&fMutex),
131         fQuitSignalHandler(this, kSigQuit),
132         fInterruptSignalHandler(this, kSigInterrupt)
133 {
134         //
135         // config - pointer to the AliShuttleConfig object which represents
136         // the configuration
137         // mainStorage - pointer to AliCDBStorage for the undelying CDBStorage
138         // localStorage (local) CDB storage to be used if mainStorage is unavailable
139         //
140
141         fShuttle = new AliShuttle(config, timeout, retries);
142
143         gSystem->AddSignalHandler(&fQuitSignalHandler);
144         gSystem->AddSignalHandler(&fInterruptSignalHandler);
145 }
146
147
148
149 //______________________________________________________________________
150 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleTrigger& /*other*/):
151         TObject(), fConfig(), fShuttle(NULL),
152         fNotified(kFALSE), fTerminate(kFALSE), fLastRun(0),
153         fMutex(), fCondition(&fMutex),
154         fQuitSignalHandler(this, kSigQuit),
155         fInterruptSignalHandler(this, kSigInterrupt)
156
157 {
158 // copy constructor (not implemented)
159
160 }
161
162 //______________________________________________________________________
163 AliShuttleTrigger &AliShuttleTrigger::operator=(const AliShuttleTrigger& /*other*/)
164 {
165 // assignment operator (not implemented)
166
167 return *this;
168 }
169
170
171
172
173
174 //______________________________________________________________________________________________
175 AliShuttleTrigger::~AliShuttleTrigger() 
176 {
177 // destructor
178
179         gSystem->RemoveSignalHandler(&fQuitSignalHandler);
180         gSystem->RemoveSignalHandler(&fInterruptSignalHandler);
181
182         delete fShuttle;
183 }
184
185 //______________________________________________________________________________________________
186 Bool_t AliShuttleTrigger::Notify() {
187         //
188         // Trigger CollectNew() methods in asynchronized (listen) mode.
189         // Usually called automaticly by DATENotifier on "end of run" 
190         // notification event.
191         //
192
193         fMutex.Lock();
194
195         fNotified = kTRUE;
196         fCondition.Signal();
197
198         fMutex.UnLock();
199
200         return kTRUE;
201 }
202
203 //______________________________________________________________________________________________
204 void AliShuttleTrigger::Terminate() {
205         //
206         // Stop triggers listen mode and exist from Run()
207         // Usually called automaticly by TerminateSignalHandler.
208         //
209
210         fTerminate = kTRUE;
211         fCondition.Signal();
212 }
213
214 //______________________________________________________________________________________________
215 void AliShuttleTrigger::Run() {
216         //
217         // AliShuttleTrigger main loop for asynchronized (listen) mode.
218         // It spawns DIM service listener and waits for DAQ "end of run"
219         // notification. Calls CollectNew() on notification.
220         //
221
222         fTerminate = kFALSE;
223
224         DATENotifier* notifier = new DATENotifier(this, "/DATE/LOGBOOK/UPDATE");
225
226         while (1) {
227         
228                 fMutex.Lock();
229
230                 while (!(fNotified || fTerminate)) {
231                         fCondition.Wait();
232                 }
233
234                 fNotified = kFALSE;
235                 
236                 fMutex.UnLock();
237
238                 if (fTerminate) {
239                         AliInfo("Terminated.");
240                         break;          
241                 }
242         
243                 CollectNew();
244         }
245
246         delete notifier;
247 }
248
249 //______________________________________________________________________________________________
250 Bool_t AliShuttleTrigger::RetrieveDATEEntries(const char* whereClause,
251                 TObjArray& entries)
252 {
253 // Retrieve start time and end time for all runs in the DAQ logbook
254 // that aren't processed yet
255
256         TString sqlQuery;
257         sqlQuery = Form("select run, time_start, time_end from logbook %s order by run",
258                 whereClause);
259
260         TSQLServer* aServer;
261         TString logbookHost=Form("mysql://%s", fConfig->GetDAQlbHost());
262
263         aServer = TSQLServer::Connect(logbookHost,
264                         fConfig->GetDAQlbUser(),
265                         fConfig->GetDAQlbPass());
266         if (!aServer) {
267                 AliError("Can't establish connection to DAQ log book DB!");
268                 return kFALSE;
269         }
270
271         aServer->GetTables("REFSYSLOG");
272
273         TSQLResult* aResult;
274         aResult = aServer->Query(sqlQuery);
275         if (!aResult) {
276                 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
277                 delete aServer;
278                 return kFALSE;
279         }
280
281         if (aResult->GetFieldCount() != 3) {
282                 AliError("Invalid SQL result field number!");
283                 delete aResult;
284                 delete aServer;
285                 return kFALSE;
286         }
287
288         TSQLRow* aRow;
289         while ((aRow = aResult->Next())) {
290                 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
291                 Int_t run = runString.Atoi();
292
293                 TString startTimeString(aRow->GetField(1),
294                                 aRow->GetFieldLength(1));
295                 Int_t startTime = startTimeString.Atoi();
296                 if (!startTime) {
297                         AliWarning(Form("Zero StartTime for run <%d>!", run));
298                         AliWarning("Going to skip this run!");
299                         continue;
300                 }
301
302                 TString endTimeString(aRow->GetField(2),
303                                 aRow->GetFieldLength(2));
304                 Int_t endTime = endTimeString.Atoi();
305                 if (!endTime) {
306                         AliWarning(Form("Zero EndTime for run <%d>!", run));
307                         AliWarning("Going to skip this run!");
308                         continue;
309                 }
310
311                 if (startTime > endTime) {
312                         AliWarning(Form("StartTime bigger than EndTime for run <%d>", run));
313                         AliWarning("Going to skip this run!");
314                         continue;
315                 }
316
317                 entries.AddLast(new AliShuttleTriggerDATEEntry(run, startTime, endTime));
318                 delete aRow;
319         }
320
321         delete aResult;
322
323         aServer->Close();
324         delete aServer;
325
326         entries.SetOwner(1);
327
328         return kTRUE;
329 }
330
331 //______________________________________________________________________________________________
332 Bool_t AliShuttleTrigger::RetrieveConditionsData(const TObjArray& dateEntries, Bool_t updateLastRun)
333 {
334   // Retrieve conditions data for all runs that aren't processed yet
335
336   Bool_t hasError = kFALSE;
337
338   TIter iter(&dateEntries);
339   AliShuttleTriggerDATEEntry* anEntry;
340
341   while ((anEntry = (AliShuttleTriggerDATEEntry*) iter.Next()))
342   {
343     if (!fShuttle->Process(anEntry->GetRun(),
344         anEntry->GetStartTime(),
345         anEntry->GetEndTime()))
346     {
347         hasError = kTRUE;
348     }
349
350     if (!hasError && updateLastRun && fLastRun < anEntry->GetRun())
351     {
352       fLastRun = anEntry->GetRun();
353       WriteLastRun();
354     }
355   }
356
357   return hasError == kFALSE;
358 }
359
360 //______________________________________________________________________________________________
361 Bool_t AliShuttleTrigger::ReadLastRun()
362 {
363   // reads the last processed run from local CDB
364
365   AliCDBEntry* cdbEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
366         ->Get("/SHUTTLE/SYSTEM/LASTRUN", 0);
367
368   if (cdbEntry)
369   {
370     TObject* anObject = cdbEntry->GetObject();
371     if (anObject == NULL || anObject->IsA() != AliDCSValue::Class())
372     {
373       AliError("Invalid last run object stored to CDB!");
374       return kFALSE;
375     }
376     AliDCSValue* dcsValue = (AliDCSValue*) anObject;
377     fLastRun = dcsValue->GetInt();
378
379     delete cdbEntry;
380   }
381   else
382   {
383     AliFatal("No last run number stored. Please set first. Aborting");
384     return kFALSE;
385   }
386
387   AliInfo(Form("Last run number <%d>", fLastRun));
388
389   return kTRUE;
390 }
391
392 //______________________________________________________________________________________________
393 Bool_t AliShuttleTrigger::WriteLastRun()
394 {
395   // writes the last succesfully processed run to local CDB
396
397   AliDCSValue lastRunObj(fLastRun, 0);
398   AliCDBMetaData metaData;
399   AliCDBId cdbID(AliCDBPath("SHUTTLE", "SYSTEM", "LASTRUN"), 0, 0);
400
401   UInt_t result = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
402       ->Put(&lastRunObj, cdbID, &metaData);
403
404   if (!result) {
405     AliError("Can't store last run to CDB!");
406     return kFALSE;
407   }
408
409   return kTRUE;
410 }
411
412 //______________________________________________________________________________________________
413 Bool_t AliShuttleTrigger::SetNewLastRun(Int_t run)
414 {
415   // sets a new run manually, use with caution!
416
417   fShuttle->Log("SHUTTLE", Form("Setting last run manually to %d", run));
418
419   fLastRun = run;
420   return WriteLastRun();
421 }
422
423 //______________________________________________________________________________________________
424 Bool_t AliShuttleTrigger::Collect(Int_t run)
425 {
426         //
427         // Collects conditions date for the given run.
428         //
429
430         AliInfo(Form("Collecting conditions data for run <%d> ...", run));
431
432         TString whereClause("where run = ");
433         whereClause += run;
434
435         TObjArray dateEntries;
436         if (!RetrieveDATEEntries(whereClause, dateEntries)) {
437                 AliError("Can't retrieve entries from DAQ log book.");
438                 return kFALSE;
439         }
440
441         if (!dateEntries.GetEntriesFast()) {
442                 AliError(Form("There isn't entry for run <%d> in DAQ log book!",
443                         run));
444                 return kFALSE;
445         }
446
447         if (dateEntries.GetEntriesFast() > 1) {
448                 AliError(Form("There is more than one entry for run <%d> in DAQ log book", run));
449                 return kFALSE;
450         }
451
452         if (!RetrieveConditionsData(dateEntries, kFALSE)) {
453                 AliError("An error occured during conditions data retrieval!");
454                 return kFALSE;
455         }
456
457         return kTRUE;
458 }
459
460 //______________________________________________________________________________________________
461 Bool_t AliShuttleTrigger::CollectNew()
462 {
463         //
464         // Collects conditions data for all new run written to DAQ LogBook.
465         //
466
467         AliInfo("Collecting conditions data for new runs ...");
468
469   if (!ReadLastRun())
470   {
471     AliError("Retrieving of last run failed");
472     return kFALSE;
473   }
474
475         TString whereClause("where run > ");
476         whereClause += fLastRun;
477
478         TObjArray dateEntries;
479         if (!RetrieveDATEEntries(whereClause, dateEntries)) {
480                 AliError("Can't retrieve entries from DAQ log book.");
481                 return kFALSE;
482         }
483
484         if (!RetrieveConditionsData(dateEntries, kTRUE)) {
485                 AliError("Process of at least one run failed!");
486                 // return kFALSE;
487         }
488
489         return kTRUE;
490 }
491
492 //______________________________________________________________________________________________
493 Bool_t AliShuttleTrigger::CollectAll()
494 {
495         //
496         // Collects conditions data for all run written in DAQ LogBook.
497         //
498
499   if (!ReadLastRun())
500   {
501     AliError("Retrieving of last run failed");
502     return kFALSE;
503   }
504
505         AliInfo("Collecting conditions data for all runs ...");
506
507         TObjArray dateEntries;
508         if (!RetrieveDATEEntries("", dateEntries)) {
509                 AliError("Can't retrieve entries from DAQ log book.");
510                 return kFALSE;
511         }
512
513         if (!RetrieveConditionsData(dateEntries, kTRUE)) {
514                 AliError("An error occured during conditions data retrieval!");
515                 return kFALSE;
516         }
517
518         return kTRUE;
519 }
520